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.

hashVec

blake3.hashVec
fn hashVec(
    comptime Vec: type,
    comptime n: comptime_int,
    inputs: [n][*]const u8,
    blocks: usize,
    key: [8]u32,
    counter: u64,
    increment_counter: bool,
    flags: Flags,
    flags_start: Flags,
    flags_end: Flags,
    out: *[n * Blake3.digest_length]u8,
) void

File

lib/std/crypto/blake3.zig:345

Code

fn hashVec(
    comptime Vec: type,
    comptime n: comptime_int,
    inputs: [n][*]const u8,
    blocks: usize,
    key: [8]u32,
    counter: u64,
    increment_counter: bool,
    flags: Flags,
    flags_start: Flags,
    flags_end: Flags,
    out: *[n * Blake3.digest_length]u8,
) void {
    var h_vecs: [8]Vec = undefined;
    for (0..8) |i| {
        h_vecs[i] = @splat(key[i]);
    }

    const counter_low_vec = if (increment_counter) blk: {
        var result: Vec = undefined;
        inline for (0..n) |i| {
            result[i] = counterLow(counter + i);
        }
        break :blk result;
    } else @as(Vec, @splat(counterLow(counter)));

    const counter_high_vec = if (increment_counter) blk: {
        var result: Vec = undefined;
        inline for (0..n) |i| {
            result[i] = counterHigh(counter + i);
        }
        break :blk result;
    } else @as(Vec, @splat(counterHigh(counter)));

    var block_flags = flags.with(flags_start);

    for (0..blocks) |block| {
        if (block + 1 == blocks) {
            block_flags = block_flags.with(flags_end);
        }

        const block_len_vec: Vec = @splat(Blake3.block_length);
        const block_flags_vec: Vec = @splat(@as(u32, block_flags.toInt()));

        var msg_vecs: [16]Vec = undefined;
        transposeMsg(Vec, n, inputs, block * Blake3.block_length, &msg_vecs);

        var v: [16]Vec = .{
            h_vecs[0],       h_vecs[1],        h_vecs[2],     h_vecs[3],
            h_vecs[4],       h_vecs[5],        h_vecs[6],     h_vecs[7],
            @splat(iv[0]),   @splat(iv[1]),    @splat(iv[2]), @splat(iv[3]),
            counter_low_vec, counter_high_vec, block_len_vec, block_flags_vec,
        };

        inline for (0..7) |r| {
            roundFnVec(Vec, &v, &msg_vecs, r);
        }

        inline for (0..8) |i| {
            h_vecs[i] = v[i] ^ v[i + 8];
        }

        block_flags = flags;
    }

    // Output serialization - different strategies for different widths
    switch (n) {
        4 => {
            // Special interleaved pattern for Vec4
            var out_vecs = [4]Vec{ h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3] };
            transposeNxN(Vec, 4, &out_vecs);
            inline for (0..4) |i| {
                mem.writeInt(u32, out[0 * 16 + i * 4 ..][0..4], out_vecs[0][i], .little);
            }
            inline for (0..4) |i| {
                mem.writeInt(u32, out[2 * 16 + i * 4 ..][0..4], out_vecs[1][i], .little);
            }
            inline for (0..4) |i| {
                mem.writeInt(u32, out[4 * 16 + i * 4 ..][0..4], out_vecs[2][i], .little);
            }
            inline for (0..4) |i| {
                mem.writeInt(u32, out[6 * 16 + i * 4 ..][0..4], out_vecs[3][i], .little);
            }

            out_vecs = [4]Vec{ h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7] };
            transposeNxN(Vec, 4, &out_vecs);
            inline for (0..4) |i| {
                mem.writeInt(u32, out[1 * 16 + i * 4 ..][0..4], out_vecs[0][i], .little);
            }
            inline for (0..4) |i| {
                mem.writeInt(u32, out[3 * 16 + i * 4 ..][0..4], out_vecs[1][i], .little);
            }
            inline for (0..4) |i| {
                mem.writeInt(u32, out[5 * 16 + i * 4 ..][0..4], out_vecs[2][i], .little);
            }
            inline for (0..4) |i| {
                mem.writeInt(u32, out[7 * 16 + i * 4 ..][0..4], out_vecs[3][i], .little);
            }
        },
        8 => {
            // Linear pattern with transpose for Vec8
            var out_vecs = [8]Vec{ h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7] };
            transposeNxN(Vec, 8, &out_vecs);
            inline for (0..8) |i| {
                mem.writeInt(u32, out[0 * 32 + i * 4 ..][0..4], out_vecs[0][i], .little);
            }
            inline for (0..8) |i| {
                mem.writeInt(u32, out[1 * 32 + i * 4 ..][0..4], out_vecs[1][i], .little);
            }
            inline for (0..8) |i| {
                mem.writeInt(u32, out[2 * 32 + i * 4 ..][0..4], out_vecs[2][i], .little);
            }
            inline for (0..8) |i| {
                mem.writeInt(u32, out[3 * 32 + i * 4 ..][0..4], out_vecs[3][i], .little);
            }
            inline for (0..8) |i| {
                mem.writeInt(u32, out[4 * 32 + i * 4 ..][0..4], out_vecs[4][i], .little);
            }
            inline for (0..8) |i| {
                mem.writeInt(u32, out[5 * 32 + i * 4 ..][0..4], out_vecs[5][i], .little);
            }
            inline for (0..8) |i| {
                mem.writeInt(u32, out[6 * 32 + i * 4 ..][0..4], out_vecs[6][i], .little);
            }
            inline for (0..8) |i| {
                mem.writeInt(u32, out[7 * 32 + i * 4 ..][0..4], out_vecs[7][i], .little);
            }
        },
        16 => {
            // Direct lane-by-lane output for Vec16 (no transpose)
            inline for (0..16) |lane| {
                const hash_offset = lane * Blake3.digest_length;
                inline for (0..8) |word_idx| {
                    const word = h_vecs[word_idx][lane];
                    out[hash_offset + word_idx * 4 + 0] = @truncate(word);
                    out[hash_offset + word_idx * 4 + 1] = @truncate(word >> 8);
                    out[hash_offset + word_idx * 4 + 2] = @truncate(word >> 16);
                    out[hash_offset + word_idx * 4 + 3] = @truncate(word >> 24);
                }
            }
        },
        else => @compileError("Unsupported SIMD width"),
    }
}