authorgravatar for ziga.zeljko@gmail.comŽiga Željko <ziga.zeljko@gmail.com> 2020-04-28 04:52:42+08:00
committergravatar for ziga.zeljko@gmail.comŽiga Željko <ziga.zeljko@gmail.com> 2020-04-28 04:52:42+08:00
log130435a17a14faba805a41da2d9ddb24c01c396c
tree1235b67177658fe021c851b103ba62edb6c15899
parent45f4a1124f80219d9237d6809ecb919a8896723a

Split AES struct into AESEncrypt and AESDecrypt


1 files changed, 66 insertions(+), 8 deletions(-)

lib/std/crypto/aes.zig+66-8
...@@ -130,21 +130,55 @@ fn AES(comptime keysize: usize) type {...@@ -130,21 +130,55 @@ fn AES(comptime keysize: usize) type {
130 return struct {130 return struct {
131 const Self = @This();131 const Self = @This();
132132
133 pub const Encrypt = AESEncrypt(keysize);
134 pub const Decrypt = AESDecrypt(keysize);
135
133 const nn = (keysize / 8) + 28;136 const nn = (keysize / 8) + 28;
134 enc: [nn]u32,137 enc: Encrypt,
135 dec: [nn]u32,138 dec: Decrypt,
136139
137 pub fn init(key: [keysize / 8]u8) Self {140 pub fn init(key: [keysize / 8]u8) Self {
138 var ctx: Self = undefined;141 var ctx: Self = undefined;
139 expandKey(&key, ctx.enc[0..], ctx.dec[0..]);142 ctx.enc = Encrypt.init(key);
143 ctx.dec = ctx.enc.toDecrypt();
140 return ctx;144 return ctx;
141 }145 }
142146
143 pub fn encrypt(ctx: Self, dst: []u8, src: []const u8) void {147 pub fn encrypt(ctx: Self, dst: []u8, src: []const u8) void {
144 encryptBlock(ctx.enc[0..], dst, src);148 ctx.enc.encrypt(dst, src);
145 }149 }
146 pub fn decrypt(ctx: Self, dst: []u8, src: []const u8) void {150 pub fn decrypt(ctx: Self, dst: []u8, src: []const u8) void {
147 decryptBlock(ctx.dec[0..], dst, src);151 ctx.dec.decrypt(dst, src);
152 }
153 pub fn ctr(ctx: Self, dst: []u8, src: []const u8, iv: [16]u8) void {
154 ctx.enc.ctr(dst, src, iv);
155 }
156 };
157}
158
159fn AESEncrypt(comptime keysize: usize) type {
160 return struct {
161 const Self = @This();
162
163 const Decrypt = AESDecrypt(keysize);
164
165 const nn = (keysize / 8) + 28;
166 enc: [nn]u32,
167
168 pub fn init(key: [keysize / 8]u8) Self {
169 var ctx: Self = undefined;
170 expandKeyEncrypt(&key, ctx.enc[0..]);
171 return ctx;
172 }
173
174 pub fn toDecrypt(ctx: Self) Decrypt {
175 var dec: Decrypt = undefined;
176 expandKeyDecrypt(ctx.enc[0..], dec.dec[0..]);
177 return dec;
178 }
179
180 pub fn encrypt(ctx: Self, dst: []u8, src: []const u8) void {
181 encryptBlock(ctx.enc[0..], dst, src);
148 }182 }
149 pub fn ctr(ctx: Self, dst: []u8, src: []const u8, iv: [16]u8) void {183 pub fn ctr(ctx: Self, dst: []u8, src: []const u8, iv: [16]u8) void {
150 std.debug.assert(dst.len >= src.len);184 std.debug.assert(dst.len >= src.len);
...@@ -163,6 +197,27 @@ fn AES(comptime keysize: usize) type {...@@ -163,6 +197,27 @@ fn AES(comptime keysize: usize) type {
163 };197 };
164}198}
165199
200fn AESDecrypt(comptime keysize: usize) type {
201 return struct {
202 const Self = @This();
203
204 const nn = (keysize / 8) + 28;
205 dec: [nn]u32,
206
207 pub fn init(key: [keysize / 8]u8) Self {
208 var ctx: Self = undefined;
209 var enc: [nn]u32 = undefined;
210 expandKeyEncrypt(key[0..], enc[0..]);
211 expandKeyDecrypt(enc[0..], ctx.dec[0..]);
212 return ctx;
213 }
214
215 pub fn decrypt(ctx: Self, dst: []u8, src: []const u8) void {
216 decryptBlock(ctx.dec[0..], dst, src);
217 }
218 };
219}
220
166test "ctr" {221test "ctr" {
167 // NIST SP 800-38A pp 55-58222 // NIST SP 800-38A pp 55-58
168 {223 {
...@@ -247,7 +302,7 @@ test "decrypt" {...@@ -247,7 +302,7 @@ test "decrypt" {
247}302}
248303
249// Key expansion algorithm. See FIPS-197, Figure 11.304// Key expansion algorithm. See FIPS-197, Figure 11.
250fn expandKey(key: []const u8, enc: []u32, dec: []u32) void {305fn expandKeyEncrypt(key: []const u8, enc: []u32) void {
251 var i: usize = 0;306 var i: usize = 0;
252 var nk = key.len / 4;307 var nk = key.len / 4;
253 while (i < nk) : (i += 1) {308 while (i < nk) : (i += 1) {
...@@ -262,9 +317,11 @@ fn expandKey(key: []const u8, enc: []u32, dec: []u32) void {...@@ -262,9 +317,11 @@ fn expandKey(key: []const u8, enc: []u32, dec: []u32) void {
262 }317 }
263 enc[i] = enc[i - nk] ^ t;318 enc[i] = enc[i - nk] ^ t;
264 }319 }
320}
265321
322fn expandKeyDecrypt(enc: []const u32, dec: []u32) void {
323 var i: usize = 0;
266 var n = enc.len;324 var n = enc.len;
267 i = 0;
268 while (i < n) : (i += 4) {325 while (i < n) : (i += 4) {
269 var ei = n - i - 4;326 var ei = n - i - 4;
270 var j: usize = 0;327 var j: usize = 0;
...@@ -308,7 +365,8 @@ test "expand key" {...@@ -308,7 +365,8 @@ test "expand key" {
308 };365 };
309 var enc: [exp_enc.len]u32 = undefined;366 var enc: [exp_enc.len]u32 = undefined;
310 var dec: [exp_dec.len]u32 = undefined;367 var dec: [exp_dec.len]u32 = undefined;
311 expandKey(key[0..], enc[0..], dec[0..]);368 expandKeyEncrypt(key[0..], enc[0..]);
369 expandKeyDecrypt(enc[0..], dec[0..]);
312 testing.expectEqualSlices(u32, exp_enc[0..], enc[0..]);370 testing.expectEqualSlices(u32, exp_enc[0..], enc[0..]);
313 testing.expectEqualSlices(u32, exp_dec[0..], dec[0..]);371 testing.expectEqualSlices(u32, exp_dec[0..], dec[0..]);
314}372}