authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2023-03-02 20:14:41+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-03-02 19:14:41+00:00
log4789cc0249f8dd6b76471abda0c6eaa16d75bd69
tree9413604157fc1a20f6a0e9425897cba519a2d88d
parent28364166e83ed52a7053029d5d7b33ad956d804d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

crypto.KeccakF: compute rotations at comptime, add a test with f=800 (#14760)


1 files changed, 41 insertions(+), 15 deletions(-)

lib/std/crypto/keccak_p.zig+41-15
......@@ -9,19 +9,6 @@ pub fn KeccakF(comptime f: u11) type {
99 const T = std.meta.Int(.unsigned, f / 25);
1010 const Block = [25]T;
1111
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
2512 const PI = [_]u5{
2613 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
2714 };
......@@ -32,6 +19,24 @@ pub fn KeccakF(comptime f: u11) type {
3219 /// Number of bytes in the state.
3320 pub const block_bytes = f / 8;
3421
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
3540 st: Block = [_]T{0} ** 25,
3641
3742 /// Initialize the state from a slice of bytes.
......@@ -146,10 +151,12 @@ pub fn KeccakF(comptime f: u11) type {
146151
147152 // rho+pi
148153 var last = st[1];
154 comptime var rotc = 0;
149155 inline for (0..24) |i| {
150156 const x = PI[i];
151157 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);
153160 last = tmp;
154161 }
155162 inline for (0..5) |i| {
......@@ -180,7 +187,7 @@ pub fn KeccakF(comptime f: u11) type {
180187
181188 /// Apply a full-round permutation to the state.
182189 pub fn permute(self: *Self) void {
183 self.permuteR(comptime 12 + 2 * math.log2(f / 25));
190 self.permuteR(max_rounds);
184191 }
185192 };
186193}
......@@ -249,3 +256,22 @@ pub fn State(comptime f: u11, comptime capacity: u11, comptime delim: u8, compti
249256 }
250257 };
251258}
259
260test "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}