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.

bcrypt.CryptFormatHasher
const CryptFormatHasher = struct

File

lib/std/crypto/bcrypt.zig:714

Code

const CryptFormatHasher = struct {
    /// Length of a string returned by the create() function
    const pwhash_str_length: usize = hash_length;

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

    /// Return a deterministic hash of the password encoded into the modular crypt format.
    /// Uses the provided salt instead of generating one randomly.
    fn createWithSalt(
        password: []const u8,
        params: Params,
        buf: []u8,
        salt: *const [salt_length]u8,
    ) HasherError![]const u8 {
        if (buf.len < pwhash_str_length) return HasherError.NoSpaceLeft;

        const hash = crypt_format.strHashInternal(password, salt, params);
        @memcpy(buf[0..hash.len], &hash);

        return buf[0..pwhash_str_length];
    }

    /// Verify a password against a string in modular crypt format
    fn verify(
        str: []const u8,
        password: []const u8,
        silently_truncate_password: bool,
    ) HasherError!void {
        if (str.len != pwhash_str_length or str[3] != '$' or str[6] != '$')
            return HasherError.InvalidEncoding;

        const rounds_log_str = str[4..][0..2];
        const rounds_log = fmt.parseInt(u6, rounds_log_str[0..], 10) catch
            return HasherError.InvalidEncoding;

        const salt_str = str[7..][0..salt_str_length];
        var salt: [salt_length]u8 = undefined;
        crypt_format.Codec.Decoder.decode(&salt, salt_str) catch return HasherError.InvalidEncoding;

        const wanted_s = crypt_format.strHashInternal(password, &salt, .{
            .rounds_log = rounds_log,
            .silently_truncate_password = silently_truncate_password,
        });
        if (!mem.eql(u8, wanted_s[0..], str[0..])) return HasherError.PasswordVerificationFailed;
    }
}