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.

CryptFormatHasher

Hash and verify passwords using the modular crypt format.

scrypt.CryptFormatHasher
const CryptFormatHasher = struct

File

lib/std/crypto/scrypt.zig:468

Code

const CryptFormatHasher = struct {
    const BinValue = crypt_format.BinValue;
    const HashResult = crypt_format.HashResult(max_hash_len);

    /// Length of a string returned by the create() function
    pub const pwhash_str_length: usize = 101;

    /// Return a non-deterministic hash of the password encoded into the modular crypt format
    pub fn create(
        allocator: mem.Allocator,
        password: []const u8,
        params: Params,
        buf: []u8,
        io: std.Io,
    ) HasherError![]const u8 {
        var salt_bin: [default_salt_len]u8 = undefined;
        io.random(&salt_bin);
        return createWithSalt(allocator, password, params, buf, &salt_bin);
    }

    /// Return a deterministic hash of the password encoded into the modular crypt format.
    /// Uses the provided salt instead of generating one randomly.
    pub fn createWithSalt(
        allocator: mem.Allocator,
        password: []const u8,
        params: Params,
        buf: []u8,
        salt_bin: *const [default_salt_len]u8,
    ) HasherError![]const u8 {
        const salt = crypt_format.saltFromBin(salt_bin.len, salt_bin.*);

        var hash: [default_hash_len]u8 = undefined;
        try kdf(allocator, &hash, password, &salt, params);

        return crypt_format.serialize(HashResult{
            .ln = params.ln,
            .r = params.r,
            .p = params.p,
            .salt = &salt,
            .hash = try BinValue(max_hash_len).fromSlice(&hash),
        }, buf);
    }

    /// Verify a password against a string in modular crypt format
    pub fn verify(
        allocator: mem.Allocator,
        str: []const u8,
        password: []const u8,
    ) HasherError!void {
        const hash_result = try crypt_format.deserialize(HashResult, str);
        const params = Params{ .ln = hash_result.ln, .r = hash_result.r, .p = hash_result.p };
        const expected_hash = hash_result.hash.constSlice();
        var hash_buf: [max_hash_len]u8 = undefined;
        if (expected_hash.len > hash_buf.len) return HasherError.InvalidEncoding;
        const hash = hash_buf[0..expected_hash.len];
        try kdf(allocator, hash, password, hash_result.salt, params);
        if (!mem.eql(u8, hash, expected_hash)) return HasherError.PasswordVerificationFailed;
    }
}