Skip to content

Commit 8b280d5

Browse files
authoredJan 16, 2018
Merge pull request #689 from zig-lang/blake2
Add Blake2X hash functions
2 parents 6a95b88 + 73b4f09 commit 8b280d5

File tree

7 files changed

+588
-93
lines changed

7 files changed

+588
-93
lines changed
 

‎CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ set(ZIG_STD_FILES
368368
"crypto/md5.zig"
369369
"crypto/sha1.zig"
370370
"crypto/sha2.zig"
371+
"crypto/blake2.zig"
371372
"cstr.zig"
372373
"debug/failing_allocator.zig"
373374
"debug/index.zig"

‎std/crypto/blake2.zig

+445
Large diffs are not rendered by default.

‎std/crypto/index.zig

+7
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,15 @@ pub const Sha256 = sha2.Sha256;
77
pub const Sha384 = sha2.Sha384;
88
pub const Sha512 = sha2.Sha512;
99

10+
const blake2 = @import("blake2.zig");
11+
pub const Blake2s224 = blake2.Blake2s224;
12+
pub const Blake2s256 = blake2.Blake2s256;
13+
pub const Blake2b384 = blake2.Blake2b384;
14+
pub const Blake2b512 = blake2.Blake2b512;
15+
1016
test "crypto" {
1117
_ = @import("md5.zig");
1218
_ = @import("sha1.zig");
1319
_ = @import("sha2.zig");
20+
_ = @import("blake2.zig");
1421
}

‎std/crypto/md5.zig

+27-20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
const mem = @import("../mem.zig");
22
const math = @import("../math/index.zig");
33
const endian = @import("../endian.zig");
4+
const builtin = @import("builtin");
45
const debug = @import("../debug/index.zig");
6+
const fmt = @import("../fmt/index.zig");
57

68
const RoundParam = struct {
79
a: usize, b: usize, c: usize, d: usize,
@@ -42,10 +44,10 @@ pub const Md5 = struct {
4244
d.total_len = 0;
4345
}
4446

45-
pub fn hash(b: []const u8) -> u128 {
47+
pub fn hash(b: []const u8, out: []u8) {
4648
var d = Md5.init();
4749
d.update(b);
48-
return d.final();
50+
d.final(out);
4951
}
5052

5153
pub fn update(d: &Self, b: []const u8) {
@@ -73,7 +75,9 @@ pub const Md5 = struct {
7375
d.total_len +%= b.len;
7476
}
7577

76-
pub fn final(d: &Self) -> u128 {
78+
pub fn final(d: &Self, out: []u8) {
79+
debug.assert(out.len >= 16);
80+
7781
// The buffer here will never be completely full.
7882
mem.set(u8, d.buf[d.buf_len..], 0);
7983

@@ -98,13 +102,9 @@ pub const Md5 = struct {
98102

99103
d.round(d.buf[0..]);
100104

101-
const r =
102-
(u128(d.s[3]) << 96) |
103-
(u128(d.s[2]) << 64) |
104-
(u128(d.s[1]) << 32) |
105-
(u128(d.s[0]) << 0);
106-
107-
return endian.swapIfLe(u128, r);
105+
for (d.s) |s, j| {
106+
mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Little);
107+
}
108108
}
109109

110110
fn round(d: &Self, b: []const u8) {
@@ -226,28 +226,35 @@ pub const Md5 = struct {
226226
}
227227
};
228228

229+
const htest = @import("test.zig");
230+
229231
test "md5 single" {
230-
debug.assert(0xd41d8cd98f00b204e9800998ecf8427e == Md5.hash(""));
231-
debug.assert(0x0cc175b9c0f1b6a831c399e269772661 == Md5.hash("a"));
232-
debug.assert(0x900150983cd24fb0d6963f7d28e17f72 == Md5.hash("abc"));
233-
debug.assert(0xf96b697d7cb7938d525a2f31aaf161d0 == Md5.hash("message digest"));
234-
debug.assert(0xc3fcd3d76192e4007dfb496cca67e13b == Md5.hash("abcdefghijklmnopqrstuvwxyz"));
235-
debug.assert(0xd174ab98d277d9f5a5611c2c9f419d9f == Md5.hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
236-
debug.assert(0x57edf4a22be3c955ac49da2e2107b67a == Md5.hash("12345678901234567890123456789012345678901234567890123456789012345678901234567890"));
232+
htest.assertEqualHash(Md5, "d41d8cd98f00b204e9800998ecf8427e", "");
233+
htest.assertEqualHash(Md5, "0cc175b9c0f1b6a831c399e269772661", "a");
234+
htest.assertEqualHash(Md5, "900150983cd24fb0d6963f7d28e17f72", "abc");
235+
htest.assertEqualHash(Md5, "f96b697d7cb7938d525a2f31aaf161d0", "message digest");
236+
htest.assertEqualHash(Md5, "c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz");
237+
htest.assertEqualHash(Md5, "d174ab98d277d9f5a5611c2c9f419d9f", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
238+
htest.assertEqualHash(Md5, "57edf4a22be3c955ac49da2e2107b67a", "12345678901234567890123456789012345678901234567890123456789012345678901234567890");
237239
}
238240

239241
test "md5 streaming" {
240242
var h = Md5.init();
243+
var out: [16]u8 = undefined;
241244

242-
debug.assert(0xd41d8cd98f00b204e9800998ecf8427e == h.final());
245+
h.final(out[0..]);
246+
htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]);
243247

244248
h.reset();
245249
h.update("abc");
246-
debug.assert(0x900150983cd24fb0d6963f7d28e17f72 == h.final());
250+
h.final(out[0..]);
251+
htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]);
247252

248253
h.reset();
249254
h.update("a");
250255
h.update("b");
251256
h.update("c");
252-
debug.assert(0x900150983cd24fb0d6963f7d28e17f72 == h.final());
257+
h.final(out[0..]);
258+
259+
htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]);
253260
}

‎std/crypto/sha1.zig

+21-17
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const mem = @import("../mem.zig");
22
const math = @import("../math/index.zig");
33
const endian = @import("../endian.zig");
44
const debug = @import("../debug/index.zig");
5+
const builtin = @import("builtin");
56

67
pub const u160 = @IntType(false, 160);
78

@@ -38,10 +39,10 @@ pub const Sha1 = struct {
3839
d.total_len = 0;
3940
}
4041

41-
pub fn hash(b: []const u8) -> u160 {
42+
pub fn hash(b: []const u8, out: []u8) {
4243
var d = Sha1.init();
4344
d.update(b);
44-
return d.final();
45+
d.final(out);
4546
}
4647

4748
pub fn update(d: &Self, b: []const u8) {
@@ -68,7 +69,9 @@ pub const Sha1 = struct {
6869
d.total_len += b.len;
6970
}
7071

71-
pub fn final(d: &Self) -> u160 {
72+
pub fn final(d: &Self, out: []u8) {
73+
debug.assert(out.len >= 20);
74+
7275
// The buffer here will never be completely full.
7376
mem.set(u8, d.buf[d.buf_len..], 0);
7477

@@ -93,14 +96,9 @@ pub const Sha1 = struct {
9396

9497
d.round(d.buf[0..]);
9598

96-
const r =
97-
(u160(d.s[0]) << 128) |
98-
(u160(d.s[1]) << 96) |
99-
(u160(d.s[2]) << 64) |
100-
(u160(d.s[3]) << 32) |
101-
(u160(d.s[4]) << 0);
102-
103-
return endian.swapIfBe(u160, r);
99+
for (d.s) |s, j| {
100+
mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Big);
101+
}
104102
}
105103

106104
fn round(d: &Self, b: []const u8) {
@@ -257,24 +255,30 @@ pub const Sha1 = struct {
257255
}
258256
};
259257

258+
const htest = @import("test.zig");
259+
260260
test "sha1 single" {
261-
debug.assert(0xda39a3ee5e6b4b0d3255bfef95601890afd80709 == Sha1.hash(""));
262-
debug.assert(0xa9993e364706816aba3e25717850c26c9cd0d89d == Sha1.hash("abc"));
263-
debug.assert(0xa49b2446a02c645bf419f995b67091253a04a259 == Sha1.hash("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
261+
htest.assertEqualHash(Sha1, "da39a3ee5e6b4b0d3255bfef95601890afd80709", "");
262+
htest.assertEqualHash(Sha1, "a9993e364706816aba3e25717850c26c9cd0d89d", "abc");
263+
htest.assertEqualHash(Sha1, "a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
264264
}
265265

266266
test "sha1 streaming" {
267267
var h = Sha1.init();
268+
var out: [20]u8 = undefined;
268269

269-
debug.assert(0xda39a3ee5e6b4b0d3255bfef95601890afd80709 == h.final());
270+
h.final(out[0..]);
271+
htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]);
270272

271273
h.reset();
272274
h.update("abc");
273-
debug.assert(0xa9993e364706816aba3e25717850c26c9cd0d89d == h.final());
275+
h.final(out[0..]);
276+
htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);
274277

275278
h.reset();
276279
h.update("a");
277280
h.update("b");
278281
h.update("c");
279-
debug.assert(0xa9993e364706816aba3e25717850c26c9cd0d89d == h.final());
282+
h.final(out[0..]);
283+
htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]);
280284
}

‎std/crypto/sha2.zig

+65-56
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const math = @import("../math/index.zig");
33
const endian = @import("../endian.zig");
44
const debug = @import("../debug/index.zig");
55
const builtin = @import("builtin");
6+
const htest = @import("test.zig");
67

78
/////////////////////
89
// Sha224 + Sha256
@@ -57,7 +58,6 @@ pub const Sha256 = Sha2_32(Sha256Params);
5758

5859
fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
5960
const Self = this;
60-
const ReturnType = @IntType(false, params.out_len);
6161

6262
s: [8]u32,
6363
// Streaming Cache
@@ -84,10 +84,10 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
8484
d.total_len = 0;
8585
}
8686

87-
pub fn hash(b: []const u8) -> ReturnType {
87+
pub fn hash(b: []const u8, out: []u8) {
8888
var d = Self.init();
8989
d.update(b);
90-
return d.final();
90+
d.final(out);
9191
}
9292

9393
pub fn update(d: &Self, b: []const u8) {
@@ -114,7 +114,9 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
114114
d.total_len += b.len;
115115
}
116116

117-
pub fn final(d: &Self) -> ReturnType {
117+
pub fn final(d: &Self, out: []u8) {
118+
debug.assert(out.len >= params.out_len / 8);
119+
118120
// The buffer here will never be completely full.
119121
mem.set(u8, d.buf[d.buf_len..], 0);
120122

@@ -142,14 +144,9 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
142144
// May truncate for possible 224 output
143145
const rr = d.s[0 .. params.out_len / 32];
144146

145-
var j: u8 = u8(rr.len - 1) * 32;
146-
var r: ReturnType = 0;
147-
for (rr) |p| {
148-
r |= ReturnType(p) << j;
149-
j -%= 32;
147+
for (rr) |s, j| {
148+
mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Big);
150149
}
151-
152-
return endian.swapIfBe(ReturnType, r);
153150
}
154151

155152
fn round(d: &Self, b: []const u8) {
@@ -270,47 +267,55 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
270267
};}
271268

272269
test "sha224 single" {
273-
debug.assert(0xd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f == Sha224.hash(""));
274-
debug.assert(0x23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7 == Sha224.hash("abc"));
275-
debug.assert(0xc97ca9a559850ce97a04a96def6d99a9e0e0e2ab14e6b8df265fc0b3 == Sha224.hash("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
270+
htest.assertEqualHash(Sha224, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "");
271+
htest.assertEqualHash(Sha224, "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "abc");
272+
htest.assertEqualHash(Sha224, "c97ca9a559850ce97a04a96def6d99a9e0e0e2ab14e6b8df265fc0b3", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
276273
}
277274

278275
test "sha224 streaming" {
279276
var h = Sha224.init();
277+
var out: [28]u8 = undefined;
280278

281-
debug.assert(0xd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f == h.final());
279+
h.final(out[0..]);
280+
htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]);
282281

283282
h.reset();
284283
h.update("abc");
285-
debug.assert(0x23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7 == h.final());
284+
h.final(out[0..]);
285+
htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]);
286286

287287
h.reset();
288288
h.update("a");
289289
h.update("b");
290290
h.update("c");
291-
debug.assert(0x23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7 == h.final());
291+
h.final(out[0..]);
292+
htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]);
292293
}
293294

