| ... | ... | @@ -9,19 +9,6 @@ pub fn KeccakF(comptime f: u11) type { |
| 9 | 9 | const T = std.meta.Int(.unsigned, f / 25); |
| 10 | 10 | const Block = [25]T; |
| 11 | 11 | |
| 12 | | const RC = [_]u64{ |
| 13 | | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, |
| 14 | | 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, |
| 15 | | 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, |
| 16 | | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, |
| 17 | | 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, |
| 18 | | 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, |
| 19 | | }; |
| 20 | | |
| 21 | | const RHO = [_]u6{ |
| 22 | | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44, |
| 23 | | }; |
| 24 | | |
| 25 | 12 | const PI = [_]u5{ |
| 26 | 13 | 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1, |
| 27 | 14 | }; |
| ... | ... | @@ -32,6 +19,24 @@ pub fn KeccakF(comptime f: u11) type { |
| 32 | 19 | /// Number of bytes in the state. |
| 33 | 20 | pub const block_bytes = f / 8; |
| 34 | 21 | |
| 22 | /// Maximum number of rounds for the given f parameter. |
| 23 | pub const max_rounds = 12 + 2 * math.log2(f / 25); |
| 24 | |
| 25 | // Round constants |
| 26 | const RC = rc: { |
| 27 | const RC64 = [_]u64{ |
| 28 | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, |
| 29 | 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, |
| 30 | 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, |
| 31 | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, |
| 32 | 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, |
| 33 | 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, |
| 34 | }; |
| 35 | var rc: [max_rounds]T = undefined; |
| 36 | for (&rc, RC64[0..max_rounds]) |*t, c| t.* = @truncate(T, c); |
| 37 | break :rc rc; |
| 38 | }; |
| 39 | |
| 35 | 40 | st: Block = [_]T{0} ** 25, |
| 36 | 41 | |
| 37 | 42 | /// Initialize the state from a slice of bytes. |
| ... | ... | @@ -146,10 +151,12 @@ pub fn KeccakF(comptime f: u11) type { |
| 146 | 151 | |
| 147 | 152 | // rho+pi |
| 148 | 153 | var last = st[1]; |
| 154 | comptime var rotc = 0; |
| 149 | 155 | inline for (0..24) |i| { |
| 150 | 156 | const x = PI[i]; |
| 151 | 157 | const tmp = st[x]; |
| 152 | | st[x] = math.rotl(T, last, RHO[i]); |
| 158 | rotc = (rotc + i + 1) % @bitSizeOf(T); |
| 159 | st[x] = math.rotl(T, last, rotc); |
| 153 | 160 | last = tmp; |
| 154 | 161 | } |
| 155 | 162 | inline for (0..5) |i| { |
| ... | ... | @@ -180,7 +187,7 @@ pub fn KeccakF(comptime f: u11) type { |
| 180 | 187 | |
| 181 | 188 | /// Apply a full-round permutation to the state. |
| 182 | 189 | pub fn permute(self: *Self) void { |
| 183 | | self.permuteR(comptime 12 + 2 * math.log2(f / 25)); |
| 190 | self.permuteR(max_rounds); |
| 184 | 191 | } |
| 185 | 192 | }; |
| 186 | 193 | } |
| ... | ... | @@ -249,3 +256,22 @@ pub fn State(comptime f: u11, comptime capacity: u11, comptime delim: u8, compti |
| 249 | 256 | } |
| 250 | 257 | }; |
| 251 | 258 | } |
| 259 | |
| 260 | test "Keccak-f800" { |
| 261 | var st: KeccakF(800) = .{ |
| 262 | .st = .{ |
| 263 | 0xE531D45D, 0xF404C6FB, 0x23A0BF99, 0xF1F8452F, 0x51FFD042, 0xE539F578, 0xF00B80A7, |
| 264 | 0xAF973664, 0xBF5AF34C, 0x227A2424, 0x88172715, 0x9F685884, 0xB15CD054, 0x1BF4FC0E, |
| 265 | 0x6166FA91, 0x1A9E599A, 0xA3970A1F, 0xAB659687, 0xAFAB8D68, 0xE74B1015, 0x34001A98, |
| 266 | 0x4119EFF3, 0x930A0E76, 0x87B28070, 0x11EFE996, |
| 267 | }, |
| 268 | }; |
| 269 | st.permute(); |
| 270 | const expected: [25]u32 = .{ |
| 271 | 0x75BF2D0D, 0x9B610E89, 0xC826AF40, 0x64CD84AB, 0xF905BDD6, 0xBC832835, 0x5F8001B9, |
| 272 | 0x15662CCE, 0x8E38C95E, 0x701FE543, 0x1B544380, 0x89ACDEFF, 0x51EDB5DE, 0x0E9702D9, |
| 273 | 0x6C19AA16, 0xA2913EEE, 0x60754E9A, 0x9819063C, 0xF4709254, 0xD09F9084, 0x772DA259, |
| 274 | 0x1DB35DF7, 0x5AA60162, 0x358825D5, 0xB3783BAB, |
| 275 | }; |
| 276 | try std.testing.expectEqualSlices(u32, &st.st, &expected); |
| 277 | } |