mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
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.
This commit is contained in:
parent
2e8f8afc83
commit
4b593a6c24
2 changed files with 45 additions and 15 deletions
|
|
@ -12,8 +12,8 @@ const Vec16 = @Vector(16, u32);
|
||||||
const chunk_length = 1024;
|
const chunk_length = 1024;
|
||||||
const max_depth = 54;
|
const max_depth = 54;
|
||||||
|
|
||||||
pub const simd_degree = std.simd.suggestVectorLength(u32) orelse 1;
|
const simd_degree = std.simd.suggestVectorLength(u32) orelse 1;
|
||||||
pub const max_simd_degree = simd_degree;
|
const max_simd_degree = simd_degree;
|
||||||
const max_simd_degree_or_2 = if (max_simd_degree > 2) max_simd_degree else 2;
|
const max_simd_degree_or_2 = if (max_simd_degree > 2) max_simd_degree else 2;
|
||||||
|
|
||||||
/// Threshold for switching to parallel processing.
|
/// Threshold for switching to parallel processing.
|
||||||
|
|
@ -502,9 +502,7 @@ fn hashManySimd(
|
||||||
var out_ptr = out.ptr;
|
var out_ptr = out.ptr;
|
||||||
var cnt = counter;
|
var cnt = counter;
|
||||||
|
|
||||||
const simd_deg = comptime simd_degree;
|
if (simd_degree >= 16) {
|
||||||
|
|
||||||
if (comptime simd_deg >= 16) {
|
|
||||||
while (remaining >= 16) {
|
while (remaining >= 16) {
|
||||||
const sixteen_inputs = [16][*]const u8{
|
const sixteen_inputs = [16][*]const u8{
|
||||||
inp[0], inp[1], inp[2], inp[3],
|
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) {
|
while (remaining >= 8) {
|
||||||
const eight_inputs = [8][*]const u8{
|
const eight_inputs = [8][*]const u8{
|
||||||
inp[0], inp[1], inp[2], inp[3],
|
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) {
|
while (remaining >= 4) {
|
||||||
const four_inputs = [4][*]const u8{
|
const four_inputs = [4][*]const u8{
|
||||||
inp[0],
|
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 {
|
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);
|
hashManySimd(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out);
|
||||||
} else {
|
} else {
|
||||||
hashManyPortable(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out);
|
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 digest_length = 32;
|
||||||
pub const key_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 {};
|
pub const KdfOptions = struct {};
|
||||||
|
|
||||||
key: [8]u32,
|
key: [8]u32,
|
||||||
|
|
|
||||||
|
|
@ -840,7 +840,21 @@ fn KTHash(
|
||||||
/// The block length, or rate, in bytes.
|
/// The block length, or rate, in bytes.
|
||||||
pub const block_length = Variant.rate;
|
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 {
|
pub const Options = struct {
|
||||||
customization: ?[]const u8 = null,
|
customization: ?[]const u8 = null,
|
||||||
};
|
};
|
||||||
|
|
@ -864,7 +878,20 @@ fn KTHash(
|
||||||
pending_count: usize, // Number of complete chunks in pending_chunks
|
pending_count: usize, // Number of complete chunks in pending_chunks
|
||||||
|
|
||||||
/// Initialize a KangarooTwelve hashing context.
|
/// 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 {
|
pub fn init(options: Options) Self {
|
||||||
const custom = options.customization orelse &[_]u8{};
|
const custom = options.customization orelse &[_]u8{};
|
||||||
return .{
|
return .{
|
||||||
|
|
@ -971,7 +998,13 @@ fn KTHash(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalize the hash and produce output.
|
/// 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 {
|
pub fn final(self: *Self, out: []u8) void {
|
||||||
const cv_size = Variant.cv_size;
|
const cv_size = Variant.cv_size;
|
||||||
|
|
||||||
|
|
@ -1063,12 +1096,11 @@ fn KTHash(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hash a message using sequential processing with SIMD acceleration.
|
/// Hash a message using sequential processing with SIMD acceleration.
|
||||||
/// Best performance for inputs under 10MB. Never allocates memory.
|
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
/// - message: Input data to hash (any length)
|
/// - message: Input data to hash (any length)
|
||||||
/// - out: Output buffer (any length, arbitrary output sizes supported)
|
/// - out: Output buffer (any length, arbitrary output sizes supported, `digest_length` recommended for standard use)
|
||||||
/// - options: Optional settings including customization string for domain separation
|
/// - options: Optional settings to include a secret key or a context separation string
|
||||||
pub fn hash(message: []const u8, out: []u8, options: Options) !void {
|
pub fn hash(message: []const u8, out: []u8, options: Options) !void {
|
||||||
const custom = options.customization orelse &[_]u8{};
|
const custom = options.customization orelse &[_]u8{};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue