| ... | ... | @@ -316,72 +316,6 @@ fn addLanesAll( |
| 316 | 316 | } |
| 317 | 317 | } |
| 318 | 318 | |
| 319 | | /// Apply Keccak-p[1600,12] to a single state (byte representation) |
| 320 | | fn 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 | 319 | /// Apply Keccak-p[1600,12] to a single state (u64 lane representation) |
| 386 | 320 | fn keccakPLanes(lanes: *[25]u64) void { |
| 387 | 321 | @setEvalBranchQuota(10000); |
| ... | ... | @@ -439,38 +373,12 @@ fn turboShakeMultiSliceToBuffer( |
| 439 | 373 | separation_byte: u8, |
| 440 | 374 | output: []u8, |
| 441 | 375 | ) void { |
| 442 | | var state: [200]u8 = @splat(0); |
| 443 | | var state_pos: usize = 0; |
| 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 | | } |
| 376 | const StateType = if (rate == TurboSHAKE128State.block_length) TurboSHAKE128State else TurboSHAKE256State; |
| 377 | comptime assert(StateType.block_length == rate); |
| 458 | 378 | |
| 459 | | // Add separation byte and padding |
| 460 | | state[state_pos] ^= separation_byte; |
| 461 | | state[rate - 1] ^= 0x80; |
| 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 | | } |
| 379 | var state = StateType.init(.{ .delim = separation_byte }); |
| 380 | for (view.slices) |slice| state.update(slice); |
| 381 | state.final(output); |
| 474 | 382 | } |
| 475 | 383 | |
| 476 | 384 | /// Generic allocating TurboSHAKE |