diff --git a/lib/std/crypto/blake3.zig b/lib/std/crypto/blake3.zig index 2985698dadec..2a8fa32b1af2 100644 --- a/lib/std/crypto/blake3.zig +++ b/lib/std/crypto/blake3.zig @@ -12,8 +12,8 @@ const Vec16 = @Vector(16, u32); const chunk_length = 1024; const max_depth = 54; -pub const simd_degree = std.simd.suggestVectorLength(u32) orelse 1; -pub const max_simd_degree = simd_degree; +const simd_degree = std.simd.suggestVectorLength(u32) orelse 1; +const max_simd_degree = simd_degree; const max_simd_degree_or_2 = if (max_simd_degree > 2) max_simd_degree else 2; /// Threshold for switching to parallel processing. @@ -502,9 +502,7 @@ fn hashManySimd( var out_ptr = out.ptr; var cnt = counter; - const simd_deg = comptime simd_degree; - - if (comptime simd_deg >= 16) { + if (simd_degree >= 16) { while (remaining >= 16) { const sixteen_inputs = [16][*]const u8{ inp[0], inp[1], inp[2], inp[3], @@ -525,7 +523,7 @@ fn hashManySimd( } } - if (comptime simd_deg >= 8) { + if (simd_degree >= 8) { while (remaining >= 8) { const eight_inputs = [8][*]const u8{ inp[0], inp[1], inp[2], inp[3], @@ -544,7 +542,7 @@ fn hashManySimd( } } - if (comptime simd_deg >= 4) { + if (simd_degree >= 4) { while (remaining >= 4) { const four_inputs = [4][*]const u8{ inp[0], @@ -571,7 +569,7 @@ fn hashManySimd( } fn hashMany(inputs: [][*]const u8, num_inputs: usize, blocks: usize, key: [8]u32, counter: u64, increment_counter: bool, flags: Flags, flags_start: Flags, flags_end: Flags, out: []u8) void { - if (comptime max_simd_degree >= 4) { + if (max_simd_degree >= 4) { hashManySimd(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out); } else { hashManyPortable(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out); @@ -909,7 +907,7 @@ pub const Blake3 = struct { pub const digest_length = 32; pub const key_length = 32; - pub const Options = struct { key: ?[digest_length]u8 = null }; + pub const Options = struct { key: ?[key_length]u8 = null }; pub const KdfOptions = struct {}; key: [8]u32, diff --git a/lib/std/crypto/kangarootwelve.zig b/lib/std/crypto/kangarootwelve.zig index 5cad301ed40e..3b740850af31 100644 --- a/lib/std/crypto/kangarootwelve.zig +++ b/lib/std/crypto/kangarootwelve.zig @@ -840,7 +840,21 @@ fn KTHash( /// The block length, or rate, in bytes. pub const block_length = Variant.rate; - /// Options for KangarooTwelve can include a customization string for domain separation. + /// Configuration options for KangarooTwelve hashing. + /// + /// Options include an optional customization string that provides domain separation, + /// ensuring that identical inputs with different customization strings + /// produce completely distinct hash outputs. + /// + /// This prevents hash collisions when the same data is hashed in different contexts. + /// + /// Customization strings can be of any length. + /// + /// Common options for customization:: + /// + /// - Key derivation or MAC: 16-byte secret for KT128, 32-byte secret for KT256 + /// - Context Separation: domain-specific strings (e.g., "email", "password", "session") + /// - Composite Keys: concatenation of secret key + context string pub const Options = struct { customization: ?[]const u8 = null, }; @@ -864,7 +878,20 @@ fn KTHash( pending_count: usize, // Number of complete chunks in pending_chunks /// Initialize a KangarooTwelve hashing context. - /// The customization string is optional and used for domain separation. + /// + /// Options include an optional customization string that provides domain separation, + /// ensuring that identical inputs with different customization strings + /// produce completely distinct hash outputs. + /// + /// This prevents hash collisions when the same data is hashed in different contexts. + /// + /// Customization strings can be of any length. + /// + /// Common options for customization:: + /// + /// - Key derivation or MAC: 16-byte secret for KT128, 32-byte secret for KT256 + /// - Context Separation: domain-specific strings (e.g., "email", "password", "session") + /// - Composite Keys: concatenation of secret key + context string pub fn init(options: Options) Self { const custom = options.customization orelse &[_]u8{}; return .{ @@ -971,7 +998,13 @@ fn KTHash( } /// Finalize the hash and produce output. - /// After calling this, the context should not be reused. + /// + /// Unlike traditional hash functions, the output can be of any length. + /// + /// When using as a regular hash function, use the recommended `digest_length` value (32 bytes for KT128, 64 bytes for KT256). + /// + /// After calling this method, the context should not be reused. However, the structure can be cloned before finalizing + /// to compute multiple hashes with the same prefix. pub fn final(self: *Self, out: []u8) void { const cv_size = Variant.cv_size; @@ -1063,12 +1096,11 @@ fn KTHash( } /// Hash a message using sequential processing with SIMD acceleration. - /// Best performance for inputs under 10MB. Never allocates memory. /// /// Parameters: /// - message: Input data to hash (any length) - /// - out: Output buffer (any length, arbitrary output sizes supported) - /// - options: Optional settings including customization string for domain separation + /// - out: Output buffer (any length, arbitrary output sizes supported, `digest_length` recommended for standard use) + /// - options: Optional settings to include a secret key or a context separation string pub fn hash(message: []const u8, out: []u8, options: Options) !void { const custom = options.customization orelse &[_]u8{};