authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-10-03 17:09:12+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-10-06 10:48:30+02:00
loga3b95e1b1a5809f2fe187d7b83a0a12262df2752
treea899d6317948760954bdff97d3598542adc38bd2
parent92d82e6a340ec4b3c229397c2a2c22f04cb395dd

For single-chunk messages, just use regular TurboShake implementation

The local kangarootwelve version was just redundant code, and only aborbed one byte at a time

1 files changed, 5 insertions(+), 97 deletions(-)

lib/std/crypto/kangarootwelve.zig+5-97
...@@ -316,72 +316,6 @@ fn addLanesAll(...@@ -316,72 +316,6 @@ fn addLanesAll(
316 }316 }
317}317}
318318
319/// Apply Keccak-p[1600,12] to a single state (byte representation)
320fn keccakP(state: *[200]u8) void {
321 @setEvalBranchQuota(10000);
322 var lanes: [5][5]u64 = undefined;
323
324 // Load state into lanes
325 inline for (0..5) |x| {
326 inline for (0..5) |y| {
327 lanes[x][y] = load64(state[8 * (x + 5 * y) ..]);
328 }
329 }
330
331 // Apply 12 rounds
332 var round: usize = 0;
333 while (round < 12) : (round += 2) {
334 inline for (0..2) |i| {
335 // θ
336 var C: [5]u64 = undefined;
337 inline for (0..5) |x| {
338 C[x] = lanes[x][0] ^ lanes[x][1] ^ lanes[x][2] ^ lanes[x][3] ^ lanes[x][4];
339 }
340 var D: [5]u64 = undefined;
341 inline for (0..5) |x| {
342 D[x] = C[(x + 4) % 5] ^ std.math.rotl(u64, C[(x + 1) % 5], 1);
343 }
344 inline for (0..5) |x| {
345 inline for (0..5) |y| {
346 lanes[x][y] ^= D[x];
347 }
348 }
349
350 // ρ and π
351 var current = lanes[1][0];
352 var px: usize = 1;
353 var py: usize = 0;
354 inline for (0..24) |t| {
355 const temp = lanes[py][(2 * px + 3 * py) % 5];
356 const rot_amount = ((t + 1) * (t + 2) / 2) % 64;
357 lanes[py][(2 * px + 3 * py) % 5] = std.math.rotl(u64, current, @as(u6, @intCast(rot_amount)));
358 current = temp;
359 const temp_x = py;
360 py = (2 * px + 3 * py) % 5;
361 px = temp_x;
362 }
363
364 // χ
365 inline for (0..5) |y| {
366 const T = [5]u64{ lanes[0][y], lanes[1][y], lanes[2][y], lanes[3][y], lanes[4][y] };
367 inline for (0..5) |x| {
368 lanes[x][y] = T[x] ^ (~T[(x + 1) % 5] & T[(x + 2) % 5]);
369 }
370 }
371
372 // ι
373 lanes[0][0] ^= RC[round + i];
374 }
375 }
376
377 // Store lanes back to state
378 inline for (0..5) |x| {
379 inline for (0..5) |y| {
380 store64(lanes[x][y], state[8 * (x + 5 * y) ..]);
381 }
382 }
383}
384
385/// Apply Keccak-p[1600,12] to a single state (u64 lane representation)319/// Apply Keccak-p[1600,12] to a single state (u64 lane representation)
386fn keccakPLanes(lanes: *[25]u64) void {320fn keccakPLanes(lanes: *[25]u64) void {
387 @setEvalBranchQuota(10000);321 @setEvalBranchQuota(10000);
...@@ -439,38 +373,12 @@ fn turboShakeMultiSliceToBuffer(...@@ -439,38 +373,12 @@ fn turboShakeMultiSliceToBuffer(
439 separation_byte: u8,373 separation_byte: u8,
440 output: []u8,374 output: []u8,
441) void {375) void {
442 var state: [200]u8 = @splat(0);376 const StateType = if (rate == TurboSHAKE128State.block_length) TurboSHAKE128State else TurboSHAKE256State;
443 var state_pos: usize = 0;377 comptime assert(StateType.block_length == rate);
444
445 // Absorb all bytes from the multi-slice view
446 const total = view.totalLen();
447 var pos: usize = 0;
448 while (pos < total) {
449 state[state_pos] ^= view.getByte(pos);
450 state_pos += 1;
451 pos += 1;
452
453 if (state_pos == rate) {
454 keccakP(&state);
455 state_pos = 0;
456 }
457 }
458378
459 // Add separation byte and padding379 var state = StateType.init(.{ .delim = separation_byte });
460 state[state_pos] ^= separation_byte;380 for (view.slices) |slice| state.update(slice);
461 state[rate - 1] ^= 0x80;381 state.final(output);
462 keccakP(&state);
463
464 // Squeeze
465 var out_offset: usize = 0;
466 while (out_offset < output.len) {
467 const chunk = @min(rate, output.len - out_offset);
468 @memcpy(output[out_offset..][0..chunk], state[0..chunk]);
469 out_offset += chunk;
470 if (out_offset < output.len) {
471 keccakP(&state);
472 }
473 }
474}382}
475383
476/// Generic allocating TurboSHAKE384/// Generic allocating TurboSHAKE