From 26793453a7cf2016ae6fa7ad3d649dca150b53f5 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 26 Oct 2020 13:23:16 +0100 Subject: [PATCH] std/crypto/blake2b: allow the initial output length to be set BLAKE2 includes the expected output length in the initial state. This length is actually distinct from the actual output length used at finalization. BLAKE2b-256/128 is thus not the same as BLAKE2b-128. This behavior can be a little bit surprising, and has been "fixed" in BLAKE3. In order to support this, we may want to provide an option to set the length used for domain separation. In Zig, there is another reason to allow this: we assume that the output length is defined at comptime. But BLAKE2 doesn't have a fixed output length. For an output length that is not known at comptime, we can't take the full block size and truncate it due to the reason above. What we can do now is set that length as an option to get the correct initial state, and truncate the output if necessary. --- lib/std/crypto/blake2.zig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index 009c7559ed7fa858d6a47c61dbaf77db89eb48be..f8b42b7a328dc1c3ea805b6371d21270b31f6fe3 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -44,7 +44,7 @@ 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 }; + 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, @@ -84,7 +84,7 @@ pub fn Blake2s(comptime out_bits: usize) type { const key_len = if (options.key) |key| key.len else 0; // default parameters - d.h[0] ^= 0x01010000 ^ @truncate(u32, key_len << 8) ^ @intCast(u32, out_bits >> 3); + d.h[0] ^= 0x01010000 ^ @truncate(u32, key_len << 8) ^ @intCast(u32, options.expected_out_bits >> 3); d.t = 0; d.buf_len = 0; @@ -385,7 +385,7 @@ 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 }; + 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, @@ -427,7 +427,7 @@ pub fn Blake2b(comptime out_bits: usize) type { const key_len = if (options.key) |key| key.len else 0; // default parameters - d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (out_bits >> 3); + d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (options.expected_out_bits >> 3); d.t = 0; d.buf_len = 0; -- 2.54.0