Skip to content

Commit 4b593a6

Browse files
authored
std.crypto: improve KT documentation, use key_length for B3 key length (#25807)
It was not obvious that the KT128/KT256 customization string can be used to set a key, or what it was designed to be used for at all. Also properly use key_length and not digest_length for the BLAKE3 key length (no practical changes as they are both 32, but that was confusing). Remove unneeded simd_degree copies by the way, and that doesn't need to be in the public interface.
1 parent 2e8f8af commit 4b593a6

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

lib/std/crypto/blake3.zig

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ const Vec16 = @Vector(16, u32);
1212
const chunk_length = 1024;
1313
const max_depth = 54;
1414

15-
pub const simd_degree = std.simd.suggestVectorLength(u32) orelse 1;
16-
pub const max_simd_degree = simd_degree;
15+
const simd_degree = std.simd.suggestVectorLength(u32) orelse 1;
16+
const max_simd_degree = simd_degree;
1717
const max_simd_degree_or_2 = if (max_simd_degree > 2) max_simd_degree else 2;
1818

1919
/// Threshold for switching to parallel processing.
@@ -502,9 +502,7 @@ fn hashManySimd(
502502
var out_ptr = out.ptr;
503503
var cnt = counter;
504504

505-
const simd_deg = comptime simd_degree;
506-
507-
if (comptime simd_deg >= 16) {
505+
if (simd_degree >= 16) {
508506
while (remaining >= 16) {
509507
const sixteen_inputs = [16][*]const u8{
510508
inp[0], inp[1], inp[2], inp[3],
@@ -525,7 +523,7 @@ fn hashManySimd(
525523
}
526524
}
527525

528-
if (comptime simd_deg >= 8) {
526+
if (simd_degree >= 8) {
529527
while (remaining >= 8) {
530528
const eight_inputs = [8][*]const u8{
531529
inp[0], inp[1], inp[2], inp[3],
@@ -544,7 +542,7 @@ fn hashManySimd(
544542
}
545543
}
546544

547-
if (comptime simd_deg >= 4) {
545+
if (simd_degree >= 4) {
548546
while (remaining >= 4) {
549547
const four_inputs = [4][*]const u8{
550548
inp[0],
@@ -571,7 +569,7 @@ fn hashManySimd(
571569
}
572570

573571
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 {
574-
if (comptime max_simd_degree >= 4) {
572+
if (max_simd_degree >= 4) {
575573
hashManySimd(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out);
576574
} else {
577575
hashManyPortable(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out);
@@ -909,7 +907,7 @@ pub const Blake3 = struct {
909907
pub const digest_length = 32;
910908
pub const key_length = 32;
911909

912-
pub const Options = struct { key: ?[digest_length]u8 = null };
910+
pub const Options = struct { key: ?[key_length]u8 = null };
913911
pub const KdfOptions = struct {};
914912

915913
key: [8]u32,

lib/std/crypto/kangarootwelve.zig

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,21 @@ fn KTHash(
840840
/// The block length, or rate, in bytes.
841841
pub const block_length = Variant.rate;
842842

843-
/// Options for KangarooTwelve can include a customization string for domain separation.
843+
/// Configuration options for KangarooTwelve hashing.
844+
///
845+
/// Options include an optional customization string that provides domain separation,
846+
/// ensuring that identical inputs with different customization strings
847+
/// produce completely distinct hash outputs.
848+
///
849+
/// This prevents hash collisions when the same data is hashed in different contexts.
850+
///
851+
/// Customization strings can be of any length.
852+
///
853+
/// Common options for customization::
854+
///
855+
/// - Key derivation or MAC: 16-byte secret for KT128, 32-byte secret for KT256
856+
/// - Context Separation: domain-specific strings (e.g., "email", "password", "session")
857+
/// - Composite Keys: concatenation of secret key + context string
844858
pub const Options = struct {
845859
customization: ?[]const u8 = null,
846860
};
@@ -864,7 +878,20 @@ fn KTHash(
864878
pending_count: usize, // Number of complete chunks in pending_chunks
865879

866880
/// Initialize a KangarooTwelve hashing context.
867-
/// The customization string is optional and used for domain separation.
881+
///
882+
/// Options include an optional customization string that provides domain separation,
883+
/// ensuring that identical inputs with different customization strings
884+
/// produce completely distinct hash outputs.
885+
///
886+
/// This prevents hash collisions when the same data is hashed in different contexts.
887+
///
888+
/// Customization strings can be of any length.
889+
///
890+
/// Common options for customization::
891+
///
892+
/// - Key derivation or MAC: 16-byte secret for KT128, 32-byte secret for KT256
893+
/// - Context Separation: domain-specific strings (e.g., "email", "password", "session")
894+
/// - Composite Keys: concatenation of secret key + context string
868895
pub fn init(options: Options) Self {
869896
const custom = options.customization orelse &[_]u8{};
870897
return .{
@@ -971,7 +998,13 @@ fn KTHash(
971998
}
972999

9731000
/// Finalize the hash and produce output.
974-
/// After calling this, the context should not be reused.
1001+
///
1002+
/// Unlike traditional hash functions, the output can be of any length.
1003+
///
1004+
/// When using as a regular hash function, use the recommended `digest_length` value (32 bytes for KT128, 64 bytes for KT256).
1005+
///
1006+
/// After calling this method, the context should not be reused. However, the structure can be cloned before finalizing
1007+
/// to compute multiple hashes with the same prefix.
9751008
pub fn final(self: *Self, out: []u8) void {
9761009
const cv_size = Variant.cv_size;
9771010

@@ -1063,12 +1096,11 @@ fn KTHash(
10631096
}
10641097

10651098
/// Hash a message using sequential processing with SIMD acceleration.
1066-
/// Best performance for inputs under 10MB. Never allocates memory.
10671099
///
10681100
/// Parameters:
10691101
/// - message: Input data to hash (any length)
1070-
/// - out: Output buffer (any length, arbitrary output sizes supported)
1071-
/// - options: Optional settings including customization string for domain separation
1102+
/// - out: Output buffer (any length, arbitrary output sizes supported, `digest_length` recommended for standard use)
1103+
/// - options: Optional settings to include a secret key or a context separation string
10721104
pub fn hash(message: []const u8, out: []u8, options: Options) !void {
10731105
const custom = options.customization orelse &[_]u8{};
10741106

0 commit comments

Comments
 (0)