Hash functions now accept an option set
- This avoids having multiple `init()` functions for every combination of optional parameters - The API is consistent across all hash functions - New options can be added later without breaking existing applications. For example, this is going to come in handy if we implement parallelization for BLAKE2 and BLAKE3. - We don't have a mix of snake_case and camelCase functions any more, at least in the public crypto API Support for BLAKE2 salt and personalization (more commonly called context) parameters have been implemented by the way to illustrate this.
This commit is contained in:
parent
adf3d00e87
commit
fc55cd458a
@ -158,7 +158,7 @@ pub fn BloomFilter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn hashFunc(out: []u8, Ki: usize, in: []const u8) void {
|
fn hashFunc(out: []u8, Ki: usize, in: []const u8) void {
|
||||||
var st = std.crypto.hash.Gimli.init();
|
var st = std.crypto.hash.Gimli.init(.{});
|
||||||
st.update(std.mem.asBytes(&Ki));
|
st.update(std.mem.asBytes(&Ki));
|
||||||
st.update(in);
|
st.update(in);
|
||||||
st.final(out);
|
st.final(out);
|
||||||
|
@ -56,7 +56,7 @@ pub const CacheHash = struct {
|
|||||||
pub fn init(allocator: *Allocator, dir: fs.Dir, manifest_dir_path: []const u8) !CacheHash {
|
pub fn init(allocator: *Allocator, dir: fs.Dir, manifest_dir_path: []const u8) !CacheHash {
|
||||||
return CacheHash{
|
return CacheHash{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.blake3 = Blake3.init(),
|
.blake3 = Blake3.init(.{}),
|
||||||
.manifest_dir = try dir.makeOpenPath(manifest_dir_path, .{}),
|
.manifest_dir = try dir.makeOpenPath(manifest_dir_path, .{}),
|
||||||
.manifest_file = null,
|
.manifest_file = null,
|
||||||
.manifest_dirty = false,
|
.manifest_dirty = false,
|
||||||
@ -137,7 +137,7 @@ pub const CacheHash = struct {
|
|||||||
|
|
||||||
base64_encoder.encode(self.b64_digest[0..], &bin_digest);
|
base64_encoder.encode(self.b64_digest[0..], &bin_digest);
|
||||||
|
|
||||||
self.blake3 = Blake3.init();
|
self.blake3 = Blake3.init(.{});
|
||||||
self.blake3.update(&bin_digest);
|
self.blake3.update(&bin_digest);
|
||||||
|
|
||||||
const manifest_file_path = try fmt.allocPrint(self.allocator, "{}.txt", .{self.b64_digest});
|
const manifest_file_path = try fmt.allocPrint(self.allocator, "{}.txt", .{self.b64_digest});
|
||||||
@ -256,7 +256,7 @@ pub const CacheHash = struct {
|
|||||||
// cache miss
|
// cache miss
|
||||||
// keep the manifest file open
|
// keep the manifest file open
|
||||||
// reset the hash
|
// reset the hash
|
||||||
self.blake3 = Blake3.init();
|
self.blake3 = Blake3.init(.{});
|
||||||
self.blake3.update(&bin_digest);
|
self.blake3.update(&bin_digest);
|
||||||
|
|
||||||
// Remove files not in the initial hash
|
// Remove files not in the initial hash
|
||||||
@ -304,7 +304,7 @@ pub const CacheHash = struct {
|
|||||||
|
|
||||||
// Hash while reading from disk, to keep the contents in the cpu cache while
|
// Hash while reading from disk, to keep the contents in the cpu cache while
|
||||||
// doing hashing.
|
// doing hashing.
|
||||||
var blake3 = Blake3.init();
|
var blake3 = Blake3.init(.{});
|
||||||
var off: usize = 0;
|
var off: usize = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
// give me everything you've got, captain
|
// give me everything you've got, captain
|
||||||
@ -434,7 +434,7 @@ pub const CacheHash = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn hashFile(file: fs.File, bin_digest: []u8) !void {
|
fn hashFile(file: fs.File, bin_digest: []u8) !void {
|
||||||
var blake3 = Blake3.init();
|
var blake3 = Blake3.init(.{});
|
||||||
var buf: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -112,7 +112,7 @@ test "issue #4532: no index out of bounds" {
|
|||||||
var block = [_]u8{'#'} ** Hasher.block_length;
|
var block = [_]u8{'#'} ** Hasher.block_length;
|
||||||
var out1: [Hasher.digest_length]u8 = undefined;
|
var out1: [Hasher.digest_length]u8 = undefined;
|
||||||
var out2: [Hasher.digest_length]u8 = undefined;
|
var out2: [Hasher.digest_length]u8 = undefined;
|
||||||
const h0 = Hasher.init();
|
const h0 = Hasher.init(.{});
|
||||||
var h = h0;
|
var h = h0;
|
||||||
h.update(block[0..]);
|
h.update(block[0..]);
|
||||||
h.final(out1[0..]);
|
h.final(out1[0..]);
|
||||||
|
@ -33,7 +33,7 @@ pub const Ed25519 = struct {
|
|||||||
/// from which the actual secret is derived.
|
/// from which the actual secret is derived.
|
||||||
pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 {
|
pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 {
|
||||||
var az: [Sha512.digest_length]u8 = undefined;
|
var az: [Sha512.digest_length]u8 = undefined;
|
||||||
var h = Sha512.init();
|
var h = Sha512.init(.{});
|
||||||
h.update(&seed);
|
h.update(&seed);
|
||||||
h.final(&az);
|
h.final(&az);
|
||||||
const p = try Curve.basePoint.clampedMul(az[0..32].*);
|
const p = try Curve.basePoint.clampedMul(az[0..32].*);
|
||||||
@ -56,11 +56,11 @@ pub const Ed25519 = struct {
|
|||||||
pub fn sign(msg: []const u8, key_pair: [keypair_length]u8, noise: ?[noise_length]u8) ![signature_length]u8 {
|
pub fn sign(msg: []const u8, key_pair: [keypair_length]u8, noise: ?[noise_length]u8) ![signature_length]u8 {
|
||||||
const public_key = key_pair[32..];
|
const public_key = key_pair[32..];
|
||||||
var az: [Sha512.digest_length]u8 = undefined;
|
var az: [Sha512.digest_length]u8 = undefined;
|
||||||
var h = Sha512.init();
|
var h = Sha512.init(.{});
|
||||||
h.update(key_pair[0..seed_length]);
|
h.update(key_pair[0..seed_length]);
|
||||||
h.final(&az);
|
h.final(&az);
|
||||||
|
|
||||||
h = Sha512.init();
|
h = Sha512.init(.{});
|
||||||
if (noise) |*z| {
|
if (noise) |*z| {
|
||||||
h.update(z);
|
h.update(z);
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ pub const Ed25519 = struct {
|
|||||||
var sig: [signature_length]u8 = undefined;
|
var sig: [signature_length]u8 = undefined;
|
||||||
mem.copy(u8, sig[0..32], &r.toBytes());
|
mem.copy(u8, sig[0..32], &r.toBytes());
|
||||||
mem.copy(u8, sig[32..], public_key);
|
mem.copy(u8, sig[32..], public_key);
|
||||||
h = Sha512.init();
|
h = Sha512.init(.{});
|
||||||
h.update(&sig);
|
h.update(&sig);
|
||||||
h.update(msg);
|
h.update(msg);
|
||||||
var hram64: [Sha512.digest_length]u8 = undefined;
|
var hram64: [Sha512.digest_length]u8 = undefined;
|
||||||
@ -98,7 +98,7 @@ pub const Ed25519 = struct {
|
|||||||
const a = try Curve.fromBytes(public_key);
|
const a = try Curve.fromBytes(public_key);
|
||||||
try a.rejectIdentity();
|
try a.rejectIdentity();
|
||||||
|
|
||||||
var h = Sha512.init();
|
var h = Sha512.init(.{});
|
||||||
h.update(r);
|
h.update(r);
|
||||||
h.update(&public_key);
|
h.update(&public_key);
|
||||||
h.update(msg);
|
h.update(msg);
|
||||||
|
@ -35,7 +35,7 @@ const hashes = [_]Crypto{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 {
|
pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 {
|
||||||
var h = Hash.init();
|
var h = Hash.init(.{});
|
||||||
|
|
||||||
var block: [Hash.digest_length]u8 = undefined;
|
var block: [Hash.digest_length]u8 = undefined;
|
||||||
prng.random.bytes(block[0..]);
|
prng.random.bytes(block[0..]);
|
||||||
|
@ -40,6 +40,7 @@ pub fn Blake2s(comptime out_len: usize) type {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const block_length = 64;
|
pub const block_length = 64;
|
||||||
pub const digest_length = out_len / 8;
|
pub const digest_length = out_len / 8;
|
||||||
|
pub const Options = struct { key: ?[]const u8 = null, salt: ?[8]u8 = null, context: ?[8]u8 = null };
|
||||||
|
|
||||||
const iv = [8]u32{
|
const iv = [8]u32{
|
||||||
0x6A09E667,
|
0x6A09E667,
|
||||||
@ -71,35 +72,36 @@ pub fn Blake2s(comptime out_len: usize) type {
|
|||||||
buf: [64]u8,
|
buf: [64]u8,
|
||||||
buf_len: u8,
|
buf_len: u8,
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init(options: Options) Self {
|
||||||
return init_keyed("");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_keyed(key: []const u8) Self {
|
|
||||||
debug.assert(8 <= out_len and out_len <= 512);
|
debug.assert(8 <= out_len and out_len <= 512);
|
||||||
|
|
||||||
var d: Self = undefined;
|
var d: Self = undefined;
|
||||||
mem.copy(u32, d.h[0..], iv[0..]);
|
mem.copy(u32, d.h[0..], iv[0..]);
|
||||||
|
|
||||||
|
const key_len = if (options.key) |key| key.len else 0;
|
||||||
// default parameters
|
// default parameters
|
||||||
d.h[0] ^= 0x01010000 ^ @truncate(u32, key.len << 8) ^ @intCast(u32, out_len >> 3);
|
d.h[0] ^= 0x01010000 ^ @truncate(u32, key_len << 8) ^ @intCast(u32, out_len >> 3);
|
||||||
d.t = 0;
|
d.t = 0;
|
||||||
d.buf_len = 0;
|
d.buf_len = 0;
|
||||||
|
|
||||||
if (key.len > 0) {
|
if (options.salt) |salt| {
|
||||||
mem.set(u8, d.buf[key.len..], 0);
|
d.h[4] ^= mem.readIntLittle(u32, salt[0..4]);
|
||||||
d.update(key);
|
d.h[5] ^= mem.readIntLittle(u32, salt[4..8]);
|
||||||
|
}
|
||||||
|
if (options.context) |context| {
|
||||||
|
d.h[6] ^= mem.readIntLittle(u32, context[0..4]);
|
||||||
|
d.h[7] ^= mem.readIntLittle(u32, context[4..8]);
|
||||||
|
}
|
||||||
|
if (key_len > 0) {
|
||||||
|
mem.set(u8, d.buf[key_len..], 0);
|
||||||
|
d.update(options.key.?);
|
||||||
d.buf_len = 64;
|
d.buf_len = 64;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(b: []const u8, out: []u8) void {
|
pub fn hash(b: []const u8, out: []u8, options: Options) void {
|
||||||
Self.hash_keyed("", b, out);
|
var d = Self.init(options);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void {
|
|
||||||
var d = Self.init_keyed(key);
|
|
||||||
d.update(b);
|
d.update(b);
|
||||||
d.final(out);
|
d.final(out);
|
||||||
}
|
}
|
||||||
@ -208,7 +210,7 @@ test "blake2s224 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "blake2s224 streaming" {
|
test "blake2s224 streaming" {
|
||||||
var h = Blake2s224.init();
|
var h = Blake2s224.init(.{});
|
||||||
var out: [28]u8 = undefined;
|
var out: [28]u8 = undefined;
|
||||||
|
|
||||||
const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4";
|
const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4";
|
||||||
@ -218,12 +220,12 @@ test "blake2s224 streaming" {
|
|||||||
|
|
||||||
const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55";
|
const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55";
|
||||||
|
|
||||||
h = Blake2s224.init();
|
h = Blake2s224.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h2, out[0..]);
|
htest.assertEqual(h2, out[0..]);
|
||||||
|
|
||||||
h = Blake2s224.init();
|
h = Blake2s224.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -232,16 +234,29 @@ test "blake2s224 streaming" {
|
|||||||
|
|
||||||
const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01";
|
const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01";
|
||||||
|
|
||||||
h = Blake2s224.init();
|
h = Blake2s224.init(.{});
|
||||||
h.update("a" ** 32);
|
h.update("a" ** 32);
|
||||||
h.update("b" ** 32);
|
h.update("b" ** 32);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h3, out[0..]);
|
htest.assertEqual(h3, out[0..]);
|
||||||
|
|
||||||
h = Blake2s224.init();
|
h = Blake2s224.init(.{});
|
||||||
h.update("a" ** 32 ++ "b" ** 32);
|
h.update("a" ** 32 ++ "b" ** 32);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h3, out[0..]);
|
htest.assertEqual(h3, out[0..]);
|
||||||
|
|
||||||
|
const h4 = "a4d6a9d253441b80e5dfd60a04db169ffab77aec56a2855c402828c3";
|
||||||
|
|
||||||
|
h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 });
|
||||||
|
h.update("a" ** 32);
|
||||||
|
h.update("b" ** 32);
|
||||||
|
h.final(out[0..]);
|
||||||
|
htest.assertEqual(h4, out[0..]);
|
||||||
|
|
||||||
|
h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 });
|
||||||
|
h.update("a" ** 32 ++ "b" ** 32);
|
||||||
|
h.final(out[0..]);
|
||||||
|
htest.assertEqual(h4, out[0..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "comptime blake2s224" {
|
test "comptime blake2s224" {
|
||||||
@ -254,7 +269,7 @@ test "comptime blake2s224" {
|
|||||||
|
|
||||||
htest.assertEqualHash(Blake2s224, h1, block[0..]);
|
htest.assertEqualHash(Blake2s224, h1, block[0..]);
|
||||||
|
|
||||||
var h = Blake2s224.init();
|
var h = Blake2s224.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
|
|
||||||
@ -277,7 +292,7 @@ test "blake2s256 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "blake2s256 streaming" {
|
test "blake2s256 streaming" {
|
||||||
var h = Blake2s256.init();
|
var h = Blake2s256.init(.{});
|
||||||
var out: [32]u8 = undefined;
|
var out: [32]u8 = undefined;
|
||||||
|
|
||||||
const h1 = "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9";
|
const h1 = "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9";
|
||||||
@ -287,12 +302,12 @@ test "blake2s256 streaming" {
|
|||||||
|
|
||||||
const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982";
|
const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982";
|
||||||
|
|
||||||
h = Blake2s256.init();
|
h = Blake2s256.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h2, out[0..]);
|
htest.assertEqual(h2, out[0..]);
|
||||||
|
|
||||||
h = Blake2s256.init();
|
h = Blake2s256.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -301,13 +316,13 @@ test "blake2s256 streaming" {
|
|||||||
|
|
||||||
const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977";
|
const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977";
|
||||||
|
|
||||||
h = Blake2s256.init();
|
h = Blake2s256.init(.{});
|
||||||
h.update("a" ** 32);
|
h.update("a" ** 32);
|
||||||
h.update("b" ** 32);
|
h.update("b" ** 32);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h3, out[0..]);
|
htest.assertEqual(h3, out[0..]);
|
||||||
|
|
||||||
h = Blake2s256.init();
|
h = Blake2s256.init(.{});
|
||||||
h.update("a" ** 32 ++ "b" ** 32);
|
h.update("a" ** 32 ++ "b" ** 32);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h3, out[0..]);
|
htest.assertEqual(h3, out[0..]);
|
||||||
@ -319,16 +334,16 @@ test "blake2s256 keyed" {
|
|||||||
const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6";
|
const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6";
|
||||||
const key = "secret_key";
|
const key = "secret_key";
|
||||||
|
|
||||||
Blake2s256.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out);
|
Blake2s256.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key });
|
||||||
htest.assertEqual(h1, out[0..]);
|
htest.assertEqual(h1, out[0..]);
|
||||||
|
|
||||||
var h = Blake2s256.init_keyed(key);
|
var h = Blake2s256.init(.{ .key = key });
|
||||||
h.update("a" ** 64 ++ "b" ** 64);
|
h.update("a" ** 64 ++ "b" ** 64);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
|
|
||||||
htest.assertEqual(h1, out[0..]);
|
htest.assertEqual(h1, out[0..]);
|
||||||
|
|
||||||
h = Blake2s256.init_keyed(key);
|
h = Blake2s256.init(.{ .key = key });
|
||||||
h.update("a" ** 64);
|
h.update("a" ** 64);
|
||||||
h.update("b" ** 64);
|
h.update("b" ** 64);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
@ -346,7 +361,7 @@ test "comptime blake2s256" {
|
|||||||
|
|
||||||
htest.assertEqualHash(Blake2s256, h1, block[0..]);
|
htest.assertEqualHash(Blake2s256, h1, block[0..]);
|
||||||
|
|
||||||
var h = Blake2s256.init();
|
var h = Blake2s256.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
|
|
||||||
@ -366,6 +381,7 @@ pub fn Blake2b(comptime out_len: usize) type {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const block_length = 128;
|
pub const block_length = 128;
|
||||||
pub const digest_length = out_len / 8;
|
pub const digest_length = out_len / 8;
|
||||||
|
pub const Options = struct { key: ?[]const u8 = null, salt: ?[16]u8 = null, context: ?[16]u8 = null };
|
||||||
|
|
||||||
const iv = [8]u64{
|
const iv = [8]u64{
|
||||||
0x6a09e667f3bcc908,
|
0x6a09e667f3bcc908,
|
||||||
@ -399,35 +415,36 @@ pub fn Blake2b(comptime out_len: usize) type {
|
|||||||
buf: [128]u8,
|
buf: [128]u8,
|
||||||
buf_len: u8,
|
buf_len: u8,
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init(options: Options) Self {
|
||||||
return init_keyed("");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_keyed(key: []const u8) Self {
|
|
||||||
debug.assert(8 <= out_len and out_len <= 512);
|
debug.assert(8 <= out_len and out_len <= 512);
|
||||||
|
|
||||||
var d: Self = undefined;
|
var d: Self = undefined;
|
||||||
mem.copy(u64, d.h[0..], iv[0..]);
|
mem.copy(u64, d.h[0..], iv[0..]);
|
||||||
|
|
||||||
|
const key_len = if (options.key) |key| key.len else 0;
|
||||||
// default parameters
|
// default parameters
|
||||||
d.h[0] ^= 0x01010000 ^ (key.len << 8) ^ (out_len >> 3);
|
d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (out_len >> 3);
|
||||||
d.t = 0;
|
d.t = 0;
|
||||||
d.buf_len = 0;
|
d.buf_len = 0;
|
||||||
|
|
||||||
if (key.len > 0) {
|
if (options.salt) |salt| {
|
||||||
mem.set(u8, d.buf[key.len..], 0);
|
d.h[4] ^= mem.readIntLittle(u64, salt[0..8]);
|
||||||
d.update(key);
|
d.h[5] ^= mem.readIntLittle(u64, salt[8..16]);
|
||||||
|
}
|
||||||
|
if (options.context) |context| {
|
||||||
|
d.h[6] ^= mem.readIntLittle(u64, context[0..8]);
|
||||||
|
d.h[7] ^= mem.readIntLittle(u64, context[8..16]);
|
||||||
|
}
|
||||||
|
if (key_len > 0) {
|
||||||
|
mem.set(u8, d.buf[key_len..], 0);
|
||||||
|
d.update(options.key.?);
|
||||||
d.buf_len = 128;
|
d.buf_len = 128;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(b: []const u8, out: []u8) void {
|
pub fn hash(b: []const u8, out: []u8, options: Options) void {
|
||||||
Self.hash_keyed("", b, out);
|
var d = Self.init(options);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void {
|
|
||||||
var d = Self.init_keyed(key);
|
|
||||||
d.update(b);
|
d.update(b);
|
||||||
d.final(out);
|
d.final(out);
|
||||||
}
|
}
|
||||||
@ -534,7 +551,7 @@ test "blake2b384 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "blake2b384 streaming" {
|
test "blake2b384 streaming" {
|
||||||
var h = Blake2b384.init();
|
var h = Blake2b384.init(.{});
|
||||||
var out: [48]u8 = undefined;
|
var out: [48]u8 = undefined;
|
||||||
|
|
||||||
const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100";
|
const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100";
|
||||||
@ -544,12 +561,12 @@ test "blake2b384 streaming" {
|
|||||||
|
|
||||||
const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4";
|
const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4";
|
||||||
|
|
||||||
h = Blake2b384.init();
|
h = Blake2b384.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h2, out[0..]);
|
htest.assertEqual(h2, out[0..]);
|
||||||
|
|
||||||
h = Blake2b384.init();
|
h = Blake2b384.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -558,16 +575,36 @@ test "blake2b384 streaming" {
|
|||||||
|
|
||||||
const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c";
|
const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c";
|
||||||
|
|
||||||
h = Blake2b384.init();
|
h = Blake2b384.init(.{});
|
||||||
h.update("a" ** 64 ++ "b" ** 64);
|
h.update("a" ** 64 ++ "b" ** 64);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h3, out[0..]);
|
htest.assertEqual(h3, out[0..]);
|
||||||
|
|
||||||
h = Blake2b384.init();
|
h = Blake2b384.init(.{});
|
||||||
h.update("a" ** 64);
|
h.update("a" ** 64);
|
||||||
h.update("b" ** 64);
|
h.update("b" ** 64);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h3, out[0..]);
|
htest.assertEqual(h3, out[0..]);
|
||||||
|
|
||||||
|
h = Blake2b384.init(.{});
|
||||||
|
h.update("a" ** 64);
|
||||||
|
h.update("b" ** 64);
|
||||||
|
h.final(out[0..]);
|
||||||
|
htest.assertEqual(h3, out[0..]);
|
||||||
|
|
||||||
|
const h4 = "934c48fcb197031c71f583d92f98703510805e72142e0b46f5752d1e971bc86c355d556035613ff7a4154b4de09dac5c";
|
||||||
|
|
||||||
|
h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 });
|
||||||
|
h.update("a" ** 64);
|
||||||
|
h.update("b" ** 64);
|
||||||
|
h.final(out[0..]);
|
||||||
|
htest.assertEqual(h4, out[0..]);
|
||||||
|
|
||||||
|
h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 });
|
||||||
|
h.update("a" ** 64);
|
||||||
|
h.update("b" ** 64);
|
||||||
|
h.final(out[0..]);
|
||||||
|
htest.assertEqual(h4, out[0..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "comptime blake2b384" {
|
test "comptime blake2b384" {
|
||||||
@ -580,7 +617,7 @@ test "comptime blake2b384" {
|
|||||||
|
|
||||||
htest.assertEqualHash(Blake2b384, h1, block[0..]);
|
htest.assertEqualHash(Blake2b384, h1, block[0..]);
|
||||||
|
|
||||||
var h = Blake2b384.init();
|
var h = Blake2b384.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
|
|
||||||
@ -603,7 +640,7 @@ test "blake2b512 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "blake2b512 streaming" {
|
test "blake2b512 streaming" {
|
||||||
var h = Blake2b512.init();
|
var h = Blake2b512.init(.{});
|
||||||
var out: [64]u8 = undefined;
|
var out: [64]u8 = undefined;
|
||||||
|
|
||||||
const h1 = "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce";
|
const h1 = "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce";
|
||||||
@ -613,12 +650,12 @@ test "blake2b512 streaming" {
|
|||||||
|
|
||||||
const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923";
|
const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923";
|
||||||
|
|
||||||
h = Blake2b512.init();
|
h = Blake2b512.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h2, out[0..]);
|
htest.assertEqual(h2, out[0..]);
|
||||||
|
|
||||||
h = Blake2b512.init();
|
h = Blake2b512.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -627,12 +664,12 @@ test "blake2b512 streaming" {
|
|||||||
|
|
||||||
const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920";
|
const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920";
|
||||||
|
|
||||||
h = Blake2b512.init();
|
h = Blake2b512.init(.{});
|
||||||
h.update("a" ** 64 ++ "b" ** 64);
|
h.update("a" ** 64 ++ "b" ** 64);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h3, out[0..]);
|
htest.assertEqual(h3, out[0..]);
|
||||||
|
|
||||||
h = Blake2b512.init();
|
h = Blake2b512.init(.{});
|
||||||
h.update("a" ** 64);
|
h.update("a" ** 64);
|
||||||
h.update("b" ** 64);
|
h.update("b" ** 64);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
@ -645,16 +682,16 @@ test "blake2b512 keyed" {
|
|||||||
const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d";
|
const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d";
|
||||||
const key = "secret_key";
|
const key = "secret_key";
|
||||||
|
|
||||||
Blake2b512.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out);
|
Blake2b512.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key });
|
||||||
htest.assertEqual(h1, out[0..]);
|
htest.assertEqual(h1, out[0..]);
|
||||||
|
|
||||||
var h = Blake2b512.init_keyed(key);
|
var h = Blake2b512.init(.{ .key = key });
|
||||||
h.update("a" ** 64 ++ "b" ** 64);
|
h.update("a" ** 64 ++ "b" ** 64);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
|
|
||||||
htest.assertEqual(h1, out[0..]);
|
htest.assertEqual(h1, out[0..]);
|
||||||
|
|
||||||
h = Blake2b512.init_keyed(key);
|
h = Blake2b512.init(.{ .key = key });
|
||||||
h.update("a" ** 64);
|
h.update("a" ** 64);
|
||||||
h.update("b" ** 64);
|
h.update("b" ** 64);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
@ -672,7 +709,7 @@ test "comptime blake2b512" {
|
|||||||
|
|
||||||
htest.assertEqualHash(Blake2b512, h1, block[0..]);
|
htest.assertEqualHash(Blake2b512, h1, block[0..]);
|
||||||
|
|
||||||
var h = Blake2b512.init();
|
var h = Blake2b512.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
|
|
||||||
|
@ -279,6 +279,9 @@ fn parent_cv(
|
|||||||
|
|
||||||
/// An incremental hasher that can accept any number of writes.
|
/// An incremental hasher that can accept any number of writes.
|
||||||
pub const Blake3 = struct {
|
pub const Blake3 = struct {
|
||||||
|
pub const Options = struct { key: ?[KEY_LEN]u8 = null };
|
||||||
|
pub const KdfOptions = struct {};
|
||||||
|
|
||||||
chunk_state: ChunkState,
|
chunk_state: ChunkState,
|
||||||
key: [8]u32,
|
key: [8]u32,
|
||||||
cv_stack: [54][8]u32 = undefined, // Space for 54 subtree chaining values:
|
cv_stack: [54][8]u32 = undefined, // Space for 54 subtree chaining values:
|
||||||
@ -296,21 +299,20 @@ pub const Blake3 = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new `Blake3` for the regular hash function.
|
/// Construct a new `Blake3` for the hash function, with an optional key
|
||||||
pub fn init() Blake3 {
|
pub fn init(options: Options) Blake3 {
|
||||||
return comptime Blake3.init_internal(IV, 0);
|
if (options.key) |key| {
|
||||||
}
|
var key_words: [8]u32 = undefined;
|
||||||
|
words_from_little_endian_bytes(key_words[0..], key[0..]);
|
||||||
/// Construct a new `Blake3` for the keyed hash function.
|
return Blake3.init_internal(key_words, KEYED_HASH);
|
||||||
pub fn init_keyed(key: [KEY_LEN]u8) Blake3 {
|
} else {
|
||||||
var key_words: [8]u32 = undefined;
|
return Blake3.init_internal(IV, 0);
|
||||||
words_from_little_endian_bytes(key_words[0..], key[0..]);
|
}
|
||||||
return Blake3.init_internal(key_words, KEYED_HASH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new `Blake3` for the key derivation function. The context
|
/// Construct a new `Blake3` for the key derivation function. The context
|
||||||
/// string should be hardcoded, globally unique, and application-specific.
|
/// string should be hardcoded, globally unique, and application-specific.
|
||||||
pub fn init_derive_key(context: []const u8) Blake3 {
|
pub fn initKdf(context: []const u8, options: KdfOptions) Blake3 {
|
||||||
var context_hasher = Blake3.init_internal(IV, DERIVE_KEY_CONTEXT);
|
var context_hasher = Blake3.init_internal(IV, DERIVE_KEY_CONTEXT);
|
||||||
context_hasher.update(context);
|
context_hasher.update(context);
|
||||||
var context_key: [KEY_LEN]u8 = undefined;
|
var context_key: [KEY_LEN]u8 = undefined;
|
||||||
@ -320,8 +322,8 @@ pub const Blake3 = struct {
|
|||||||
return Blake3.init_internal(context_key_words, DERIVE_KEY_MATERIAL);
|
return Blake3.init_internal(context_key_words, DERIVE_KEY_MATERIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(in: []const u8, out: []u8) void {
|
pub fn hash(in: []const u8, out: []u8, options: Options) void {
|
||||||
var hasher = Blake3.init();
|
var hasher = Blake3.init(options);
|
||||||
hasher.update(in);
|
hasher.update(in);
|
||||||
hasher.final(out);
|
hasher.final(out);
|
||||||
}
|
}
|
||||||
@ -589,9 +591,9 @@ fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "BLAKE3 reference test cases" {
|
test "BLAKE3 reference test cases" {
|
||||||
var hash = &Blake3.init();
|
var hash = &Blake3.init(.{});
|
||||||
var keyed_hash = &Blake3.init_keyed(reference_test.key.*);
|
var keyed_hash = &Blake3.init(.{ .key = reference_test.key.* });
|
||||||
var derive_key = &Blake3.init_derive_key(reference_test.context_string);
|
var derive_key = &Blake3.initKdf(reference_test.context_string, .{});
|
||||||
|
|
||||||
for (reference_test.cases) |t| {
|
for (reference_test.cases) |t| {
|
||||||
test_blake3(hash, t.input_len, t.hash.*);
|
test_blake3(hash, t.input_len, t.hash.*);
|
||||||
|
@ -110,10 +110,11 @@ pub const Hash = struct {
|
|||||||
buf_off: usize,
|
buf_off: usize,
|
||||||
|
|
||||||
pub const block_length = State.RATE;
|
pub const block_length = State.RATE;
|
||||||
|
pub const Options = struct {};
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init(options: Options) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) },
|
.state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) },
|
||||||
.buf_off = 0,
|
.buf_off = 0,
|
||||||
@ -160,8 +161,8 @@ pub const Hash = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn hash(out: []u8, in: []const u8) void {
|
pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void {
|
||||||
var st = Hash.init();
|
var st = Hash.init(options);
|
||||||
st.update(in);
|
st.update(in);
|
||||||
st.final(out);
|
st.final(out);
|
||||||
}
|
}
|
||||||
@ -174,7 +175,7 @@ test "hash" {
|
|||||||
var msg: [58 / 2]u8 = undefined;
|
var msg: [58 / 2]u8 = undefined;
|
||||||
try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
|
try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
|
||||||
var md: [32]u8 = undefined;
|
var md: [32]u8 = undefined;
|
||||||
hash(&md, &msg);
|
hash(&md, &msg, .{});
|
||||||
htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md);
|
htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ pub fn Hmac(comptime Hash: type) type {
|
|||||||
|
|
||||||
// Normalize key length to block size of hash
|
// Normalize key length to block size of hash
|
||||||
if (key.len > Hash.block_length) {
|
if (key.len > Hash.block_length) {
|
||||||
Hash.hash(key, ctx.scratch[0..mac_length]);
|
Hash.hash(key, ctx.scratch[0..mac_length], .{});
|
||||||
mem.set(u8, ctx.scratch[mac_length..Hash.block_length], 0);
|
mem.set(u8, ctx.scratch[mac_length..Hash.block_length], 0);
|
||||||
} else if (key.len < Hash.block_length) {
|
} else if (key.len < Hash.block_length) {
|
||||||
mem.copy(u8, ctx.scratch[0..key.len], key);
|
mem.copy(u8, ctx.scratch[0..key.len], key);
|
||||||
@ -62,7 +62,7 @@ pub fn Hmac(comptime Hash: type) type {
|
|||||||
b.* = ctx.scratch[i] ^ 0x36;
|
b.* = ctx.scratch[i] ^ 0x36;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.hash = Hash.init();
|
ctx.hash = Hash.init(.{});
|
||||||
ctx.hash.update(ctx.i_key_pad[0..]);
|
ctx.hash.update(ctx.i_key_pad[0..]);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ pub fn Hmac(comptime Hash: type) type {
|
|||||||
debug.assert(Hash.block_length >= out.len and out.len >= mac_length);
|
debug.assert(Hash.block_length >= out.len and out.len >= mac_length);
|
||||||
|
|
||||||
ctx.hash.final(ctx.scratch[0..mac_length]);
|
ctx.hash.final(ctx.scratch[0..mac_length]);
|
||||||
var ohash = Hash.init();
|
var ohash = Hash.init(.{});
|
||||||
ohash.update(ctx.o_key_pad[0..]);
|
ohash.update(ctx.o_key_pad[0..]);
|
||||||
ohash.update(ctx.scratch[0..mac_length]);
|
ohash.update(ctx.scratch[0..mac_length]);
|
||||||
ohash.final(out[0..mac_length]);
|
ohash.final(out[0..mac_length]);
|
||||||
|
@ -39,6 +39,7 @@ pub const Md5 = struct {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const block_length = 64;
|
pub const block_length = 64;
|
||||||
pub const digest_length = 16;
|
pub const digest_length = 16;
|
||||||
|
pub const Options = struct {};
|
||||||
|
|
||||||
s: [4]u32,
|
s: [4]u32,
|
||||||
// Streaming Cache
|
// Streaming Cache
|
||||||
@ -46,7 +47,7 @@ pub const Md5 = struct {
|
|||||||
buf_len: u8,
|
buf_len: u8,
|
||||||
total_len: u64,
|
total_len: u64,
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init(options: Options) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.s = [_]u32{
|
.s = [_]u32{
|
||||||
0x67452301,
|
0x67452301,
|
||||||
@ -60,8 +61,8 @@ pub const Md5 = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(b: []const u8, out: []u8) void {
|
pub fn hash(b: []const u8, out: []u8, options: Options) void {
|
||||||
var d = Md5.init();
|
var d = Md5.init(options);
|
||||||
d.update(b);
|
d.update(b);
|
||||||
d.final(out);
|
d.final(out);
|
||||||
}
|
}
|
||||||
@ -257,18 +258,18 @@ test "md5 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "md5 streaming" {
|
test "md5 streaming" {
|
||||||
var h = Md5.init();
|
var h = Md5.init(.{});
|
||||||
var out: [16]u8 = undefined;
|
var out: [16]u8 = undefined;
|
||||||
|
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]);
|
htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]);
|
||||||
|
|
||||||
h = Md5.init();
|
h = Md5.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]);
|
htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]);
|
||||||
|
|
||||||
h = Md5.init();
|
h = Md5.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -281,7 +282,7 @@ test "md5 aligned final" {
|
|||||||
var block = [_]u8{0} ** Md5.block_length;
|
var block = [_]u8{0} ** Md5.block_length;
|
||||||
var out: [Md5.digest_length]u8 = undefined;
|
var out: [Md5.digest_length]u8 = undefined;
|
||||||
|
|
||||||
var h = Md5.init();
|
var h = Md5.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ pub const Sha1 = struct {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const block_length = 64;
|
pub const block_length = 64;
|
||||||
pub const digest_length = 20;
|
pub const digest_length = 20;
|
||||||
|
pub const Options = struct {};
|
||||||
|
|
||||||
s: [5]u32,
|
s: [5]u32,
|
||||||
// Streaming Cache
|
// Streaming Cache
|
||||||
@ -43,7 +44,7 @@ pub const Sha1 = struct {
|
|||||||
buf_len: u8 = 0,
|
buf_len: u8 = 0,
|
||||||
total_len: u64 = 0,
|
total_len: u64 = 0,
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init(options: Options) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.s = [_]u32{
|
.s = [_]u32{
|
||||||
0x67452301,
|
0x67452301,
|
||||||
@ -55,8 +56,8 @@ pub const Sha1 = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(b: []const u8, out: []u8) void {
|
pub fn hash(b: []const u8, out: []u8, options: Options) void {
|
||||||
var d = Sha1.init();
|
var d = Sha1.init(options);
|
||||||
d.update(b);
|
d.update(b);
|
||||||
d.final(out);
|
d.final(out);
|
||||||
}
|
}
|
||||||
@ -276,18 +277,18 @@ test "sha1 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha1 streaming" {
|
test "sha1 streaming" {
|
||||||
var h = Sha1.init();
|
var h = Sha1.init(.{});
|
||||||
var out: [20]u8 = undefined;
|
var out: [20]u8 = undefined;
|
||||||
|
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]);
|
htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]);
|
||||||
|
|
||||||
h = Sha1.init();
|
h = Sha1.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);
|
htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);
|
||||||
|
|
||||||
h = Sha1.init();
|
h = Sha1.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -299,7 +300,7 @@ test "sha1 aligned final" {
|
|||||||
var block = [_]u8{0} ** Sha1.block_length;
|
var block = [_]u8{0} ** Sha1.block_length;
|
||||||
var out: [Sha1.digest_length]u8 = undefined;
|
var out: [Sha1.digest_length]u8 = undefined;
|
||||||
|
|
||||||
var h = Sha1.init();
|
var h = Sha1.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const block_length = 64;
|
pub const block_length = 64;
|
||||||
pub const digest_length = params.out_len / 8;
|
pub const digest_length = params.out_len / 8;
|
||||||
|
pub const Options = struct {};
|
||||||
|
|
||||||
s: [8]u32,
|
s: [8]u32,
|
||||||
// Streaming Cache
|
// Streaming Cache
|
||||||
@ -95,7 +96,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
|
|||||||
buf_len: u8 = 0,
|
buf_len: u8 = 0,
|
||||||
total_len: u64 = 0,
|
total_len: u64 = 0,
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init(options: Options) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.s = [_]u32{
|
.s = [_]u32{
|
||||||
params.iv0,
|
params.iv0,
|
||||||
@ -110,8 +111,8 @@ fn Sha2_32(comptime params: Sha2Params32) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(b: []const u8, out: []u8) void {
|
pub fn hash(b: []const u8, out: []u8, options: Options) void {
|
||||||
var d = Self.init();
|
var d = Self.init(options);
|
||||||
d.update(b);
|
d.update(b);
|
||||||
d.final(out);
|
d.final(out);
|
||||||
}
|
}
|
||||||
@ -296,18 +297,18 @@ test "sha224 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha224 streaming" {
|
test "sha224 streaming" {
|
||||||
var h = Sha224.init();
|
var h = Sha224.init(.{});
|
||||||
var out: [28]u8 = undefined;
|
var out: [28]u8 = undefined;
|
||||||
|
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]);
|
htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]);
|
||||||
|
|
||||||
h = Sha224.init();
|
h = Sha224.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]);
|
htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]);
|
||||||
|
|
||||||
h = Sha224.init();
|
h = Sha224.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -322,18 +323,18 @@ test "sha256 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha256 streaming" {
|
test "sha256 streaming" {
|
||||||
var h = Sha256.init();
|
var h = Sha256.init(.{});
|
||||||
var out: [32]u8 = undefined;
|
var out: [32]u8 = undefined;
|
||||||
|
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]);
|
htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]);
|
||||||
|
|
||||||
h = Sha256.init();
|
h = Sha256.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]);
|
htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]);
|
||||||
|
|
||||||
h = Sha256.init();
|
h = Sha256.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -345,7 +346,7 @@ test "sha256 aligned final" {
|
|||||||
var block = [_]u8{0} ** Sha256.block_length;
|
var block = [_]u8{0} ** Sha256.block_length;
|
||||||
var out: [Sha256.digest_length]u8 = undefined;
|
var out: [Sha256.digest_length]u8 = undefined;
|
||||||
|
|
||||||
var h = Sha256.init();
|
var h = Sha256.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
}
|
}
|
||||||
@ -458,6 +459,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const block_length = 128;
|
pub const block_length = 128;
|
||||||
pub const digest_length = params.out_len / 8;
|
pub const digest_length = params.out_len / 8;
|
||||||
|
pub const Options = struct {};
|
||||||
|
|
||||||
s: [8]u64,
|
s: [8]u64,
|
||||||
// Streaming Cache
|
// Streaming Cache
|
||||||
@ -465,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
|
|||||||
buf_len: u8 = 0,
|
buf_len: u8 = 0,
|
||||||
total_len: u128 = 0,
|
total_len: u128 = 0,
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init(options: Options) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.s = [_]u64{
|
.s = [_]u64{
|
||||||
params.iv0,
|
params.iv0,
|
||||||
@ -480,8 +482,8 @@ fn Sha2_64(comptime params: Sha2Params64) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(b: []const u8, out: []u8) void {
|
pub fn hash(b: []const u8, out: []u8, options: Options) void {
|
||||||
var d = Self.init();
|
var d = Self.init(options);
|
||||||
d.update(b);
|
d.update(b);
|
||||||
d.final(out);
|
d.final(out);
|
||||||
}
|
}
|
||||||
@ -693,7 +695,7 @@ test "sha384 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha384 streaming" {
|
test "sha384 streaming" {
|
||||||
var h = Sha384.init();
|
var h = Sha384.init(.{});
|
||||||
var out: [48]u8 = undefined;
|
var out: [48]u8 = undefined;
|
||||||
|
|
||||||
const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";
|
const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";
|
||||||
@ -702,12 +704,12 @@ test "sha384 streaming" {
|
|||||||
|
|
||||||
const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
|
const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
|
||||||
|
|
||||||
h = Sha384.init();
|
h = Sha384.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h2, out[0..]);
|
htest.assertEqual(h2, out[0..]);
|
||||||
|
|
||||||
h = Sha384.init();
|
h = Sha384.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -727,7 +729,7 @@ test "sha512 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha512 streaming" {
|
test "sha512 streaming" {
|
||||||
var h = Sha512.init();
|
var h = Sha512.init(.{});
|
||||||
var out: [64]u8 = undefined;
|
var out: [64]u8 = undefined;
|
||||||
|
|
||||||
const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";
|
const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";
|
||||||
@ -736,12 +738,12 @@ test "sha512 streaming" {
|
|||||||
|
|
||||||
const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
|
const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
|
||||||
|
|
||||||
h = Sha512.init();
|
h = Sha512.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h2, out[0..]);
|
htest.assertEqual(h2, out[0..]);
|
||||||
|
|
||||||
h = Sha512.init();
|
h = Sha512.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -753,7 +755,7 @@ test "sha512 aligned final" {
|
|||||||
var block = [_]u8{0} ** Sha512.block_length;
|
var block = [_]u8{0} ** Sha512.block_length;
|
||||||
var out: [Sha512.digest_length]u8 = undefined;
|
var out: [Sha512.digest_length]u8 = undefined;
|
||||||
|
|
||||||
var h = Sha512.init();
|
var h = Sha512.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
}
|
}
|
||||||
|
@ -20,17 +20,18 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const block_length = 200;
|
pub const block_length = 200;
|
||||||
pub const digest_length = bits / 8;
|
pub const digest_length = bits / 8;
|
||||||
|
pub const Options = struct {};
|
||||||
|
|
||||||
s: [200]u8,
|
s: [200]u8,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
rate: usize,
|
rate: usize,
|
||||||
|
|
||||||
pub fn init() Self {
|
pub fn init(options: Options) Self {
|
||||||
return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) };
|
return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(b: []const u8, out: []u8) void {
|
pub fn hash(b: []const u8, out: []u8, options: Options) void {
|
||||||
var d = Self.init();
|
var d = Self.init(options);
|
||||||
d.update(b);
|
d.update(b);
|
||||||
d.final(out);
|
d.final(out);
|
||||||
}
|
}
|
||||||
@ -175,18 +176,18 @@ test "sha3-224 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha3-224 streaming" {
|
test "sha3-224 streaming" {
|
||||||
var h = Sha3_224.init();
|
var h = Sha3_224.init(.{});
|
||||||
var out: [28]u8 = undefined;
|
var out: [28]u8 = undefined;
|
||||||
|
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]);
|
htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]);
|
||||||
|
|
||||||
h = Sha3_224.init();
|
h = Sha3_224.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]);
|
htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]);
|
||||||
|
|
||||||
h = Sha3_224.init();
|
h = Sha3_224.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -201,18 +202,18 @@ test "sha3-256 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha3-256 streaming" {
|
test "sha3-256 streaming" {
|
||||||
var h = Sha3_256.init();
|
var h = Sha3_256.init(.{});
|
||||||
var out: [32]u8 = undefined;
|
var out: [32]u8 = undefined;
|
||||||
|
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]);
|
htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]);
|
||||||
|
|
||||||
h = Sha3_256.init();
|
h = Sha3_256.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]);
|
htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]);
|
||||||
|
|
||||||
h = Sha3_256.init();
|
h = Sha3_256.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -224,7 +225,7 @@ test "sha3-256 aligned final" {
|
|||||||
var block = [_]u8{0} ** Sha3_256.block_length;
|
var block = [_]u8{0} ** Sha3_256.block_length;
|
||||||
var out: [Sha3_256.digest_length]u8 = undefined;
|
var out: [Sha3_256.digest_length]u8 = undefined;
|
||||||
|
|
||||||
var h = Sha3_256.init();
|
var h = Sha3_256.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
}
|
}
|
||||||
@ -239,7 +240,7 @@ test "sha3-384 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha3-384 streaming" {
|
test "sha3-384 streaming" {
|
||||||
var h = Sha3_384.init();
|
var h = Sha3_384.init(.{});
|
||||||
var out: [48]u8 = undefined;
|
var out: [48]u8 = undefined;
|
||||||
|
|
||||||
const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004";
|
const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004";
|
||||||
@ -247,12 +248,12 @@ test "sha3-384 streaming" {
|
|||||||
htest.assertEqual(h1, out[0..]);
|
htest.assertEqual(h1, out[0..]);
|
||||||
|
|
||||||
const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25";
|
const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25";
|
||||||
h = Sha3_384.init();
|
h = Sha3_384.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h2, out[0..]);
|
htest.assertEqual(h2, out[0..]);
|
||||||
|
|
||||||
h = Sha3_384.init();
|
h = Sha3_384.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -270,7 +271,7 @@ test "sha3-512 single" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "sha3-512 streaming" {
|
test "sha3-512 streaming" {
|
||||||
var h = Sha3_512.init();
|
var h = Sha3_512.init(.{});
|
||||||
var out: [64]u8 = undefined;
|
var out: [64]u8 = undefined;
|
||||||
|
|
||||||
const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26";
|
const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26";
|
||||||
@ -278,12 +279,12 @@ test "sha3-512 streaming" {
|
|||||||
htest.assertEqual(h1, out[0..]);
|
htest.assertEqual(h1, out[0..]);
|
||||||
|
|
||||||
const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0";
|
const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0";
|
||||||
h = Sha3_512.init();
|
h = Sha3_512.init(.{});
|
||||||
h.update("abc");
|
h.update("abc");
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
htest.assertEqual(h2, out[0..]);
|
htest.assertEqual(h2, out[0..]);
|
||||||
|
|
||||||
h = Sha3_512.init();
|
h = Sha3_512.init(.{});
|
||||||
h.update("a");
|
h.update("a");
|
||||||
h.update("b");
|
h.update("b");
|
||||||
h.update("c");
|
h.update("c");
|
||||||
@ -295,7 +296,7 @@ test "sha3-512 aligned final" {
|
|||||||
var block = [_]u8{0} ** Sha3_512.block_length;
|
var block = [_]u8{0} ** Sha3_512.block_length;
|
||||||
var out: [Sha3_512.digest_length]u8 = undefined;
|
var out: [Sha3_512.digest_length]u8 = undefined;
|
||||||
|
|
||||||
var h = Sha3_512.init();
|
var h = Sha3_512.init(.{});
|
||||||
h.update(&block);
|
h.update(&block);
|
||||||
h.final(out[0..]);
|
h.final(out[0..]);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ const fmt = std.fmt;
|
|||||||
// Hash using the specified hasher `H` asserting `expected == H(input)`.
|
// Hash using the specified hasher `H` asserting `expected == H(input)`.
|
||||||
pub fn assertEqualHash(comptime Hasher: anytype, comptime expected: []const u8, input: []const u8) void {
|
pub fn assertEqualHash(comptime Hasher: anytype, comptime expected: []const u8, input: []const u8) void {
|
||||||
var h: [expected.len / 2]u8 = undefined;
|
var h: [expected.len / 2]u8 = undefined;
|
||||||
Hasher.hash(input, h[0..]);
|
Hasher.hash(input, h[0..], .{});
|
||||||
|
|
||||||
assertEqual(expected, &h);
|
assertEqual(expected, &h);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ pub fn hashSrc(src: []const u8) SrcHash {
|
|||||||
std.mem.copy(u8, &out, src);
|
std.mem.copy(u8, &out, src);
|
||||||
std.mem.set(u8, out[src.len..], 0);
|
std.mem.set(u8, out[src.len..], 0);
|
||||||
} else {
|
} else {
|
||||||
std.crypto.hash.Blake3.hash(src, &out);
|
std.crypto.hash.Blake3.hash(src, &out, .{});
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user