| ... | ... | @@ -38,7 +38,7 @@ pub const State = struct { |
| 38 | 38 | return mem.sliceAsBytes(self.data[0..]); |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | | pub fn permute(self: *Self) void { |
| 41 | fn _permute_unrolled(self: *Self) void { |
| 42 | 42 | const state = &self.data; |
| 43 | 43 | comptime var round = @as(u32, 24); |
| 44 | 44 | inline while (round > 0) : (round -= 1) { |
| ... | ... | @@ -66,6 +66,42 @@ pub const State = struct { |
| 66 | 66 | } |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | fn _permute_small(self: *Self) void { |
| 70 | const state = &self.data; |
| 71 | var round = @as(u32, 24); |
| 72 | while (round > 0) : (round -= 1) { |
| 73 | var column = @as(usize, 0); |
| 74 | while (column < 4) : (column += 1) { |
| 75 | const x = math.rotl(u32, state[column], 24); |
| 76 | const y = math.rotl(u32, state[4 + column], 9); |
| 77 | const z = state[8 + column]; |
| 78 | state[8 + column] = ((x ^ (z << 1)) ^ ((y & z) << 2)); |
| 79 | state[4 + column] = ((y ^ x) ^ ((x | z) << 1)); |
| 80 | state[column] = ((z ^ y) ^ ((x & y) << 3)); |
| 81 | } |
| 82 | switch (round & 3) { |
| 83 | 0 => { |
| 84 | mem.swap(u32, &state[0], &state[1]); |
| 85 | mem.swap(u32, &state[2], &state[3]); |
| 86 | state[0] ^= round | 0x9e377900; |
| 87 | }, |
| 88 | 2 => { |
| 89 | mem.swap(u32, &state[0], &state[2]); |
| 90 | mem.swap(u32, &state[1], &state[3]); |
| 91 | }, |
| 92 | else => {}, |
| 93 | } |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | pub fn permute(self: *Self) void { |
| 98 | if (std.builtin.mode == .ReleaseSmall) { |
| 99 | self._permute_small(); |
| 100 | } else { |
| 101 | self._permute_unrolled(); |
| 102 | } |
| 103 | } |
| 104 | |
| 69 | 105 | pub fn squeeze(self: *Self, out: []u8) void { |
| 70 | 106 | var i = @as(usize, 0); |
| 71 | 107 | while (i + RATE <= out.len) : (i += RATE) { |