Commit 4194714965

Frank Denis <github@pureftpd.org>
2020-09-29 13:09:11
Don't unroll the gimli permutation on release-small
1 parent 613f8fe
Changed files (1)
lib
std
crypto
lib/std/crypto/gimli.zig
@@ -38,7 +38,7 @@ pub const State = struct {
         return mem.sliceAsBytes(self.data[0..]);
     }
 
-    pub fn permute(self: *Self) void {
+    fn _permute_unrolled(self: *Self) void {
         const state = &self.data;
         comptime var round = @as(u32, 24);
         inline while (round > 0) : (round -= 1) {
@@ -66,6 +66,42 @@ pub const State = struct {
         }
     }
 
+    fn _permute_small(self: *Self) void {
+        const state = &self.data;
+        var round = @as(u32, 24);
+        while (round > 0) : (round -= 1) {
+            var column = @as(usize, 0);
+            while (column < 4) : (column += 1) {
+                const x = math.rotl(u32, state[column], 24);
+                const y = math.rotl(u32, state[4 + column], 9);
+                const z = state[8 + column];
+                state[8 + column] = ((x ^ (z << 1)) ^ ((y & z) << 2));
+                state[4 + column] = ((y ^ x) ^ ((x | z) << 1));
+                state[column] = ((z ^ y) ^ ((x & y) << 3));
+            }
+            switch (round & 3) {
+                0 => {
+                    mem.swap(u32, &state[0], &state[1]);
+                    mem.swap(u32, &state[2], &state[3]);
+                    state[0] ^= round | 0x9e377900;
+                },
+                2 => {
+                    mem.swap(u32, &state[0], &state[2]);
+                    mem.swap(u32, &state[1], &state[3]);
+                },
+                else => {},
+            }
+        }
+    }
+
+    pub fn permute(self: *Self) void {
+        if (std.builtin.mode == .ReleaseSmall) {
+            self._permute_small();
+        } else {
+            self._permute_unrolled();
+        }
+    }
+
     pub fn squeeze(self: *Self, out: []u8) void {
         var i = @as(usize, 0);
         while (i + RATE <= out.len) : (i += RATE) {