authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-08-21 00:51:14+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-08-21 00:51:14+02:00
logfc55cd458a7cd72ea876cf747b1ddd43d8dc6e20
tree421c3e4036ac5288aa9312d4af68608884f8dae1
parentadf3d00e874275557b69ef65164a2b2a0dd88167

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.

15 files changed, 194 insertions(+), 149 deletions(-)

lib/std/bloom_filter.zig+1-1
......@@ -158,7 +158,7 @@ pub fn BloomFilter(
158158}
159159
160160fn hashFunc(out: []u8, Ki: usize, in: []const u8) void {
161 var st = std.crypto.hash.Gimli.init();
161 var st = std.crypto.hash.Gimli.init(.{});
162162 st.update(std.mem.asBytes(&Ki));
163163 st.update(in);
164164 st.final(out);
lib/std/cache_hash.zig+5-5
......@@ -56,7 +56,7 @@ pub const CacheHash = struct {
5656 pub fn init(allocator: *Allocator, dir: fs.Dir, manifest_dir_path: []const u8) !CacheHash {
5757 return CacheHash{
5858 .allocator = allocator,
59 .blake3 = Blake3.init(),
59 .blake3 = Blake3.init(.{}),
6060 .manifest_dir = try dir.makeOpenPath(manifest_dir_path, .{}),
6161 .manifest_file = null,
6262 .manifest_dirty = false,
......@@ -137,7 +137,7 @@ pub const CacheHash = struct {
137137
138138 base64_encoder.encode(self.b64_digest[0..], &bin_digest);
139139
140 self.blake3 = Blake3.init();
140 self.blake3 = Blake3.init(.{});
141141 self.blake3.update(&bin_digest);
142142
143143 const manifest_file_path = try fmt.allocPrint(self.allocator, "{}.txt", .{self.b64_digest});
......@@ -256,7 +256,7 @@ pub const CacheHash = struct {
256256 // cache miss
257257 // keep the manifest file open
258258 // reset the hash
259 self.blake3 = Blake3.init();
259 self.blake3 = Blake3.init(.{});
260260 self.blake3.update(&bin_digest);
261261
262262 // Remove files not in the initial hash
......@@ -304,7 +304,7 @@ pub const CacheHash = struct {
304304
305305 // Hash while reading from disk, to keep the contents in the cpu cache while
306306 // doing hashing.
307 var blake3 = Blake3.init();
307 var blake3 = Blake3.init(.{});
308308 var off: usize = 0;
309309 while (true) {
310310 // give me everything you've got, captain
......@@ -434,7 +434,7 @@ pub const CacheHash = struct {
434434};
435435
436436fn hashFile(file: fs.File, bin_digest: []u8) !void {
437 var blake3 = Blake3.init();
437 var blake3 = Blake3.init(.{});
438438 var buf: [1024]u8 = undefined;
439439
440440 while (true) {
lib/std/crypto.zig+1-1
......@@ -112,7 +112,7 @@ test "issue #4532: no index out of bounds" {
112112 var block = [_]u8{'#'} ** Hasher.block_length;
113113 var out1: [Hasher.digest_length]u8 = undefined;
114114 var out2: [Hasher.digest_length]u8 = undefined;
115 const h0 = Hasher.init();
115 const h0 = Hasher.init(.{});
116116 var h = h0;
117117 h.update(block[0..]);
118118 h.final(out1[0..]);
lib/std/crypto/25519/ed25519.zig+5-5
......@@ -33,7 +33,7 @@ pub const Ed25519 = struct {
3333 /// from which the actual secret is derived.
3434 pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 {
3535 var az: [Sha512.digest_length]u8 = undefined;
36 var h = Sha512.init();
36 var h = Sha512.init(.{});
3737 h.update(&seed);
3838 h.final(&az);
3939 const p = try Curve.basePoint.clampedMul(az[0..32].*);
......@@ -56,11 +56,11 @@ pub const Ed25519 = struct {
5656 pub fn sign(msg: []const u8, key_pair: [keypair_length]u8, noise: ?[noise_length]u8) ![signature_length]u8 {
5757 const public_key = key_pair[32..];
5858 var az: [Sha512.digest_length]u8 = undefined;
59 var h = Sha512.init();
59 var h = Sha512.init(.{});
6060 h.update(key_pair[0..seed_length]);
6161 h.final(&az);
6262
63 h = Sha512.init();
63 h = Sha512.init(.{});
6464 if (noise) |*z| {
6565 h.update(z);
6666 }
......@@ -74,7 +74,7 @@ pub const Ed25519 = struct {
7474 var sig: [signature_length]u8 = undefined;
7575 mem.copy(u8, sig[0..32], &r.toBytes());
7676 mem.copy(u8, sig[32..], public_key);
77 h = Sha512.init();
77 h = Sha512.init(.{});
7878 h.update(&sig);
7979 h.update(msg);
8080 var hram64: [Sha512.digest_length]u8 = undefined;
......@@ -98,7 +98,7 @@ pub const Ed25519 = struct {
9898 const a = try Curve.fromBytes(public_key);
9999 try a.rejectIdentity();
100100
101 var h = Sha512.init();
101 var h = Sha512.init(.{});
102102 h.update(r);
103103 h.update(&public_key);
104104 h.update(msg);
lib/std/crypto/benchmark.zig+1-1
......@@ -35,7 +35,7 @@ const hashes = [_]Crypto{
3535};
3636
3737pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 {
38 var h = Hash.init();
38 var h = Hash.init(.{});
3939
4040 var block: [Hash.digest_length]u8 = undefined;
4141 prng.random.bytes(block[0..]);
lib/std/crypto/blake2.zig+97-60
......@@ -40,6 +40,7 @@ pub fn Blake2s(comptime out_len: usize) type {
4040 const Self = @This();
4141 pub const block_length = 64;
4242 pub const digest_length = out_len / 8;
43 pub const Options = struct { key: ?[]const u8 = null, salt: ?[8]u8 = null, context: ?[8]u8 = null };
4344
4445 const iv = [8]u32{
4546 0x6A09E667,
......@@ -71,35 +72,36 @@ pub fn Blake2s(comptime out_len: usize) type {
7172 buf: [64]u8,
7273 buf_len: u8,
7374
74 pub fn init() Self {
75 return init_keyed("");
76 }
77
78 pub fn init_keyed(key: []const u8) Self {
75 pub fn init(options: Options) Self {
7976 debug.assert(8 <= out_len and out_len <= 512);
8077
8178 var d: Self = undefined;
8279 mem.copy(u32, d.h[0..], iv[0..]);
8380
81 const key_len = if (options.key) |key| key.len else 0;
8482 // default parameters
85 d.h[0] ^= 0x01010000 ^ @truncate(u32, key.len << 8) ^ @intCast(u32, out_len >> 3);
83 d.h[0] ^= 0x01010000 ^ @truncate(u32, key_len << 8) ^ @intCast(u32, out_len >> 3);
8684 d.t = 0;
8785 d.buf_len = 0;
8886
89 if (key.len > 0) {
90 mem.set(u8, d.buf[key.len..], 0);
91 d.update(key);
87 if (options.salt) |salt| {
88 d.h[4] ^= mem.readIntLittle(u32, salt[0..4]);
89 d.h[5] ^= mem.readIntLittle(u32, salt[4..8]);
90 }
91 if (options.context) |context| {
92 d.h[6] ^= mem.readIntLittle(u32, context[0..4]);
93 d.h[7] ^= mem.readIntLittle(u32, context[4..8]);
94 }
95 if (key_len > 0) {
96 mem.set(u8, d.buf[key_len..], 0);
97 d.update(options.key.?);
9298 d.buf_len = 64;
9399 }
94100 return d;
95101 }
96102
97 pub fn hash(b: []const u8, out: []u8) void {
98 Self.hash_keyed("", b, out);
99 }
100
101 pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void {
102 var d = Self.init_keyed(key);
103 pub fn hash(b: []const u8, out: []u8, options: Options) void {
104 var d = Self.init(options);
103105 d.update(b);
104106 d.final(out);
105107 }
......@@ -208,7 +210,7 @@ test "blake2s224 single" {
208210}
209211
210212test "blake2s224 streaming" {
211 var h = Blake2s224.init();
213 var h = Blake2s224.init(.{});
212214 var out: [28]u8 = undefined;
213215
214216 const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4";
......@@ -218,12 +220,12 @@ test "blake2s224 streaming" {
218220
219221 const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55";
220222
221 h = Blake2s224.init();
223 h = Blake2s224.init(.{});
222224 h.update("abc");
223225 h.final(out[0..]);
224226 htest.assertEqual(h2, out[0..]);
225227
226 h = Blake2s224.init();
228 h = Blake2s224.init(.{});
227229 h.update("a");
228230 h.update("b");
229231 h.update("c");
......@@ -232,16 +234,29 @@ test "blake2s224 streaming" {
232234
233235 const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01";
234236
235 h = Blake2s224.init();
237 h = Blake2s224.init(.{});
236238 h.update("a" ** 32);
237239 h.update("b" ** 32);
238240 h.final(out[0..]);
239241 htest.assertEqual(h3, out[0..]);
240242
241 h = Blake2s224.init();
243 h = Blake2s224.init(.{});
242244 h.update("a" ** 32 ++ "b" ** 32);
243245 h.final(out[0..]);
244246 htest.assertEqual(h3, out[0..]);
247
248 const h4 = "a4d6a9d253441b80e5dfd60a04db169ffab77aec56a2855c402828c3";
249
250 h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 });
251 h.update("a" ** 32);
252 h.update("b" ** 32);
253 h.final(out[0..]);
254 htest.assertEqual(h4, out[0..]);
255
256 h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 });
257 h.update("a" ** 32 ++ "b" ** 32);
258 h.final(out[0..]);
259 htest.assertEqual(h4, out[0..]);
245260}
246261
247262test "comptime blake2s224" {
......@@ -254,7 +269,7 @@ test "comptime blake2s224" {
254269
255270 htest.assertEqualHash(Blake2s224, h1, block[0..]);
256271
257 var h = Blake2s224.init();
272 var h = Blake2s224.init(.{});
258273 h.update(&block);
259274 h.final(out[0..]);
260275
......@@ -277,7 +292,7 @@ test "blake2s256 single" {
277292}
278293
279294test "blake2s256 streaming" {
280 var h = Blake2s256.init();
295 var h = Blake2s256.init(.{});
281296 var out: [32]u8 = undefined;
282297
283298 const h1 = "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9";
......@@ -287,12 +302,12 @@ test "blake2s256 streaming" {
287302
288303 const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982";
289304
290 h = Blake2s256.init();
305 h = Blake2s256.init(.{});
291306 h.update("abc");
292307 h.final(out[0..]);
293308 htest.assertEqual(h2, out[0..]);
294309
295 h = Blake2s256.init();
310 h = Blake2s256.init(.{});
296311 h.update("a");
297312 h.update("b");
298313 h.update("c");
......@@ -301,13 +316,13 @@ test "blake2s256 streaming" {
301316
302317 const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977";
303318
304 h = Blake2s256.init();
319 h = Blake2s256.init(.{});
305320 h.update("a" ** 32);
306321 h.update("b" ** 32);
307322 h.final(out[0..]);
308323 htest.assertEqual(h3, out[0..]);
309324
310 h = Blake2s256.init();
325 h = Blake2s256.init(.{});
311326 h.update("a" ** 32 ++ "b" ** 32);
312327 h.final(out[0..]);
313328 htest.assertEqual(h3, out[0..]);
......@@ -319,16 +334,16 @@ test "blake2s256 keyed" {
319334 const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6";
320335 const key = "secret_key";
321336
322 Blake2s256.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out);
337 Blake2s256.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key });
323338 htest.assertEqual(h1, out[0..]);
324339
325 var h = Blake2s256.init_keyed(key);
340 var h = Blake2s256.init(.{ .key = key });
326341 h.update("a" ** 64 ++ "b" ** 64);
327342 h.final(out[0..]);
328343
329344 htest.assertEqual(h1, out[0..]);
330345
331 h = Blake2s256.init_keyed(key);
346 h = Blake2s256.init(.{ .key = key });
332347 h.update("a" ** 64);
333348 h.update("b" ** 64);
334349 h.final(out[0..]);
......@@ -346,7 +361,7 @@ test "comptime blake2s256" {
346361
347362 htest.assertEqualHash(Blake2s256, h1, block[0..]);
348363
349 var h = Blake2s256.init();
364 var h = Blake2s256.init(.{});
350365 h.update(&block);
351366 h.final(out[0..]);
352367
......@@ -366,6 +381,7 @@ pub fn Blake2b(comptime out_len: usize) type {
366381 const Self = @This();
367382 pub const block_length = 128;
368383 pub const digest_length = out_len / 8;
384 pub const Options = struct { key: ?[]const u8 = null, salt: ?[16]u8 = null, context: ?[16]u8 = null };
369385
370386 const iv = [8]u64{
371387 0x6a09e667f3bcc908,
......@@ -399,35 +415,36 @@ pub fn Blake2b(comptime out_len: usize) type {
399415 buf: [128]u8,
400416 buf_len: u8,
401417
402 pub fn init() Self {
403 return init_keyed("");
404 }
405
406 pub fn init_keyed(key: []const u8) Self {
418 pub fn init(options: Options) Self {
407419 debug.assert(8 <= out_len and out_len <= 512);
408420
409421 var d: Self = undefined;
410422 mem.copy(u64, d.h[0..], iv[0..]);
411423
424 const key_len = if (options.key) |key| key.len else 0;
412425 // default parameters
413 d.h[0] ^= 0x01010000 ^ (key.len << 8) ^ (out_len >> 3);
426 d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (out_len >> 3);
414427 d.t = 0;
415428 d.buf_len = 0;
416429
417 if (key.len > 0) {
418 mem.set(u8, d.buf[key.len..], 0);
419 d.update(key);
430 if (options.salt) |salt| {
431 d.h[4] ^= mem.readIntLittle(u64, salt[0..8]);
432 d.h[5] ^= mem.readIntLittle(u64, salt[8..16]);
433 }
434 if (options.context) |context| {
435 d.h[6] ^= mem.readIntLittle(u64, context[0..8]);
436 d.h[7] ^= mem.readIntLittle(u64, context[8..16]);
437 }
438 if (key_len > 0) {
439 mem.set(u8, d.buf[key_len..], 0);
440 d.update(options.key.?);
420441 d.buf_len = 128;
421442 }
422443 return d;
423444 }
424445
425 pub fn hash(b: []const u8, out: []u8) void {
426 Self.hash_keyed("", b, out);
427 }
428
429 pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void {
430 var d = Self.init_keyed(key);
446 pub fn hash(b: []const u8, out: []u8, options: Options) void {
447 var d = Self.init(options);
431448 d.update(b);
432449 d.final(out);
433450 }
......@@ -534,7 +551,7 @@ test "blake2b384 single" {
534551}
535552
536553test "blake2b384 streaming" {
537 var h = Blake2b384.init();
554 var h = Blake2b384.init(.{});
538555 var out: [48]u8 = undefined;
539556
540557 const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100";
......@@ -544,12 +561,12 @@ test "blake2b384 streaming" {
544561
545562 const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4";
546563
547 h = Blake2b384.init();
564 h = Blake2b384.init(.{});
548565 h.update("abc");
549566 h.final(out[0..]);
550567 htest.assertEqual(h2, out[0..]);
551568
552 h = Blake2b384.init();
569 h = Blake2b384.init(.{});
553570 h.update("a");
554571 h.update("b");
555572 h.update("c");
......@@ -558,16 +575,36 @@ test "blake2b384 streaming" {
558575
559576 const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c";
560577
561 h = Blake2b384.init();
578 h = Blake2b384.init(.{});
562579 h.update("a" ** 64 ++ "b" ** 64);
563580 h.final(out[0..]);
564581 htest.assertEqual(h3, out[0..]);
565582
566 h = Blake2b384.init();
583 h = Blake2b384.init(.{});
567584 h.update("a" ** 64);
568585 h.update("b" ** 64);
569586 h.final(out[0..]);
570587 htest.assertEqual(h3, out[0..]);
588
589 h = Blake2b384.init(.{});
590 h.update("a" ** 64);
591 h.update("b" ** 64);
592 h.final(out[0..]);
593 htest.assertEqual(h3, out[0..]);
594
595 const h4 = "934c48fcb197031c71f583d92f98703510805e72142e0b46f5752d1e971bc86c355d556035613ff7a4154b4de09dac5c";
596
597 h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 });
598 h.update("a" ** 64);
599 h.update("b" ** 64);
600 h.final(out[0..]);
601 htest.assertEqual(h4, out[0..]);
602
603 h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 });
604 h.update("a" ** 64);
605 h.update("b" ** 64);
606 h.final(out[0..]);
607 htest.assertEqual(h4, out[0..]);
571608}
572609
573610test "comptime blake2b384" {
......@@ -580,7 +617,7 @@ test "comptime blake2b384" {
580617
581618 htest.assertEqualHash(Blake2b384, h1, block[0..]);
582619
583 var h = Blake2b384.init();
620 var h = Blake2b384.init(.{});
584621 h.update(&block);
585622 h.final(out[0..]);
586623
......@@ -603,7 +640,7 @@ test "blake2b512 single" {
603640}
604641
605642test "blake2b512 streaming" {
606 var h = Blake2b512.init();
643 var h = Blake2b512.init(.{});
607644 var out: [64]u8 = undefined;
608645
609646 const h1 = "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce";
......@@ -613,12 +650,12 @@ test "blake2b512 streaming" {
613650
614651 const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923";
615652
616 h = Blake2b512.init();
653 h = Blake2b512.init(.{});
617654 h.update("abc");
618655 h.final(out[0..]);
619656 htest.assertEqual(h2, out[0..]);
620657
621 h = Blake2b512.init();
658 h = Blake2b512.init(.{});
622659 h.update("a");
623660 h.update("b");
624661 h.update("c");
......@@ -627,12 +664,12 @@ test "blake2b512 streaming" {
627664
628665 const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920";
629666
630 h = Blake2b512.init();
667 h = Blake2b512.init(.{});
631668 h.update("a" ** 64 ++ "b" ** 64);
632669 h.final(out[0..]);
633670 htest.assertEqual(h3, out[0..]);
634671
635 h = Blake2b512.init();
672 h = Blake2b512.init(.{});
636673 h.update("a" ** 64);
637674 h.update("b" ** 64);
638675 h.final(out[0..]);
......@@ -645,16 +682,16 @@ test "blake2b512 keyed" {
645682 const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d";
646683 const key = "secret_key";
647684
648 Blake2b512.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out);
685 Blake2b512.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key });
649686 htest.assertEqual(h1, out[0..]);
650687
651 var h = Blake2b512.init_keyed(key);
688 var h = Blake2b512.init(.{ .key = key });
652689 h.update("a" ** 64 ++ "b" ** 64);
653690 h.final(out[0..]);
654691
655692 htest.assertEqual(h1, out[0..]);
656693
657 h = Blake2b512.init_keyed(key);
694 h = Blake2b512.init(.{ .key = key });
658695 h.update("a" ** 64);
659696 h.update("b" ** 64);
660697 h.final(out[0..]);
......@@ -672,7 +709,7 @@ test "comptime blake2b512" {
672709
673710 htest.assertEqualHash(Blake2b512, h1, block[0..]);
674711
675 var h = Blake2b512.init();
712 var h = Blake2b512.init(.{});
676713 h.update(&block);
677714 h.final(out[0..]);
678715
lib/std/crypto/blake3.zig+18-16
......@@ -279,6 +279,9 @@ fn parent_cv(
279279
280280/// An incremental hasher that can accept any number of writes.
281281pub const Blake3 = struct {
282 pub const Options = struct { key: ?[KEY_LEN]u8 = null };
283 pub const KdfOptions = struct {};
284
282285 chunk_state: ChunkState,
283286 key: [8]u32,
284287 cv_stack: [54][8]u32 = undefined, // Space for 54 subtree chaining values:
......@@ -296,21 +299,20 @@ pub const Blake3 = struct {
296299 };
297300 }
298301
299 /// Construct a new `Blake3` for the regular hash function.
300 pub fn init() Blake3 {
301 return comptime Blake3.init_internal(IV, 0);
302 }
303
304 /// Construct a new `Blake3` for the keyed hash function.
305 pub fn init_keyed(key: [KEY_LEN]u8) Blake3 {
306 var key_words: [8]u32 = undefined;
307 words_from_little_endian_bytes(key_words[0..], key[0..]);
308 return Blake3.init_internal(key_words, KEYED_HASH);
302 /// Construct a new `Blake3` for the hash function, with an optional key
303 pub fn init(options: Options) Blake3 {
304 if (options.key) |key| {
305 var key_words: [8]u32 = undefined;
306 words_from_little_endian_bytes(key_words[0..], key[0..]);
307 return Blake3.init_internal(key_words, KEYED_HASH);
308 } else {
309 return Blake3.init_internal(IV, 0);
310 }
309311 }
310312
311313 /// Construct a new `Blake3` for the key derivation function. The context
312314 /// string should be hardcoded, globally unique, and application-specific.
313 pub fn init_derive_key(context: []const u8) Blake3 {
315 pub fn initKdf(context: []const u8, options: KdfOptions) Blake3 {
314316 var context_hasher = Blake3.init_internal(IV, DERIVE_KEY_CONTEXT);
315317 context_hasher.update(context);
316318 var context_key: [KEY_LEN]u8 = undefined;
......@@ -320,8 +322,8 @@ pub const Blake3 = struct {
320322 return Blake3.init_internal(context_key_words, DERIVE_KEY_MATERIAL);
321323 }
322324
323 pub fn hash(in: []const u8, out: []u8) void {
324 var hasher = Blake3.init();
325 pub fn hash(in: []const u8, out: []u8, options: Options) void {
326 var hasher = Blake3.init(options);
325327 hasher.update(in);
326328 hasher.final(out);
327329 }
......@@ -589,9 +591,9 @@ fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void {
589591}
590592
591593test "BLAKE3 reference test cases" {
592 var hash = &Blake3.init();
593 var keyed_hash = &Blake3.init_keyed(reference_test.key.*);
594 var derive_key = &Blake3.init_derive_key(reference_test.context_string);
594 var hash = &Blake3.init(.{});
595 var keyed_hash = &Blake3.init(.{ .key = reference_test.key.* });
596 var derive_key = &Blake3.initKdf(reference_test.context_string, .{});
595597
596598 for (reference_test.cases) |t| {
597599 test_blake3(hash, t.input_len, t.hash.*);
lib/std/crypto/gimli.zig+5-4
......@@ -110,10 +110,11 @@ pub const Hash = struct {
110110 buf_off: usize,
111111
112112 pub const block_length = State.RATE;
113 pub const Options = struct {};
113114
114115 const Self = @This();
115116
116 pub fn init() Self {
117 pub fn init(options: Options) Self {
117118 return Self{
118119 .state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) },
119120 .buf_off = 0,
......@@ -160,8 +161,8 @@ pub const Hash = struct {
160161 }
161162};
162163
163pub fn hash(out: []u8, in: []const u8) void {
164 var st = Hash.init();
164pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void {
165 var st = Hash.init(options);
165166 st.update(in);
166167 st.final(out);
167168}
......@@ -174,7 +175,7 @@ test "hash" {
174175 var msg: [58 / 2]u8 = undefined;
175176 try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
176177 var md: [32]u8 = undefined;
177 hash(&md, &msg);
178 hash(&md, &msg, .{});
178179 htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md);
179180}
180181
lib/std/crypto/hmac.zig+3-3
......@@ -45,7 +45,7 @@ pub fn Hmac(comptime Hash: type) type {
4545
4646 // Normalize key length to block size of hash
4747 if (key.len > Hash.block_length) {
48 Hash.hash(key, ctx.scratch[0..mac_length]);
48 Hash.hash(key, ctx.scratch[0..mac_length], .{});
4949 mem.set(u8, ctx.scratch[mac_length..Hash.block_length], 0);
5050 } else if (key.len < Hash.block_length) {
5151 mem.copy(u8, ctx.scratch[0..key.len], key);
......@@ -62,7 +62,7 @@ pub fn Hmac(comptime Hash: type) type {
6262 b.* = ctx.scratch[i] ^ 0x36;
6363 }
6464
65 ctx.hash = Hash.init();
65 ctx.hash = Hash.init(.{});
6666 ctx.hash.update(ctx.i_key_pad[0..]);
6767 return ctx;
6868 }
......@@ -75,7 +75,7 @@ pub fn Hmac(comptime Hash: type) type {
7575 debug.assert(Hash.block_length >= out.len and out.len >= mac_length);
7676
7777 ctx.hash.final(ctx.scratch[0..mac_length]);
78 var ohash = Hash.init();
78 var ohash = Hash.init(.{});
7979 ohash.update(ctx.o_key_pad[0..]);
8080 ohash.update(ctx.scratch[0..mac_length]);
8181 ohash.final(out[0..mac_length]);
lib/std/crypto/md5.zig+8-7
......@@ -39,6 +39,7 @@ pub const Md5 = struct {
3939 const Self = @This();
4040 pub const block_length = 64;
4141 pub const digest_length = 16;
42 pub const Options = struct {};
4243
4344 s: [4]u32,
4445 // Streaming Cache
......@@ -46,7 +47,7 @@ pub const Md5 = struct {
4647 buf_len: u8,
4748 total_len: u64,
4849
49 pub fn init() Self {
50 pub fn init(options: Options) Self {
5051 return Self{
5152 .s = [_]u32{
5253 0x67452301,
......@@ -60,8 +61,8 @@ pub const Md5 = struct {
6061 };
6162 }
6263
63 pub fn hash(b: []const u8, out: []u8) void {
64 var d = Md5.init();
64 pub fn hash(b: []const u8, out: []u8, options: Options) void {
65 var d = Md5.init(options);
6566 d.update(b);
6667 d.final(out);
6768 }
......@@ -257,18 +258,18 @@ test "md5 single" {
257258}
258259
259260test "md5 streaming" {
260 var h = Md5.init();
261 var h = Md5.init(.{});
261262 var out: [16]u8 = undefined;
262263
263264 h.final(out[0..]);
264265 htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]);
265266
266 h = Md5.init();
267 h = Md5.init(.{});
267268 h.update("abc");
268269 h.final(out[0..]);
269270 htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]);
270271
271 h = Md5.init();
272 h = Md5.init(.{});
272273 h.update("a");
273274 h.update("b");
274275 h.update("c");
......@@ -281,7 +282,7 @@ test "md5 aligned final" {
281282 var block = [_]u8{0} ** Md5.block_length;
282283 var out: [Md5.digest_length]u8 = undefined;
283284
284 var h = Md5.init();
285 var h = Md5.init(.{});
285286 h.update(&block);
286287 h.final(out[0..]);
287288}
lib/std/crypto/sha1.zig+8-7
......@@ -36,6 +36,7 @@ pub const Sha1 = struct {
3636 const Self = @This();
3737 pub const block_length = 64;
3838 pub const digest_length = 20;
39 pub const Options = struct {};
3940
4041 s: [5]u32,
4142 // Streaming Cache
......@@ -43,7 +44,7 @@ pub const Sha1 = struct {
4344 buf_len: u8 = 0,
4445 total_len: u64 = 0,
4546
46 pub fn init() Self {
47 pub fn init(options: Options) Self {
4748 return Self{
4849 .s = [_]u32{
4950 0x67452301,
......@@ -55,8 +56,8 @@ pub const Sha1 = struct {
5556 };
5657 }
5758
58 pub fn hash(b: []const u8, out: []u8) void {
59 var d = Sha1.init();
59 pub fn hash(b: []const u8, out: []u8, options: Options) void {
60 var d = Sha1.init(options);
6061 d.update(b);
6162 d.final(out);
6263 }
......@@ -276,18 +277,18 @@ test "sha1 single" {
276277}
277278
278279test "sha1 streaming" {
279 var h = Sha1.init();
280 var h = Sha1.init(.{});
280281 var out: [20]u8 = undefined;
281282
282283 h.final(out[0..]);
283284 htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]);
284285
285 h = Sha1.init();
286 h = Sha1.init(.{});
286287 h.update("abc");
287288 h.final(out[0..]);
288289 htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);
289290
290 h = Sha1.init();
291 h = Sha1.init(.{});
291292 h.update("a");
292293 h.update("b");
293294 h.update("c");
......@@ -299,7 +300,7 @@ test "sha1 aligned final" {
299300 var block = [_]u8{0} ** Sha1.block_length;
300301 var out: [Sha1.digest_length]u8 = undefined;
301302
302 var h = Sha1.init();
303 var h = Sha1.init(.{});
303304 h.update(&block);
304305 h.final(out[0..]);
305306}
lib/std/crypto/sha2.zig+22-20
......@@ -88,6 +88,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
8888 const Self = @This();
8989 pub const block_length = 64;
9090 pub const digest_length = params.out_len / 8;
91 pub const Options = struct {};
9192
9293 s: [8]u32,
9394 // Streaming Cache
......@@ -95,7 +96,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
9596 buf_len: u8 = 0,
9697 total_len: u64 = 0,
9798
98 pub fn init() Self {
99 pub fn init(options: Options) Self {
99100 return Self{
100101 .s = [_]u32{
101102 params.iv0,
......@@ -110,8 +111,8 @@ fn Sha2_32(comptime params: Sha2Params32) type {
110111 };
111112 }
112113
113 pub fn hash(b: []const u8, out: []u8) void {
114 var d = Self.init();
114 pub fn hash(b: []const u8, out: []u8, options: Options) void {
115 var d = Self.init(options);
115116 d.update(b);
116117 d.final(out);
117118 }
......@@ -296,18 +297,18 @@ test "sha224 single" {
296297}
297298
298299test "sha224 streaming" {
299 var h = Sha224.init();
300 var h = Sha224.init(.{});
300301 var out: [28]u8 = undefined;
301302
302303 h.final(out[0..]);
303304 htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]);
304305
305 h = Sha224.init();
306 h = Sha224.init(.{});
306307 h.update("abc");
307308 h.final(out[0..]);
308309 htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]);
309310
310 h = Sha224.init();
311 h = Sha224.init(.{});
311312 h.update("a");
312313 h.update("b");
313314 h.update("c");
......@@ -322,18 +323,18 @@ test "sha256 single" {
322323}
323324
324325test "sha256 streaming" {
325 var h = Sha256.init();
326 var h = Sha256.init(.{});
326327 var out: [32]u8 = undefined;
327328
328329 h.final(out[0..]);
329330 htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]);
330331
331 h = Sha256.init();
332 h = Sha256.init(.{});
332333 h.update("abc");
333334 h.final(out[0..]);
334335 htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]);
335336
336 h = Sha256.init();
337 h = Sha256.init(.{});
337338 h.update("a");
338339 h.update("b");
339340 h.update("c");
......@@ -345,7 +346,7 @@ test "sha256 aligned final" {
345346 var block = [_]u8{0} ** Sha256.block_length;
346347 var out: [Sha256.digest_length]u8 = undefined;
347348
348 var h = Sha256.init();
349 var h = Sha256.init(.{});
349350 h.update(&block);
350351 h.final(out[0..]);
351352}
......@@ -458,6 +459,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
458459 const Self = @This();
459460 pub const block_length = 128;
460461 pub const digest_length = params.out_len / 8;
462 pub const Options = struct {};
461463
462464 s: [8]u64,
463465 // Streaming Cache
......@@ -465,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
465467 buf_len: u8 = 0,
466468 total_len: u128 = 0,
467469
468 pub fn init() Self {
470 pub fn init(options: Options) Self {
469471 return Self{
470472 .s = [_]u64{
471473 params.iv0,
......@@ -480,8 +482,8 @@ fn Sha2_64(comptime params: Sha2Params64) type {
480482 };
481483 }
482484
483 pub fn hash(b: []const u8, out: []u8) void {
484 var d = Self.init();
485 pub fn hash(b: []const u8, out: []u8, options: Options) void {
486 var d = Self.init(options);
485487 d.update(b);
486488 d.final(out);
487489 }
......@@ -693,7 +695,7 @@ test "sha384 single" {
693695}
694696
695697test "sha384 streaming" {
696 var h = Sha384.init();
698 var h = Sha384.init(.{});
697699 var out: [48]u8 = undefined;
698700
699701 const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";
......@@ -702,12 +704,12 @@ test "sha384 streaming" {
702704
703705 const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
704706
705 h = Sha384.init();
707 h = Sha384.init(.{});
706708 h.update("abc");
707709 h.final(out[0..]);
708710 htest.assertEqual(h2, out[0..]);
709711
710 h = Sha384.init();
712 h = Sha384.init(.{});
711713 h.update("a");
712714 h.update("b");
713715 h.update("c");
......@@ -727,7 +729,7 @@ test "sha512 single" {
727729}
728730
729731test "sha512 streaming" {
730 var h = Sha512.init();
732 var h = Sha512.init(.{});
731733 var out: [64]u8 = undefined;
732734
733735 const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";
......@@ -736,12 +738,12 @@ test "sha512 streaming" {
736738
737739 const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
738740
739 h = Sha512.init();
741 h = Sha512.init(.{});
740742 h.update("abc");
741743 h.final(out[0..]);
742744 htest.assertEqual(h2, out[0..]);
743745
744 h = Sha512.init();
746 h = Sha512.init(.{});
745747 h.update("a");
746748 h.update("b");
747749 h.update("c");
......@@ -753,7 +755,7 @@ test "sha512 aligned final" {
753755 var block = [_]u8{0} ** Sha512.block_length;
754756 var out: [Sha512.digest_length]u8 = undefined;
755757
756 var h = Sha512.init();
758 var h = Sha512.init(.{});
757759 h.update(&block);
758760 h.final(out[0..]);
759761}
lib/std/crypto/sha3.zig+18-17
......@@ -20,17 +20,18 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
2020 const Self = @This();
2121 pub const block_length = 200;
2222 pub const digest_length = bits / 8;
23 pub const Options = struct {};
2324
2425 s: [200]u8,
2526 offset: usize,
2627 rate: usize,
2728
28 pub fn init() Self {
29 pub fn init(options: Options) Self {
2930 return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) };
3031 }
3132
32 pub fn hash(b: []const u8, out: []u8) void {
33 var d = Self.init();
33 pub fn hash(b: []const u8, out: []u8, options: Options) void {
34 var d = Self.init(options);
3435 d.update(b);
3536 d.final(out);
3637 }
......@@ -175,18 +176,18 @@ test "sha3-224 single" {
175176}
176177
177178test "sha3-224 streaming" {
178 var h = Sha3_224.init();
179 var h = Sha3_224.init(.{});
179180 var out: [28]u8 = undefined;
180181
181182 h.final(out[0..]);
182183 htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]);
183184
184 h = Sha3_224.init();
185 h = Sha3_224.init(.{});
185186 h.update("abc");
186187 h.final(out[0..]);
187188 htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]);
188189
189 h = Sha3_224.init();
190 h = Sha3_224.init(.{});
190191 h.update("a");
191192 h.update("b");
192193 h.update("c");
......@@ -201,18 +202,18 @@ test "sha3-256 single" {
201202}
202203
203204test "sha3-256 streaming" {
204 var h = Sha3_256.init();
205 var h = Sha3_256.init(.{});
205206 var out: [32]u8 = undefined;
206207
207208 h.final(out[0..]);
208209 htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]);
209210
210 h = Sha3_256.init();
211 h = Sha3_256.init(.{});
211212 h.update("abc");
212213 h.final(out[0..]);
213214 htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]);
214215
215 h = Sha3_256.init();
216 h = Sha3_256.init(.{});
216217 h.update("a");
217218 h.update("b");
218219 h.update("c");
......@@ -224,7 +225,7 @@ test "sha3-256 aligned final" {
224225 var block = [_]u8{0} ** Sha3_256.block_length;
225226 var out: [Sha3_256.digest_length]u8 = undefined;
226227
227 var h = Sha3_256.init();
228 var h = Sha3_256.init(.{});
228229 h.update(&block);
229230 h.final(out[0..]);
230231}
......@@ -239,7 +240,7 @@ test "sha3-384 single" {
239240}
240241
241242test "sha3-384 streaming" {
242 var h = Sha3_384.init();
243 var h = Sha3_384.init(.{});
243244 var out: [48]u8 = undefined;
244245
245246 const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004";
......@@ -247,12 +248,12 @@ test "sha3-384 streaming" {
247248 htest.assertEqual(h1, out[0..]);
248249
249250 const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25";
250 h = Sha3_384.init();
251 h = Sha3_384.init(.{});
251252 h.update("abc");
252253 h.final(out[0..]);
253254 htest.assertEqual(h2, out[0..]);
254255
255 h = Sha3_384.init();
256 h = Sha3_384.init(.{});
256257 h.update("a");
257258 h.update("b");
258259 h.update("c");
......@@ -270,7 +271,7 @@ test "sha3-512 single" {
270271}
271272
272273test "sha3-512 streaming" {
273 var h = Sha3_512.init();
274 var h = Sha3_512.init(.{});
274275 var out: [64]u8 = undefined;
275276
276277 const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26";
......@@ -278,12 +279,12 @@ test "sha3-512 streaming" {
278279 htest.assertEqual(h1, out[0..]);
279280
280281 const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0";
281 h = Sha3_512.init();
282 h = Sha3_512.init(.{});
282283 h.update("abc");
283284 h.final(out[0..]);
284285 htest.assertEqual(h2, out[0..]);
285286
286 h = Sha3_512.init();
287 h = Sha3_512.init(.{});
287288 h.update("a");
288289 h.update("b");
289290 h.update("c");
......@@ -295,7 +296,7 @@ test "sha3-512 aligned final" {
295296 var block = [_]u8{0} ** Sha3_512.block_length;
296297 var out: [Sha3_512.digest_length]u8 = undefined;
297298
298 var h = Sha3_512.init();
299 var h = Sha3_512.init(.{});
299300 h.update(&block);
300301 h.final(out[0..]);
301302}
lib/std/crypto/test.zig+1-1
......@@ -11,7 +11,7 @@ const fmt = std.fmt;
1111// Hash using the specified hasher `H` asserting `expected == H(input)`.
1212pub fn assertEqualHash(comptime Hasher: anytype, comptime expected: []const u8, input: []const u8) void {
1313 var h: [expected.len / 2]u8 = undefined;
14 Hasher.hash(input, h[0..]);
14 Hasher.hash(input, h[0..], .{});
1515
1616 assertEqual(expected, &h);
1717}
lib/std/zig.zig+1-1
......@@ -26,7 +26,7 @@ pub fn hashSrc(src: []const u8) SrcHash {
2626 std.mem.copy(u8, &out, src);
2727 std.mem.set(u8, out[src.len..], 0);
2828 } else {
29 std.crypto.hash.Blake3.hash(src, &out);
29 std.crypto.hash.Blake3.hash(src, &out, .{});
3030 }
3131 return out;
3232}