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(...@@ -158,7 +158,7 @@ pub fn BloomFilter(
158}158}
159159
160fn hashFunc(out: []u8, Ki: usize, in: []const u8) void {160fn 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(.{});
162 st.update(std.mem.asBytes(&Ki));162 st.update(std.mem.asBytes(&Ki));
163 st.update(in);163 st.update(in);
164 st.final(out);164 st.final(out);
lib/std/cache_hash.zig+5-5
...@@ -56,7 +56,7 @@ pub const CacheHash = struct {...@@ -56,7 +56,7 @@ pub const CacheHash = struct {
56 pub fn init(allocator: *Allocator, dir: fs.Dir, manifest_dir_path: []const u8) !CacheHash {56 pub fn init(allocator: *Allocator, dir: fs.Dir, manifest_dir_path: []const u8) !CacheHash {
57 return CacheHash{57 return CacheHash{
58 .allocator = allocator,58 .allocator = allocator,
59 .blake3 = Blake3.init(),59 .blake3 = Blake3.init(.{}),
60 .manifest_dir = try dir.makeOpenPath(manifest_dir_path, .{}),60 .manifest_dir = try dir.makeOpenPath(manifest_dir_path, .{}),
61 .manifest_file = null,61 .manifest_file = null,
62 .manifest_dirty = false,62 .manifest_dirty = false,
...@@ -137,7 +137,7 @@ pub const CacheHash = struct {...@@ -137,7 +137,7 @@ pub const CacheHash = struct {
137137
138 base64_encoder.encode(self.b64_digest[0..], &bin_digest);138 base64_encoder.encode(self.b64_digest[0..], &bin_digest);
139139
140 self.blake3 = Blake3.init();140 self.blake3 = Blake3.init(.{});
141 self.blake3.update(&bin_digest);141 self.blake3.update(&bin_digest);
142142
143 const manifest_file_path = try fmt.allocPrint(self.allocator, "{}.txt", .{self.b64_digest});143 const manifest_file_path = try fmt.allocPrint(self.allocator, "{}.txt", .{self.b64_digest});
...@@ -256,7 +256,7 @@ pub const CacheHash = struct {...@@ -256,7 +256,7 @@ pub const CacheHash = struct {
256 // cache miss256 // cache miss
257 // keep the manifest file open257 // keep the manifest file open
258 // reset the hash258 // reset the hash
259 self.blake3 = Blake3.init();259 self.blake3 = Blake3.init(.{});
260 self.blake3.update(&bin_digest);260 self.blake3.update(&bin_digest);
261261
262 // Remove files not in the initial hash262 // Remove files not in the initial hash
...@@ -304,7 +304,7 @@ pub const CacheHash = struct {...@@ -304,7 +304,7 @@ pub const CacheHash = struct {
304304
305 // Hash while reading from disk, to keep the contents in the cpu cache while305 // Hash while reading from disk, to keep the contents in the cpu cache while
306 // doing hashing.306 // doing hashing.
307 var blake3 = Blake3.init();307 var blake3 = Blake3.init(.{});
308 var off: usize = 0;308 var off: usize = 0;
309 while (true) {309 while (true) {
310 // give me everything you've got, captain310 // give me everything you've got, captain
...@@ -434,7 +434,7 @@ pub const CacheHash = struct {...@@ -434,7 +434,7 @@ pub const CacheHash = struct {
434};434};
435435
436fn hashFile(file: fs.File, bin_digest: []u8) !void {436fn hashFile(file: fs.File, bin_digest: []u8) !void {
437 var blake3 = Blake3.init();437 var blake3 = Blake3.init(.{});
438 var buf: [1024]u8 = undefined;438 var buf: [1024]u8 = undefined;
439439
440 while (true) {440 while (true) {
lib/std/crypto.zig+1-1
...@@ -112,7 +112,7 @@ test "issue #4532: no index out of bounds" {...@@ -112,7 +112,7 @@ test "issue #4532: no index out of bounds" {
112 var block = [_]u8{'#'} ** Hasher.block_length;112 var block = [_]u8{'#'} ** Hasher.block_length;
113 var out1: [Hasher.digest_length]u8 = undefined;113 var out1: [Hasher.digest_length]u8 = undefined;
114 var out2: [Hasher.digest_length]u8 = undefined;114 var out2: [Hasher.digest_length]u8 = undefined;
115 const h0 = Hasher.init();115 const h0 = Hasher.init(.{});
116 var h = h0;116 var h = h0;
117 h.update(block[0..]);117 h.update(block[0..]);
118 h.final(out1[0..]);118 h.final(out1[0..]);
lib/std/crypto/25519/ed25519.zig+5-5
...@@ -33,7 +33,7 @@ pub const Ed25519 = struct {...@@ -33,7 +33,7 @@ pub const Ed25519 = struct {
33 /// from which the actual secret is derived.33 /// from which the actual secret is derived.
34 pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 {34 pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 {
35 var az: [Sha512.digest_length]u8 = undefined;35 var az: [Sha512.digest_length]u8 = undefined;
36 var h = Sha512.init();36 var h = Sha512.init(.{});
37 h.update(&seed);37 h.update(&seed);
38 h.final(&az);38 h.final(&az);
39 const p = try Curve.basePoint.clampedMul(az[0..32].*);39 const p = try Curve.basePoint.clampedMul(az[0..32].*);
...@@ -56,11 +56,11 @@ pub const Ed25519 = struct {...@@ -56,11 +56,11 @@ pub const Ed25519 = struct {
56 pub fn sign(msg: []const u8, key_pair: [keypair_length]u8, noise: ?[noise_length]u8) ![signature_length]u8 {56 pub fn sign(msg: []const u8, key_pair: [keypair_length]u8, noise: ?[noise_length]u8) ![signature_length]u8 {
57 const public_key = key_pair[32..];57 const public_key = key_pair[32..];
58 var az: [Sha512.digest_length]u8 = undefined;58 var az: [Sha512.digest_length]u8 = undefined;
59 var h = Sha512.init();59 var h = Sha512.init(.{});
60 h.update(key_pair[0..seed_length]);60 h.update(key_pair[0..seed_length]);
61 h.final(&az);61 h.final(&az);
6262
63 h = Sha512.init();63 h = Sha512.init(.{});
64 if (noise) |*z| {64 if (noise) |*z| {
65 h.update(z);65 h.update(z);
66 }66 }
...@@ -74,7 +74,7 @@ pub const Ed25519 = struct {...@@ -74,7 +74,7 @@ pub const Ed25519 = struct {
74 var sig: [signature_length]u8 = undefined;74 var sig: [signature_length]u8 = undefined;
75 mem.copy(u8, sig[0..32], &r.toBytes());75 mem.copy(u8, sig[0..32], &r.toBytes());
76 mem.copy(u8, sig[32..], public_key);76 mem.copy(u8, sig[32..], public_key);
77 h = Sha512.init();77 h = Sha512.init(.{});
78 h.update(&sig);78 h.update(&sig);
79 h.update(msg);79 h.update(msg);
80 var hram64: [Sha512.digest_length]u8 = undefined;80 var hram64: [Sha512.digest_length]u8 = undefined;
...@@ -98,7 +98,7 @@ pub const Ed25519 = struct {...@@ -98,7 +98,7 @@ pub const Ed25519 = struct {
98 const a = try Curve.fromBytes(public_key);98 const a = try Curve.fromBytes(public_key);
99 try a.rejectIdentity();99 try a.rejectIdentity();
100100
101 var h = Sha512.init();101 var h = Sha512.init(.{});
102 h.update(r);102 h.update(r);
103 h.update(&public_key);103 h.update(&public_key);
104 h.update(msg);104 h.update(msg);
lib/std/crypto/benchmark.zig+1-1
...@@ -35,7 +35,7 @@ const hashes = [_]Crypto{...@@ -35,7 +35,7 @@ const hashes = [_]Crypto{
35};35};
3636
37pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 {37pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 {
38 var h = Hash.init();38 var h = Hash.init(.{});
3939
40 var block: [Hash.digest_length]u8 = undefined;40 var block: [Hash.digest_length]u8 = undefined;
41 prng.random.bytes(block[0..]);41 prng.random.bytes(block[0..]);
lib/std/crypto/blake2.zig+97-60
...@@ -40,6 +40,7 @@ pub fn Blake2s(comptime out_len: usize) type {...@@ -40,6 +40,7 @@ pub fn Blake2s(comptime out_len: usize) type {
40 const Self = @This();40 const Self = @This();
41 pub const block_length = 64;41 pub const block_length = 64;
42 pub const digest_length = out_len / 8;42 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
44 const iv = [8]u32{45 const iv = [8]u32{
45 0x6A09E667,46 0x6A09E667,
...@@ -71,35 +72,36 @@ pub fn Blake2s(comptime out_len: usize) type {...@@ -71,35 +72,36 @@ pub fn Blake2s(comptime out_len: usize) type {
71 buf: [64]u8,72 buf: [64]u8,
72 buf_len: u8,73 buf_len: u8,
7374
74 pub fn init() Self {75 pub fn init(options: Options) Self {
75 return init_keyed("");
76 }
77
78 pub fn init_keyed(key: []const u8) Self {
79 debug.assert(8 <= out_len and out_len <= 512);76 debug.assert(8 <= out_len and out_len <= 512);
8077
81 var d: Self = undefined;78 var d: Self = undefined;
82 mem.copy(u32, d.h[0..], iv[0..]);79 mem.copy(u32, d.h[0..], iv[0..]);
8380
81 const key_len = if (options.key) |key| key.len else 0;
84 // default parameters82 // 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);
86 d.t = 0;84 d.t = 0;
87 d.buf_len = 0;85 d.buf_len = 0;
8886
89 if (key.len > 0) {87 if (options.salt) |salt| {
90 mem.set(u8, d.buf[key.len..], 0);88 d.h[4] ^= mem.readIntLittle(u32, salt[0..4]);
91 d.update(key);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.?);
92 d.buf_len = 64;98 d.buf_len = 64;
93 }99 }
94 return d;100 return d;
95 }101 }
96102
97 pub fn hash(b: []const u8, out: []u8) void {103 pub fn hash(b: []const u8, out: []u8, options: Options) void {
98 Self.hash_keyed("", b, out);104 var d = Self.init(options);
99 }
100
101 pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void {
102 var d = Self.init_keyed(key);
103 d.update(b);105 d.update(b);
104 d.final(out);106 d.final(out);
105 }107 }
...@@ -208,7 +210,7 @@ test "blake2s224 single" {...@@ -208,7 +210,7 @@ test "blake2s224 single" {
208}210}
209211
210test "blake2s224 streaming" {212test "blake2s224 streaming" {
211 var h = Blake2s224.init();213 var h = Blake2s224.init(.{});
212 var out: [28]u8 = undefined;214 var out: [28]u8 = undefined;
213215
214 const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4";216 const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4";
...@@ -218,12 +220,12 @@ test "blake2s224 streaming" {...@@ -218,12 +220,12 @@ test "blake2s224 streaming" {
218220
219 const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55";221 const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55";
220222
221 h = Blake2s224.init();223 h = Blake2s224.init(.{});
222 h.update("abc");224 h.update("abc");
223 h.final(out[0..]);225 h.final(out[0..]);
224 htest.assertEqual(h2, out[0..]);226 htest.assertEqual(h2, out[0..]);
225227
226 h = Blake2s224.init();228 h = Blake2s224.init(.{});
227 h.update("a");229 h.update("a");
228 h.update("b");230 h.update("b");
229 h.update("c");231 h.update("c");
...@@ -232,16 +234,29 @@ test "blake2s224 streaming" {...@@ -232,16 +234,29 @@ test "blake2s224 streaming" {
232234
233 const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01";235 const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01";
234236
235 h = Blake2s224.init();237 h = Blake2s224.init(.{});
236 h.update("a" ** 32);238 h.update("a" ** 32);
237 h.update("b" ** 32);239 h.update("b" ** 32);
238 h.final(out[0..]);240 h.final(out[0..]);
239 htest.assertEqual(h3, out[0..]);241 htest.assertEqual(h3, out[0..]);
240242
241 h = Blake2s224.init();243 h = Blake2s224.init(.{});
242 h.update("a" ** 32 ++ "b" ** 32);244 h.update("a" ** 32 ++ "b" ** 32);
243 h.final(out[0..]);245 h.final(out[0..]);
244 htest.assertEqual(h3, out[0..]);246 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..]);
245}260}
246261
247test "comptime blake2s224" {262test "comptime blake2s224" {
...@@ -254,7 +269,7 @@ test "comptime blake2s224" {...@@ -254,7 +269,7 @@ test "comptime blake2s224" {
254269
255 htest.assertEqualHash(Blake2s224, h1, block[0..]);270 htest.assertEqualHash(Blake2s224, h1, block[0..]);
256271
257 var h = Blake2s224.init();272 var h = Blake2s224.init(.{});
258 h.update(&block);273 h.update(&block);
259 h.final(out[0..]);274 h.final(out[0..]);
260275
...@@ -277,7 +292,7 @@ test "blake2s256 single" {...@@ -277,7 +292,7 @@ test "blake2s256 single" {
277}292}
278293
279test "blake2s256 streaming" {294test "blake2s256 streaming" {
280 var h = Blake2s256.init();295 var h = Blake2s256.init(.{});
281 var out: [32]u8 = undefined;296 var out: [32]u8 = undefined;
282297
283 const h1 = "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9";298 const h1 = "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9";
...@@ -287,12 +302,12 @@ test "blake2s256 streaming" {...@@ -287,12 +302,12 @@ test "blake2s256 streaming" {
287302
288 const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982";303 const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982";
289304
290 h = Blake2s256.init();305 h = Blake2s256.init(.{});
291 h.update("abc");306 h.update("abc");
292 h.final(out[0..]);307 h.final(out[0..]);
293 htest.assertEqual(h2, out[0..]);308 htest.assertEqual(h2, out[0..]);
294309
295 h = Blake2s256.init();310 h = Blake2s256.init(.{});
296 h.update("a");311 h.update("a");
297 h.update("b");312 h.update("b");
298 h.update("c");313 h.update("c");
...@@ -301,13 +316,13 @@ test "blake2s256 streaming" {...@@ -301,13 +316,13 @@ test "blake2s256 streaming" {
301316
302 const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977";317 const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977";
303318
304 h = Blake2s256.init();319 h = Blake2s256.init(.{});
305 h.update("a" ** 32);320 h.update("a" ** 32);
306 h.update("b" ** 32);321 h.update("b" ** 32);
307 h.final(out[0..]);322 h.final(out[0..]);
308 htest.assertEqual(h3, out[0..]);323 htest.assertEqual(h3, out[0..]);
309324
310 h = Blake2s256.init();325 h = Blake2s256.init(.{});
311 h.update("a" ** 32 ++ "b" ** 32);326 h.update("a" ** 32 ++ "b" ** 32);
312 h.final(out[0..]);327 h.final(out[0..]);
313 htest.assertEqual(h3, out[0..]);328 htest.assertEqual(h3, out[0..]);
...@@ -319,16 +334,16 @@ test "blake2s256 keyed" {...@@ -319,16 +334,16 @@ test "blake2s256 keyed" {
319 const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6";334 const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6";
320 const key = "secret_key";335 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 });
323 htest.assertEqual(h1, out[0..]);338 htest.assertEqual(h1, out[0..]);
324339
325 var h = Blake2s256.init_keyed(key);340 var h = Blake2s256.init(.{ .key = key });
326 h.update("a" ** 64 ++ "b" ** 64);341 h.update("a" ** 64 ++ "b" ** 64);
327 h.final(out[0..]);342 h.final(out[0..]);
328343
329 htest.assertEqual(h1, out[0..]);344 htest.assertEqual(h1, out[0..]);
330345
331 h = Blake2s256.init_keyed(key);346 h = Blake2s256.init(.{ .key = key });
332 h.update("a" ** 64);347 h.update("a" ** 64);
333 h.update("b" ** 64);348 h.update("b" ** 64);
334 h.final(out[0..]);349 h.final(out[0..]);
...@@ -346,7 +361,7 @@ test "comptime blake2s256" {...@@ -346,7 +361,7 @@ test "comptime blake2s256" {
346361
347 htest.assertEqualHash(Blake2s256, h1, block[0..]);362 htest.assertEqualHash(Blake2s256, h1, block[0..]);
348363
349 var h = Blake2s256.init();364 var h = Blake2s256.init(.{});
350 h.update(&block);365 h.update(&block);
351 h.final(out[0..]);366 h.final(out[0..]);
352367
...@@ -366,6 +381,7 @@ pub fn Blake2b(comptime out_len: usize) type {...@@ -366,6 +381,7 @@ pub fn Blake2b(comptime out_len: usize) type {
366 const Self = @This();381 const Self = @This();
367 pub const block_length = 128;382 pub const block_length = 128;
368 pub const digest_length = out_len / 8;383 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
370 const iv = [8]u64{386 const iv = [8]u64{
371 0x6a09e667f3bcc908,387 0x6a09e667f3bcc908,
...@@ -399,35 +415,36 @@ pub fn Blake2b(comptime out_len: usize) type {...@@ -399,35 +415,36 @@ pub fn Blake2b(comptime out_len: usize) type {
399 buf: [128]u8,415 buf: [128]u8,
400 buf_len: u8,416 buf_len: u8,
401417
402 pub fn init() Self {418 pub fn init(options: Options) Self {
403 return init_keyed("");
404 }
405
406 pub fn init_keyed(key: []const u8) Self {
407 debug.assert(8 <= out_len and out_len <= 512);419 debug.assert(8 <= out_len and out_len <= 512);
408420
409 var d: Self = undefined;421 var d: Self = undefined;
410 mem.copy(u64, d.h[0..], iv[0..]);422 mem.copy(u64, d.h[0..], iv[0..]);
411423
424 const key_len = if (options.key) |key| key.len else 0;
412 // default parameters425 // default parameters
413 d.h[0] ^= 0x01010000 ^ (key.len << 8) ^ (out_len >> 3);426 d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (out_len >> 3);
414 d.t = 0;427 d.t = 0;
415 d.buf_len = 0;428 d.buf_len = 0;
416429
417 if (key.len > 0) {430 if (options.salt) |salt| {
418 mem.set(u8, d.buf[key.len..], 0);431 d.h[4] ^= mem.readIntLittle(u64, salt[0..8]);
419 d.update(key);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.?);
420 d.buf_len = 128;441 d.buf_len = 128;
421 }442 }
422 return d;443 return d;
423 }444 }
424445
425 pub fn hash(b: []const u8, out: []u8) void {446 pub fn hash(b: []const u8, out: []u8, options: Options) void {
426 Self.hash_keyed("", b, out);447 var d = Self.init(options);
427 }
428
429 pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void {
430 var d = Self.init_keyed(key);
431 d.update(b);448 d.update(b);
432 d.final(out);449 d.final(out);
433 }450 }
...@@ -534,7 +551,7 @@ test "blake2b384 single" {...@@ -534,7 +551,7 @@ test "blake2b384 single" {
534}551}
535552
536test "blake2b384 streaming" {553test "blake2b384 streaming" {
537 var h = Blake2b384.init();554 var h = Blake2b384.init(.{});
538 var out: [48]u8 = undefined;555 var out: [48]u8 = undefined;
539556
540 const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100";557 const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100";
...@@ -544,12 +561,12 @@ test "blake2b384 streaming" {...@@ -544,12 +561,12 @@ test "blake2b384 streaming" {
544561
545 const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4";562 const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4";
546563
547 h = Blake2b384.init();564 h = Blake2b384.init(.{});
548 h.update("abc");565 h.update("abc");
549 h.final(out[0..]);566 h.final(out[0..]);
550 htest.assertEqual(h2, out[0..]);567 htest.assertEqual(h2, out[0..]);
551568
552 h = Blake2b384.init();569 h = Blake2b384.init(.{});
553 h.update("a");570 h.update("a");
554 h.update("b");571 h.update("b");
555 h.update("c");572 h.update("c");
...@@ -558,16 +575,36 @@ test "blake2b384 streaming" {...@@ -558,16 +575,36 @@ test "blake2b384 streaming" {
558575
559 const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c";576 const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c";
560577
561 h = Blake2b384.init();578 h = Blake2b384.init(.{});
562 h.update("a" ** 64 ++ "b" ** 64);579 h.update("a" ** 64 ++ "b" ** 64);
563 h.final(out[0..]);580 h.final(out[0..]);
564 htest.assertEqual(h3, out[0..]);581 htest.assertEqual(h3, out[0..]);
565582
566 h = Blake2b384.init();583 h = Blake2b384.init(.{});
567 h.update("a" ** 64);584 h.update("a" ** 64);
568 h.update("b" ** 64);585 h.update("b" ** 64);
569 h.final(out[0..]);586 h.final(out[0..]);
570 htest.assertEqual(h3, out[0..]);587 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..]);
571}608}
572609
573test "comptime blake2b384" {610test "comptime blake2b384" {
...@@ -580,7 +617,7 @@ test "comptime blake2b384" {...@@ -580,7 +617,7 @@ test "comptime blake2b384" {
580617
581 htest.assertEqualHash(Blake2b384, h1, block[0..]);618 htest.assertEqualHash(Blake2b384, h1, block[0..]);
582619
583 var h = Blake2b384.init();620 var h = Blake2b384.init(.{});
584 h.update(&block);621 h.update(&block);
585 h.final(out[0..]);622 h.final(out[0..]);
586623
...@@ -603,7 +640,7 @@ test "blake2b512 single" {...@@ -603,7 +640,7 @@ test "blake2b512 single" {
603}640}
604641
605test "blake2b512 streaming" {642test "blake2b512 streaming" {
606 var h = Blake2b512.init();643 var h = Blake2b512.init(.{});
607 var out: [64]u8 = undefined;644 var out: [64]u8 = undefined;
608645
609 const h1 = "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce";646 const h1 = "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce";
...@@ -613,12 +650,12 @@ test "blake2b512 streaming" {...@@ -613,12 +650,12 @@ test "blake2b512 streaming" {
613650
614 const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923";651 const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923";
615652
616 h = Blake2b512.init();653 h = Blake2b512.init(.{});
617 h.update("abc");654 h.update("abc");
618 h.final(out[0..]);655 h.final(out[0..]);
619 htest.assertEqual(h2, out[0..]);656 htest.assertEqual(h2, out[0..]);
620657
621 h = Blake2b512.init();658 h = Blake2b512.init(.{});
622 h.update("a");659 h.update("a");
623 h.update("b");660 h.update("b");
624 h.update("c");661 h.update("c");
...@@ -627,12 +664,12 @@ test "blake2b512 streaming" {...@@ -627,12 +664,12 @@ test "blake2b512 streaming" {
627664
628 const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920";665 const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920";
629666
630 h = Blake2b512.init();667 h = Blake2b512.init(.{});
631 h.update("a" ** 64 ++ "b" ** 64);668 h.update("a" ** 64 ++ "b" ** 64);
632 h.final(out[0..]);669 h.final(out[0..]);
633 htest.assertEqual(h3, out[0..]);670 htest.assertEqual(h3, out[0..]);
634671
635 h = Blake2b512.init();672 h = Blake2b512.init(.{});
636 h.update("a" ** 64);673 h.update("a" ** 64);
637 h.update("b" ** 64);674 h.update("b" ** 64);
638 h.final(out[0..]);675 h.final(out[0..]);
...@@ -645,16 +682,16 @@ test "blake2b512 keyed" {...@@ -645,16 +682,16 @@ test "blake2b512 keyed" {
645 const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d";682 const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d";
646 const key = "secret_key";683 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 });
649 htest.assertEqual(h1, out[0..]);686 htest.assertEqual(h1, out[0..]);
650687
651 var h = Blake2b512.init_keyed(key);688 var h = Blake2b512.init(.{ .key = key });
652 h.update("a" ** 64 ++ "b" ** 64);689 h.update("a" ** 64 ++ "b" ** 64);
653 h.final(out[0..]);690 h.final(out[0..]);
654691
655 htest.assertEqual(h1, out[0..]);692 htest.assertEqual(h1, out[0..]);
656693
657 h = Blake2b512.init_keyed(key);694 h = Blake2b512.init(.{ .key = key });
658 h.update("a" ** 64);695 h.update("a" ** 64);
659 h.update("b" ** 64);696 h.update("b" ** 64);
660 h.final(out[0..]);697 h.final(out[0..]);
...@@ -672,7 +709,7 @@ test "comptime blake2b512" {...@@ -672,7 +709,7 @@ test "comptime blake2b512" {
672709
673 htest.assertEqualHash(Blake2b512, h1, block[0..]);710 htest.assertEqualHash(Blake2b512, h1, block[0..]);
674711
675 var h = Blake2b512.init();712 var h = Blake2b512.init(.{});
676 h.update(&block);713 h.update(&block);
677 h.final(out[0..]);714 h.final(out[0..]);
678715
lib/std/crypto/blake3.zig+18-16
...@@ -279,6 +279,9 @@ fn parent_cv(...@@ -279,6 +279,9 @@ fn parent_cv(
279279
280/// An incremental hasher that can accept any number of writes.280/// An incremental hasher that can accept any number of writes.
281pub const Blake3 = struct {281pub const Blake3 = struct {
282 pub const Options = struct { key: ?[KEY_LEN]u8 = null };
283 pub const KdfOptions = struct {};
284
282 chunk_state: ChunkState,285 chunk_state: ChunkState,
283 key: [8]u32,286 key: [8]u32,
284 cv_stack: [54][8]u32 = undefined, // Space for 54 subtree chaining values:287 cv_stack: [54][8]u32 = undefined, // Space for 54 subtree chaining values:
...@@ -296,21 +299,20 @@ pub const Blake3 = struct {...@@ -296,21 +299,20 @@ pub const Blake3 = struct {
296 };299 };
297 }300 }
298301
299 /// Construct a new `Blake3` for the regular hash function.302 /// Construct a new `Blake3` for the hash function, with an optional key
300 pub fn init() Blake3 {303 pub fn init(options: Options) Blake3 {
301 return comptime Blake3.init_internal(IV, 0);304 if (options.key) |key| {
302 }305 var key_words: [8]u32 = undefined;
303306 words_from_little_endian_bytes(key_words[0..], key[0..]);
304 /// Construct a new `Blake3` for the keyed hash function.307 return Blake3.init_internal(key_words, KEYED_HASH);
305 pub fn init_keyed(key: [KEY_LEN]u8) Blake3 {308 } else {
306 var key_words: [8]u32 = undefined;309 return Blake3.init_internal(IV, 0);
307 words_from_little_endian_bytes(key_words[0..], key[0..]);310 }
308 return Blake3.init_internal(key_words, KEYED_HASH);
309 }311 }
310312
311 /// Construct a new `Blake3` for the key derivation function. The context313 /// Construct a new `Blake3` for the key derivation function. The context
312 /// string should be hardcoded, globally unique, and application-specific.314 /// 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 {
314 var context_hasher = Blake3.init_internal(IV, DERIVE_KEY_CONTEXT);316 var context_hasher = Blake3.init_internal(IV, DERIVE_KEY_CONTEXT);
315 context_hasher.update(context);317 context_hasher.update(context);
316 var context_key: [KEY_LEN]u8 = undefined;318 var context_key: [KEY_LEN]u8 = undefined;
...@@ -320,8 +322,8 @@ pub const Blake3 = struct {...@@ -320,8 +322,8 @@ pub const Blake3 = struct {
320 return Blake3.init_internal(context_key_words, DERIVE_KEY_MATERIAL);322 return Blake3.init_internal(context_key_words, DERIVE_KEY_MATERIAL);
321 }323 }
322324
323 pub fn hash(in: []const u8, out: []u8) void {325 pub fn hash(in: []const u8, out: []u8, options: Options) void {
324 var hasher = Blake3.init();326 var hasher = Blake3.init(options);
325 hasher.update(in);327 hasher.update(in);
326 hasher.final(out);328 hasher.final(out);
327 }329 }
...@@ -589,9 +591,9 @@ fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void {...@@ -589,9 +591,9 @@ fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void {
589}591}
590592
591test "BLAKE3 reference test cases" {593test "BLAKE3 reference test cases" {
592 var hash = &Blake3.init();594 var hash = &Blake3.init(.{});
593 var keyed_hash = &Blake3.init_keyed(reference_test.key.*);595 var keyed_hash = &Blake3.init(.{ .key = reference_test.key.* });
594 var derive_key = &Blake3.init_derive_key(reference_test.context_string);596 var derive_key = &Blake3.initKdf(reference_test.context_string, .{});
595597
596 for (reference_test.cases) |t| {598 for (reference_test.cases) |t| {
597 test_blake3(hash, t.input_len, t.hash.*);599 test_blake3(hash, t.input_len, t.hash.*);
lib/std/crypto/gimli.zig+5-4
...@@ -110,10 +110,11 @@ pub const Hash = struct {...@@ -110,10 +110,11 @@ pub const Hash = struct {
110 buf_off: usize,110 buf_off: usize,
111111
112 pub const block_length = State.RATE;112 pub const block_length = State.RATE;
113 pub const Options = struct {};
113114
114 const Self = @This();115 const Self = @This();
115116
116 pub fn init() Self {117 pub fn init(options: Options) Self {
117 return Self{118 return Self{
118 .state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) },119 .state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) },
119 .buf_off = 0,120 .buf_off = 0,
...@@ -160,8 +161,8 @@ pub const Hash = struct {...@@ -160,8 +161,8 @@ pub const Hash = struct {
160 }161 }
161};162};
162163
163pub fn hash(out: []u8, in: []const u8) void {164pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void {
164 var st = Hash.init();165 var st = Hash.init(options);
165 st.update(in);166 st.update(in);
166 st.final(out);167 st.final(out);
167}168}
...@@ -174,7 +175,7 @@ test "hash" {...@@ -174,7 +175,7 @@ test "hash" {
174 var msg: [58 / 2]u8 = undefined;175 var msg: [58 / 2]u8 = undefined;
175 try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");176 try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
176 var md: [32]u8 = undefined;177 var md: [32]u8 = undefined;
177 hash(&md, &msg);178 hash(&md, &msg, .{});
178 htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md);179 htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md);
179}180}
180181
lib/std/crypto/hmac.zig+3-3
...@@ -45,7 +45,7 @@ pub fn Hmac(comptime Hash: type) type {...@@ -45,7 +45,7 @@ pub fn Hmac(comptime Hash: type) type {
4545
46 // Normalize key length to block size of hash46 // Normalize key length to block size of hash
47 if (key.len > Hash.block_length) {47 if (key.len > Hash.block_length) {
48 Hash.hash(key, ctx.scratch[0..mac_length]);48 Hash.hash(key, ctx.scratch[0..mac_length], .{});
49 mem.set(u8, ctx.scratch[mac_length..Hash.block_length], 0);49 mem.set(u8, ctx.scratch[mac_length..Hash.block_length], 0);
50 } else if (key.len < Hash.block_length) {50 } else if (key.len < Hash.block_length) {
51 mem.copy(u8, ctx.scratch[0..key.len], key);51 mem.copy(u8, ctx.scratch[0..key.len], key);
...@@ -62,7 +62,7 @@ pub fn Hmac(comptime Hash: type) type {...@@ -62,7 +62,7 @@ pub fn Hmac(comptime Hash: type) type {
62 b.* = ctx.scratch[i] ^ 0x36;62 b.* = ctx.scratch[i] ^ 0x36;
63 }63 }
6464
65 ctx.hash = Hash.init();65 ctx.hash = Hash.init(.{});
66 ctx.hash.update(ctx.i_key_pad[0..]);66 ctx.hash.update(ctx.i_key_pad[0..]);
67 return ctx;67 return ctx;
68 }68 }
...@@ -75,7 +75,7 @@ pub fn Hmac(comptime Hash: type) type {...@@ -75,7 +75,7 @@ pub fn Hmac(comptime Hash: type) type {
75 debug.assert(Hash.block_length >= out.len and out.len >= mac_length);75 debug.assert(Hash.block_length >= out.len and out.len >= mac_length);
7676
77 ctx.hash.final(ctx.scratch[0..mac_length]);77 ctx.hash.final(ctx.scratch[0..mac_length]);
78 var ohash = Hash.init();78 var ohash = Hash.init(.{});
79 ohash.update(ctx.o_key_pad[0..]);79 ohash.update(ctx.o_key_pad[0..]);
80 ohash.update(ctx.scratch[0..mac_length]);80 ohash.update(ctx.scratch[0..mac_length]);
81 ohash.final(out[0..mac_length]);81 ohash.final(out[0..mac_length]);
lib/std/crypto/md5.zig+8-7
...@@ -39,6 +39,7 @@ pub const Md5 = struct {...@@ -39,6 +39,7 @@ pub const Md5 = struct {
39 const Self = @This();39 const Self = @This();
40 pub const block_length = 64;40 pub const block_length = 64;
41 pub const digest_length = 16;41 pub const digest_length = 16;
42 pub const Options = struct {};
4243
43 s: [4]u32,44 s: [4]u32,
44 // Streaming Cache45 // Streaming Cache
...@@ -46,7 +47,7 @@ pub const Md5 = struct {...@@ -46,7 +47,7 @@ pub const Md5 = struct {
46 buf_len: u8,47 buf_len: u8,
47 total_len: u64,48 total_len: u64,
4849
49 pub fn init() Self {50 pub fn init(options: Options) Self {
50 return Self{51 return Self{
51 .s = [_]u32{52 .s = [_]u32{
52 0x67452301,53 0x67452301,
...@@ -60,8 +61,8 @@ pub const Md5 = struct {...@@ -60,8 +61,8 @@ pub const Md5 = struct {
60 };61 };
61 }62 }
6263
63 pub fn hash(b: []const u8, out: []u8) void {64 pub fn hash(b: []const u8, out: []u8, options: Options) void {
64 var d = Md5.init();65 var d = Md5.init(options);
65 d.update(b);66 d.update(b);
66 d.final(out);67 d.final(out);
67 }68 }
...@@ -257,18 +258,18 @@ test "md5 single" {...@@ -257,18 +258,18 @@ test "md5 single" {
257}258}
258259
259test "md5 streaming" {260test "md5 streaming" {
260 var h = Md5.init();261 var h = Md5.init(.{});
261 var out: [16]u8 = undefined;262 var out: [16]u8 = undefined;
262263
263 h.final(out[0..]);264 h.final(out[0..]);
264 htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]);265 htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]);
265266
266 h = Md5.init();267 h = Md5.init(.{});
267 h.update("abc");268 h.update("abc");
268 h.final(out[0..]);269 h.final(out[0..]);
269 htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]);270 htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]);
270271
271 h = Md5.init();272 h = Md5.init(.{});
272 h.update("a");273 h.update("a");
273 h.update("b");274 h.update("b");
274 h.update("c");275 h.update("c");
...@@ -281,7 +282,7 @@ test "md5 aligned final" {...@@ -281,7 +282,7 @@ test "md5 aligned final" {
281 var block = [_]u8{0} ** Md5.block_length;282 var block = [_]u8{0} ** Md5.block_length;
282 var out: [Md5.digest_length]u8 = undefined;283 var out: [Md5.digest_length]u8 = undefined;
283284
284 var h = Md5.init();285 var h = Md5.init(.{});
285 h.update(&block);286 h.update(&block);
286 h.final(out[0..]);287 h.final(out[0..]);
287}288}
lib/std/crypto/sha1.zig+8-7
...@@ -36,6 +36,7 @@ pub const Sha1 = struct {...@@ -36,6 +36,7 @@ pub const Sha1 = struct {
36 const Self = @This();36 const Self = @This();
37 pub const block_length = 64;37 pub const block_length = 64;
38 pub const digest_length = 20;38 pub const digest_length = 20;
39 pub const Options = struct {};
3940
40 s: [5]u32,41 s: [5]u32,
41 // Streaming Cache42 // Streaming Cache
...@@ -43,7 +44,7 @@ pub const Sha1 = struct {...@@ -43,7 +44,7 @@ pub const Sha1 = struct {
43 buf_len: u8 = 0,44 buf_len: u8 = 0,
44 total_len: u64 = 0,45 total_len: u64 = 0,
4546
46 pub fn init() Self {47 pub fn init(options: Options) Self {
47 return Self{48 return Self{
48 .s = [_]u32{49 .s = [_]u32{
49 0x67452301,50 0x67452301,
...@@ -55,8 +56,8 @@ pub const Sha1 = struct {...@@ -55,8 +56,8 @@ pub const Sha1 = struct {
55 };56 };
56 }57 }
5758
58 pub fn hash(b: []const u8, out: []u8) void {59 pub fn hash(b: []const u8, out: []u8, options: Options) void {
59 var d = Sha1.init();60 var d = Sha1.init(options);
60 d.update(b);61 d.update(b);
61 d.final(out);62 d.final(out);
62 }63 }
...@@ -276,18 +277,18 @@ test "sha1 single" {...@@ -276,18 +277,18 @@ test "sha1 single" {
276}277}
277278
278test "sha1 streaming" {279test "sha1 streaming" {
279 var h = Sha1.init();280 var h = Sha1.init(.{});
280 var out: [20]u8 = undefined;281 var out: [20]u8 = undefined;
281282
282 h.final(out[0..]);283 h.final(out[0..]);
283 htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]);284 htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]);
284285
285 h = Sha1.init();286 h = Sha1.init(.{});
286 h.update("abc");287 h.update("abc");
287 h.final(out[0..]);288 h.final(out[0..]);
288 htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);289 htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);
289290
290 h = Sha1.init();291 h = Sha1.init(.{});
291 h.update("a");292 h.update("a");
292 h.update("b");293 h.update("b");
293 h.update("c");294 h.update("c");
...@@ -299,7 +300,7 @@ test "sha1 aligned final" {...@@ -299,7 +300,7 @@ test "sha1 aligned final" {
299 var block = [_]u8{0} ** Sha1.block_length;300 var block = [_]u8{0} ** Sha1.block_length;
300 var out: [Sha1.digest_length]u8 = undefined;301 var out: [Sha1.digest_length]u8 = undefined;
301302
302 var h = Sha1.init();303 var h = Sha1.init(.{});
303 h.update(&block);304 h.update(&block);
304 h.final(out[0..]);305 h.final(out[0..]);
305}306}
lib/std/crypto/sha2.zig+22-20
...@@ -88,6 +88,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {...@@ -88,6 +88,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
88 const Self = @This();88 const Self = @This();
89 pub const block_length = 64;89 pub const block_length = 64;
90 pub const digest_length = params.out_len / 8;90 pub const digest_length = params.out_len / 8;
91 pub const Options = struct {};
9192
92 s: [8]u32,93 s: [8]u32,
93 // Streaming Cache94 // Streaming Cache
...@@ -95,7 +96,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {...@@ -95,7 +96,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
95 buf_len: u8 = 0,96 buf_len: u8 = 0,
96 total_len: u64 = 0,97 total_len: u64 = 0,
9798
98 pub fn init() Self {99 pub fn init(options: Options) Self {
99 return Self{100 return Self{
100 .s = [_]u32{101 .s = [_]u32{
101 params.iv0,102 params.iv0,
...@@ -110,8 +111,8 @@ fn Sha2_32(comptime params: Sha2Params32) type {...@@ -110,8 +111,8 @@ fn Sha2_32(comptime params: Sha2Params32) type {
110 };111 };
111 }112 }
112113
113 pub fn hash(b: []const u8, out: []u8) void {114 pub fn hash(b: []const u8, out: []u8, options: Options) void {
114 var d = Self.init();115 var d = Self.init(options);
115 d.update(b);116 d.update(b);
116 d.final(out);117 d.final(out);
117 }118 }
...@@ -296,18 +297,18 @@ test "sha224 single" {...@@ -296,18 +297,18 @@ test "sha224 single" {
296}297}
297298
298test "sha224 streaming" {299test "sha224 streaming" {
299 var h = Sha224.init();300 var h = Sha224.init(.{});
300 var out: [28]u8 = undefined;301 var out: [28]u8 = undefined;
301302
302 h.final(out[0..]);303 h.final(out[0..]);
303 htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]);304 htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]);
304305
305 h = Sha224.init();306 h = Sha224.init(.{});
306 h.update("abc");307 h.update("abc");
307 h.final(out[0..]);308 h.final(out[0..]);
308 htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]);309 htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]);
309310
310 h = Sha224.init();311 h = Sha224.init(.{});
311 h.update("a");312 h.update("a");
312 h.update("b");313 h.update("b");
313 h.update("c");314 h.update("c");
...@@ -322,18 +323,18 @@ test "sha256 single" {...@@ -322,18 +323,18 @@ test "sha256 single" {
322}323}
323324
324test "sha256 streaming" {325test "sha256 streaming" {
325 var h = Sha256.init();326 var h = Sha256.init(.{});
326 var out: [32]u8 = undefined;327 var out: [32]u8 = undefined;
327328
328 h.final(out[0..]);329 h.final(out[0..]);
329 htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]);330 htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]);
330331
331 h = Sha256.init();332 h = Sha256.init(.{});
332 h.update("abc");333 h.update("abc");
333 h.final(out[0..]);334 h.final(out[0..]);
334 htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]);335 htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]);
335336
336 h = Sha256.init();337 h = Sha256.init(.{});
337 h.update("a");338 h.update("a");
338 h.update("b");339 h.update("b");
339 h.update("c");340 h.update("c");
...@@ -345,7 +346,7 @@ test "sha256 aligned final" {...@@ -345,7 +346,7 @@ test "sha256 aligned final" {
345 var block = [_]u8{0} ** Sha256.block_length;346 var block = [_]u8{0} ** Sha256.block_length;
346 var out: [Sha256.digest_length]u8 = undefined;347 var out: [Sha256.digest_length]u8 = undefined;
347348
348 var h = Sha256.init();349 var h = Sha256.init(.{});
349 h.update(&block);350 h.update(&block);
350 h.final(out[0..]);351 h.final(out[0..]);
351}352}
...@@ -458,6 +459,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {...@@ -458,6 +459,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
458 const Self = @This();459 const Self = @This();
459 pub const block_length = 128;460 pub const block_length = 128;
460 pub const digest_length = params.out_len / 8;461 pub const digest_length = params.out_len / 8;
462 pub const Options = struct {};
461463
462 s: [8]u64,464 s: [8]u64,
463 // Streaming Cache465 // Streaming Cache
...@@ -465,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {...@@ -465,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
465 buf_len: u8 = 0,467 buf_len: u8 = 0,
466 total_len: u128 = 0,468 total_len: u128 = 0,
467469
468 pub fn init() Self {470 pub fn init(options: Options) Self {
469 return Self{471 return Self{
470 .s = [_]u64{472 .s = [_]u64{
471 params.iv0,473 params.iv0,
...@@ -480,8 +482,8 @@ fn Sha2_64(comptime params: Sha2Params64) type {...@@ -480,8 +482,8 @@ fn Sha2_64(comptime params: Sha2Params64) type {
480 };482 };
481 }483 }
482484
483 pub fn hash(b: []const u8, out: []u8) void {485 pub fn hash(b: []const u8, out: []u8, options: Options) void {
484 var d = Self.init();486 var d = Self.init(options);
485 d.update(b);487 d.update(b);
486 d.final(out);488 d.final(out);
487 }489 }
...@@ -693,7 +695,7 @@ test "sha384 single" {...@@ -693,7 +695,7 @@ test "sha384 single" {
693}695}
694696
695test "sha384 streaming" {697test "sha384 streaming" {
696 var h = Sha384.init();698 var h = Sha384.init(.{});
697 var out: [48]u8 = undefined;699 var out: [48]u8 = undefined;
698700
699 const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";701 const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";
...@@ -702,12 +704,12 @@ test "sha384 streaming" {...@@ -702,12 +704,12 @@ test "sha384 streaming" {
702704
703 const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";705 const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
704706
705 h = Sha384.init();707 h = Sha384.init(.{});
706 h.update("abc");708 h.update("abc");
707 h.final(out[0..]);709 h.final(out[0..]);
708 htest.assertEqual(h2, out[0..]);710 htest.assertEqual(h2, out[0..]);
709711
710 h = Sha384.init();712 h = Sha384.init(.{});
711 h.update("a");713 h.update("a");
712 h.update("b");714 h.update("b");
713 h.update("c");715 h.update("c");
...@@ -727,7 +729,7 @@ test "sha512 single" {...@@ -727,7 +729,7 @@ test "sha512 single" {
727}729}
728730
729test "sha512 streaming" {731test "sha512 streaming" {
730 var h = Sha512.init();732 var h = Sha512.init(.{});
731 var out: [64]u8 = undefined;733 var out: [64]u8 = undefined;
732734
733 const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";735 const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";
...@@ -736,12 +738,12 @@ test "sha512 streaming" {...@@ -736,12 +738,12 @@ test "sha512 streaming" {
736738
737 const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";739 const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
738740
739 h = Sha512.init();741 h = Sha512.init(.{});
740 h.update("abc");742 h.update("abc");
741 h.final(out[0..]);743 h.final(out[0..]);
742 htest.assertEqual(h2, out[0..]);744 htest.assertEqual(h2, out[0..]);
743745
744 h = Sha512.init();746 h = Sha512.init(.{});
745 h.update("a");747 h.update("a");
746 h.update("b");748 h.update("b");
747 h.update("c");749 h.update("c");
...@@ -753,7 +755,7 @@ test "sha512 aligned final" {...@@ -753,7 +755,7 @@ test "sha512 aligned final" {
753 var block = [_]u8{0} ** Sha512.block_length;755 var block = [_]u8{0} ** Sha512.block_length;
754 var out: [Sha512.digest_length]u8 = undefined;756 var out: [Sha512.digest_length]u8 = undefined;
755757
756 var h = Sha512.init();758 var h = Sha512.init(.{});
757 h.update(&block);759 h.update(&block);
758 h.final(out[0..]);760 h.final(out[0..]);
759}761}
lib/std/crypto/sha3.zig+18-17
...@@ -20,17 +20,18 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {...@@ -20,17 +20,18 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
20 const Self = @This();20 const Self = @This();
21 pub const block_length = 200;21 pub const block_length = 200;
22 pub const digest_length = bits / 8;22 pub const digest_length = bits / 8;
23 pub const Options = struct {};
2324
24 s: [200]u8,25 s: [200]u8,
25 offset: usize,26 offset: usize,
26 rate: usize,27 rate: usize,
2728
28 pub fn init() Self {29 pub fn init(options: Options) Self {
29 return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) };30 return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) };
30 }31 }
3132
32 pub fn hash(b: []const u8, out: []u8) void {33 pub fn hash(b: []const u8, out: []u8, options: Options) void {
33 var d = Self.init();34 var d = Self.init(options);
34 d.update(b);35 d.update(b);
35 d.final(out);36 d.final(out);
36 }37 }
...@@ -175,18 +176,18 @@ test "sha3-224 single" {...@@ -175,18 +176,18 @@ test "sha3-224 single" {
175}176}
176177
177test "sha3-224 streaming" {178test "sha3-224 streaming" {
178 var h = Sha3_224.init();179 var h = Sha3_224.init(.{});
179 var out: [28]u8 = undefined;180 var out: [28]u8 = undefined;
180181
181 h.final(out[0..]);182 h.final(out[0..]);
182 htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]);183 htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]);
183184
184 h = Sha3_224.init();185 h = Sha3_224.init(.{});
185 h.update("abc");186 h.update("abc");
186 h.final(out[0..]);187 h.final(out[0..]);
187 htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]);188 htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]);
188189
189 h = Sha3_224.init();190 h = Sha3_224.init(.{});
190 h.update("a");191 h.update("a");
191 h.update("b");192 h.update("b");
192 h.update("c");193 h.update("c");
...@@ -201,18 +202,18 @@ test "sha3-256 single" {...@@ -201,18 +202,18 @@ test "sha3-256 single" {
201}202}
202203
203test "sha3-256 streaming" {204test "sha3-256 streaming" {
204 var h = Sha3_256.init();205 var h = Sha3_256.init(.{});
205 var out: [32]u8 = undefined;206 var out: [32]u8 = undefined;
206207
207 h.final(out[0..]);208 h.final(out[0..]);
208 htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]);209 htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]);
209210
210 h = Sha3_256.init();211 h = Sha3_256.init(.{});
211 h.update("abc");212 h.update("abc");
212 h.final(out[0..]);213 h.final(out[0..]);
213 htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]);214 htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]);
214215
215 h = Sha3_256.init();216 h = Sha3_256.init(.{});
216 h.update("a");217 h.update("a");
217 h.update("b");218 h.update("b");
218 h.update("c");219 h.update("c");
...@@ -224,7 +225,7 @@ test "sha3-256 aligned final" {...@@ -224,7 +225,7 @@ test "sha3-256 aligned final" {
224 var block = [_]u8{0} ** Sha3_256.block_length;225 var block = [_]u8{0} ** Sha3_256.block_length;
225 var out: [Sha3_256.digest_length]u8 = undefined;226 var out: [Sha3_256.digest_length]u8 = undefined;
226227
227 var h = Sha3_256.init();228 var h = Sha3_256.init(.{});
228 h.update(&block);229 h.update(&block);
229 h.final(out[0..]);230 h.final(out[0..]);
230}231}
...@@ -239,7 +240,7 @@ test "sha3-384 single" {...@@ -239,7 +240,7 @@ test "sha3-384 single" {
239}240}
240241
241test "sha3-384 streaming" {242test "sha3-384 streaming" {
242 var h = Sha3_384.init();243 var h = Sha3_384.init(.{});
243 var out: [48]u8 = undefined;244 var out: [48]u8 = undefined;
244245
245 const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004";246 const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004";
...@@ -247,12 +248,12 @@ test "sha3-384 streaming" {...@@ -247,12 +248,12 @@ test "sha3-384 streaming" {
247 htest.assertEqual(h1, out[0..]);248 htest.assertEqual(h1, out[0..]);
248249
249 const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25";250 const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25";
250 h = Sha3_384.init();251 h = Sha3_384.init(.{});
251 h.update("abc");252 h.update("abc");
252 h.final(out[0..]);253 h.final(out[0..]);
253 htest.assertEqual(h2, out[0..]);254 htest.assertEqual(h2, out[0..]);
254255
255 h = Sha3_384.init();256 h = Sha3_384.init(.{});
256 h.update("a");257 h.update("a");
257 h.update("b");258 h.update("b");
258 h.update("c");259 h.update("c");
...@@ -270,7 +271,7 @@ test "sha3-512 single" {...@@ -270,7 +271,7 @@ test "sha3-512 single" {
270}271}
271272
272test "sha3-512 streaming" {273test "sha3-512 streaming" {
273 var h = Sha3_512.init();274 var h = Sha3_512.init(.{});
274 var out: [64]u8 = undefined;275 var out: [64]u8 = undefined;
275276
276 const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26";277 const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26";
...@@ -278,12 +279,12 @@ test "sha3-512 streaming" {...@@ -278,12 +279,12 @@ test "sha3-512 streaming" {
278 htest.assertEqual(h1, out[0..]);279 htest.assertEqual(h1, out[0..]);
279280
280 const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0";281 const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0";
281 h = Sha3_512.init();282 h = Sha3_512.init(.{});
282 h.update("abc");283 h.update("abc");
283 h.final(out[0..]);284 h.final(out[0..]);
284 htest.assertEqual(h2, out[0..]);285 htest.assertEqual(h2, out[0..]);
285286
286 h = Sha3_512.init();287 h = Sha3_512.init(.{});
287 h.update("a");288 h.update("a");
288 h.update("b");289 h.update("b");
289 h.update("c");290 h.update("c");
...@@ -295,7 +296,7 @@ test "sha3-512 aligned final" {...@@ -295,7 +296,7 @@ test "sha3-512 aligned final" {
295 var block = [_]u8{0} ** Sha3_512.block_length;296 var block = [_]u8{0} ** Sha3_512.block_length;
296 var out: [Sha3_512.digest_length]u8 = undefined;297 var out: [Sha3_512.digest_length]u8 = undefined;
297298
298 var h = Sha3_512.init();299 var h = Sha3_512.init(.{});
299 h.update(&block);300 h.update(&block);
300 h.final(out[0..]);301 h.final(out[0..]);
301}302}
lib/std/crypto/test.zig+1-1
...@@ -11,7 +11,7 @@ const fmt = std.fmt;...@@ -11,7 +11,7 @@ const fmt = std.fmt;
11// Hash using the specified hasher `H` asserting `expected == H(input)`.11// Hash using the specified hasher `H` asserting `expected == H(input)`.
12pub fn assertEqualHash(comptime Hasher: anytype, comptime expected: []const u8, input: []const u8) void {12pub fn assertEqualHash(comptime Hasher: anytype, comptime expected: []const u8, input: []const u8) void {
13 var h: [expected.len / 2]u8 = undefined;13 var h: [expected.len / 2]u8 = undefined;
14 Hasher.hash(input, h[0..]);14 Hasher.hash(input, h[0..], .{});
1515
16 assertEqual(expected, &h);16 assertEqual(expected, &h);
17}17}
lib/std/zig.zig+1-1
...@@ -26,7 +26,7 @@ pub fn hashSrc(src: []const u8) SrcHash {...@@ -26,7 +26,7 @@ pub fn hashSrc(src: []const u8) SrcHash {
26 std.mem.copy(u8, &out, src);26 std.mem.copy(u8, &out, src);
27 std.mem.set(u8, out[src.len..], 0);27 std.mem.set(u8, out[src.len..], 0);
28 } else {28 } else {
29 std.crypto.hash.Blake3.hash(src, &out);29 std.crypto.hash.Blake3.hash(src, &out, .{});
30 }30 }
31 return out;31 return out;
32}32}