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.

PhcFormatHasher

Hash and verify passwords using the PHC format.

bcrypt.PhcFormatHasher
const PhcFormatHasher = struct

File

lib/std/crypto/bcrypt.zig:649

Code

const PhcFormatHasher = struct {
    const alg_id = "bcrypt";
    const BinValue = phc_format.BinValue;

    const HashResult = struct {
        alg_id: []const u8,
        r: u6,
        salt: BinValue(salt_length),
        hash: BinValue(dk_length),
    };

    /// Return a non-deterministic hash of the password encoded as a PHC-format string.
    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 as a PHC-format string.
    /// Uses the provided salt instead of generating one randomly.
    fn createWithSalt(
        password: []const u8,
        params: Params,
        buf: []u8,
        salt: [salt_length]u8,
    ) HasherError![]const u8 {
        const hash = bcrypt(password, &salt, params);

        return phc_format.serialize(HashResult{
            .alg_id = alg_id,
            .r = params.rounds_log,
            .salt = try BinValue(salt_length).fromSlice(&salt),
            .hash = try BinValue(dk_length).fromSlice(&hash),
        }, buf);
    }

    /// Verify a password against a PHC-format encoded string
    fn verify(
        str: []const u8,
        password: []const u8,
        silently_truncate_password: bool,
    ) HasherError!void {
        const hash_result = try phc_format.deserialize(HashResult, str);

        if (!mem.eql(u8, hash_result.alg_id, alg_id)) return HasherError.PasswordVerificationFailed;
        if (hash_result.salt.len != salt_length or hash_result.hash.len != dk_length)
            return HasherError.InvalidEncoding;

        const params: Params = .{
            .rounds_log = hash_result.r,
            .silently_truncate_password = silently_truncate_password,
        };
        const hash = bcrypt(password, &hash_result.salt.buf, params);
        const expected_hash = hash_result.hash.constSlice();

        if (!mem.eql(u8, &hash, expected_hash)) return HasherError.PasswordVerificationFailed;
    }
}