294295
test "sha256 single" {
295-
debug.assert(0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 == Sha256.hash(""));
296-
debug.assert(0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad == Sha256.hash("abc"));
297-
debug.assert(0xcf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1 == Sha256.hash("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
296+
htest.assertEqualHash(Sha256, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "");
297+
htest.assertEqualHash(Sha256, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "abc");
298+
htest.assertEqualHash(Sha256, "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
298299
}
299300

300301
test "sha256 streaming" {
301302
var h = Sha256.init();
303+
var out: [32]u8 = undefined;
302304

303-
debug.assert(0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 == h.final());
305+
h.final(out[0..]);
306+
htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]);
304307

305308
h.reset();
306309
h.update("abc");
307-
debug.assert(0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad == h.final());
310+
h.final(out[0..]);
311+
htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]);
308312

309313
h.reset();
310314
h.update("a");
311315
h.update("b");
312316
h.update("c");
313-
debug.assert(0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad == h.final());
317+
h.final(out[0..]);
318+
htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]);
314319
}
315320

316321

@@ -367,7 +372,6 @@ pub const Sha512 = Sha2_64(Sha512Params);
367372

368373
fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
369374
const Self = this;
370-
const ReturnType = @IntType(false, params.out_len);
371375
const u9 = @IntType(false, 9);
372376

