authorgravatar for mantas@jonytis.euMantas Jonytis <mantas@jonytis.eu> 2020-08-01 16:56:11+03:00
committergravatar for mantas@jonytis.euMantas Jonytis <mantas@jonytis.eu> 2020-08-01 16:56:11+03:00
log8286cc77f8fdd33d7b2426b385375f94f04fdae0
treef26c31801e630908291dfec36e8ef7335dd94206
parent36ed4623a8355cd06be84e015142d81ae4429e4f

implement keyed blake2


1 files changed, 113 insertions(+), 28 deletions(-)

lib/std/crypto/blake2.zig+113-28
...@@ -1,8 +1,7 @@...@@ -1,8 +1,7 @@
1const mem = @import("../mem.zig");1const mem = @import("../mem.zig");
2const math = @import("../math.zig");
3const endian = @import("../endian.zig");
4const debug = @import("../debug.zig");
5const builtin = @import("builtin");2const builtin = @import("builtin");
3const debug = @import("../debug.zig");
4const math = @import("../math.zig");
6const htest = @import("test.zig");5const htest = @import("test.zig");
76
8const RoundParam = struct {7const RoundParam = struct {
...@@ -67,10 +66,17 @@ pub fn Blake2s(comptime out_len: usize) type {...@@ -67,10 +66,17 @@ pub fn Blake2s(comptime out_len: usize) type {
67 buf: [64]u8,66 buf: [64]u8,
68 buf_len: u8,67 buf_len: u8,
6968
69 key: []const u8,
70
70 pub fn init() Self {71 pub fn init() Self {
72 return init_keyed("");
73 }
74
75 pub fn init_keyed(key: []const u8) Self {
71 debug.assert(8 <= out_len and out_len <= 512);76 debug.assert(8 <= out_len and out_len <= 512);
7277
73 var s: Self = undefined;78 var s: Self = undefined;
79 s.key = key;
74 s.reset();80 s.reset();
75 return s;81 return s;
76 }82 }
...@@ -78,14 +84,24 @@ pub fn Blake2s(comptime out_len: usize) type {...@@ -78,14 +84,24 @@ pub fn Blake2s(comptime out_len: usize) type {
78 pub fn reset(d: *Self) void {84 pub fn reset(d: *Self) void {
79 mem.copy(u32, d.h[0..], iv[0..]);85 mem.copy(u32, d.h[0..], iv[0..]);
8086
81 // No key plus default parameters87 // default parameters
82 d.h[0] ^= 0x01010000 ^ @intCast(u32, out_len >> 3);88 d.h[0] ^= 0x01010000 ^ @truncate(u32, d.key.len << 8) ^ @intCast(u32, out_len >> 3);
83 d.t = 0;89 d.t = 0;
84 d.buf_len = 0;90 d.buf_len = 0;
91
92 if (d.key.len > 0) {
93 mem.set(u8, d.buf[d.key.len..], 0);
94 d.update(d.key);
95 d.buf_len = 64;
96 }
85 }97 }
8698
87 pub fn hash(b: []const u8, out: []u8) void {99 pub fn hash(b: []const u8, out: []u8) void {
88 var d = Self.init();100 Self.hash_keyed("", b, out);
101 }
102
103 pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void {
104 var d = Self.init_keyed(key);
89 d.update(b);105 d.update(b);
90 d.final(out);106 d.final(out);
91 }107 }
...@@ -230,19 +246,22 @@ test "blake2s224 streaming" {...@@ -230,19 +246,22 @@ test "blake2s224 streaming" {
230 htest.assertEqual(h3, out[0..]);246 htest.assertEqual(h3, out[0..]);
231}247}
232248
233test "blake2s224 aligned final" {249test "comptime blake2s224" {
234 var block = [_]u8{0} ** Blake2s224.block_length;250 comptime {
235 var out: [Blake2s224.digest_length]u8 = undefined;251 @setEvalBranchQuota(6000);
252 var block = [_]u8{0} ** Blake2s224.block_length;
253 var out: [Blake2s224.digest_length]u8 = undefined;
236254
237 const h1 = "86b7611563293f8c73627df7a6d6ba25ca0548c2a6481f7d116ee576";255 const h1 = "86b7611563293f8c73627df7a6d6ba25ca0548c2a6481f7d116ee576";
238256
239 htest.assertEqualHash(Blake2s224, h1, block[0..]);257 htest.assertEqualHash(Blake2s224, h1, block[0..]);
240258
241 var h = Blake2s224.init();259 var h = Blake2s224.init();
242 h.update(&block);260 h.update(&block);
243 h.final(out[0..]);261 h.final(out[0..]);
244262
245 htest.assertEqual(h1, out[0..]);263 htest.assertEqual(h1, out[0..]);
264 }
246}265}
247266
248test "blake2s256 single" {267test "blake2s256 single" {
...@@ -296,9 +315,32 @@ test "blake2s256 streaming" {...@@ -296,9 +315,32 @@ test "blake2s256 streaming" {
296 htest.assertEqual(h3, out[0..]);315 htest.assertEqual(h3, out[0..]);
297}316}
298317
318test "blake2s256 keyed" {
319 var out: [32]u8 = undefined;
320
321 const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6";
322 const key = "secret_key";
323
324 Blake2s256.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out);
325 htest.assertEqual(h1, out[0..]);
326
327 var h = Blake2s256.init_keyed(key);
328 h.update("a" ** 64 ++ "b" ** 64);
329 h.final(out[0..]);
330
331 htest.assertEqual(h1, out[0..]);
332
333 h.reset();
334 h.update("a" ** 64);
335 h.update("b" ** 64);
336 h.final(out[0..]);
337
338 htest.assertEqual(h1, out[0..]);
339}
340
299test "comptime blake2s256" {341test "comptime blake2s256" {
300 comptime {342 comptime {
301 @setEvalBranchQuota(8000);343 @setEvalBranchQuota(6000);
302 var block = [_]u8{0} ** Blake2s256.block_length;344 var block = [_]u8{0} ** Blake2s256.block_length;
303 var out: [Blake2s256.digest_length]u8 = undefined;345 var out: [Blake2s256.digest_length]u8 = undefined;
304346
...@@ -358,10 +400,17 @@ pub fn Blake2b(comptime out_len: usize) type {...@@ -358,10 +400,17 @@ pub fn Blake2b(comptime out_len: usize) type {
358 buf: [128]u8,400 buf: [128]u8,
359 buf_len: u8,401 buf_len: u8,
360402
403 key: []const u8,
404
361 pub fn init() Self {405 pub fn init() Self {
406 return init_keyed("");
407 }
408
409 pub fn init_keyed(key: []const u8) Self {
362 debug.assert(8 <= out_len and out_len <= 512);410 debug.assert(8 <= out_len and out_len <= 512);
363411
364 var s: Self = undefined;412 var s: Self = undefined;
413 s.key = key;
365 s.reset();414 s.reset();
366 return s;415 return s;
367 }416 }
...@@ -369,14 +418,24 @@ pub fn Blake2b(comptime out_len: usize) type {...@@ -369,14 +418,24 @@ pub fn Blake2b(comptime out_len: usize) type {
369 pub fn reset(d: *Self) void {418 pub fn reset(d: *Self) void {
370 mem.copy(u64, d.h[0..], iv[0..]);419 mem.copy(u64, d.h[0..], iv[0..]);
371420
372 // No key plus default parameters421 // default parameters
373 d.h[0] ^= 0x01010000 ^ (out_len >> 3);422 d.h[0] ^= 0x01010000 ^ @truncate(u32, d.key.len << 8) ^ @intCast(u32, out_len >> 3);
374 d.t = 0;423 d.t = 0;
375 d.buf_len = 0;424 d.buf_len = 0;
425
426 if (d.key.len > 0) {
427 mem.set(u8, d.buf[d.key.len..], 0);
428 d.update(d.key);
429 d.buf_len = 128;
430 }
376 }431 }
377432
378 pub fn hash(b: []const u8, out: []u8) void {433 pub fn hash(b: []const u8, out: []u8) void {
379 var d = Self.init();434 Self.hash_keyed("", b, out);
435 }
436
437 pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void {
438 var d = Self.init_keyed(key);
380 d.update(b);439 d.update(b);
381 d.final(out);440 d.final(out);
382 }441 }
...@@ -519,19 +578,22 @@ test "blake2b384 streaming" {...@@ -519,19 +578,22 @@ test "blake2b384 streaming" {
519 htest.assertEqual(h3, out[0..]);578 htest.assertEqual(h3, out[0..]);
520}579}
521580
522test "blake2b384 aligned final" {581test "comptime blake2b384" {
523 var block = [_]u8{0} ** Blake2b384.block_length;582 comptime {
524 var out: [Blake2b384.digest_length]u8 = undefined;583 @setEvalBranchQuota(7000);
584 var block = [_]u8{0} ** Blake2b384.block_length;
585 var out: [Blake2b384.digest_length]u8 = undefined;
525586
526 const h1 = "e8aa1931ea0422e4446fecdd25c16cf35c240b10cb4659dd5c776eddcaa4d922397a589404b46eb2e53d78132d05fd7d";587 const h1 = "e8aa1931ea0422e4446fecdd25c16cf35c240b10cb4659dd5c776eddcaa4d922397a589404b46eb2e53d78132d05fd7d";
527588
528 htest.assertEqualHash(Blake2b384, h1, block[0..]);589 htest.assertEqualHash(Blake2b384, h1, block[0..]);
529590
530 var h = Blake2b384.init();591 var h = Blake2b384.init();
531 h.update(&block);592 h.update(&block);
532 h.final(out[0..]);593 h.final(out[0..]);
533594
534 htest.assertEqual(h1, out[0..]);595 htest.assertEqual(h1, out[0..]);
596 }
535}597}
536598
537test "blake2b512 single" {599test "blake2b512 single" {
...@@ -585,6 +647,29 @@ test "blake2b512 streaming" {...@@ -585,6 +647,29 @@ test "blake2b512 streaming" {
585 htest.assertEqual(h3, out[0..]);647 htest.assertEqual(h3, out[0..]);
586}648}
587649
650test "blake2b512 keyed" {
651 var out: [64]u8 = undefined;
652
653 const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d";
654 const key = "secret_key";
655
656 Blake2b512.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out);
657 htest.assertEqual(h1, out[0..]);
658
659 var h = Blake2b512.init_keyed(key);
660 h.update("a" ** 64 ++ "b" ** 64);
661 h.final(out[0..]);
662
663 htest.assertEqual(h1, out[0..]);
664
665 h.reset();
666 h.update("a" ** 64);
667 h.update("b" ** 64);
668 h.final(out[0..]);
669
670 htest.assertEqual(h1, out[0..]);
671}
672
588test "comptime blake2b512" {673test "comptime blake2b512" {
589 comptime {674 comptime {
590 @setEvalBranchQuota(8000);675 @setEvalBranchQuota(8000);