Commit 130435a17a

Žiga Željko <ziga.zeljko@gmail.com>
2020-04-27 22:52:42
Split AES struct into AESEncrypt and AESDecrypt
1 parent 45f4a11
Changed files (1)
lib
std
crypto
lib/std/crypto/aes.zig
@@ -130,21 +130,55 @@ fn AES(comptime keysize: usize) type {
     return struct {
         const Self = @This();
 
+        pub const Encrypt = AESEncrypt(keysize);
+        pub const Decrypt = AESDecrypt(keysize);
+
         const nn = (keysize / 8) + 28;
-        enc: [nn]u32,
-        dec: [nn]u32,
+        enc: Encrypt,
+        dec: Decrypt,
 
         pub fn init(key: [keysize / 8]u8) Self {
             var ctx: Self = undefined;
-            expandKey(&key, ctx.enc[0..], ctx.dec[0..]);
+            ctx.enc = Encrypt.init(key);
+            ctx.dec = ctx.enc.toDecrypt();
             return ctx;
         }
 
         pub fn encrypt(ctx: Self, dst: []u8, src: []const u8) void {
-            encryptBlock(ctx.enc[0..], dst, src);
+            ctx.enc.encrypt(dst, src);
         }
         pub fn decrypt(ctx: Self, dst: []u8, src: []const u8) void {
-            decryptBlock(ctx.dec[0..], dst, src);
+            ctx.dec.decrypt(dst, src);
+        }
+        pub fn ctr(ctx: Self, dst: []u8, src: []const u8, iv: [16]u8) void {
+            ctx.enc.ctr(dst, src, iv);
+        }
+    };
+}
+
+fn AESEncrypt(comptime keysize: usize) type {
+    return struct {
+        const Self = @This();
+
+        const Decrypt = AESDecrypt(keysize);
+
+        const nn = (keysize / 8) + 28;
+        enc: [nn]u32,
+
+        pub fn init(key: [keysize / 8]u8) Self {
+            var ctx: Self = undefined;
+            expandKeyEncrypt(&key, ctx.enc[0..]);
+            return ctx;
+        }
+
+        pub fn toDecrypt(ctx: Self) Decrypt {
+            var dec: Decrypt = undefined;
+            expandKeyDecrypt(ctx.enc[0..], dec.dec[0..]);
+            return dec;
+        }
+
+        pub fn encrypt(ctx: Self, dst: []u8, src: []const u8) void {
+            encryptBlock(ctx.enc[0..], dst, src);
         }
         pub fn ctr(ctx: Self, dst: []u8, src: []const u8, iv: [16]u8) void {
             std.debug.assert(dst.len >= src.len);
@@ -163,6 +197,27 @@ fn AES(comptime keysize: usize) type {
     };
 }
 
+fn AESDecrypt(comptime keysize: usize) type {
+    return struct {
+        const Self = @This();
+
+        const nn = (keysize / 8) + 28;
+        dec: [nn]u32,
+
+        pub fn init(key: [keysize / 8]u8) Self {
+            var ctx: Self = undefined;
+            var enc: [nn]u32 = undefined;
+            expandKeyEncrypt(key[0..], enc[0..]);
+            expandKeyDecrypt(enc[0..], ctx.dec[0..]);
+            return ctx;
+        }
+
+        pub fn decrypt(ctx: Self, dst: []u8, src: []const u8) void {
+            decryptBlock(ctx.dec[0..], dst, src);
+        }
+    };
+}
+
 test "ctr" {
     // NIST SP 800-38A pp 55-58
     {
@@ -247,7 +302,7 @@ test "decrypt" {
 }
 
 // Key expansion algorithm. See FIPS-197, Figure 11.
-fn expandKey(key: []const u8, enc: []u32, dec: []u32) void {
+fn expandKeyEncrypt(key: []const u8, enc: []u32) void {
     var i: usize = 0;
     var nk = key.len / 4;
     while (i < nk) : (i += 1) {
@@ -262,9 +317,11 @@ fn expandKey(key: []const u8, enc: []u32, dec: []u32) void {
         }
         enc[i] = enc[i - nk] ^ t;
     }
+}
 
+fn expandKeyDecrypt(enc: []const u32, dec: []u32) void {
+    var i: usize = 0;
     var n = enc.len;
-    i = 0;
     while (i < n) : (i += 4) {
         var ei = n - i - 4;
         var j: usize = 0;
@@ -308,7 +365,8 @@ test "expand key" {
     };
     var enc: [exp_enc.len]u32 = undefined;
     var dec: [exp_dec.len]u32 = undefined;
-    expandKey(key[0..], enc[0..], dec[0..]);
+    expandKeyEncrypt(key[0..], enc[0..]);
+    expandKeyDecrypt(enc[0..], dec[0..]);
     testing.expectEqualSlices(u32, exp_enc[0..], enc[0..]);
     testing.expectEqualSlices(u32, exp_dec[0..], dec[0..]);
 }