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.

CShakeLike

sha3.CShakeLike
fn CShakeLike(comptime security_level: u11, comptime default_delim: u8, comptime rounds: u5, comptime fname: ?[]const u8) type

File

lib/std/crypto/sha3.zig:197

Code

fn CShakeLike(comptime security_level: u11, comptime default_delim: u8, comptime rounds: u5, comptime fname: ?[]const u8) type {
    return struct {
        const Shaker = ShakeLike(security_level, default_delim, rounds);
        shaker: Shaker,

        /// The recommended output length, in bytes.
        pub const digest_length = Shaker.digest_length;
        /// The block length, or rate, in bytes.
        pub const block_length = Shaker.block_length;

        /// cSHAKE options can include a context string.
        pub const Options = struct { context: ?[]const u8 = null };

        const Self = @This();

        /// Initialize a SHAKE extensible hash function.
        pub fn init(options: Options) Self {
            if (fname == null and options.context == null) {
                return Self{ .shaker = Shaker.init(.{ .delim = 0x1f }) };
            }
            var shaker = Shaker.init(.{});
            comptime assert(Shaker.block_length % 8 == 0);
            const encoded_rate_len = NistLengthEncoding.encode(.left, block_length / 8);
            shaker.update(encoded_rate_len.slice());
            const encoded_zero = comptime NistLengthEncoding.encode(.left, 0);
            if (fname) |name| {
                const encoded_fname_len = comptime NistLengthEncoding.encode(.left, name.len);
                const encoded_fname = comptime encoded_fname_len.slice() ++ name;
                shaker.update(encoded_fname);
            } else {
                shaker.update(encoded_zero.slice());
            }
            if (options.context) |context| {
                const encoded_context_len = NistLengthEncoding.encode(.left, context.len);
                shaker.update(encoded_context_len.slice());
                shaker.update(context);
            } else {
                shaker.update(encoded_zero.slice());
            }
            shaker.st.fillBlock();
            return Self{ .shaker = shaker };
        }

        /// Hash a slice of bytes.
        /// `out` can be any length.
        pub fn hash(bytes: []const u8, out: []u8, options: Options) void {
            var st = Self.init(options);
            st.update(bytes);
            st.squeeze(out);
        }

        /// Absorb a slice of bytes into the state.
        pub fn update(self: *Self, bytes: []const u8) void {
            self.shaker.update(bytes);
        }

        /// Squeeze a slice of bytes from the state.
        /// `out` can be any length, and the function can be called multiple times.
        pub fn squeeze(self: *Self, out: []u8) void {
            self.shaker.squeeze(out);
        }

        /// Return the hash of the absorbed bytes.
        /// `out` can be of any length, but the function must not be called multiple times (use `squeeze` for that purpose instead).
        pub fn final(self: *Self, out: []u8) void {
            self.shaker.final(out);
        }

        /// Align the input to a block boundary.
        pub fn fillBlock(self: *Self) void {
            self.shaker.fillBlock();
        }
    };
}