Generic non-allocating TurboSHAKE: write output to provided buffer
fn turboShakeMultiSliceToBuffer(
comptime rate: usize,
view: *const MultiSliceView,
separation_byte: u8,
output: []u8,
) void
fn turboShakeMultiSliceToBuffer(
comptime rate: usize,
view: *const MultiSliceView,
separation_byte: u8,
output: []u8,
) void {
var state: [200]u8 = @splat(0);
var state_pos: usize = 0;
// Absorb all bytes from the multi-slice view
const total = view.totalLen();
var pos: usize = 0;
while (pos < total) {
state[state_pos] ^= view.getByte(pos);
state_pos += 1;
pos += 1;
if (state_pos == rate) {
keccakP(&state);
state_pos = 0;
}
}
// Add separation byte and padding
state[state_pos] ^= separation_byte;
state[rate - 1] ^= 0x80;
keccakP(&state);
// Squeeze
var out_offset: usize = 0;
while (out_offset < output.len) {
const chunk = @min(rate, output.len - out_offset);
@memcpy(output[out_offset..][0..chunk], state[0..chunk]);
out_offset += chunk;
if (out_offset < output.len) {
keccakP(&state);
}
}
}