373377
s: [8]u64,
@@ -395,10 +399,10 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
395399
d.total_len = 0;
396400
}
397401

398-
pub fn hash(b: []const u8) -> ReturnType {
402+
pub fn hash(b: []const u8, out: []u8) {
399403
var d = Self.init();
400404
d.update(b);
401-
return d.final();
405+
d.final(out);
402406
}
403407

404408
pub fn update(d: &Self, b: []const u8) {
@@ -425,7 +429,9 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
425429
d.total_len += b.len;
426430
}
427431

428-
pub fn final(d: &Self) -> ReturnType {
432+
pub fn final(d: &Self, out: []u8) {
433+
debug.assert(out.len >= params.out_len / 8);
434+
429435
// The buffer here will never be completely full.
430436
mem.set(u8, d.buf[d.buf_len..], 0);
431437

@@ -453,14 +459,9 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
453459
// May truncate for possible 384 output
454460
const rr = d.s[0 .. params.out_len / 64];
455461

456-
var j: u9 = u9(rr.len - 1) * 64;
457-
var r: ReturnType = 0;
458-
for (rr) |p| {
459-
r |= ReturnType(p) << j;
460-
j -%= 64;
462+
for (rr) |s, j| {
463+
mem.writeInt(out[8*j .. 8*j + 8], s, builtin.Endian.Big);
461464
}
462-
463-
return endian.swapIfBe(ReturnType, r);
464465
}
465466

466467
fn round(d: &Self, b: []const u8) {
@@ -601,61 +602,69 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
601602
};}
602603

603604
test "sha384 single" {
604-
const h1 = 0x38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b;
605-
debug.assert(h1 == Sha384.hash(""));
605+
const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";
606+
htest.assertEqualHash(Sha384, h1, "");
606607

607-
const h2 = 0xcb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7;
608-
debug.assert(h2 == Sha384.hash("abc"));
608+
const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
609+
htest.assertEqualHash(Sha384, h2, "abc");
609610

610-
const h3 = 0x09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039;
611-
debug.assert(h3 == Sha384.hash("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
611+
const h3 = "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039";
612+
htest.assertEqualHash(Sha384, h3, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
612613
}
613614

614615
test "sha384 streaming" {
615616
var h = Sha384.init();
617+
var out: [48]u8 = undefined;
616618

617-
const h1 = 0x38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b;
618-
debug.assert(h1 == h.final());
619+
const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b";
620+
h.final(out[0..]);
621+
htest.assertEqual(h1, out[0..]);
619622

620-
const h2 = 0xcb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7;
623+
const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
621624

622625
h.reset();
623626
h.update("abc");
624-
debug.assert(h2 == h.final());
627+
h.final(out[0..]);
628+
htest.assertEqual(h2, out[0..]);
625629

626630
h.reset();
627631
h.update("a");
628632
h.update("b");
629633
h.update("c");
630-
debug.assert(h2 == h.final());
634+
h.final(out[0..]);
635+
htest.assertEqual(h2, out[0..]);
631636
}
632637

633638
test "sha512 single" {
634-
const h1 = 0xcf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e;
635-
debug.assert(h1 == Sha512.hash(""));
639+
const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";
640+
htest.assertEqualHash(Sha512, h1, "");
636641

637-
const h2 = 0xddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f;
638-
debug.assert(h2 == Sha512.hash("abc"));
642+
const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
643+
htest.assertEqualHash(Sha512, h2, "abc");
639644

640-
const h3 = 0x8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909;
641-
debug.assert(h3 == Sha512.hash("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
645+
const h3 = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909";
646+
htest.assertEqualHash(Sha512, h3, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
642647
}
643648

644649
test "sha512 streaming" {
645650
var h = Sha512.init();
651+
var out: [64]u8 = undefined;
646652

647-
const h1 = 0xcf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e;
648-
debug.assert(h1 == h.final());
653+
const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";
654+
h.final(out[0..]);
655+
htest.assertEqual(h1, out[0..]);
649656

650-
const h2 = 0xddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f;
657+
const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
651658

652659
h.reset();
653660
h.update("abc");
654-
debug.assert(h2 == h.final());
661+
h.final(out[0..]);
662+
htest.assertEqual(h2, out[0..]);
655663

656664
h.reset();
657665
h.update("a");
658666
h.update("b");
659667
h.update("c");
660-
debug.assert(h2 == h.final());
668+
h.final(out[0..]);
669+
htest.assertEqual(h2, out[0..]);
661670
}

‎std/crypto/test.zig

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const debug = @import("../debug/index.zig");
2+
const mem = @import("../mem.zig");
3+
const fmt = @import("../fmt/index.zig");
4+
5+
// Hash using the specified hasher `H` asserting `expected == H(input)`.
6+
pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, input: []const u8) {
7+
var h: [expected.len / 2]u8 = undefined;
8+
Hasher.hash(input, h[0..]);
9+
10+
assertEqual(expected, h);
11+
}
12+
13+
// Assert `expected` == `input` where `input` is a bytestring.
14+
pub fn assertEqual(comptime expected: []const u8, input: []const u8) {
15+
var expected_bytes: [expected.len / 2]u8 = undefined;
16+
for (expected_bytes) |*r, i| {
17+
*r = fmt.parseInt(u8, expected[2*i .. 2*i+2], 16) catch unreachable;
18+
}
19+
20+
debug.assert(mem.eql(u8, expected_bytes, input));
21+
}
22+

0 commit comments

Comments
 (0)
Please sign in to comment.