From 8703053296a10f971ef119369116e6b7ef2e3798 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 30 Jul 2025 17:22:42 -0700 Subject: [PATCH] std.crypto: support for hashes without options --- lib/std/Build/Step/Compile.zig | 3 +- lib/std/compress/xz/block.zig | 3 +- lib/std/crypto.zig | 2 +- lib/std/crypto/25519/ed25519.zig | 16 +-- lib/std/crypto/25519/edwards25519.zig | 6 +- lib/std/crypto/25519/x25519.zig | 3 +- lib/std/crypto/Certificate.zig | 5 +- lib/std/crypto/Sha1.zig | 6 +- lib/std/crypto/argon2.zig | 10 +- lib/std/crypto/bcrypt.zig | 8 +- lib/std/crypto/blake2.zig | 150 +++++++++++++++----------- lib/std/crypto/ecdsa.zig | 2 +- lib/std/crypto/hash_composition.zig | 9 +- lib/std/crypto/hmac.zig | 2 +- lib/std/crypto/md5.zig | 22 ++-- lib/std/crypto/ml_kem.zig | 18 ++-- lib/std/crypto/salsa20.zig | 2 +- lib/std/crypto/sha2.zig | 60 +++++------ lib/std/crypto/sha3.zig | 50 +++++---- lib/std/crypto/test.zig | 10 -- lib/std/crypto/tls.zig | 6 -- lib/std/crypto/tls/Client.zig | 2 +- src/Package.zig | 3 +- src/link/MachO/CodeSignature.zig | 4 +- src/link/MachO/hasher.zig | 2 +- src/link/MachO/uuid.zig | 2 +- 26 files changed, 211 insertions(+), 195 deletions(-) diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 141d18a7bf..768c0526b6 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -1821,8 +1821,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { const partially_quoted = try std.mem.join(arena, "\" \"", escaped_args.items); const args = try std.mem.concat(arena, u8, &[_][]const u8{ "\"", partially_quoted, "\"" }); - var args_hash: [Sha256.digest_length]u8 = undefined; - Sha256.hash(args, &args_hash, .{}); + const args_hash = Sha256.hash(args); var args_hex_hash: [Sha256.digest_length * 2]u8 = undefined; _ = try std.fmt.bufPrint(&args_hex_hash, "{x}", .{&args_hash}); diff --git a/lib/std/compress/xz/block.zig b/lib/std/compress/xz/block.zig index abf939a85d..a2ef7adea0 100644 --- a/lib/std/compress/xz/block.zig +++ b/lib/std/compress/xz/block.zig @@ -190,8 +190,7 @@ pub fn Decoder(comptime ReaderType: type) type { return error.WrongChecksum; }, .sha256 => { - var hash_a: [Sha256.digest_length]u8 = undefined; - Sha256.hash(unpacked_bytes, &hash_a); + const hash_a = Sha256.hash(unpacked_bytes); var hash_b: [Sha256.digest_length]u8 = undefined; try self.inner_reader.readNoEof(&hash_b); diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index 2cf09e76e7..8d4fc9e45b 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -368,7 +368,7 @@ test "issue #4532: no index out of bounds" { var block = [_]u8{'#'} ** Hasher.block_length; var out1: [Hasher.digest_length]u8 = undefined; var out2: [Hasher.digest_length]u8 = undefined; - const h0 = Hasher.init(.{}); + const h0 = Hasher.init(); var h = h0; h.update(block[0..]); h.final(&out1); diff --git a/lib/std/crypto/25519/ed25519.zig b/lib/std/crypto/25519/ed25519.zig index 27b94c3448..3a9beb029b 100644 --- a/lib/std/crypto/25519/ed25519.zig +++ b/lib/std/crypto/25519/ed25519.zig @@ -54,7 +54,7 @@ pub const Ed25519 = struct { // Return the clamped secret scalar and prefix for this secret key fn scalarAndPrefix(self: SecretKey) struct { scalar: CompressedScalar, prefix: [32]u8 } { var az: [Sha512.digest_length]u8 = undefined; - var h = Sha512.init(.{}); + var h = Sha512.init(); h.update(&self.seed()); h.final(&az); @@ -80,7 +80,7 @@ pub const Ed25519 = struct { var t: [64]u8 = undefined; t[0..32].* = r_bytes; t[32..].* = public_key.bytes; - var h = Sha512.init(.{}); + var h = Sha512.init(); h.update(&t); return Signer{ .h = h, .scalar = scalar, .nonce = nonce, .r_bytes = r_bytes }; @@ -128,7 +128,7 @@ pub const Ed25519 = struct { } fn computeNonceAndSign(public_key: PublicKey, msg: []const u8, noise: ?[noise_length]u8, scalar: CompressedScalar, prefix: []const u8) (IdentityElementError || NonCanonicalError || KeyMismatchError || WeakPublicKeyError)!Signature { - var h = Sha512.init(.{}); + var h = Sha512.init(); if (noise) |*z| { h.update(z); } @@ -257,7 +257,7 @@ pub const Ed25519 = struct { /// from which the actual secret is derived. pub fn generateDeterministic(seed: [seed_length]u8) IdentityElementError!KeyPair { var az: [Sha512.digest_length]u8 = undefined; - var h = Sha512.init(.{}); + var h = Sha512.init(); h.update(&seed); h.final(&az); const pk_p = Curve.basePoint.clampedMul(az[0..32].*) catch return error.IdentityElement; @@ -335,7 +335,7 @@ pub const Ed25519 = struct { return error.KeyMismatch; } const scalar_and_prefix = key_pair.secret_key.scalarAndPrefix(); - var h = Sha512.init(.{}); + var h = Sha512.init(); h.update(&scalar_and_prefix.prefix); var noise2: [noise_length]u8 = undefined; crypto.random.bytes(&noise2); @@ -382,7 +382,7 @@ pub const Ed25519 = struct { var hram_batch: [count]Curve.scalar.CompressedScalar = undefined; for (signature_batch, 0..) |signature, i| { - var h = Sha512.init(.{}); + var h = Sha512.init(); h.update(&r_batch[i]); h.update(&signature.public_key.bytes); h.update(signature.msg); @@ -452,7 +452,7 @@ pub const Ed25519 = struct { /// Create an blind key pair from an existing key pair, a blinding seed and a context. pub fn init(key_pair: Ed25519.KeyPair, blind_seed: [blind_seed_length]u8, ctx: []const u8) (NonCanonicalError || IdentityElementError)!BlindKeyPair { var h: [Sha512.digest_length]u8 = undefined; - Sha512.hash(&key_pair.secret_key.seed(), &h, .{}); + h = Sha512.hash(&key_pair.secret_key.seed()); Curve.scalar.clamp(h[0..32]); const scalar = Curve.scalar.reduce(h[0..32].*); @@ -494,7 +494,7 @@ pub const Ed25519 = struct { /// Compute a blind context from a blinding seed and a context. fn blindCtx(blind_seed: [blind_seed_length]u8, ctx: []const u8) [Sha512.digest_length]u8 { var blind_h: [Sha512.digest_length]u8 = undefined; - var hx = Sha512.init(.{}); + var hx = Sha512.init(); hx.update(&blind_seed); hx.update(&[1]u8{0}); hx.update(ctx); diff --git a/lib/std/crypto/25519/edwards25519.zig b/lib/std/crypto/25519/edwards25519.zig index da8b84a96b..343a219742 100644 --- a/lib/std/crypto/25519/edwards25519.zig +++ b/lib/std/crypto/25519/edwards25519.zig @@ -467,7 +467,7 @@ pub const Edwards25519 = struct { var xctx = ctx; var hctx: [H.digest_length]u8 = undefined; if (ctx.len > 0xff) { - var st = H.init(.{}); + var st = H.init(); st.update("H2C-OVERSIZE-DST-"); st.update(ctx); st.final(&hctx); @@ -476,7 +476,7 @@ pub const Edwards25519 = struct { const empty_block = [_]u8{0} ** H.block_length; var t = [3]u8{ 0, n * h_l, 0 }; var xctx_len_u8 = [1]u8{@as(u8, @intCast(xctx.len))}; - var st = H.init(.{}); + var st = H.init(); st.update(empty_block[0..]); st.update(s); st.update(t[0..]); @@ -493,7 +493,7 @@ pub const Edwards25519 = struct { u[i + j] ^= u[i + j - H.digest_length]; } t[2] += 1; - st = H.init(.{}); + st = H.init(); st.update(u[i..][0..H.digest_length]); st.update(t[2..3]); st.update(xctx); diff --git a/lib/std/crypto/25519/x25519.zig b/lib/std/crypto/25519/x25519.zig index ee40f34940..9a494150b5 100644 --- a/lib/std/crypto/25519/x25519.zig +++ b/lib/std/crypto/25519/x25519.zig @@ -55,8 +55,7 @@ pub const X25519 = struct { /// Create a key pair from an Ed25519 key pair pub fn fromEd25519(ed25519_key_pair: crypto.sign.Ed25519.KeyPair) (IdentityElementError || EncodingError)!KeyPair { const seed = ed25519_key_pair.secret_key.seed(); - var az: [Sha512.digest_length]u8 = undefined; - Sha512.hash(&seed, &az, .{}); + const az = Sha512.hash(&seed); var sk = az[0..32].*; Curve.scalar.clamp(&sk); const pk = try publicKeyFromEd25519(ed25519_key_pair.public_key); diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig index 6dc58c5bca..b1a41deb46 100644 --- a/lib/std/crypto/Certificate.zig +++ b/lib/std/crypto/Certificate.zig @@ -1037,8 +1037,7 @@ pub const rsa = struct { std.mem.copyForwards(u8, m_p[(8 + Hash.digest_length)..], salt); // 13. Let H' = Hash(M'), an octet string of length hLen. - var h_p: [Hash.digest_length]u8 = undefined; - Hash.hash(m_p, &h_p); + const h_p = Hash.hash(m_p); // 14. If H = H', output "consistent". Otherwise, output // "inconsistent". @@ -1054,7 +1053,7 @@ pub const rsa = struct { while (idx < len) { std.mem.writeInt(u32, hash[seed.len..][0..4], counter, .big); - Hash.hash(&hash, out[idx..][0..Hash.digest_length]); + out[idx..][0..Hash.digest_length].* = Hash.hash(&hash); idx += Hash.digest_length; counter += 1; } diff --git a/lib/std/crypto/Sha1.zig b/lib/std/crypto/Sha1.zig index 0aa05eba4a..b7ac85d23a 100644 --- a/lib/std/crypto/Sha1.zig +++ b/lib/std/crypto/Sha1.zig @@ -277,9 +277,9 @@ const RoundParam = struct { const htest = @import("test.zig"); test "sha1 single" { - try htest.assertEqualHashInterface(Sha1, "da39a3ee5e6b4b0d3255bfef95601890afd80709", ""); - try htest.assertEqualHashInterface(Sha1, "a9993e364706816aba3e25717850c26c9cd0d89d", "abc"); - try htest.assertEqualHashInterface(Sha1, "a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); + try htest.assertEqualHash(Sha1, "da39a3ee5e6b4b0d3255bfef95601890afd80709", ""); + try htest.assertEqualHash(Sha1, "a9993e364706816aba3e25717850c26c9cd0d89d", "abc"); + try htest.assertEqualHash(Sha1, "a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); } test "sha1 streaming" { diff --git a/lib/std/crypto/argon2.zig b/lib/std/crypto/argon2.zig index 77c878e779..d778bc6f41 100644 --- a/lib/std/crypto/argon2.zig +++ b/lib/std/crypto/argon2.zig @@ -113,7 +113,7 @@ fn initHash( var h0: H0 = undefined; var parameters: [24]u8 = undefined; var tmp: [4]u8 = undefined; - var b2 = Blake2b512.init(.{}); + var b2 = Blake2b512.init(); mem.writeInt(u32, parameters[0..4], params.p, .little); mem.writeInt(u32, parameters[4..8], @as(u32, @intCast(dk_len)), .little); mem.writeInt(u32, parameters[8..12], params.m, .little); @@ -149,7 +149,7 @@ fn blake2bLong(out: []u8, in: []const u8) void { var out_buf: [H.digest_length]u8 = undefined; if (out.len <= H.digest_length) { - var h = H.init(.{ .expected_out_bits = out.len * 8 }); + var h = H.initOptions(.{ .expected_out_bits = out.len * 8 }); h.update(&outlen_bytes); h.update(in); h.final(&out_buf); @@ -157,7 +157,7 @@ fn blake2bLong(out: []u8, in: []const u8) void { return; } - var h = H.init(.{}); + var h = H.init(); h.update(&outlen_bytes); h.update(in); h.final(&out_buf); @@ -168,12 +168,12 @@ fn blake2bLong(out: []u8, in: []const u8) void { var in_buf: [H.digest_length]u8 = undefined; while (out_slice.len > H.digest_length) { in_buf = out_buf; - H.hash(&in_buf, &out_buf, .{}); + out_buf = H.hash(&in_buf); out_slice[0 .. H.digest_length / 2].* = out_buf[0 .. H.digest_length / 2].*; out_slice = out_slice[H.digest_length / 2 ..]; } in_buf = out_buf; - H.hash(&in_buf, &out_buf, .{ .expected_out_bits = out_slice.len * 8 }); + out_buf = H.hashOptions(&in_buf, .{ .expected_out_bits = out_slice.len * 8 }); @memcpy(out_slice, out_buf[0..out_slice.len]); } diff --git a/lib/std/crypto/bcrypt.zig b/lib/std/crypto/bcrypt.zig index 62fc4fd4cc..fe270d4919 100644 --- a/lib/std/crypto/bcrypt.zig +++ b/lib/std/crypto/bcrypt.zig @@ -499,7 +499,7 @@ const pbkdf_prf = struct { pub fn init(key: []const u8) Self { var self: Self = undefined; - self.hasher = Sha512.init(.{}); + self.hasher = Sha512.init(); Sha512.hash(key, &self.sha2pass, .{}); return self; } @@ -575,7 +575,7 @@ pub fn opensshKdf(pass: []const u8, salt: []const u8, key: []u8, rounds: u32) !v return error.InvalidInput; } var sha2pass: [Sha512.digest_length]u8 = undefined; - Sha512.hash(pass, &sha2pass, .{}); + sha2pass = Sha512.hash(pass); const stride = (key.len + tmp.len - 1) / tmp.len; var amt = (key.len + stride - 1) / stride; if (math.shr(usize, key.len, 32) >= amt) { @@ -587,14 +587,14 @@ pub fn opensshKdf(pass: []const u8, salt: []const u8, key: []u8, rounds: u32) !v var count_salt: [4]u8 = undefined; std.mem.writeInt(u32, count_salt[0..], count, .big); var sha2salt: [Sha512.digest_length]u8 = undefined; - var h = Sha512.init(.{}); + var h = Sha512.init(); h.update(salt); h.update(&count_salt); h.final(&sha2salt); tmp2 = pbkdf_prf.hash(sha2pass, sha2salt); tmp = tmp2; for (1..rounds) |_| { - Sha512.hash(&tmp2, &sha2salt, .{}); + sha2salt = Sha512.hash(&tmp2); tmp2 = pbkdf_prf.hash(sha2pass, sha2salt); for (&tmp, tmp2) |*o, t| o.* ^= t; } diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index cd40978cf3..09e89b271e 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -40,7 +40,12 @@ pub fn Blake2s(comptime out_bits: usize) type { pub const key_length_min = 0; pub const key_length_max = 32; pub const key_length = 32; // recommended key length - pub const Options = struct { key: ?[]const u8 = null, salt: ?[8]u8 = null, context: ?[8]u8 = null, expected_out_bits: usize = out_bits }; + pub const Options = struct { + key: ?[]const u8 = null, + salt: ?[8]u8 = null, + context: ?[8]u8 = null, + expected_out_bits: usize = out_bits, + }; const iv = [8]u32{ 0x6A09E667, @@ -72,7 +77,7 @@ pub fn Blake2s(comptime out_bits: usize) type { buf: [64]u8, buf_len: u8, - pub fn init(options: Options) Self { + pub fn initOptions(options: Options) Self { comptime debug.assert(8 <= out_bits and out_bits <= 256); var d: Self = undefined; @@ -100,10 +105,20 @@ pub fn Blake2s(comptime out_bits: usize) type { return d; } - pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { - var d = Self.init(options); + pub fn init() Self { + return initOptions(.{}); + } + + pub fn hash(b: []const u8) [digest_length]u8 { + return hashOptions(b, .{}); + } + + pub fn hashOptions(b: []const u8, options: Options) [digest_length]u8 { + var out: [digest_length]u8 = undefined; + var d = Self.initOptions(options); d.update(b); - d.final(out); + d.final(&out); + return out; } pub fn update(d: *Self, b: []const u8) void { @@ -215,7 +230,7 @@ test "blake2s160 single" { } test "blake2s160 streaming" { - var h = Blake2s160.init(.{}); + var h = Blake2s160.init(); var out: [20]u8 = undefined; const h1 = "354c9c33f735962418bdacb9479873429c34916f"; @@ -225,12 +240,12 @@ test "blake2s160 streaming" { const h2 = "5ae3b99be29b01834c3b508521ede60438f8de17"; - h = Blake2s160.init(.{}); + h = Blake2s160.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Blake2s160.init(.{}); + h = Blake2s160.init(); h.update("a"); h.update("b"); h.update("c"); @@ -239,26 +254,26 @@ test "blake2s160 streaming" { const h3 = "b60c4dc60e2681e58fbc24e77f07e02c69e72ed0"; - h = Blake2s160.init(.{}); + h = Blake2s160.init(); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); - h = Blake2s160.init(.{}); + h = Blake2s160.init(); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); const h4 = "4667fd60791a7fe41f939bca646b4529e296bd68"; - h = Blake2s160.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); + h = Blake2s160.initOptions(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); - h = Blake2s160.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); + h = Blake2s160.initOptions(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); @@ -275,7 +290,7 @@ test "comptime blake2s160" { try htest.assertEqualHash(Blake2s160, h1, block[0..]); - var h = Blake2s160.init(.{}); + var h = Blake2s160.init(); h.update(&block); h.final(out[0..]); @@ -298,7 +313,7 @@ test "blake2s224 single" { } test "blake2s224 streaming" { - var h = Blake2s224.init(.{}); + var h = Blake2s224.init(); var out: [28]u8 = undefined; const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4"; @@ -308,12 +323,12 @@ test "blake2s224 streaming" { const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55"; - h = Blake2s224.init(.{}); + h = Blake2s224.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Blake2s224.init(.{}); + h = Blake2s224.init(); h.update("a"); h.update("b"); h.update("c"); @@ -322,26 +337,26 @@ test "blake2s224 streaming" { const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01"; - h = Blake2s224.init(.{}); + h = Blake2s224.init(); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); - h = Blake2s224.init(.{}); + h = Blake2s224.init(); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); const h4 = "a4d6a9d253441b80e5dfd60a04db169ffab77aec56a2855c402828c3"; - h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); + h = Blake2s224.initOptions(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); - h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); + h = Blake2s224.initOptions(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); @@ -357,7 +372,7 @@ test "comptime blake2s224" { try htest.assertEqualHash(Blake2s224, h1, block[0..]); - var h = Blake2s224.init(.{}); + var h = Blake2s224.init(); h.update(&block); h.final(out[0..]); @@ -380,7 +395,7 @@ test "blake2s256 single" { } test "blake2s256 streaming" { - var h = Blake2s256.init(.{}); + var h = Blake2s256.init(); var out: [32]u8 = undefined; const h1 = "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"; @@ -390,12 +405,12 @@ test "blake2s256 streaming" { const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"; - h = Blake2s256.init(.{}); + h = Blake2s256.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Blake2s256.init(.{}); + h = Blake2s256.init(); h.update("a"); h.update("b"); h.update("c"); @@ -404,13 +419,13 @@ test "blake2s256 streaming" { const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977"; - h = Blake2s256.init(.{}); + h = Blake2s256.init(); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); - h = Blake2s256.init(.{}); + h = Blake2s256.init(); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); @@ -422,16 +437,16 @@ test "blake2s256 keyed" { const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6"; const key = "secret_key"; - Blake2s256.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key }); + out = Blake2s256.hashOptions("a" ** 64 ++ "b" ** 64, .{ .key = key }); try htest.assertEqual(h1, out[0..]); - var h = Blake2s256.init(.{ .key = key }); + var h = Blake2s256.initOptions(.{ .key = key }); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); try htest.assertEqual(h1, out[0..]); - h = Blake2s256.init(.{ .key = key }); + h = Blake2s256.initOptions(.{ .key = key }); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -449,7 +464,7 @@ test "comptime blake2s256" { try htest.assertEqualHash(Blake2s256, h1, block[0..]); - var h = Blake2s256.init(.{}); + var h = Blake2s256.init(); h.update(&block); h.final(out[0..]); @@ -474,7 +489,12 @@ pub fn Blake2b(comptime out_bits: usize) type { pub const key_length_min = 0; pub const key_length_max = 64; pub const key_length = 32; // recommended key length - pub const Options = struct { key: ?[]const u8 = null, salt: ?[16]u8 = null, context: ?[16]u8 = null, expected_out_bits: usize = out_bits }; + pub const Options = struct { + key: ?[]const u8 = null, + salt: ?[16]u8 = null, + context: ?[16]u8 = null, + expected_out_bits: usize = out_bits, + }; const iv = [8]u64{ 0x6a09e667f3bcc908, @@ -508,7 +528,7 @@ pub fn Blake2b(comptime out_bits: usize) type { buf: [128]u8, buf_len: u8, - pub fn init(options: Options) Self { + pub fn initOptions(options: Options) Self { comptime debug.assert(8 <= out_bits and out_bits <= 512); var d: Self = undefined; @@ -536,10 +556,20 @@ pub fn Blake2b(comptime out_bits: usize) type { return d; } - pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { - var d = Self.init(options); + pub fn init() Self { + return initOptions(.{}); + } + + pub fn hash(b: []const u8) [digest_length]u8 { + return hashOptions(b, .{}); + } + + pub fn hashOptions(b: []const u8, options: Options) [digest_length]u8 { + var out: [digest_length]u8 = undefined; + var d = Self.initOptions(options); d.update(b); - d.final(out); + d.final(&out); + return out; } pub fn update(d: *Self, b: []const u8) void { @@ -639,7 +669,7 @@ test "blake2b160 single" { } test "blake2b160 streaming" { - var h = Blake2b160.init(.{}); + var h = Blake2b160.init(); var out: [20]u8 = undefined; const h1 = "3345524abf6bbe1809449224b5972c41790b6cf2"; @@ -649,12 +679,12 @@ test "blake2b160 streaming" { const h2 = "384264f676f39536840523f284921cdc68b6846b"; - h = Blake2b160.init(.{}); + h = Blake2b160.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Blake2b160.init(.{}); + h = Blake2b160.init(); h.update("a"); h.update("b"); h.update("c"); @@ -663,18 +693,18 @@ test "blake2b160 streaming" { const h3 = "43758f5de1740f651f1ae39de92260fe8bd5a11f"; - h = Blake2b160.init(.{}); + h = Blake2b160.init(); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); - h = Blake2b160.init(.{}); + h = Blake2b160.init(); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); - h = Blake2b160.init(.{}); + h = Blake2b160.init(); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -682,13 +712,13 @@ test "blake2b160 streaming" { const h4 = "72328f8a8200663752fc302d372b5dd9b49dd8dc"; - h = Blake2b160.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); + h = Blake2b160.initOptions(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); - h = Blake2b160.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); + h = Blake2b160.initOptions(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -705,7 +735,7 @@ test "comptime blake2b160" { try htest.assertEqualHash(Blake2b160, h1, block[0..]); - var h = Blake2b160.init(.{}); + var h = Blake2b160.init(); h.update(&block); h.final(out[0..]); @@ -728,7 +758,7 @@ test "blake2b384 single" { } test "blake2b384 streaming" { - var h = Blake2b384.init(.{}); + var h = Blake2b384.init(); var out: [48]u8 = undefined; const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100"; @@ -738,12 +768,12 @@ test "blake2b384 streaming" { const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4"; - h = Blake2b384.init(.{}); + h = Blake2b384.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Blake2b384.init(.{}); + h = Blake2b384.init(); h.update("a"); h.update("b"); h.update("c"); @@ -752,18 +782,18 @@ test "blake2b384 streaming" { const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c"; - h = Blake2b384.init(.{}); + h = Blake2b384.init(); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); - h = Blake2b384.init(.{}); + h = Blake2b384.init(); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); - h = Blake2b384.init(.{}); + h = Blake2b384.init(); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -771,13 +801,13 @@ test "blake2b384 streaming" { const h4 = "934c48fcb197031c71f583d92f98703510805e72142e0b46f5752d1e971bc86c355d556035613ff7a4154b4de09dac5c"; - h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); + h = Blake2b384.initOptions(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); - h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); + h = Blake2b384.initOptions(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -794,7 +824,7 @@ test "comptime blake2b384" { try htest.assertEqualHash(Blake2b384, h1, block[0..]); - var h = Blake2b384.init(.{}); + var h = Blake2b384.init(); h.update(&block); h.final(out[0..]); @@ -817,7 +847,7 @@ test "blake2b512 single" { } test "blake2b512 streaming" { - var h = Blake2b512.init(.{}); + var h = Blake2b512.init(); var out: [64]u8 = undefined; const h1 = "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"; @@ -827,12 +857,12 @@ test "blake2b512 streaming" { const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"; - h = Blake2b512.init(.{}); + h = Blake2b512.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Blake2b512.init(.{}); + h = Blake2b512.init(); h.update("a"); h.update("b"); h.update("c"); @@ -841,12 +871,12 @@ test "blake2b512 streaming" { const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920"; - h = Blake2b512.init(.{}); + h = Blake2b512.init(); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); - h = Blake2b512.init(.{}); + h = Blake2b512.init(); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -859,7 +889,7 @@ test "blake2b512 keyed" { const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d"; const key = "secret_key"; - Blake2b512.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key }); + out = Blake2b512.hashOptions("a" ** 64 ++ "b" ** 64, .{ .key = key }); try htest.assertEqual(h1, out[0..]); var h = Blake2b512.init(.{ .key = key }); @@ -886,7 +916,7 @@ test "comptime blake2b512" { try htest.assertEqualHash(Blake2b512, h1, block[0..]); - var h = Blake2b512.init(.{}); + var h = Blake2b512.init(); h.update(&block); h.final(out[0..]); diff --git a/lib/std/crypto/ecdsa.zig b/lib/std/crypto/ecdsa.zig index b54054e258..95692316d1 100644 --- a/lib/std/crypto/ecdsa.zig +++ b/lib/std/crypto/ecdsa.zig @@ -200,7 +200,7 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { fn init(secret_key: SecretKey, noise: ?[noise_length]u8) !Signer { return Signer{ - .h = Hash.init(.{}), + .h = Hash.init(), .secret_key = secret_key, .noise = noise, }; diff --git a/lib/std/crypto/hash_composition.zig b/lib/std/crypto/hash_composition.zig index 1ffa3d4c47..8d292bc160 100644 --- a/lib/std/crypto/hash_composition.zig +++ b/lib/std/crypto/hash_composition.zig @@ -25,14 +25,17 @@ pub fn Composition(comptime H1: type, comptime H2: type) type { /// Options for both hashes. pub const Options = struct { /// Options for H1. - H1: H1.Options = .{}, + H1: if (@hasDecl(H1, "Options")) H1.Options else struct {} = .{}, /// Options for H2. - H2: H2.Options = .{}, + H2: if (@hasDecl(H2, "Options")) H2.Options else struct {} = .{}, }; /// Initialize the hash composition with the given options. pub fn init(options: Options) Self { - return Self{ .H1 = H1.init(options.H1), .H2 = H2.init(options.H2) }; + return .{ + .H1 = if (@hasDecl(H1, "Options")) H1.init(options.H1) else H1.init(), + .H2 = if (@hasDecl(H2, "Options")) H2.init(options.H2) else H2.init(), + }; } /// Compute H1(H2(b)). diff --git a/lib/std/crypto/hmac.zig b/lib/std/crypto/hmac.zig index 2c71e167fe..357fffaf8c 100644 --- a/lib/std/crypto/hmac.zig +++ b/lib/std/crypto/hmac.zig @@ -37,7 +37,7 @@ pub fn Hmac(comptime Hash: type) type { // Normalize key length to block size of hash if (key.len > Hash.block_length) { - Hash.hash(key, scratch[0..mac_length]); + scratch[0..mac_length].* = Hash.hash(key); @memset(scratch[mac_length..Hash.block_length], 0); } else if (key.len < Hash.block_length) { @memcpy(scratch[0..key.len], key); diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig index 78b1d01f2b..60ada8293f 100644 --- a/lib/std/crypto/md5.zig +++ b/lib/std/crypto/md5.zig @@ -52,15 +52,9 @@ pub const Md5 = struct { }; } - pub fn hash(data: []const u8, out: *[digest_length]u8) void { - var d = Md5.init(); - d.update(data); - d.final(out); - } - - pub fn hashResult(data: []const u8) [digest_length]u8 { + pub fn hash(data: []const u8) [digest_length]u8 { var out: [digest_length]u8 = undefined; - var d = Md5.init(.{}); + var d = Md5.init(); d.update(data); d.final(&out); return out; @@ -249,22 +243,22 @@ test "single" { } test "streaming" { - var h = Md5.init(.{}); + var h = Md5.init(); var out: [16]u8 = undefined; h.final(out[0..]); try htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]); - h = Md5.init(.{}); + h = Md5.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]); - h = Md5.init(.{}); + h = Md5.init(); h.update("a"); h.update("b"); h.update("c"); - h.final(out[0..]); + h.final(&out); try htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]); } @@ -273,7 +267,7 @@ test "aligned final" { var block = [_]u8{0} ** Md5.block_length; var out: [Md5.digest_length]u8 = undefined; - var h = Md5.init(.{}); + var h = Md5.init(); h.update(&block); - h.final(out[0..]); + h.final(&out); } diff --git a/lib/std/crypto/ml_kem.zig b/lib/std/crypto/ml_kem.zig index ce3edf9eb5..821f789aa2 100644 --- a/lib/std/crypto/ml_kem.zig +++ b/lib/std/crypto/ml_kem.zig @@ -254,7 +254,7 @@ fn Kyber(comptime p: Params) type { @memcpy(&m, &seed); } else { // m = H(seed) - sha3.Sha3_256.hash(&seed, &m, .{}); + m = sha3.Sha3_256.hash(&seed); } } else { crypto.random.bytes(&m); @@ -262,7 +262,7 @@ fn Kyber(comptime p: Params) type { // (K', r) = G(m ‖ H(pk)) var kr: [inner_plaintext_length + h_length]u8 = undefined; - var g = sha3.Sha3_512.init(.{}); + var g = sha3.Sha3_512.init(); g.update(&m); g.update(&pk.hpk); g.final(&kr); @@ -277,7 +277,7 @@ fn Kyber(comptime p: Params) type { }; } else { // Compute H(c) and put in second slot of kr, which will be (K', H(c)). - sha3.Sha3_256.hash(&ct, kr[32..], .{}); + kr[32..].* = sha3.Sha3_256.hash(&ct); var ss: [shared_length]u8 = undefined; sha3.Shake256.hash(&kr, &ss, .{}); @@ -297,7 +297,7 @@ fn Kyber(comptime p: Params) type { pub fn fromBytes(buf: *const [bytes_length]u8) errors.NonCanonicalError!PublicKey { var ret: PublicKey = undefined; ret.pk = try InnerPk.fromBytes(buf[0..InnerPk.bytes_length]); - sha3.Sha3_256.hash(buf, &ret.hpk, .{}); + ret.hpk = sha3.Sha3_256.hash(buf); return ret; } }; @@ -320,7 +320,7 @@ fn Kyber(comptime p: Params) type { // (K'', r') = G(m' ‖ H(pk)) var kr2: [64]u8 = undefined; - var g = sha3.Sha3_512.init(.{}); + var g = sha3.Sha3_512.init(); g.update(&m2); g.update(&sk.hpk); g.final(&kr2); @@ -329,7 +329,7 @@ fn Kyber(comptime p: Params) type { const ct2 = sk.pk.encrypt(&m2, kr2[32..64]); // Compute H(ct) and put in the second slot of kr2 which will be (K'', H(ct)). - sha3.Sha3_256.hash(ct, kr2[32..], .{}); + kr2[32..].* = sha3.Sha3_256.hash(ct); // Replace K'' by z in the first slot of kr2 if ct ≠ ct'. cmov(32, kr2[0..32], sk.z, ctneq(ciphertext_length, ct.*, ct2)); @@ -389,7 +389,7 @@ fn Kyber(comptime p: Params) type { ret.secret_key.z = seed[inner_seed_length..seed_length].*; // Compute H(pk) - sha3.Sha3_256.hash(&ret.public_key.pk.toBytes(), &ret.secret_key.hpk, .{}); + ret.secret_key.hpk = sha3.Sha3_256.hash(&ret.public_key.pk.toBytes()); ret.public_key.hpk = ret.secret_key.hpk; return ret; @@ -505,7 +505,7 @@ fn Kyber(comptime p: Params) type { // Derives inner PKE keypair from given seed. fn innerKeyFromSeed(seed: [inner_seed_length]u8, pk: *InnerPk, sk: *InnerSk) void { var expanded_seed: [64]u8 = undefined; - var h = sha3.Sha3_512.init(.{}); + var h = sha3.Sha3_512.init(); if (p.ml_kem) h.update(&[1]u8{p.k}); h.update(&seed); h.final(&expanded_seed); @@ -1734,7 +1734,7 @@ test "NIST KAT test" { for (&seed, 0..) |*s, i| { s.* = @as(u8, @intCast(i)); } - var f = sha2.Sha256.init(.{}); + var f = sha2.Sha256.init(); const fw = f.writer(); var g = NistDRBG.init(seed); try std.fmt.format(fw, "# {s}\n\n", .{mode.name}); diff --git a/lib/std/crypto/salsa20.zig b/lib/std/crypto/salsa20.zig index eb434ed15a..e909f6668c 100644 --- a/lib/std/crypto/salsa20.zig +++ b/lib/std/crypto/salsa20.zig @@ -523,7 +523,7 @@ pub const SealedBox = struct { pub const KeyPair = Box.KeyPair; fn createNonce(pk1: [public_length]u8, pk2: [public_length]u8) [Box.nonce_length]u8 { - var hasher = Blake2b(Box.nonce_length * 8).init(.{}); + var hasher = Blake2b(Box.nonce_length * 8).init(); hasher.update(&pk1); hasher.update(&pk2); var nonce: [Box.nonce_length]u8 = undefined; diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index 1abc2b0edc..6d0dbb69a7 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -92,7 +92,6 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type { const Self = @This(); pub const block_length = 64; pub const digest_length = digest_bits / 8; - pub const Options = struct {}; s: [8]u32 align(16), // Streaming Cache @@ -100,15 +99,16 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type { buf_len: u8 = 0, total_len: u64 = 0, - pub fn init(options: Options) Self { - _ = options; + pub fn init() Self { return Self{ .s = iv }; } - pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { - var d = Self.init(options); + pub fn hash(b: []const u8) [digest_length]u8 { + var out: [digest_length]u8 = undefined; + var d = Self.init(); d.update(b); - d.final(out); + d.final(&out); + return out; } pub fn update(d: *Self, b: []const u8) void { @@ -421,18 +421,18 @@ test Sha224 { } test "sha224 streaming" { - var h = Sha224.init(.{}); + var h = Sha224.init(); var out: [28]u8 = undefined; h.final(out[0..]); try htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]); - h = Sha224.init(.{}); + h = Sha224.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]); - h = Sha224.init(.{}); + h = Sha224.init(); h.update("a"); h.update("b"); h.update("c"); @@ -453,18 +453,18 @@ test Sha256T192 { } test "sha256 streaming" { - var h = Sha256.init(.{}); + var h = Sha256.init(); var out: [32]u8 = undefined; h.final(out[0..]); try htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]); - h = Sha256.init(.{}); + h = Sha256.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]); - h = Sha256.init(.{}); + h = Sha256.init(); h.update("a"); h.update("b"); h.update("c"); @@ -473,12 +473,12 @@ test "sha256 streaming" { } test "sha256 aligned final" { - var block = [_]u8{0} ** Sha256.block_length; + var block: [Sha256.block_length]u8 = @splat(0); var out: [Sha256.digest_length]u8 = undefined; - var h = Sha256.init(.{}); + var h = Sha256.init(); h.update(&block); - h.final(out[0..]); + h.final(&out); } const Iv64 = [8]u64; @@ -487,7 +487,6 @@ fn Sha2x64(comptime iv: Iv64, digest_bits: comptime_int) type { const Self = @This(); pub const block_length = 128; pub const digest_length = std.math.divCeil(comptime_int, digest_bits, 8) catch unreachable; - pub const Options = struct {}; s: Iv64, // Streaming Cache @@ -495,15 +494,16 @@ fn Sha2x64(comptime iv: Iv64, digest_bits: comptime_int) type { buf_len: u8 = 0, total_len: u128 = 0, - pub fn init(options: Options) Self { - _ = options; - return Self{ .s = iv }; + pub fn init() Self { + return .{ .s = iv }; } - pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { - var d = Self.init(options); + pub fn hash(b: []const u8) [digest_length]u8 { + var out: [digest_length]u8 = undefined; + var d = Self.init(); d.update(b); - d.final(out); + d.final(&out); + return out; } pub fn update(d: *Self, b: []const u8) void { @@ -737,7 +737,7 @@ fn truncatedSha512Iv(digest_len: comptime_int) Iv64 { var params: [@sizeOf(Iv64)]u8 = undefined; const algo_str = std.fmt.comptimePrint("SHA-512/{d}", .{digest_len}); - GenHash.hash(algo_str, ¶ms, .{}); + params = GenHash.hash(algo_str); return Iv64{ std.mem.readInt(u64, params[0..8], .big), @@ -788,7 +788,7 @@ test Sha384 { } test "sha384 streaming" { - var h = Sha384.init(.{}); + var h = Sha384.init(); var out: [48]u8 = undefined; const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"; @@ -797,12 +797,12 @@ test "sha384 streaming" { const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"; - h = Sha384.init(.{}); + h = Sha384.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Sha384.init(.{}); + h = Sha384.init(); h.update("a"); h.update("b"); h.update("c"); @@ -822,7 +822,7 @@ test Sha512 { } test "sha512 streaming" { - var h = Sha512.init(.{}); + var h = Sha512.init(); var out: [64]u8 = undefined; const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"; @@ -831,12 +831,12 @@ test "sha512 streaming" { const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; - h = Sha512.init(.{}); + h = Sha512.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Sha512.init(.{}); + h = Sha512.init(); h.update("a"); h.update("b"); h.update("c"); @@ -848,7 +848,7 @@ test "sha512 aligned final" { var block = [_]u8{0} ** Sha512.block_length; var out: [Sha512.digest_length]u8 = undefined; - var h = Sha512.init(.{}); + var h = Sha512.init(); h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index 78c3ff5527..4b626b148b 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -59,15 +59,25 @@ pub fn Keccak(comptime f: u11, comptime output_bits: u11, comptime default_delim pub const Options = struct { delim: u8 = default_delim }; /// Initialize a Keccak hash function. - pub fn init(options: Options) Self { + pub fn initOptions(options: Options) Self { return Self{ .st = .{ .delim = options.delim } }; } + pub fn init() Self { + return initOptions(.{}); + } + + pub fn hash(bytes: []const u8) [digest_length]u8 { + return hashOptions(bytes, .{}); + } + /// Hash a slice of bytes. - pub fn hash(bytes: []const u8, out: *[digest_length]u8, options: Options) void { - var st = Self.init(options); + pub fn hashOptions(bytes: []const u8, options: Options) [digest_length]u8 { + var out: [digest_length]u8 = undefined; + var st = Self.initOptions(options); st.update(bytes); - st.final(out); + st.final(&out); + return out; } /// Absorb a slice of bytes into the state. @@ -547,18 +557,18 @@ test "sha3-224 single" { } test "sha3-224 streaming" { - var h = Sha3_224.init(.{}); + var h = Sha3_224.init(); var out: [28]u8 = undefined; h.final(out[0..]); try htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]); - h = Sha3_224.init(.{}); + h = Sha3_224.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]); - h = Sha3_224.init(.{}); + h = Sha3_224.init(); h.update("a"); h.update("b"); h.update("c"); @@ -573,18 +583,18 @@ test "sha3-256 single" { } test "sha3-256 streaming" { - var h = Sha3_256.init(.{}); + var h = Sha3_256.init(); var out: [32]u8 = undefined; h.final(out[0..]); try htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]); - h = Sha3_256.init(.{}); + h = Sha3_256.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]); - h = Sha3_256.init(.{}); + h = Sha3_256.init(); h.update("a"); h.update("b"); h.update("c"); @@ -596,7 +606,7 @@ test "sha3-256 aligned final" { var block = [_]u8{0} ** Sha3_256.block_length; var out: [Sha3_256.digest_length]u8 = undefined; - var h = Sha3_256.init(.{}); + var h = Sha3_256.init(); h.update(&block); h.final(out[0..]); } @@ -611,7 +621,7 @@ test "sha3-384 single" { } test "sha3-384 streaming" { - var h = Sha3_384.init(.{}); + var h = Sha3_384.init(); var out: [48]u8 = undefined; const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"; @@ -619,12 +629,12 @@ test "sha3-384 streaming" { try htest.assertEqual(h1, out[0..]); const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25"; - h = Sha3_384.init(.{}); + h = Sha3_384.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Sha3_384.init(.{}); + h = Sha3_384.init(); h.update("a"); h.update("b"); h.update("c"); @@ -642,7 +652,7 @@ test "sha3-512 single" { } test "sha3-512 streaming" { - var h = Sha3_512.init(.{}); + var h = Sha3_512.init(); var out: [64]u8 = undefined; const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"; @@ -650,12 +660,12 @@ test "sha3-512 streaming" { try htest.assertEqual(h1, out[0..]); const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"; - h = Sha3_512.init(.{}); + h = Sha3_512.init(); h.update("abc"); h.final(out[0..]); try htest.assertEqual(h2, out[0..]); - h = Sha3_512.init(.{}); + h = Sha3_512.init(); h.update("a"); h.update("b"); h.update("c"); @@ -667,7 +677,7 @@ test "sha3-512 aligned final" { var block = [_]u8{0} ** Sha3_512.block_length; var out: [Sha3_512.digest_length]u8 = undefined; - var h = Sha3_512.init(.{}); + var h = Sha3_512.init(); h.update(&block); h.final(out[0..]); } @@ -730,10 +740,10 @@ test "SHA-3 with streaming" { var msg: [613]u8 = [613]u8{ 0x97, 0xd1, 0x2d, 0x1a, 0x16, 0x2d, 0x36, 0x4d, 0x20, 0x62, 0x19, 0x0b, 0x14, 0x93, 0xbb, 0xf8, 0x5b, 0xea, 0x04, 0xc2, 0x61, 0x8e, 0xd6, 0x08, 0x81, 0xa1, 0x1d, 0x73, 0x27, 0x48, 0xbf, 0xa4, 0xba, 0xb1, 0x9a, 0x48, 0x9c, 0xf9, 0x9b, 0xff, 0x34, 0x48, 0xa9, 0x75, 0xea, 0xc8, 0xa3, 0x48, 0x24, 0x9d, 0x75, 0x27, 0x48, 0xec, 0x03, 0xb0, 0xbb, 0xdf, 0x33, 0x90, 0xe3, 0x93, 0xed, 0x68, 0x24, 0x39, 0x12, 0xdf, 0xea, 0xee, 0x8c, 0x9f, 0x96, 0xde, 0x42, 0x46, 0x8c, 0x2b, 0x17, 0x83, 0x36, 0xfb, 0xf4, 0xf7, 0xff, 0x79, 0xb9, 0x45, 0x41, 0xc9, 0x56, 0x1a, 0x6b, 0x0c, 0xa4, 0x1a, 0xdd, 0x6b, 0x95, 0xe8, 0x03, 0x0f, 0x09, 0x29, 0x40, 0x1b, 0xea, 0x87, 0xfa, 0xb9, 0x18, 0xa9, 0x95, 0x07, 0x7c, 0x2f, 0x7c, 0x33, 0xfb, 0xc5, 0x11, 0x5e, 0x81, 0x0e, 0xbc, 0xae, 0xec, 0xb3, 0xe1, 0x4a, 0x26, 0x56, 0xe8, 0x5b, 0x11, 0x9d, 0x37, 0x06, 0x9b, 0x34, 0x31, 0x6e, 0xa3, 0xba, 0x41, 0xbc, 0x11, 0xd8, 0xc5, 0x15, 0xc9, 0x30, 0x2c, 0x9b, 0xb6, 0x71, 0xd8, 0x7c, 0xbc, 0x38, 0x2f, 0xd5, 0xbd, 0x30, 0x96, 0xd4, 0xa3, 0x00, 0x77, 0x9d, 0x55, 0x4a, 0x33, 0x53, 0xb6, 0xb3, 0x35, 0x1b, 0xae, 0xe5, 0xdc, 0x22, 0x23, 0x85, 0x95, 0x88, 0xf9, 0x3b, 0xbf, 0x74, 0x13, 0xaa, 0xcb, 0x0a, 0x60, 0x79, 0x13, 0x79, 0xc0, 0x4a, 0x02, 0xdb, 0x1c, 0xc9, 0xff, 0x60, 0x57, 0x9a, 0x70, 0x28, 0x58, 0x60, 0xbc, 0x57, 0x07, 0xc7, 0x47, 0x1a, 0x45, 0x71, 0x76, 0x94, 0xfb, 0x05, 0xad, 0xec, 0x12, 0x29, 0x5a, 0x44, 0x6a, 0x81, 0xd9, 0xc6, 0xf0, 0xb6, 0x9b, 0x97, 0x83, 0x69, 0xfb, 0xdc, 0x0d, 0x4a, 0x67, 0xbc, 0x72, 0xf5, 0x43, 0x5e, 0x9b, 0x13, 0xf2, 0xe4, 0x6d, 0x49, 0xdb, 0x76, 0xcb, 0x42, 0x6a, 0x3c, 0x9f, 0xa1, 0xfe, 0x5e, 0xca, 0x0a, 0xfc, 0xfa, 0x39, 0x27, 0xd1, 0x3c, 0xcb, 0x9a, 0xde, 0x4c, 0x6b, 0x09, 0x8b, 0x49, 0xfd, 0x1e, 0x3d, 0x5e, 0x67, 0x7c, 0x57, 0xad, 0x90, 0xcc, 0x46, 0x5f, 0x5c, 0xae, 0x6a, 0x9c, 0xb2, 0xcd, 0x2c, 0x89, 0x78, 0xcf, 0xf1, 0x49, 0x96, 0x55, 0x1e, 0x04, 0xef, 0x0e, 0x1c, 0xde, 0x6c, 0x96, 0x51, 0x00, 0xee, 0x9a, 0x1f, 0x8d, 0x61, 0xbc, 0xeb, 0xb1, 0xa6, 0xa5, 0x21, 0x8b, 0xa7, 0xf8, 0x25, 0x41, 0x48, 0x62, 0x5b, 0x01, 0x6c, 0x7c, 0x2a, 0xe8, 0xff, 0xf9, 0xf9, 0x1f, 0xe2, 0x79, 0x2e, 0xd1, 0xff, 0xa3, 0x2e, 0x1c, 0x3a, 0x1a, 0x5d, 0x2b, 0x7b, 0x87, 0x25, 0x22, 0xa4, 0x90, 0xea, 0x26, 0x9d, 0xdd, 0x13, 0x60, 0x4c, 0x10, 0x03, 0xf6, 0x99, 0xd3, 0x21, 0x0c, 0x69, 0xc6, 0xd8, 0xc8, 0x9e, 0x94, 0x89, 0x51, 0x21, 0xe3, 0x9a, 0xcd, 0xda, 0x54, 0x72, 0x64, 0xae, 0x94, 0x79, 0x36, 0x81, 0x44, 0x14, 0x6d, 0x3a, 0x0e, 0xa6, 0x30, 0xbf, 0x95, 0x99, 0xa6, 0xf5, 0x7f, 0x4f, 0xef, 0xc6, 0x71, 0x2f, 0x36, 0x13, 0x14, 0xa2, 0x9d, 0xc2, 0x0c, 0x0d, 0x4e, 0xc0, 0x02, 0xd3, 0x6f, 0xee, 0x98, 0x5e, 0x24, 0x31, 0x74, 0x11, 0x96, 0x6e, 0x43, 0x57, 0xe8, 0x8e, 0xa0, 0x8d, 0x3d, 0x79, 0x38, 0x20, 0xc2, 0x0f, 0xb4, 0x75, 0x99, 0x3b, 0xb1, 0xf0, 0xe8, 0xe1, 0xda, 0xf9, 0xd4, 0xe6, 0xd6, 0xf4, 0x8a, 0x32, 0x4a, 0x4a, 0x25, 0xa8, 0xd9, 0x60, 0xd6, 0x33, 0x31, 0x97, 0xb9, 0xb6, 0xed, 0x5f, 0xfc, 0x15, 0xbd, 0x13, 0xc0, 0x3a, 0x3f, 0x1f, 0x2d, 0x09, 0x1d, 0xeb, 0x69, 0x6a, 0xfe, 0xd7, 0x95, 0x3e, 0x8a, 0x4e, 0xe1, 0x6e, 0x61, 0xb2, 0x6c, 0xe3, 0x2b, 0x70, 0x60, 0x7e, 0x8c, 0xe4, 0xdd, 0x27, 0x30, 0x7e, 0x0d, 0xc7, 0xb7, 0x9a, 0x1a, 0x3c, 0xcc, 0xa7, 0x22, 0x77, 0x14, 0x05, 0x50, 0x57, 0x31, 0x1b, 0xc8, 0xbf, 0xce, 0x52, 0xaf, 0x9c, 0x8e, 0x10, 0x2e, 0xd2, 0x16, 0xb6, 0x6e, 0x43, 0x10, 0xaf, 0x8b, 0xde, 0x1d, 0x60, 0xb2, 0x7d, 0xe6, 0x2f, 0x08, 0x10, 0x12, 0x7e, 0xb4, 0x76, 0x45, 0xb6, 0xd8, 0x9b, 0x26, 0x40, 0xa1, 0x63, 0x5c, 0x7a, 0x2a, 0xb1, 0x8c, 0xd6, 0xa4, 0x6f, 0x5a, 0xae, 0x33, 0x7e, 0x6d, 0x71, 0xf5, 0xc8, 0x6d, 0x80, 0x1c, 0x35, 0xfc, 0x3f, 0xc1, 0xa6, 0xc6, 0x1a, 0x15, 0x04, 0x6d, 0x76, 0x38, 0x32, 0x95, 0xb2, 0x51, 0x1a, 0xe9, 0x3e, 0x89, 0x9f, 0x0c, 0x79 }; var out: [Sha3_256.digest_length]u8 = undefined; - Sha3_256.hash(&msg, &out, .{}); + out = Sha3_256.hash(&msg); try htest.assertEqual("5780048dfa381a1d01c747906e4a08711dd34fd712ecd7c6801dd2b38fd81a89", &out); - var h = Sha3_256.init(.{}); + var h = Sha3_256.init(); h.update(msg[0..64]); h.update(msg[64..613]); h.final(&out); diff --git a/lib/std/crypto/test.zig b/lib/std/crypto/test.zig index eae18d0685..882cc0a6b3 100644 --- a/lib/std/crypto/test.zig +++ b/lib/std/crypto/test.zig @@ -7,16 +7,6 @@ pub fn assertEqualHash( comptime Hasher: type, expected_hex: *const [Hasher.digest_length * 2:0]u8, input: []const u8, -) !void { - var h: [Hasher.digest_length]u8 = undefined; - Hasher.hash(input, &h, .{}); - try assertEqual(expected_hex, &h); -} - -pub fn assertEqualHashInterface( - comptime Hasher: type, - expected_hex: *const [Hasher.digest_length * 2:0]u8, - input: []const u8, ) !void { const digest = Hasher.hash(input); try assertEqual(expected_hex, &digest); diff --git a/lib/std/crypto/tls.zig b/lib/std/crypto/tls.zig index 21f256b104..16dde4ba20 100644 --- a/lib/std/crypto/tls.zig +++ b/lib/std/crypto/tls.zig @@ -576,12 +576,6 @@ pub fn hkdfExpandLabel( return result; } -pub fn emptyHash(comptime Hash: type) [Hash.digest_length]u8 { - var result: [Hash.digest_length]u8 = undefined; - Hash.hash(&.{}, &result); - return result; -} - pub fn hmac(comptime Hmac: type, message: []const u8, key: [Hmac.key_length]u8) [Hmac.mac_length]u8 { var result: [Hmac.mac_length]u8 = undefined; Hmac.create(&result, message, &key); diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig index 25636ac92f..6a8fbd1d33 100644 --- a/lib/std/crypto/tls/Client.zig +++ b/lib/std/crypto/tls/Client.zig @@ -524,7 +524,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client const hello_hash = p.transcript_hash.peek(); const zeroes = [1]u8{0} ** P.Hash.digest_length; const early_secret = P.Hkdf.extract(&[1]u8{0}, &zeroes); - const empty_hash = tls.emptyHash(P.Hash); + const empty_hash = P.Hash.hash(&.{}); p.version = .{ .tls_1_3 = undefined }; const pv = &p.version.tls_1_3; const hs_derived_secret = hkdfExpandLabel(P.Hkdf, early_secret, "derived", &empty_hash, P.Hash.digest_length); diff --git a/src/Package.zig b/src/Package.zig index 1dafd3f060..25cccd3ac7 100644 --- a/src/Package.zig +++ b/src/Package.zig @@ -132,8 +132,7 @@ pub const Hash = struct { @memcpy(result.bytes[i..][0..sub_path.len], sub_path); return result; } - var bin_digest: [Algo.digest_length]u8 = undefined; - Algo.hash(sub_path, &bin_digest); + const bin_digest = Algo.hash(sub_path); _ = std.fmt.bufPrint(result.bytes[i..], "{x}", .{&bin_digest}) catch unreachable; return result; } diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig index c76eb2912e..39795247bd 100644 --- a/src/link/MachO/CodeSignature.zig +++ b/src/link/MachO/CodeSignature.zig @@ -307,7 +307,7 @@ pub fn writeAdhocSignature( var buf = std.ArrayList(u8).init(allocator); defer buf.deinit(); try req.write(buf.writer()); - Sha256.hash(buf.items, &hash); + hash = Sha256.hash(buf.items); self.code_directory.addSpecialHash(req.slotType(), hash); try blobs.append(.{ .requirements = req }); @@ -319,7 +319,7 @@ pub fn writeAdhocSignature( var buf = std.ArrayList(u8).init(allocator); defer buf.deinit(); try ents.write(buf.writer()); - Sha256.hash(buf.items, &hash); + hash = Sha256.hash(buf.items); self.code_directory.addSpecialHash(ents.slotType(), hash); try blobs.append(.{ .entitlements = ents }); diff --git a/src/link/MachO/hasher.zig b/src/link/MachO/hasher.zig index ce2b5d967d..c0d681bfbd 100644 --- a/src/link/MachO/hasher.zig +++ b/src/link/MachO/hasher.zig @@ -58,7 +58,7 @@ pub fn ParallelHasher(comptime Hasher: type) type { const tracy = trace(@src()); defer tracy.end(); err.* = file.preadAll(buffer, fstart); - Hasher.hash(buffer, out); + out.* = Hasher.hash(buffer); } const Self = @This(); diff --git a/src/link/MachO/uuid.zig b/src/link/MachO/uuid.zig index 70b8169af7..302d9c8d55 100644 --- a/src/link/MachO/uuid.zig +++ b/src/link/MachO/uuid.zig @@ -28,7 +28,7 @@ pub fn calcUuid(comp: *const Compilation, file: fs.File, file_size: u64, out: *[ @memcpy(final_buffer[i * Md5.digest_length ..][0..Md5.digest_length], &hash); } - Md5.hash(final_buffer, out); + out.* = Md5.hash(final_buffer); conform(out); }