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.

scrypt.PhcFormatHasher
const PhcFormatHasher = struct

File

lib/std/crypto/scrypt.zig:401

Code

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

    const HashResult = struct {
        alg_id: []const u8,
        ln: u6,
        r: u30,
        p: u30,
        salt: BinValue(max_salt_len),
        hash: BinValue(max_hash_len),
    };

    /// Return a non-deterministic hash of the password encoded as a PHC-format string
    pub fn create(
        allocator: mem.Allocator,
        password: []const u8,
        params: Params,
        buf: []u8,
        io: std.Io,
    ) HasherError![]const u8 {
        var salt: [default_salt_len]u8 = undefined;
        io.random(&salt);
        return createWithSalt(allocator, 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.
    pub fn createWithSalt(
        allocator: mem.Allocator,
        password: []const u8,
        params: Params,
        buf: []u8,
        salt: *const [default_salt_len]u8,
    ) HasherError![]const u8 {
        var hash: [default_hash_len]u8 = undefined;
        try kdf(allocator, &hash, password, salt, params);

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

    /// Verify a password against a PHC-format encoded string
    pub fn verify(
        allocator: mem.Allocator,
        str: []const u8,
        password: []const u8,
    ) HasherError!void {
        const hash_result = try phc_format.deserialize(HashResult, str);
        if (!mem.eql(u8, hash_result.alg_id, alg_id)) return HasherError.PasswordVerificationFailed;
        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.constSlice(), params);
        if (!mem.eql(u8, hash, expected_hash)) return HasherError.PasswordVerificationFailed;
    }
}