authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-30 16:23:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-30 16:23:22-07:00
log18bc68847107d5bd183df0023b5bb123139f5343
treedd8f14a52e41177093958fdfa13f11fd7ef3aa90
parenteb1a4970dae76b49fe8cf1fa792a571cfebed86d

std.crypto.Sha1: make it a Writer


18 files changed, 196 insertions(+), 145 deletions(-)

lib/std/compress/xz/block.zig+1-1
......@@ -191,7 +191,7 @@ pub fn Decoder(comptime ReaderType: type) type {
191191 },
192192 .sha256 => {
193193 var hash_a: [Sha256.digest_length]u8 = undefined;
194 Sha256.hash(unpacked_bytes, &hash_a, .{});
194 Sha256.hash(unpacked_bytes, &hash_a);
195195
196196 var hash_b: [Sha256.digest_length]u8 = undefined;
197197 try self.inner_reader.readNoEof(&hash_b);
lib/std/crypto.zig+19-1
......@@ -347,7 +347,6 @@ test "CSPRNG" {
347347test "issue #4532: no index out of bounds" {
348348 const types = [_]type{
349349 hash.Md5,
350 hash.Sha1,
351350 hash.sha2.Sha224,
352351 hash.sha2.Sha256,
353352 hash.sha2.Sha384,
......@@ -380,6 +379,25 @@ test "issue #4532: no index out of bounds" {
380379
381380 try std.testing.expectEqual(out1, out2);
382381 }
382
383 try checkIndexOob(hash.Sha1);
384}
385
386fn checkIndexOob(Hasher: type) !void {
387 var buffer1: [Hasher.block_length]u8 = undefined;
388 var buffer2: [Hasher.block_length]u8 = undefined;
389 var block: [Hasher.block_length]u8 = @splat('#');
390 var out1: [Hasher.digest_length]u8 = undefined;
391 var out2: [Hasher.digest_length]u8 = undefined;
392 var h0: Hasher = .init(&buffer1);
393 var h = h0.copy(&buffer2);
394 h.update(&block);
395 out1 = h.final();
396 h = h0.copy(&buffer2);
397 h.update(block[0..1]);
398 h.update(block[1..]);
399 out2 = h.final();
400 try std.testing.expectEqualSlices(u8, &out1, &out2);
383401}
384402
385403/// Sets a slice to zeroes.
lib/std/crypto/25519/ed25519.zig+1-1
......@@ -163,7 +163,7 @@ pub const Ed25519 = struct {
163163 const expected_r = try Curve.fromBytes(r);
164164 try expected_r.rejectIdentity();
165165
166 var h = Sha512.init(.{});
166 var h = Sha512.init();
167167 h.update(&r);
168168 h.update(&public_key.bytes);
169169
lib/std/crypto/Certificate.zig+22-10
......@@ -949,7 +949,7 @@ pub const rsa = struct {
949949 // 2. Let mHash = Hash(M), an octet string of length hLen.
950950 var mHash: [Hash.digest_length]u8 = undefined;
951951 {
952 var hasher: Hash = .init(.{});
952 var hasher: Hash = .init();
953953 for (msg) |part| hasher.update(part);
954954 hasher.final(&mHash);
955955 }
......@@ -1038,7 +1038,7 @@ pub const rsa = struct {
10381038
10391039 // 13. Let H' = Hash(M'), an octet string of length hLen.
10401040 var h_p: [Hash.digest_length]u8 = undefined;
1041 Hash.hash(m_p, &h_p, .{});
1041 Hash.hash(m_p, &h_p);
10421042
10431043 // 14. If H = H', output "consistent". Otherwise, output
10441044 // "inconsistent".
......@@ -1054,7 +1054,7 @@ pub const rsa = struct {
10541054
10551055 while (idx < len) {
10561056 std.mem.writeInt(u32, hash[seed.len..][0..4], counter, .big);
1057 Hash.hash(&hash, out[idx..][0..Hash.digest_length], .{});
1057 Hash.hash(&hash, out[idx..][0..Hash.digest_length]);
10581058 idx += Hash.digest_length;
10591059 counter += 1;
10601060 }
......@@ -1081,13 +1081,14 @@ pub const rsa = struct {
10811081 public_key: PublicKey,
10821082 comptime Hash: type,
10831083 ) VerifyError!void {
1084 try concatVerify(modulus_len, sig, &.{msg}, public_key, Hash);
1084 var msgs: [1][]const u8 = .{msg};
1085 try concatVerify(modulus_len, sig, &msgs, public_key, Hash);
10851086 }
10861087
10871088 pub fn concatVerify(
10881089 comptime modulus_len: usize,
10891090 sig: [modulus_len]u8,
1090 msg: []const []const u8,
1091 msg: [][]const u8,
10911092 public_key: PublicKey,
10921093 comptime Hash: type,
10931094 ) VerifyError!void {
......@@ -1096,7 +1097,7 @@ pub const rsa = struct {
10961097 if (!std.mem.eql(u8, &em_dec, &em)) return error.InvalidSignature;
10971098 }
10981099
1099 fn EMSA_PKCS1_V1_5_ENCODE(msg: []const []const u8, comptime emLen: usize, comptime Hash: type) VerifyError![emLen]u8 {
1100 fn EMSA_PKCS1_V1_5_ENCODE(msg: [][]const u8, comptime emLen: usize, comptime Hash: type) VerifyError![emLen]u8 {
11001101 comptime var em_index = emLen;
11011102 var em: [emLen]u8 = undefined;
11021103
......@@ -1107,10 +1108,21 @@ pub const rsa = struct {
11071108 //
11081109 // If the hash function outputs "message too long," output "message
11091110 // too long" and stop.
1110 var hasher: Hash = .init(.{});
1111 for (msg) |part| hasher.update(part);
1112 em_index -= Hash.digest_length;
1113 hasher.final(em[em_index..]);
1111 switch (Hash) {
1112 crypto.hash.Sha1 => {
1113 var buffer: [64]u8 = undefined;
1114 var hasher: Hash = .init(&buffer);
1115 hasher.writer.writeVecAll(msg) catch unreachable; // writing to hasher cannot fail
1116 em_index -= Hash.digest_length;
1117 em[em_index..][0..Hash.digest_length].* = hasher.final();
1118 },
1119 else => {
1120 var hasher: Hash = .init();
1121 for (msg) |part| hasher.update(part);
1122 em_index -= Hash.digest_length;
1123 hasher.final(em[em_index..]);
1124 },
1125 }
11141126
11151127 // 2. Encode the algorithm ID for the hash function and the hash value
11161128 // into an ASN.1 value of type DigestInfo (see Appendix A.2.4) with
lib/std/crypto/Sha1.zig+98-90
......@@ -2,115 +2,121 @@
22//! Namely, it is feasible to find multiple inputs producing the same hash.
33//! For a fast-performing, cryptographically secure hash function, see SHA512/256, BLAKE2 or BLAKE3.
44
5const Sha1 = @This();
56const std = @import("../std.zig");
67const mem = std.mem;
78const math = std.math;
8const Sha1 = @This();
9const assert = std.debug.assert;
10const Writer = std.Io.Writer;
911
1012pub const block_length = 64;
1113pub const digest_length = 20;
12pub const Options = struct {};
1314
1415s: [5]u32,
15/// Streaming Cache
16buf: [64]u8 = undefined,
17buf_len: u8 = 0,
18total_len: u64 = 0,
16total_len: u64,
17writer: Writer,
1918
20pub fn init(options: Options) Sha1 {
21 _ = options;
19pub fn init(buffer: []u8) Sha1 {
20 assert(buffer.len >= block_length);
2221 return .{
23 .s = [_]u32{
24 0x67452301,
25 0xEFCDAB89,
26 0x98BADCFE,
27 0x10325476,
28 0xC3D2E1F0,
22 .s = .{ 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
23 .total_len = 0,
24 .writer = .{
25 .buffer = buffer,
26 .vtable = &vtable,
2927 },
3028 };
3129}
3230
33pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void {
34 var d = Sha1.init(options);
35 d.update(b);
36 d.final(out);
31pub fn copy(sha1: *Sha1, buffer: []u8) Sha1 {
32 assert(buffer.len >= block_length);
33 const mine = sha1.writer.buffered();
34 assert(mine.len <= block_length);
35 @memcpy(buffer[0..mine.len], mine);
36 return .{
37 .s = sha1.s,
38 .total_len = sha1.total_len,
39 .writer = .{
40 .buffer = buffer,
41 .end = mine.len,
42 .vtable = &vtable,
43 },
44 };
3745}
3846
39pub fn update(d: *Sha1, b: []const u8) void {
40 var off: usize = 0;
41
42 // Partial buffer exists from previous update. Copy into buffer then hash.
43 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
44 off += 64 - d.buf_len;
45 @memcpy(d.buf[d.buf_len..][0..off], b[0..off]);
46
47 d.round(d.buf[0..]);
48 d.buf_len = 0;
47const vtable: Writer.VTable = .{ .drain = drain };
48
49fn drain(w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize {
50 const d: *Sha1 = @alignCast(@fieldParentPtr("writer", w));
51 {
52 const buf = w.buffered();
53 var off: usize = 0;
54 while (off + block_length <= buf.len) : (off += block_length) {
55 round(&d.s, buf[off..][0..block_length]);
56 }
57 d.total_len += off;
58 if (off != buf.len) return w.consume(off);
59 w.end = 0;
4960 }
50
51 // Full middle blocks.
52 while (off + 64 <= b.len) : (off += 64) {
53 d.round(b[off..][0..64]);
61 if (data.len == 1 and splat == 0) return 0;
62 var total_off: usize = 0;
63 for (data) |buf| {
64 var off: usize = 0;
65 while (off + block_length <= buf.len) : (off += block_length) {
66 round(&d.s, buf[off..][0..block_length]);
67 }
68 total_off += off;
69 if (off != buf.len) break;
5470 }
55
56 // Copy any remainder for next pass.
57 @memcpy(d.buf[d.buf_len..][0 .. b.len - off], b[off..]);
58 d.buf_len += @as(u8, @intCast(b[off..].len));
59
60 d.total_len += b.len;
71 d.total_len += total_off;
72 return total_off;
6173}
6274
63pub fn peek(d: Sha1) [digest_length]u8 {
64 var copy = d;
65 return copy.finalResult();
75pub fn hash(data: []const u8) [digest_length]u8 {
76 var buf: [block_length]u8 = undefined;
77 var s: Sha1 = .init(&buf);
78 s.writer.writeAll(data) catch unreachable;
79 return s.final();
6680}
6781
68pub fn final(d: *Sha1, out: *[digest_length]u8) void {
69 // The buffer here will never be completely full.
70 @memset(d.buf[d.buf_len..], 0);
82pub fn update(d: *Sha1, b: []const u8) void {
83 d.writer.writeAll(b) catch unreachable;
84}
7185
72 // Append padding bits.
73 d.buf[d.buf_len] = 0x80;
74 d.buf_len += 1;
86pub fn final(d: *Sha1) [digest_length]u8 {
87 _ = drain(&d.writer, &.{""}, 1) catch unreachable;
88 const buf = d.writer.buffer[0..block_length];
89 const pad = d.writer.end;
90 assert(pad < block_length);
91 d.total_len += pad;
92 buf[pad] = 0x80; // Append padding bits.
93 const end = pad + 1;
94 @memset(buf[end..], 0);
7595
7696 // > 448 mod 512 so need to add an extra round to wrap around.
77 if (64 - d.buf_len < 8) {
78 d.round(d.buf[0..]);
79 @memset(d.buf[0..], 0);
97 if (block_length - end < 8) {
98 round(&d.s, buf);
99 @memset(buf, 0);
80100 }
81101
82102 // Append message length.
83 var i: usize = 1;
84103 var len = d.total_len >> 5;
85 d.buf[63] = @as(u8, @intCast(d.total_len & 0x1f)) << 3;
86 while (i < 8) : (i += 1) {
87 d.buf[63 - i] = @as(u8, @intCast(len & 0xff));
104 buf[63] = @as(u8, @intCast(d.total_len & 0x1f)) << 3;
105 for (1..8) |i| {
106 buf[63 - i] = @as(u8, @intCast(len & 0xff));
88107 len >>= 8;
89108 }
90109
91 d.round(d.buf[0..]);
110 round(&d.s, buf);
92111
93 for (d.s, 0..) |s, j| {
94 mem.writeInt(u32, out[4 * j ..][0..4], s, .big);
95 }
112 var out: [digest_length]u8 = undefined;
113 for (&d.s, 0..) |s, j| mem.writeInt(u32, out[4 * j ..][0..4], s, .big);
114 return out;
96115}
97116
98pub fn finalResult(d: *Sha1) [digest_length]u8 {
99 var result: [digest_length]u8 = undefined;
100 d.final(&result);
101 return result;
102}
103
104fn round(d: *Sha1, b: *const [64]u8) void {
117pub fn round(d_s: *[5]u32, b: *const [block_length]u8) void {
105118 var s: [16]u32 = undefined;
106
107 var v: [5]u32 = [_]u32{
108 d.s[0],
109 d.s[1],
110 d.s[2],
111 d.s[3],
112 d.s[4],
113 };
119 var v = d_s.*;
114120
115121 const round0a = comptime [_]RoundParam{
116122 .abcdei(0, 1, 2, 3, 4, 0),
......@@ -241,11 +247,11 @@ fn round(d: *Sha1, b: *const [64]u8) void {
241247 v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
242248 }
243249
244 d.s[0] +%= v[0];
245 d.s[1] +%= v[1];
246 d.s[2] +%= v[2];
247 d.s[3] +%= v[3];
248 d.s[4] +%= v[4];
250 d_s[0] +%= v[0];
251 d_s[1] +%= v[1];
252 d_s[2] +%= v[2];
253 d_s[3] +%= v[3];
254 d_s[4] +%= v[4];
249255}
250256
251257const RoundParam = struct {
......@@ -271,36 +277,38 @@ const RoundParam = struct {
271277const htest = @import("test.zig");
272278
273279test "sha1 single" {
274 try htest.assertEqualHash(Sha1, "da39a3ee5e6b4b0d3255bfef95601890afd80709", "");
275 try htest.assertEqualHash(Sha1, "a9993e364706816aba3e25717850c26c9cd0d89d", "abc");
276 try htest.assertEqualHash(Sha1, "a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
280 try htest.assertEqualHashInterface(Sha1, "da39a3ee5e6b4b0d3255bfef95601890afd80709", "");
281 try htest.assertEqualHashInterface(Sha1, "a9993e364706816aba3e25717850c26c9cd0d89d", "abc");
282 try htest.assertEqualHashInterface(Sha1, "a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
277283}
278284
279285test "sha1 streaming" {
280 var h = Sha1.init(.{});
286 var buffer: [block_length]u8 = undefined;
287 var h: Sha1 = .init(&buffer);
281288 var out: [20]u8 = undefined;
282289
283 h.final(&out);
290 out = h.final();
284291 try htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]);
285292
286 h = Sha1.init(.{});
293 h = .init(&buffer);
287294 h.update("abc");
288 h.final(&out);
295 out = h.final();
289296 try htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);
290297
291 h = Sha1.init(.{});
298 h = .init(&buffer);
292299 h.update("a");
293300 h.update("b");
294301 h.update("c");
295 h.final(&out);
302 out = h.final();
296303 try htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);
297304}
298305
299306test "sha1 aligned final" {
300 var block = [_]u8{0} ** Sha1.block_length;
307 var block: [block_length]u8 = @splat(0);
301308 var out: [Sha1.digest_length]u8 = undefined;
309 var buffer: [block_length]u8 = undefined;
302310
303 var h = Sha1.init(.{});
311 var h: Sha1 = .init(&buffer);
304312 h.update(&block);
305 h.final(out[0..]);
313 out = h.final();
306314}
lib/std/crypto/ecdsa.zig+2-2
......@@ -258,8 +258,8 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {
258258 const s = try Curve.scalar.Scalar.fromBytes(sig.s, .big);
259259 if (r.isZero() or s.isZero()) return error.IdentityElement;
260260
261 return Verifier{
262 .h = Hash.init(.{}),
261 return .{
262 .h = Hash.init(),
263263 .r = r,
264264 .s = s,
265265 .public_key = public_key,
lib/std/crypto/hmac.zig+3-3
......@@ -37,7 +37,7 @@ pub fn Hmac(comptime Hash: type) type {
3737
3838 // Normalize key length to block size of hash
3939 if (key.len > Hash.block_length) {
40 Hash.hash(key, scratch[0..mac_length], .{});
40 Hash.hash(key, scratch[0..mac_length]);
4141 @memset(scratch[mac_length..Hash.block_length], 0);
4242 } else if (key.len < Hash.block_length) {
4343 @memcpy(scratch[0..key.len], key);
......@@ -54,7 +54,7 @@ pub fn Hmac(comptime Hash: type) type {
5454 b.* = scratch[i] ^ 0x36;
5555 }
5656
57 ctx.hash = Hash.init(.{});
57 ctx.hash = Hash.init();
5858 ctx.hash.update(&i_key_pad);
5959 return ctx;
6060 }
......@@ -66,7 +66,7 @@ pub fn Hmac(comptime Hash: type) type {
6666 pub fn final(ctx: *Self, out: *[mac_length]u8) void {
6767 var scratch: [mac_length]u8 = undefined;
6868 ctx.hash.final(&scratch);
69 var ohash = Hash.init(.{});
69 var ohash = Hash.init();
7070 ohash.update(&ctx.o_key_pad);
7171 ohash.update(&scratch);
7272 ohash.final(out);
lib/std/crypto/md5.zig+3-5
......@@ -31,7 +31,6 @@ pub const Md5 = struct {
3131 const Self = @This();
3232 pub const block_length = 64;
3333 pub const digest_length = 16;
34 pub const Options = struct {};
3534
3635 s: [4]u32,
3736 // Streaming Cache
......@@ -39,8 +38,7 @@ pub const Md5 = struct {
3938 buf_len: u8,
4039 total_len: u64,
4140
42 pub fn init(options: Options) Self {
43 _ = options;
41 pub fn init() Self {
4442 return Self{
4543 .s = [_]u32{
4644 0x67452301,
......@@ -54,8 +52,8 @@ pub const Md5 = struct {
5452 };
5553 }
5654
57 pub fn hash(data: []const u8, out: *[digest_length]u8, options: Options) void {
58 var d = Md5.init(options);
55 pub fn hash(data: []const u8, out: *[digest_length]u8) void {
56 var d = Md5.init();
5957 d.update(data);
6058 d.final(out);
6159 }
lib/std/crypto/test.zig+17-9
......@@ -3,19 +3,27 @@ const testing = std.testing;
33const fmt = std.fmt;
44
55// Hash using the specified hasher `H` asserting `expected == H(input)`.
6pub fn assertEqualHash(comptime Hasher: anytype, comptime expected_hex: *const [Hasher.digest_length * 2:0]u8, input: []const u8) !void {
6pub fn assertEqualHash(
7 comptime Hasher: type,
8 expected_hex: *const [Hasher.digest_length * 2:0]u8,
9 input: []const u8,
10) !void {
711 var h: [Hasher.digest_length]u8 = undefined;
812 Hasher.hash(input, &h, .{});
9
1013 try assertEqual(expected_hex, &h);
1114}
1215
13// Assert `expected` == hex(`input`) where `input` is a bytestring
14pub fn assertEqual(comptime expected_hex: [:0]const u8, input: []const u8) !void {
15 var expected_bytes: [expected_hex.len / 2]u8 = undefined;
16 for (&expected_bytes, 0..) |*r, i| {
17 r.* = fmt.parseInt(u8, expected_hex[2 * i .. 2 * i + 2], 16) catch unreachable;
18 }
16pub fn assertEqualHashInterface(
17 comptime Hasher: type,
18 expected_hex: *const [Hasher.digest_length * 2:0]u8,
19 input: []const u8,
20) !void {
21 const digest = Hasher.hash(input);
22 try assertEqual(expected_hex, &digest);
23}
1924
20 try testing.expectEqualSlices(u8, &expected_bytes, input);
25pub fn assertEqual(expected_hex: [:0]const u8, actual_bin_digest: []const u8) !void {
26 var buffer: [200]u8 = undefined;
27 const actual_hex = std.fmt.bufPrint(&buffer, "{x}", .{actual_bin_digest}) catch @panic("buffer too small");
28 try testing.expectEqualStrings(expected_hex, actual_hex);
2129}
lib/std/crypto/tls.zig+1-1
......@@ -578,7 +578,7 @@ pub fn hkdfExpandLabel(
578578
579579pub fn emptyHash(comptime Hash: type) [Hash.digest_length]u8 {
580580 var result: [Hash.digest_length]u8 = undefined;
581 Hash.hash(&.{}, &result, .{});
581 Hash.hash(&.{}, &result);
582582 return result;
583583}
584584
lib/std/crypto/tls/Client.zig+7-5
......@@ -498,7 +498,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
498498 .ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
499499 => |tag| {
500500 handshake_cipher = @unionInit(tls.HandshakeCipher, @tagName(tag.with()), .{
501 .transcript_hash = .init(.{}),
501 .transcript_hash = .init(),
502502 .version = undefined,
503503 });
504504 const p = &@field(handshake_cipher, @tagName(tag.with()));
......@@ -680,7 +680,8 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
680680 const key_size = hsd.decode(u8);
681681 try hsd.ensure(key_size);
682682 const server_pub_key = hsd.slice(key_size);
683 try main_cert_pub_key.verifySignature(&hsd, &.{ &client_hello_rand, &server_hello_rand, hsd.buf[0..hsd.idx] });
683 var msgs: [3][]const u8 = .{ &client_hello_rand, &server_hello_rand, hsd.buf[0..hsd.idx] };
684 try main_cert_pub_key.verifySignature(&hsd, &msgs);
684685 try key_share.exchange(named_group, server_pub_key);
685686 handshake_state = .server_hello_done;
686687 },
......@@ -776,10 +777,11 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
776777 }
777778 switch (handshake_cipher) {
778779 inline else => |*p| {
779 try main_cert_pub_key.verifySignature(&hsd, &.{
780 var msgs: [2][]const u8 = .{
780781 " " ** 64 ++ "TLS 1.3, server CertificateVerify\x00",
781782 &p.transcript_hash.peek(),
782 });
783 };
784 try main_cert_pub_key.verifySignature(&hsd, &msgs);
783785 p.transcript_hash.update(wrapped_handshake);
784786 },
785787 }
......@@ -1755,7 +1757,7 @@ const CertificatePublicKey = struct {
17551757 fn verifySignature(
17561758 cert_pub_key: *const CertificatePublicKey,
17571759 sigd: *tls.Decoder,
1758 msg: []const []const u8,
1760 msg: [][]const u8,
17591761 ) VerifyError!void {
17601762 const pub_key = cert_pub_key.buf[0..cert_pub_key.len];
17611763
lib/std/http/WebSocket.zig+3-3
......@@ -45,11 +45,11 @@ pub fn init(
4545
4646 const key = sec_websocket_key orelse return error.WebSocketUpgradeMissingKey;
4747
48 var sha1 = std.crypto.hash.Sha1.init(.{});
48 var sha1_buffer: [64]u8 = undefined;
49 var sha1: std.crypto.hash.Sha1 = .init(&sha1_buffer);
4950 sha1.update(key);
5051 sha1.update("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
51 var digest: [std.crypto.hash.Sha1.digest_length]u8 = undefined;
52 sha1.final(&digest);
52 const digest = sha1.final();
5353 var base64_digest: [28]u8 = undefined;
5454 assert(std.base64.standard.Encoder.encode(&base64_digest, &digest).len == base64_digest.len);
5555
src/Package.zig+1-1
......@@ -133,7 +133,7 @@ pub const Hash = struct {
133133 return result;
134134 }
135135 var bin_digest: [Algo.digest_length]u8 = undefined;
136 Algo.hash(sub_path, &bin_digest, .{});
136 Algo.hash(sub_path, &bin_digest);
137137 _ = std.fmt.bufPrint(result.bytes[i..], "{x}", .{&bin_digest}) catch unreachable;
138138 return result;
139139 }
src/Package/Fetch.zig+2-2
......@@ -1621,7 +1621,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute
16211621
16221622 std.mem.sortUnstable(*HashedFile, all_files.items, {}, HashedFile.lessThan);
16231623
1624 var hasher = Package.Hash.Algo.init(.{});
1624 var hasher = Package.Hash.Algo.init();
16251625 var any_failures = false;
16261626 for (all_files.items) |hashed_file| {
16271627 hashed_file.failure catch |err| {
......@@ -1690,7 +1690,7 @@ fn workerDeleteFile(dir: fs.Dir, deleted_file: *DeletedFile) void {
16901690
16911691fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void {
16921692 var buf: [8000]u8 = undefined;
1693 var hasher = Package.Hash.Algo.init(.{});
1693 var hasher = Package.Hash.Algo.init();
16941694 hasher.update(hashed_file.normalized_path);
16951695 var file_size: u64 = 0;
16961696
src/Package/Fetch/git.zig+12-7
......@@ -45,10 +45,10 @@ pub const Oid = union(Format) {
4545 sha1: Sha1,
4646 sha256: Sha256,
4747
48 fn init(oid_format: Format) Hasher {
48 fn init(oid_format: Format, buffer: []u8) Hasher {
4949 return switch (oid_format) {
50 .sha1 => .{ .sha1 = Sha1.init(.{}) },
51 .sha256 => .{ .sha256 = Sha256.init(.{}) },
50 .sha1 => .{ .sha1 = .init(buffer) },
51 .sha256 => .{ .sha256 = Sha256.init() },
5252 };
5353 }
5454
......@@ -61,6 +61,7 @@ pub const Oid = union(Format) {
6161
6262 fn finalResult(hasher: *Hasher) Oid {
6363 return switch (hasher.*) {
64 .sha1 => |*inner| .{ .sha1 = inner.final() },
6465 inline else => |*inner, tag| @unionInit(Oid, @tagName(tag), inner.finalResult()),
6566 };
6667 }
......@@ -1281,7 +1282,8 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in
12811282 }
12821283 @memset(fan_out_table[fan_out_index..], count);
12831284
1284 var index_hashed_writer = hashedWriter(index_writer, Oid.Hasher.init(format));
1285 var hash_buffer: [64]u8 = undefined;
1286 var index_hashed_writer = hashedWriter(index_writer, Oid.Hasher.init(format, &hash_buffer));
12851287 const writer = index_hashed_writer.writer();
12861288 try writer.writeAll(IndexHeader.signature);
12871289 try writer.writeInt(u32, IndexHeader.supported_version, .big);
......@@ -1331,7 +1333,8 @@ fn indexPackFirstPass(
13311333) !Oid {
13321334 var pack_buffered_reader = std.io.bufferedReader(pack.deprecatedReader());
13331335 var pack_counting_reader = std.io.countingReader(pack_buffered_reader.reader());
1334 var pack_hashed_reader = hashedReader(pack_counting_reader.reader(), Oid.Hasher.init(format));
1336 var hash_buffer: [64]u8 = undefined;
1337 var pack_hashed_reader = hashedReader(pack_counting_reader.reader(), Oid.Hasher.init(format, &hash_buffer));
13351338 const pack_reader = pack_hashed_reader.reader();
13361339
13371340 const pack_header = try PackHeader.read(pack_reader);
......@@ -1345,7 +1348,8 @@ fn indexPackFirstPass(
13451348 .commit, .tree, .blob, .tag => |object| {
13461349 var entry_decompress_stream = std.compress.zlib.decompressor(entry_crc32_reader.reader());
13471350 var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader());
1348 var entry_hashed_writer = hashedWriter(std.io.null_writer, Oid.Hasher.init(format));
1351 var entry_hash_buffer: [64]u8 = undefined;
1352 var entry_hashed_writer = hashedWriter(std.io.null_writer, Oid.Hasher.init(format, &entry_hash_buffer));
13491353 const entry_writer = entry_hashed_writer.writer();
13501354 // The object header is not included in the pack data but is
13511355 // part of the object's ID
......@@ -1431,7 +1435,8 @@ fn indexPackHashDelta(
14311435
14321436 const base_data = try resolveDeltaChain(allocator, format, pack, base_object, delta_offsets.items, cache);
14331437
1434 var entry_hasher: Oid.Hasher = .init(format);
1438 var hash_buffer: [64]u8 = undefined;
1439 var entry_hasher: Oid.Hasher = .init(format, &hash_buffer);
14351440 var entry_hashed_writer = hashedWriter(std.io.null_writer, &entry_hasher);
14361441 try entry_hashed_writer.writer().print("{s} {}\x00", .{ @tagName(base_object.type), base_data.len });
14371442 entry_hasher.update(base_data);
src/link/MachO/CodeSignature.zig+2-2
......@@ -307,7 +307,7 @@ pub fn writeAdhocSignature(
307307 var buf = std.ArrayList(u8).init(allocator);
308308 defer buf.deinit();
309309 try req.write(buf.writer());
310 Sha256.hash(buf.items, &hash, .{});
310 Sha256.hash(buf.items, &hash);
311311 self.code_directory.addSpecialHash(req.slotType(), hash);
312312
313313 try blobs.append(.{ .requirements = req });
......@@ -319,7 +319,7 @@ pub fn writeAdhocSignature(
319319 var buf = std.ArrayList(u8).init(allocator);
320320 defer buf.deinit();
321321 try ents.write(buf.writer());
322 Sha256.hash(buf.items, &hash, .{});
322 Sha256.hash(buf.items, &hash);
323323 self.code_directory.addSpecialHash(ents.slotType(), hash);
324324
325325 try blobs.append(.{ .entitlements = ents });
src/link/MachO/hasher.zig+1-1
......@@ -58,7 +58,7 @@ pub fn ParallelHasher(comptime Hasher: type) type {
5858 const tracy = trace(@src());
5959 defer tracy.end();
6060 err.* = file.preadAll(buffer, fstart);
61 Hasher.hash(buffer, out, .{});
61 Hasher.hash(buffer, out);
6262 }
6363
6464 const Self = @This();
src/link/MachO/uuid.zig+1-1
......@@ -28,7 +28,7 @@ pub fn calcUuid(comp: *const Compilation, file: fs.File, file_size: u64, out: *[
2828 @memcpy(final_buffer[i * Md5.digest_length ..][0..Md5.digest_length], &hash);
2929 }
3030
31 Md5.hash(final_buffer, out, .{});
31 Md5.hash(final_buffer, out);
3232 conform(out);
3333}
3434