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.

SipHash

siphash.SipHash
fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) type

File

lib/std/crypto/siphash.zig:164

Code

fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) type {
    assert(T == u64 or T == u128);
    assert(c_rounds > 0 and d_rounds > 0);

    return struct {
        const State = SipHashStateless(T, c_rounds, d_rounds);
        const Self = @This();
        pub const key_length = 16;
        pub const mac_length = @sizeOf(T);
        pub const block_length = 8;

        state: State,
        buf: [8]u8,
        buf_len: usize,

        /// Initialize a state for a SipHash function
        pub fn init(key: *const [key_length]u8) Self {
            return Self{
                .state = State.init(key),
                .buf = undefined,
                .buf_len = 0,
            };
        }

        /// Add data to the state
        pub fn update(self: *Self, b: []const u8) void {
            var off: usize = 0;

            if (self.buf_len != 0 and self.buf_len + b.len >= 8) {
                off += 8 - self.buf_len;
                @memcpy(self.buf[self.buf_len..][0..off], b[0..off]);
                self.state.update(self.buf[0..]);
                self.buf_len = 0;
            }

            const remain_len = b.len - off;
            const aligned_len = remain_len - (remain_len % 8);
            self.state.update(b[off .. off + aligned_len]);

            const b_slice = b[off + aligned_len ..];
            @memcpy(self.buf[self.buf_len..][0..b_slice.len], b_slice);
            self.buf_len += @as(u8, @intCast(b_slice.len));
        }

        pub fn peek(self: Self) [mac_length]u8 {
            var copy = self;
            return copy.finalResult();
        }

        /// Return an authentication tag for the current state
        /// Assumes `out` is less than or equal to `mac_length`.
        pub fn final(self: *Self, out: *[mac_length]u8) void {
            mem.writeInt(T, out, self.state.final(self.buf[0..self.buf_len]), .little);
        }

        pub fn finalResult(self: *Self) [mac_length]u8 {
            var result: [mac_length]u8 = undefined;
            self.final(&result);
            return result;
        }

        /// Return an authentication tag for a message and a key
        pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [key_length]u8) void {
            var ctx = Self.init(key);
            ctx.update(msg);
            ctx.final(out);
        }

        /// Return an authentication tag for the current state, as an integer
        pub fn finalInt(self: *Self) T {
            return self.state.final(self.buf[0..self.buf_len]);
        }

        /// Return an authentication tag for a message and a key, as an integer
        pub fn toInt(msg: []const u8, key: *const [key_length]u8) T {
            return State.hash(msg, key);
        }
    };
}