authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-10-15 10:09:06+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-10-15 10:09:06+02:00
log4ebb70525257f216b3cb23735bb1bd31552b6729
tree42bbe79b3e02647fc8317f0e350c0866325343b1
parentba450411c0e4086819d0790cc3ae4371823a323e
parentbb5ba74ab1d9e10fc4657ef68800192bab538341

Merge pull request 'crypto.keccak_p: allow arbitrary round numbers (still <= 24)' (#37126) from jedisct1/zig:keccakanyround into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37126

3 files changed, 3 insertions(+), 51 deletions(-)

lib/std/crypto.zig+1
...@@ -300,6 +300,7 @@ test {...@@ -300,6 +300,7 @@ test {
300 _ = auth.siphash;300 _ = auth.siphash;
301301
302 _ = core.aes;302 _ = core.aes;
303 _ = core.keccak;
303 _ = core.Ascon;304 _ = core.Ascon;
304 _ = core.modes;305 _ = core.modes;
305306
lib/std/crypto/kangarootwelve.zig-50
...@@ -316,56 +316,6 @@ fn addLanesAll(...@@ -316,56 +316,6 @@ fn addLanesAll(
316 }316 }
317}317}
318318
319/// Apply Keccak-p[1600,12] to a single state (u64 lane representation)
320fn keccakPLanes(lanes: *[25]u64) void {
321 @setEvalBranchQuota(10000);
322
323 // Apply 12 rounds
324 inline for (RC) |rc| {
325 // θ
326 var C: [5]u64 = undefined;
327 inline for (0..5) |x| {
328 C[x] = lanes[x] ^ lanes[x + 5] ^ lanes[x + 10] ^ lanes[x + 15] ^ lanes[x + 20];
329 }
330 var D: [5]u64 = undefined;
331 inline for (0..5) |x| {
332 D[x] = C[(x + 4) % 5] ^ std.math.rotl(u64, C[(x + 1) % 5], 1);
333 }
334 inline for (0..5) |x| {
335 inline for (0..5) |y| {
336 lanes[x + 5 * y] ^= D[x];
337 }
338 }
339
340 // ρ and π
341 var current = lanes[1];
342 var px: usize = 1;
343 var py: usize = 0;
344 inline for (0..24) |t| {
345 const next_y = (2 * px + 3 * py) % 5;
346 const next_idx = py + 5 * next_y;
347 const temp = lanes[next_idx];
348 const rot_amount = ((t + 1) * (t + 2) / 2) % 64;
349 lanes[next_idx] = std.math.rotl(u64, current, @as(u6, @intCast(rot_amount)));
350 current = temp;
351 px = py;
352 py = next_y;
353 }
354
355 // χ
356 inline for (0..5) |y| {
357 const idx = 5 * y;
358 const T = [5]u64{ lanes[idx], lanes[idx + 1], lanes[idx + 2], lanes[idx + 3], lanes[idx + 4] };
359 inline for (0..5) |x| {
360 lanes[idx + x] = T[x] ^ (~T[(x + 1) % 5] & T[(x + 2) % 5]);
361 }
362 }
363
364 // ι
365 lanes[0] ^= rc;
366 }
367}
368
369/// Generic non-allocating TurboSHAKE: write output to provided buffer319/// Generic non-allocating TurboSHAKE: write output to provided buffer
370fn turboShakeMultiSliceToBuffer(320fn turboShakeMultiSliceToBuffer(
371 comptime rate: usize,321 comptime rate: usize,
lib/std/crypto/keccak_p.zig+2-1
...@@ -177,8 +177,9 @@ pub fn KeccakF(comptime f: u11) type {...@@ -177,8 +177,9 @@ pub fn KeccakF(comptime f: u11) type {
177177
178 /// Apply a (possibly) reduced-round permutation to the state.178 /// Apply a (possibly) reduced-round permutation to the state.
179 pub fn permuteR(self: *Self, comptime rounds: u5) void {179 pub fn permuteR(self: *Self, comptime rounds: u5) void {
180 comptime assert(rounds <= max_rounds); // Keccak only supports up to 24 rounds
180 var i = RC.len - rounds;181 var i = RC.len - rounds;
181 while (i < RC.len - RC.len % 3) : (i += 3) {182 while (i < RC.len - rounds % 3) : (i += 3) {
182 self.round(RC[i]);183 self.round(RC[i]);
183 self.round(RC[i + 1]);184 self.round(RC[i + 1]);
184 self.round(RC[i + 2]);185 self.round(RC[i + 2]);