Hash and verify passwords using the PHC format.
const PhcFormatHasher = struct
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;
}
}