From 7e286fe8b700c42b97e0047cc23519df740f7aeb Mon Sep 17 00:00:00 2001 From: aumetra Date: Mon, 22 Sep 2025 21:04:10 +0200 Subject: [PATCH 1/4] Add BLAKE3 support --- Cargo.toml | 11 ++++++++- README.md | 52 +++++++++++++++++++++------------------- src/params/mod.rs | 5 +++- src/resolvers/default.rs | 37 ++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c811ecc..c1f8a86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,13 +42,21 @@ pqclean_kyber1024 = ["use-pqcrypto-kyber1024"] xchachapoly = ["use-xchacha20poly1305"] # Enable std features on dependencies if possible. -std = ["getrandom?/std", "subtle/std", "ring?/std", "blake2?/std", "sha2?/std"] +std = [ + "getrandom?/std", + "subtle/std", + "ring?/std", + "blake2?/std", + "blake3?/std", + "sha2?/std", +] # Crypto primitives for default-resolver. use-curve25519 = ["curve25519-dalek", "default-resolver"] use-chacha20poly1305 = ["chacha20poly1305", "default-resolver"] use-xchacha20poly1305 = ["chacha20poly1305", "default-resolver"] use-blake2 = ["blake2", "default-resolver"] +use-blake3 = ["blake3", "default-resolver"] use-sha2 = ["sha2", "default-resolver"] use-aes-gcm = ["aes-gcm", "default-resolver"] use-getrandom = ["getrandom", "default-resolver"] @@ -77,6 +85,7 @@ aes-gcm = { version = "0.10", optional = true, default-features = false, feature ] } chacha20poly1305 = { version = "0.10", optional = true, default-features = false } blake2 = { version = "0.10", optional = true, default-features = false } +blake3 = { version = "1.8", optional = true, default-features = false } sha2 = { version = "0.10", optional = true, default-features = false } curve25519-dalek = { version = "4.1.3", optional = true, default-features = false } p256 = { version = "0.13.2", features = ["ecdh"], optional = true } diff --git a/README.md b/README.md index e71823f..f473543 100644 --- a/README.md +++ b/README.md @@ -64,23 +64,24 @@ crypto implementations when available. ### Resolver primitives supported -| | default | ring | +| | default | ring | | -------------------------------------: | :----------------: | :----------------: | -| CSPRNG | :heavy_check_mark: | :heavy_check_mark: | -| 25519 | :heavy_check_mark: | :heavy_check_mark: | -| 448 | | | -| P-256:checkered_flag: | :heavy_check_mark: | | -| AESGCM | :heavy_check_mark: | :heavy_check_mark: | -| ChaChaPoly | :heavy_check_mark: | :heavy_check_mark: | +| CSPRNG | :heavy_check_mark: | :heavy_check_mark: | +| 25519 | :heavy_check_mark: | :heavy_check_mark: | +| 448 | | | +| P-256:checkered_flag: | :heavy_check_mark: | | +| AESGCM | :heavy_check_mark: | :heavy_check_mark: | +| ChaChaPoly | :heavy_check_mark: | :heavy_check_mark: | | XChaChaPoly:checkered_flag: | :heavy_check_mark: | | -| SHA256 | :heavy_check_mark: | :heavy_check_mark: | -| SHA512 | :heavy_check_mark: | :heavy_check_mark: | -| BLAKE2s | :heavy_check_mark: | | -| BLAKE2b | :heavy_check_mark: | | +| SHA256 | :heavy_check_mark: | :heavy_check_mark: | +| SHA512 | :heavy_check_mark: | :heavy_check_mark: | +| BLAKE2s | :heavy_check_mark: | | +| BLAKE2b | :heavy_check_mark: | | +| BLAKE3 | :heavy_check_mark: | | > [!Note] > :checkered_flag: P-256 and XChaChaPoly are not in the official specification of Noise, and thus need to be enabled -via the feature flags `use-p256` and `use-xchacha20poly1305`, respectively. +> via the feature flags `use-p256` and `use-xchacha20poly1305`, respectively. ## `no_std` support and feature selection @@ -94,25 +95,27 @@ currently supports `no_std`. To use a custom setup with `default-resolver`, enable your desired selection of cryptographic primitives: -| | Primitive | Feature flag | -| ----------: | :------------------------------------- | :--------------------- | -| **DHs** | Curve25519 | `use-curve25519` | -| | P-256:checkered_flag: | `use-p256` | -| **Ciphers** | AES-GCM | `use-aes-gcm` | -| | ChaChaPoly | `use-chacha20poly1305` | -| | XChaChaPoly:checkered_flag: | `use-xchacha20poly1305`| -| **Hashes** | SHA-256 | `use-sha2` | -| | SHA-512 | `use-sha2` | -| | BLAKE2s | `use-blake2` | -| | BLAKE2b | `use-blake2` | +| | Primitive | Feature flag | +| ----------: | :------------------------------------- | :---------------------- | +| **DHs** | Curve25519 | `use-curve25519` | +| | P-256:checkered_flag: | `use-p256` | +| **Ciphers** | AES-GCM | `use-aes-gcm` | +| | ChaChaPoly | `use-chacha20poly1305` | +| | XChaChaPoly:checkered_flag: | `use-xchacha20poly1305` | +| **Hashes** | SHA-256 | `use-sha2` | +| | SHA-512 | `use-sha2` | +| | BLAKE2s | `use-blake2` | +| | BLAKE2b | `use-blake2` | +| | BLAKE3:checkered_flag: | `use-blake3` | > [!Note] > :checkered_flag: XChaChaPoly and P-256 are not in the official specification of Noise, but they are supported -by Snow. +> by Snow. ### Example configurations **Curve25519 + AES-GCM + SHA-2** with standard library features. + ```toml default-features = false features = [ @@ -124,6 +127,7 @@ features = [ ``` **Curve25519 + ChaChaPoly + BLAKE2** without standard library. + ```toml default-features = false features = [ diff --git a/src/params/mod.rs b/src/params/mod.rs index 3a941a5..de263d7 100644 --- a/src/params/mod.rs +++ b/src/params/mod.rs @@ -1,4 +1,3 @@ -#![allow(clippy::match_on_vec_items)] #![allow(clippy::enum_glob_use)] //! All structures related to Noise parameter definitions (cryptographic primitive choices, protocol @@ -105,6 +104,9 @@ pub enum HashChoice { Blake2s, /// The BLAKE2b hash function, designed to be more efficient on 64-bit architectures. Blake2b, + /// The BLAKE3 hash function, designed to be more efficient than BLAKE3 through, + /// in part, parallelism. + Blake3, } impl FromStr for HashChoice { @@ -117,6 +119,7 @@ impl FromStr for HashChoice { "SHA512" => Ok(SHA512), "BLAKE2s" => Ok(Blake2s), "BLAKE2b" => Ok(Blake2b), + "BLAKE3" => Ok(Blake3), _ => Err(PatternProblem::UnsupportedHashType.into()), } } diff --git a/src/resolvers/default.rs b/src/resolvers/default.rs index d693ab9..1694de7 100644 --- a/src/resolvers/default.rs +++ b/src/resolvers/default.rs @@ -98,6 +98,8 @@ impl CryptoResolver for DefaultResolver { HashChoice::Blake2s => Some(Box::::default()), #[cfg(feature = "use-blake2")] HashChoice::Blake2b => Some(Box::::default()), + #[cfg(feature = "use-blake3")] + HashChoice::Blake3 => Some(Box::::default()), _ => None, } } @@ -188,6 +190,13 @@ struct HashBLAKE2s { hasher: Blake2s256, } +/// Wraps `blake3`'s implementation +#[cfg(feature = "use-blake3")] +#[derive(Default)] +struct HashBlake3 { + hasher: blake3::Hasher, +} + /// Wraps `kyber1024`'s implementation #[cfg(feature = "use-pqcrypto-kyber1024")] struct Kyber1024 { @@ -582,6 +591,34 @@ impl Hash for HashBLAKE2s { } } +#[cfg(feature = "use-blake3")] +impl Hash for HashBlake3 { + fn name(&self) -> &'static str { + "BLAKE3" + } + + fn block_len(&self) -> usize { + blake3::BLOCK_LEN + } + + fn hash_len(&self) -> usize { + blake3::OUT_LEN + } + + fn reset(&mut self) { + self.hasher = blake3::Hasher::new(); + } + + fn input(&mut self, data: &[u8]) { + self.hasher.update(data); + } + + fn result(&mut self, out: &mut [u8]) { + let hash = self.hasher.finalize(); + out[..blake3::OUT_LEN].copy_from_slice(hash.as_bytes()); + } +} + #[cfg(feature = "use-pqcrypto-kyber1024")] impl Default for Kyber1024 { fn default() -> Self { From d0c4249e4770230f423b157678cae75bdc78de88 Mon Sep 17 00:00:00 2001 From: Aumetra Weisman Date: Tue, 23 Sep 2025 01:58:49 +0200 Subject: [PATCH 2/4] Gate enum case behind the BLAKE3 feature flag --- src/params/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/params/mod.rs b/src/params/mod.rs index de263d7..24b68c6 100644 --- a/src/params/mod.rs +++ b/src/params/mod.rs @@ -104,6 +104,7 @@ pub enum HashChoice { Blake2s, /// The BLAKE2b hash function, designed to be more efficient on 64-bit architectures. Blake2b, + #[cfg(feature = "use-blake3")] /// The BLAKE3 hash function, designed to be more efficient than BLAKE3 through, /// in part, parallelism. Blake3, @@ -119,6 +120,7 @@ impl FromStr for HashChoice { "SHA512" => Ok(SHA512), "BLAKE2s" => Ok(Blake2s), "BLAKE2b" => Ok(Blake2b), + #[cfg(feature = "use-blake3")] "BLAKE3" => Ok(Blake3), _ => Err(PatternProblem::UnsupportedHashType.into()), } From a2a1dd4659fa97b62c929bdab4d167012af1fcf5 Mon Sep 17 00:00:00 2001 From: Aumetra Weisman Date: Tue, 23 Sep 2025 02:00:25 +0200 Subject: [PATCH 3/4] Fix comment --- src/params/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/params/mod.rs b/src/params/mod.rs index 24b68c6..41016da 100644 --- a/src/params/mod.rs +++ b/src/params/mod.rs @@ -105,8 +105,8 @@ pub enum HashChoice { /// The BLAKE2b hash function, designed to be more efficient on 64-bit architectures. Blake2b, #[cfg(feature = "use-blake3")] - /// The BLAKE3 hash function, designed to be more efficient than BLAKE3 through, - /// in part, parallelism. + /// The BLAKE3 hash function, designed to be more efficient than BLAKE2 through, + /// in part, parallelism and a reduced round count. Blake3, } From a3ce0746f4e69964ac46d6db83eb314e057d7217 Mon Sep 17 00:00:00 2001 From: Aumetra Weisman Date: Tue, 23 Sep 2025 12:32:09 +0200 Subject: [PATCH 4/4] Add BLAKE3 to the default-resolver gate --- src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3ab1147..9aa6a29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -133,7 +133,11 @@ extern crate alloc; feature = "use-chacha20poly1305", feature = "use-xchacha20poly1305" )), - not(any(feature = "use-sha2", feature = "use-blake2")) + not(any( + feature = "use-sha2", + feature = "use-blake2", + feature = "use-blake3" + )) ))] compile_error!( "Valid selection of crypto primitived must be enabled when using feature 'default-resolver'.