| author | |
| committer | |
| log | 18bc68847107d5bd183df0023b5bb123139f5343 |
| tree | dd8f14a52e41177093958fdfa13f11fd7ef3aa90 |
| parent | eb1a4970dae76b49fe8cf1fa792a571cfebed86d |
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 { |
| 191 | 191 | }, |
| 192 | 192 | .sha256 => { |
| 193 | 193 | var hash_a: [Sha256.digest_length]u8 = undefined; |
| 194 | Sha256.hash(unpacked_bytes, &hash_a, .{}); | |
| 194 | Sha256.hash(unpacked_bytes, &hash_a); | |
| 195 | 195 | |
| 196 | 196 | var hash_b: [Sha256.digest_length]u8 = undefined; |
| 197 | 197 | try self.inner_reader.readNoEof(&hash_b); |
lib/std/crypto.zig+19-1| ... | ... | @@ -347,7 +347,6 @@ test "CSPRNG" { |
| 347 | 347 | test "issue #4532: no index out of bounds" { |
| 348 | 348 | const types = [_]type{ |
| 349 | 349 | hash.Md5, |
| 350 | hash.Sha1, | |
| 351 | 350 | hash.sha2.Sha224, |
| 352 | 351 | hash.sha2.Sha256, |
| 353 | 352 | hash.sha2.Sha384, |
| ... | ... | @@ -380,6 +379,25 @@ test "issue #4532: no index out of bounds" { |
| 380 | 379 | |
| 381 | 380 | try std.testing.expectEqual(out1, out2); |
| 382 | 381 | } |
| 382 | ||
| 383 | try checkIndexOob(hash.Sha1); | |
| 384 | } | |
| 385 | ||
| 386 | fn 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); | |
| 383 | 401 | } |
| 384 | 402 | |
| 385 | 403 | /// Sets a slice to zeroes. |
lib/std/crypto/25519/ed25519.zig+1-1| ... | ... | @@ -163,7 +163,7 @@ pub const Ed25519 = struct { |
| 163 | 163 | const expected_r = try Curve.fromBytes(r); |
| 164 | 164 | try expected_r.rejectIdentity(); |
| 165 | 165 | |
| 166 | var h = Sha512.init(.{}); | |
| 166 | var h = Sha512.init(); | |
| 167 | 167 | h.update(&r); |
| 168 | 168 | h.update(&public_key.bytes); |
| 169 | 169 |
lib/std/crypto/Certificate.zig+22-10| ... | ... | @@ -949,7 +949,7 @@ pub const rsa = struct { |
| 949 | 949 | // 2. Let mHash = Hash(M), an octet string of length hLen. |
| 950 | 950 | var mHash: [Hash.digest_length]u8 = undefined; |
| 951 | 951 | { |
| 952 | var hasher: Hash = .init(.{}); | |
| 952 | var hasher: Hash = .init(); | |
| 953 | 953 | for (msg) |part| hasher.update(part); |
| 954 | 954 | hasher.final(&mHash); |
| 955 | 955 | } |
| ... | ... | @@ -1038,7 +1038,7 @@ pub const rsa = struct { |
| 1038 | 1038 | |
| 1039 | 1039 | // 13. Let H' = Hash(M'), an octet string of length hLen. |
| 1040 | 1040 | var h_p: [Hash.digest_length]u8 = undefined; |
| 1041 | Hash.hash(m_p, &h_p, .{}); | |
| 1041 | Hash.hash(m_p, &h_p); | |
| 1042 | 1042 | |
| 1043 | 1043 | // 14. If H = H', output "consistent". Otherwise, output |
| 1044 | 1044 | // "inconsistent". |
| ... | ... | @@ -1054,7 +1054,7 @@ pub const rsa = struct { |
| 1054 | 1054 | |
| 1055 | 1055 | while (idx < len) { |
| 1056 | 1056 | 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]); | |
| 1058 | 1058 | idx += Hash.digest_length; |
| 1059 | 1059 | counter += 1; |
| 1060 | 1060 | } |
| ... | ... | @@ -1081,13 +1081,14 @@ pub const rsa = struct { |
| 1081 | 1081 | public_key: PublicKey, |
| 1082 | 1082 | comptime Hash: type, |
| 1083 | 1083 | ) 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); | |
| 1085 | 1086 | } |
| 1086 | 1087 | |
| 1087 | 1088 | pub fn concatVerify( |
| 1088 | 1089 | comptime modulus_len: usize, |
| 1089 | 1090 | sig: [modulus_len]u8, |
| 1090 | msg: []const []const u8, | |
| 1091 | msg: [][]const u8, | |
| 1091 | 1092 | public_key: PublicKey, |
| 1092 | 1093 | comptime Hash: type, |
| 1093 | 1094 | ) VerifyError!void { |
| ... | ... | @@ -1096,7 +1097,7 @@ pub const rsa = struct { |
| 1096 | 1097 | if (!std.mem.eql(u8, &em_dec, &em)) return error.InvalidSignature; |
| 1097 | 1098 | } |
| 1098 | 1099 | |
| 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 { | |
| 1100 | 1101 | comptime var em_index = emLen; |
| 1101 | 1102 | var em: [emLen]u8 = undefined; |
| 1102 | 1103 | |
| ... | ... | @@ -1107,10 +1108,21 @@ pub const rsa = struct { |
| 1107 | 1108 | // |
| 1108 | 1109 | // If the hash function outputs "message too long," output "message |
| 1109 | 1110 | // 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 | } | |
| 1114 | 1126 | |
| 1115 | 1127 | // 2. Encode the algorithm ID for the hash function and the hash value |
| 1116 | 1128 | // 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 @@ |
| 2 | 2 | //! Namely, it is feasible to find multiple inputs producing the same hash. |
| 3 | 3 | //! For a fast-performing, cryptographically secure hash function, see SHA512/256, BLAKE2 or BLAKE3. |
| 4 | 4 | |
| 5 | const Sha1 = @This(); | |
| 5 | 6 | const std = @import("../std.zig"); |
| 6 | 7 | const mem = std.mem; |
| 7 | 8 | const math = std.math; |
| 8 | const Sha1 = @This(); | |
| 9 | const assert = std.debug.assert; | |
| 10 | const Writer = std.Io.Writer; | |
| 9 | 11 | |
| 10 | 12 | pub const block_length = 64; |
| 11 | 13 | pub const digest_length = 20; |
| 12 | pub const Options = struct {}; | |
| 13 | 14 | |
| 14 | 15 | s: [5]u32, |
| 15 | /// Streaming Cache | |
| 16 | buf: [64]u8 = undefined, | |
| 17 | buf_len: u8 = 0, | |
| 18 | total_len: u64 = 0, | |
| 16 | total_len: u64, | |
| 17 | writer: Writer, | |
| 19 | 18 | |
| 20 | pub fn init(options: Options) Sha1 { | |
| 21 | _ = options; | |
| 19 | pub fn init(buffer: []u8) Sha1 { | |
| 20 | assert(buffer.len >= block_length); | |
| 22 | 21 | 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, | |
| 29 | 27 | }, |
| 30 | 28 | }; |
| 31 | 29 | } |
| 32 | 30 | |
| 33 | pub 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); | |
| 31 | pub 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 | }; | |
| 37 | 45 | } |
| 38 | 46 | |
| 39 | pub 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; | |
| 47 | const vtable: Writer.VTable = .{ .drain = drain }; | |
| 48 | ||
| 49 | fn 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; | |
| 49 | 60 | } |
| 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; | |
| 54 | 70 | } |
| 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; | |
| 61 | 73 | } |
| 62 | 74 | |
| 63 | pub fn peek(d: Sha1) [digest_length]u8 { | |
| 64 | var copy = d; | |
| 65 | return copy.finalResult(); | |
| 75 | pub 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(); | |
| 66 | 80 | } |
| 67 | 81 | |
| 68 | pub 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); | |
| 82 | pub fn update(d: *Sha1, b: []const u8) void { | |
| 83 | d.writer.writeAll(b) catch unreachable; | |
| 84 | } | |
| 71 | 85 | |
| 72 | // Append padding bits. | |
| 73 | d.buf[d.buf_len] = 0x80; | |
| 74 | d.buf_len += 1; | |
| 86 | pub 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); | |
| 75 | 95 | |
| 76 | 96 | // > 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); | |
| 80 | 100 | } |
| 81 | 101 | |
| 82 | 102 | // Append message length. |
| 83 | var i: usize = 1; | |
| 84 | 103 | 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)); | |
| 88 | 107 | len >>= 8; |
| 89 | 108 | } |
| 90 | 109 | |
| 91 | d.round(d.buf[0..]); | |
| 110 | round(&d.s, buf); | |
| 92 | 111 | |
| 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; | |
| 96 | 115 | } |
| 97 | 116 | |
| 98 | pub fn finalResult(d: *Sha1) [digest_length]u8 { | |
| 99 | var result: [digest_length]u8 = undefined; | |
| 100 | d.final(&result); | |
| 101 | return result; | |
| 102 | } | |
| 103 | ||
| 104 | fn round(d: *Sha1, b: *const [64]u8) void { | |
| 117 | pub fn round(d_s: *[5]u32, b: *const [block_length]u8) void { | |
| 105 | 118 | 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.*; | |
| 114 | 120 | |
| 115 | 121 | const round0a = comptime [_]RoundParam{ |
| 116 | 122 | .abcdei(0, 1, 2, 3, 4, 0), |
| ... | ... | @@ -241,11 +247,11 @@ fn round(d: *Sha1, b: *const [64]u8) void { |
| 241 | 247 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); |
| 242 | 248 | } |
| 243 | 249 | |
| 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]; | |
| 249 | 255 | } |
| 250 | 256 | |
| 251 | 257 | const RoundParam = struct { |
| ... | ... | @@ -271,36 +277,38 @@ const RoundParam = struct { |
| 271 | 277 | const htest = @import("test.zig"); |
| 272 | 278 | |
| 273 | 279 | test "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"); | |
| 277 | 283 | } |
| 278 | 284 | |
| 279 | 285 | test "sha1 streaming" { |
| 280 | var h = Sha1.init(.{}); | |
| 286 | var buffer: [block_length]u8 = undefined; | |
| 287 | var h: Sha1 = .init(&buffer); | |
| 281 | 288 | var out: [20]u8 = undefined; |
| 282 | 289 | |
| 283 | h.final(&out); | |
| 290 | out = h.final(); | |
| 284 | 291 | try htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]); |
| 285 | 292 | |
| 286 | h = Sha1.init(.{}); | |
| 293 | h = .init(&buffer); | |
| 287 | 294 | h.update("abc"); |
| 288 | h.final(&out); | |
| 295 | out = h.final(); | |
| 289 | 296 | try htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); |
| 290 | 297 | |
| 291 | h = Sha1.init(.{}); | |
| 298 | h = .init(&buffer); | |
| 292 | 299 | h.update("a"); |
| 293 | 300 | h.update("b"); |
| 294 | 301 | h.update("c"); |
| 295 | h.final(&out); | |
| 302 | out = h.final(); | |
| 296 | 303 | try htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); |
| 297 | 304 | } |
| 298 | 305 | |
| 299 | 306 | test "sha1 aligned final" { |
| 300 | var block = [_]u8{0} ** Sha1.block_length; | |
| 307 | var block: [block_length]u8 = @splat(0); | |
| 301 | 308 | var out: [Sha1.digest_length]u8 = undefined; |
| 309 | var buffer: [block_length]u8 = undefined; | |
| 302 | 310 | |
| 303 | var h = Sha1.init(.{}); | |
| 311 | var h: Sha1 = .init(&buffer); | |
| 304 | 312 | h.update(&block); |
| 305 | h.final(out[0..]); | |
| 313 | out = h.final(); | |
| 306 | 314 | } |
lib/std/crypto/ecdsa.zig+2-2| ... | ... | @@ -258,8 +258,8 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { |
| 258 | 258 | const s = try Curve.scalar.Scalar.fromBytes(sig.s, .big); |
| 259 | 259 | if (r.isZero() or s.isZero()) return error.IdentityElement; |
| 260 | 260 | |
| 261 | return Verifier{ | |
| 262 | .h = Hash.init(.{}), | |
| 261 | return .{ | |
| 262 | .h = Hash.init(), | |
| 263 | 263 | .r = r, |
| 264 | 264 | .s = s, |
| 265 | 265 | .public_key = public_key, |
lib/std/crypto/hmac.zig+3-3| ... | ... | @@ -37,7 +37,7 @@ pub fn Hmac(comptime Hash: type) type { |
| 37 | 37 | |
| 38 | 38 | // Normalize key length to block size of hash |
| 39 | 39 | if (key.len > Hash.block_length) { |
| 40 | Hash.hash(key, scratch[0..mac_length], .{}); | |
| 40 | Hash.hash(key, scratch[0..mac_length]); | |
| 41 | 41 | @memset(scratch[mac_length..Hash.block_length], 0); |
| 42 | 42 | } else if (key.len < Hash.block_length) { |
| 43 | 43 | @memcpy(scratch[0..key.len], key); |
| ... | ... | @@ -54,7 +54,7 @@ pub fn Hmac(comptime Hash: type) type { |
| 54 | 54 | b.* = scratch[i] ^ 0x36; |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | ctx.hash = Hash.init(.{}); | |
| 57 | ctx.hash = Hash.init(); | |
| 58 | 58 | ctx.hash.update(&i_key_pad); |
| 59 | 59 | return ctx; |
| 60 | 60 | } |
| ... | ... | @@ -66,7 +66,7 @@ pub fn Hmac(comptime Hash: type) type { |
| 66 | 66 | pub fn final(ctx: *Self, out: *[mac_length]u8) void { |
| 67 | 67 | var scratch: [mac_length]u8 = undefined; |
| 68 | 68 | ctx.hash.final(&scratch); |
| 69 | var ohash = Hash.init(.{}); | |
| 69 | var ohash = Hash.init(); | |
| 70 | 70 | ohash.update(&ctx.o_key_pad); |
| 71 | 71 | ohash.update(&scratch); |
| 72 | 72 | ohash.final(out); |
lib/std/crypto/md5.zig+3-5| ... | ... | @@ -31,7 +31,6 @@ pub const Md5 = struct { |
| 31 | 31 | const Self = @This(); |
| 32 | 32 | pub const block_length = 64; |
| 33 | 33 | pub const digest_length = 16; |
| 34 | pub const Options = struct {}; | |
| 35 | 34 | |
| 36 | 35 | s: [4]u32, |
| 37 | 36 | // Streaming Cache |
| ... | ... | @@ -39,8 +38,7 @@ pub const Md5 = struct { |
| 39 | 38 | buf_len: u8, |
| 40 | 39 | total_len: u64, |
| 41 | 40 | |
| 42 | pub fn init(options: Options) Self { | |
| 43 | _ = options; | |
| 41 | pub fn init() Self { | |
| 44 | 42 | return Self{ |
| 45 | 43 | .s = [_]u32{ |
| 46 | 44 | 0x67452301, |
| ... | ... | @@ -54,8 +52,8 @@ pub const Md5 = struct { |
| 54 | 52 | }; |
| 55 | 53 | } |
| 56 | 54 | |
| 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(); | |
| 59 | 57 | d.update(data); |
| 60 | 58 | d.final(out); |
| 61 | 59 | } |
lib/std/crypto/test.zig+17-9| ... | ... | @@ -3,19 +3,27 @@ const testing = std.testing; |
| 3 | 3 | const fmt = std.fmt; |
| 4 | 4 | |
| 5 | 5 | // Hash using the specified hasher `H` asserting `expected == H(input)`. |
| 6 | pub fn assertEqualHash(comptime Hasher: anytype, comptime expected_hex: *const [Hasher.digest_length * 2:0]u8, input: []const u8) !void { | |
| 6 | pub fn assertEqualHash( | |
| 7 | comptime Hasher: type, | |
| 8 | expected_hex: *const [Hasher.digest_length * 2:0]u8, | |
| 9 | input: []const u8, | |
| 10 | ) !void { | |
| 7 | 11 | var h: [Hasher.digest_length]u8 = undefined; |
| 8 | 12 | Hasher.hash(input, &h, .{}); |
| 9 | ||
| 10 | 13 | try assertEqual(expected_hex, &h); |
| 11 | 14 | } |
| 12 | 15 | |
| 13 | // Assert `expected` == hex(`input`) where `input` is a bytestring | |
| 14 | pub 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 | } | |
| 16 | pub 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 | } | |
| 19 | 24 | |
| 20 | try testing.expectEqualSlices(u8, &expected_bytes, input); | |
| 25 | pub 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); | |
| 21 | 29 | } |
lib/std/crypto/tls.zig+1-1| ... | ... | @@ -578,7 +578,7 @@ pub fn hkdfExpandLabel( |
| 578 | 578 | |
| 579 | 579 | pub fn emptyHash(comptime Hash: type) [Hash.digest_length]u8 { |
| 580 | 580 | var result: [Hash.digest_length]u8 = undefined; |
| 581 | Hash.hash(&.{}, &result, .{}); | |
| 581 | Hash.hash(&.{}, &result); | |
| 582 | 582 | return result; |
| 583 | 583 | } |
| 584 | 584 |
lib/std/crypto/tls/Client.zig+7-5| ... | ... | @@ -498,7 +498,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client |
| 498 | 498 | .ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
| 499 | 499 | => |tag| { |
| 500 | 500 | handshake_cipher = @unionInit(tls.HandshakeCipher, @tagName(tag.with()), .{ |
| 501 | .transcript_hash = .init(.{}), | |
| 501 | .transcript_hash = .init(), | |
| 502 | 502 | .version = undefined, |
| 503 | 503 | }); |
| 504 | 504 | const p = &@field(handshake_cipher, @tagName(tag.with())); |
| ... | ... | @@ -680,7 +680,8 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client |
| 680 | 680 | const key_size = hsd.decode(u8); |
| 681 | 681 | try hsd.ensure(key_size); |
| 682 | 682 | 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); | |
| 684 | 685 | try key_share.exchange(named_group, server_pub_key); |
| 685 | 686 | handshake_state = .server_hello_done; |
| 686 | 687 | }, |
| ... | ... | @@ -776,10 +777,11 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client |
| 776 | 777 | } |
| 777 | 778 | switch (handshake_cipher) { |
| 778 | 779 | inline else => |*p| { |
| 779 | try main_cert_pub_key.verifySignature(&hsd, &.{ | |
| 780 | var msgs: [2][]const u8 = .{ | |
| 780 | 781 | " " ** 64 ++ "TLS 1.3, server CertificateVerify\x00", |
| 781 | 782 | &p.transcript_hash.peek(), |
| 782 | }); | |
| 783 | }; | |
| 784 | try main_cert_pub_key.verifySignature(&hsd, &msgs); | |
| 783 | 785 | p.transcript_hash.update(wrapped_handshake); |
| 784 | 786 | }, |
| 785 | 787 | } |
| ... | ... | @@ -1755,7 +1757,7 @@ const CertificatePublicKey = struct { |
| 1755 | 1757 | fn verifySignature( |
| 1756 | 1758 | cert_pub_key: *const CertificatePublicKey, |
| 1757 | 1759 | sigd: *tls.Decoder, |
| 1758 | msg: []const []const u8, | |
| 1760 | msg: [][]const u8, | |
| 1759 | 1761 | ) VerifyError!void { |
| 1760 | 1762 | const pub_key = cert_pub_key.buf[0..cert_pub_key.len]; |
| 1761 | 1763 |
lib/std/http/WebSocket.zig+3-3| ... | ... | @@ -45,11 +45,11 @@ pub fn init( |
| 45 | 45 | |
| 46 | 46 | const key = sec_websocket_key orelse return error.WebSocketUpgradeMissingKey; |
| 47 | 47 | |
| 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); | |
| 49 | 50 | sha1.update(key); |
| 50 | 51 | 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(); | |
| 53 | 53 | var base64_digest: [28]u8 = undefined; |
| 54 | 54 | assert(std.base64.standard.Encoder.encode(&base64_digest, &digest).len == base64_digest.len); |
| 55 | 55 |
src/Package.zig+1-1| ... | ... | @@ -133,7 +133,7 @@ pub const Hash = struct { |
| 133 | 133 | return result; |
| 134 | 134 | } |
| 135 | 135 | var bin_digest: [Algo.digest_length]u8 = undefined; |
| 136 | Algo.hash(sub_path, &bin_digest, .{}); | |
| 136 | Algo.hash(sub_path, &bin_digest); | |
| 137 | 137 | _ = std.fmt.bufPrint(result.bytes[i..], "{x}", .{&bin_digest}) catch unreachable; |
| 138 | 138 | return result; |
| 139 | 139 | } |
src/Package/Fetch.zig+2-2| ... | ... | @@ -1621,7 +1621,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute |
| 1621 | 1621 | |
| 1622 | 1622 | std.mem.sortUnstable(*HashedFile, all_files.items, {}, HashedFile.lessThan); |
| 1623 | 1623 | |
| 1624 | var hasher = Package.Hash.Algo.init(.{}); | |
| 1624 | var hasher = Package.Hash.Algo.init(); | |
| 1625 | 1625 | var any_failures = false; |
| 1626 | 1626 | for (all_files.items) |hashed_file| { |
| 1627 | 1627 | hashed_file.failure catch |err| { |
| ... | ... | @@ -1690,7 +1690,7 @@ fn workerDeleteFile(dir: fs.Dir, deleted_file: *DeletedFile) void { |
| 1690 | 1690 | |
| 1691 | 1691 | fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void { |
| 1692 | 1692 | var buf: [8000]u8 = undefined; |
| 1693 | var hasher = Package.Hash.Algo.init(.{}); | |
| 1693 | var hasher = Package.Hash.Algo.init(); | |
| 1694 | 1694 | hasher.update(hashed_file.normalized_path); |
| 1695 | 1695 | var file_size: u64 = 0; |
| 1696 | 1696 |
src/Package/Fetch/git.zig+12-7| ... | ... | @@ -45,10 +45,10 @@ pub const Oid = union(Format) { |
| 45 | 45 | sha1: Sha1, |
| 46 | 46 | sha256: Sha256, |
| 47 | 47 | |
| 48 | fn init(oid_format: Format) Hasher { | |
| 48 | fn init(oid_format: Format, buffer: []u8) Hasher { | |
| 49 | 49 | return switch (oid_format) { |
| 50 | .sha1 => .{ .sha1 = Sha1.init(.{}) }, | |
| 51 | .sha256 => .{ .sha256 = Sha256.init(.{}) }, | |
| 50 | .sha1 => .{ .sha1 = .init(buffer) }, | |
| 51 | .sha256 => .{ .sha256 = Sha256.init() }, | |
| 52 | 52 | }; |
| 53 | 53 | } |
| 54 | 54 | |
| ... | ... | @@ -61,6 +61,7 @@ pub const Oid = union(Format) { |
| 61 | 61 | |
| 62 | 62 | fn finalResult(hasher: *Hasher) Oid { |
| 63 | 63 | return switch (hasher.*) { |
| 64 | .sha1 => |*inner| .{ .sha1 = inner.final() }, | |
| 64 | 65 | inline else => |*inner, tag| @unionInit(Oid, @tagName(tag), inner.finalResult()), |
| 65 | 66 | }; |
| 66 | 67 | } |
| ... | ... | @@ -1281,7 +1282,8 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in |
| 1281 | 1282 | } |
| 1282 | 1283 | @memset(fan_out_table[fan_out_index..], count); |
| 1283 | 1284 | |
| 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)); | |
| 1285 | 1287 | const writer = index_hashed_writer.writer(); |
| 1286 | 1288 | try writer.writeAll(IndexHeader.signature); |
| 1287 | 1289 | try writer.writeInt(u32, IndexHeader.supported_version, .big); |
| ... | ... | @@ -1331,7 +1333,8 @@ fn indexPackFirstPass( |
| 1331 | 1333 | ) !Oid { |
| 1332 | 1334 | var pack_buffered_reader = std.io.bufferedReader(pack.deprecatedReader()); |
| 1333 | 1335 | 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)); | |
| 1335 | 1338 | const pack_reader = pack_hashed_reader.reader(); |
| 1336 | 1339 | |
| 1337 | 1340 | const pack_header = try PackHeader.read(pack_reader); |
| ... | ... | @@ -1345,7 +1348,8 @@ fn indexPackFirstPass( |
| 1345 | 1348 | .commit, .tree, .blob, .tag => |object| { |
| 1346 | 1349 | var entry_decompress_stream = std.compress.zlib.decompressor(entry_crc32_reader.reader()); |
| 1347 | 1350 | 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)); | |
| 1349 | 1353 | const entry_writer = entry_hashed_writer.writer(); |
| 1350 | 1354 | // The object header is not included in the pack data but is |
| 1351 | 1355 | // part of the object's ID |
| ... | ... | @@ -1431,7 +1435,8 @@ fn indexPackHashDelta( |
| 1431 | 1435 | |
| 1432 | 1436 | const base_data = try resolveDeltaChain(allocator, format, pack, base_object, delta_offsets.items, cache); |
| 1433 | 1437 | |
| 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); | |
| 1435 | 1440 | var entry_hashed_writer = hashedWriter(std.io.null_writer, &entry_hasher); |
| 1436 | 1441 | try entry_hashed_writer.writer().print("{s} {}\x00", .{ @tagName(base_object.type), base_data.len }); |
| 1437 | 1442 | entry_hasher.update(base_data); |
src/link/MachO/CodeSignature.zig+2-2| ... | ... | @@ -307,7 +307,7 @@ pub fn writeAdhocSignature( |
| 307 | 307 | var buf = std.ArrayList(u8).init(allocator); |
| 308 | 308 | defer buf.deinit(); |
| 309 | 309 | try req.write(buf.writer()); |
| 310 | Sha256.hash(buf.items, &hash, .{}); | |
| 310 | Sha256.hash(buf.items, &hash); | |
| 311 | 311 | self.code_directory.addSpecialHash(req.slotType(), hash); |
| 312 | 312 | |
| 313 | 313 | try blobs.append(.{ .requirements = req }); |
| ... | ... | @@ -319,7 +319,7 @@ pub fn writeAdhocSignature( |
| 319 | 319 | var buf = std.ArrayList(u8).init(allocator); |
| 320 | 320 | defer buf.deinit(); |
| 321 | 321 | try ents.write(buf.writer()); |
| 322 | Sha256.hash(buf.items, &hash, .{}); | |
| 322 | Sha256.hash(buf.items, &hash); | |
| 323 | 323 | self.code_directory.addSpecialHash(ents.slotType(), hash); |
| 324 | 324 | |
| 325 | 325 | try blobs.append(.{ .entitlements = ents }); |
src/link/MachO/hasher.zig+1-1| ... | ... | @@ -58,7 +58,7 @@ pub fn ParallelHasher(comptime Hasher: type) type { |
| 58 | 58 | const tracy = trace(@src()); |
| 59 | 59 | defer tracy.end(); |
| 60 | 60 | err.* = file.preadAll(buffer, fstart); |
| 61 | Hasher.hash(buffer, out, .{}); | |
| 61 | Hasher.hash(buffer, out); | |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | 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: *[ |
| 28 | 28 | @memcpy(final_buffer[i * Md5.digest_length ..][0..Md5.digest_length], &hash); |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | Md5.hash(final_buffer, out, .{}); | |
| 31 | Md5.hash(final_buffer, out); | |
| 32 | 32 | conform(out); |
| 33 | 33 | } |
| 34 | 34 |