Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

processLeaves

Process N leaves (8KiB chunks) in parallel - generic version

kangarootwelve.processLeaves
fn processLeaves(
    comptime Variant: type,
    comptime N: usize,
    data: []const u8,
    result: *[N * Variant.cv_size]u8,
) void

File

lib/std/crypto/kangarootwelve.zig:528

Code

fn processLeaves(
    comptime Variant: type,
    comptime N: usize,
    data: []const u8,
    result: *[N * Variant.cv_size]u8,
) void {
    const rate_in_lanes: usize = Variant.rate_in_lanes;
    const rate_in_bytes: usize = rate_in_lanes * 8;
    const cv_size: usize = Variant.cv_size;

    // Initialize N all-zero states with cache alignment
    var states: [5][5]@Vector(N, u64) align(cache_line_size) = undefined;
    inline for (0..5) |x| {
        inline for (0..5) |y| {
            states[x][y] = @splat(0);
        }
    }

    // Process complete blocks
    var j: usize = 0;
    while (j + rate_in_bytes <= chunk_size) : (j += rate_in_bytes) {
        addLanesAll(N, &states, data[j..], rate_in_lanes, chunk_size / 8);
        keccakP1600timesN(N, &states);
    }

    // Process last incomplete block
    const remaining_lanes = (chunk_size - j) / 8;
    if (remaining_lanes > 0) {
        addLanesAll(N, &states, data[j..], remaining_lanes, chunk_size / 8);
    }

    // Add suffix 0x0B and padding
    const suffix_pos = Variant.separation_byte_pos;
    const padding_pos = Variant.padding_pos;

    const suffix_splat: @Vector(N, u64) = @splat(0x0B);
    states[suffix_pos.x][suffix_pos.y] ^= suffix_splat;
    const padding_splat: @Vector(N, u64) = @splat(0x8000000000000000);
    states[padding_pos.x][padding_pos.y] ^= padding_splat;

    keccakP1600timesN(N, &states);

    // Extract chaining values from each state
    const lanes_to_extract = cv_size / 8;
    comptime var lane_idx: usize = 0;
    inline while (lane_idx < lanes_to_extract) : (lane_idx += 1) {
        const x = lane_idx % 5;
        const y = lane_idx / 5;
        inline for (0..N) |i| {
            store64(states[x][y][i], result[i * cv_size + lane_idx * 8 ..]);
        }
    }
}