From d2eaab6b2864a7d1b7494924d5261c8fe96b1030 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 13:50:38 +0200 Subject: [PATCH 01/56] move evercrypt_provider to libcrux_provider --- {evercrypt_provider => libcrux_provider}/CHANGELOG.md | 0 {evercrypt_provider => libcrux_provider}/Cargo.toml | 0 {evercrypt_provider => libcrux_provider}/Readme.md | 0 {evercrypt_provider => libcrux_provider}/benches/bench_hkdf.rs | 0 {evercrypt_provider => libcrux_provider}/benches/bench_p256.rs | 0 {evercrypt_provider => libcrux_provider}/benches/bench_x25519.rs | 0 {evercrypt_provider => libcrux_provider}/src/lib.rs | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename {evercrypt_provider => libcrux_provider}/CHANGELOG.md (100%) rename {evercrypt_provider => libcrux_provider}/Cargo.toml (100%) rename {evercrypt_provider => libcrux_provider}/Readme.md (100%) rename {evercrypt_provider => libcrux_provider}/benches/bench_hkdf.rs (100%) rename {evercrypt_provider => libcrux_provider}/benches/bench_p256.rs (100%) rename {evercrypt_provider => libcrux_provider}/benches/bench_x25519.rs (100%) rename {evercrypt_provider => libcrux_provider}/src/lib.rs (100%) diff --git a/evercrypt_provider/CHANGELOG.md b/libcrux_provider/CHANGELOG.md similarity index 100% rename from evercrypt_provider/CHANGELOG.md rename to libcrux_provider/CHANGELOG.md diff --git a/evercrypt_provider/Cargo.toml b/libcrux_provider/Cargo.toml similarity index 100% rename from evercrypt_provider/Cargo.toml rename to libcrux_provider/Cargo.toml diff --git a/evercrypt_provider/Readme.md b/libcrux_provider/Readme.md similarity index 100% rename from evercrypt_provider/Readme.md rename to libcrux_provider/Readme.md diff --git a/evercrypt_provider/benches/bench_hkdf.rs b/libcrux_provider/benches/bench_hkdf.rs similarity index 100% rename from evercrypt_provider/benches/bench_hkdf.rs rename to libcrux_provider/benches/bench_hkdf.rs diff --git a/evercrypt_provider/benches/bench_p256.rs b/libcrux_provider/benches/bench_p256.rs similarity index 100% rename from evercrypt_provider/benches/bench_p256.rs rename to libcrux_provider/benches/bench_p256.rs diff --git a/evercrypt_provider/benches/bench_x25519.rs b/libcrux_provider/benches/bench_x25519.rs similarity index 100% rename from evercrypt_provider/benches/bench_x25519.rs rename to libcrux_provider/benches/bench_x25519.rs diff --git a/evercrypt_provider/src/lib.rs b/libcrux_provider/src/lib.rs similarity index 100% rename from evercrypt_provider/src/lib.rs rename to libcrux_provider/src/lib.rs From fb358eed369a8d0818b69e45d2b9cb02d0bc275f Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 13:52:18 +0200 Subject: [PATCH 02/56] update Cargo.toml --- libcrux_provider/Cargo.toml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index f40a2e8..adc9487 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -1,18 +1,19 @@ [package] -name = "hpke-rs-evercrypt" -version = "0.1.3-pre.1" +name = "hpke-rs-libcrux" +version = "0.2.0-pre.1" authors = ["Franziskus Kiefer "] edition = "2021" license = "MPL-2.0" documentation = "https://docs.rs/hpke-rs-evercrypt" -description = "Crypto backend for HPKE using formally verified code from Evercrypt." +description = "Crypto backend for HPKE using formally verified code from libcrux." readme = "Readme.md" -repository = "https://github.com/franziskuskiefer/hpke-rs" +repository = "https://github.com/cryspen/hpke-rs" [dependencies] -hpke-rs-crypto = { version = "0.1.2-pre.1", path = "../traits" } -# Evercrypt -evercrypt = { version = "0.0.11", features = ["serialization"] } +hpke-rs-crypto = { version = "0.2.0", path = "../traits" } +libcrux-hkdf = { version = "0.0.2" } +libcrux-kem = { version = "0.0.2" } +libcrux-chacha20poly1305 = { version = "0.0.2" } # Randomness rand = { version = "0.8" } rand_chacha = { version = "0.3" } From 525bcb96f75a3da38ff9b8e3e89036d491c7390e Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 13:52:57 +0200 Subject: [PATCH 03/56] add `.gitignore` --- libcrux_provider/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 libcrux_provider/.gitignore diff --git a/libcrux_provider/.gitignore b/libcrux_provider/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/libcrux_provider/.gitignore @@ -0,0 +1 @@ +/target From cfdb84624d5c4cd90fc7cfa2a91062e07cf13544 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 15:01:28 +0200 Subject: [PATCH 04/56] begin replacing with pure Rust crates --- libcrux_provider/Cargo.toml | 10 +- libcrux_provider/src/lib.rs | 235 +++++++++++++++++++++--------------- 2 files changed, 145 insertions(+), 100 deletions(-) diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index adc9487..3f89adc 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -11,12 +11,18 @@ repository = "https://github.com/cryspen/hpke-rs" [dependencies] hpke-rs-crypto = { version = "0.2.0", path = "../traits" } +libcrux-ecdh = { version = "0.0.2" } libcrux-hkdf = { version = "0.0.2" } libcrux-kem = { version = "0.0.2" } libcrux-chacha20poly1305 = { version = "0.0.2" } +libcrux-ed25519 = { version = "0.0.2", features=["rand"] } # Randomness -rand = { version = "0.8" } -rand_chacha = { version = "0.3" } +rand = { version = "0.9" } +rand_core = { version = "0.9" } +rand_chacha = { version = "0.9" } +rand_old = { version = "0.8", package = "rand"} +rand_core_old = { version = "0.6", package = "rand_core" } +rand_chacha_old = { version = "0.3.1", package = "rand_chacha"} [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 61c7c64..0645d5a 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -2,35 +2,41 @@ use std::{fmt::Display, sync::RwLock}; -use evercrypt::prelude::*; use hpke_rs_crypto::{ error::Error, types::{AeadAlgorithm, KdfAlgorithm, KemAlgorithm}, HpkeCrypto, HpkeTestRng, }; -use rand::{CryptoRng, RngCore, SeedableRng}; +use rand_old::{CryptoRng, RngCore, SeedableRng}; -/// The Evercrypt HPKE Provider +/// The Libcrux HPKE Provider #[derive(Debug)] -pub struct HpkeEvercrypt {} +pub struct HpkeLibcrux {} -/// The PRNG for the Evercrypt Provider. -pub struct HpkeEvercryptPrng { +/// The PRNG for the Libcrux Provider. +pub struct HpkeLibcruxPrng { #[cfg(feature = "deterministic-prng")] fake_rng: Vec, - rng: RwLock, + rng: RwLock, } -impl HpkeCrypto for HpkeEvercrypt { +impl HpkeCrypto for HpkeLibcrux { fn name() -> String { - "Evercrypt".into() + "Libcrux".into() } fn kdf_extract(alg: KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Vec { + // TODO: error handling match alg { - KdfAlgorithm::HkdfSha256 => hkdf_extract(HmacMode::Sha256, salt, ikm), - KdfAlgorithm::HkdfSha384 => hkdf_extract(HmacMode::Sha384, salt, ikm), - KdfAlgorithm::HkdfSha512 => hkdf_extract(HmacMode::Sha512, salt, ikm), + KdfAlgorithm::HkdfSha256 => { + libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha256, salt, ikm).unwrap() + } + KdfAlgorithm::HkdfSha384 => { + libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha384, salt, ikm).unwrap() + } + KdfAlgorithm::HkdfSha512 => { + libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha512, salt, ikm).unwrap() + } } } @@ -40,54 +46,78 @@ impl HpkeCrypto for HpkeEvercrypt { info: &[u8], output_size: usize, ) -> Result, Error> { + // TODO: error handling Ok(match alg { - KdfAlgorithm::HkdfSha256 => hkdf_expand(HmacMode::Sha256, prk, info, output_size), - KdfAlgorithm::HkdfSha384 => hkdf_expand(HmacMode::Sha384, prk, info, output_size), - KdfAlgorithm::HkdfSha512 => hkdf_expand(HmacMode::Sha512, prk, info, output_size), + KdfAlgorithm::HkdfSha256 => { + libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha256, prk, info, output_size) + .unwrap() + } + KdfAlgorithm::HkdfSha384 => { + libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha384, prk, info, output_size) + .unwrap() + } + KdfAlgorithm::HkdfSha512 => { + libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha512, prk, info, output_size) + .unwrap() + } }) } fn kem_derive(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error> { - let evercrypt_mode = kem_key_type_to_mode(alg)?; - ecdh_derive(evercrypt_mode, pk, sk) + let alg = kem_key_type_to_ecdh_alg(alg)?; + + libcrux_ecdh::derive(alg, pk, sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive error: {:?}", e))) - .map(|mut p| { - if evercrypt_mode == EcdhMode::P256 { - // We only want the x-coordinate here but evercrypt gives us the entire point - p.truncate(32); - p - } else { - p - } - }) + /* + .map(|mut p| { + if emode == EcdhMode::P256 { + // We only want the x-coordinate here but evercrypt gives us the entire point + p.truncate(32); + p + } else { + p + } + }) + */ } fn kem_derive_base(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { - let evercrypt_mode = kem_key_type_to_mode(alg)?; - ecdh_derive_base(evercrypt_mode, sk) + let alg = kem_key_type_to_ecdh_alg(alg)?; + + todo!() + + /* + ecdh_derive_base(mode, sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive base error: {:?}", e))) - .map(|p| { - if evercrypt_mode == EcdhMode::P256 { - nist_format_uncompressed(p) - } else { - p - } - }) + .map(|p| { + if evercrypt_mode == EcdhMode::P256 { + nist_format_uncompressed(p) + } else { + p + } + }) + */ } fn kem_key_gen(alg: KemAlgorithm, _: &mut Self::HpkePrng) -> Result, Error> { - // XXX: Evercypt doesn't support bring your own randomness yet. - // https://github.com/franziskuskiefer/evercrypt-rust/issues/35 - let evercrypt_mode = kem_key_type_to_mode(alg)?; - ecdh::key_gen(evercrypt_mode) - .map_err(|e| Error::CryptoLibraryError(format!("ECDH key gen error: {:?}", e))) + let mode = kem_key_type_to_mode(alg)?; + + use rand::TryRngCore; + let mut rng = rand::rngs::OsRng; + let (pk, sk) = libcrux_kem::key_gen(mode, &mut rng.unwrap_mut()) + .map_err(|e| Error::CryptoLibraryError(format!("ECDH key gen error: {:?}", e)))?; + + // return both keys as single vec + todo!() } fn kem_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { match alg { - KemAlgorithm::DhKemP256 => p256_validate_sk(&sk) + //KemAlgorithm::DhKemP256 => p256_validate_sk(&sk) + // XXX: do we support this? + KemAlgorithm::DhKemP256 => libcrux_ecdh::p256::validate_scalar_slice(&sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH invalid sk error: {:?}", e))) - .map(|sk| sk.to_vec()), + .map(|sk| sk.0.to_vec()), _ => Err(Error::UnknownKemAlgorithm), } } @@ -99,19 +129,20 @@ impl HpkeCrypto for HpkeEvercrypt { aad: &[u8], msg: &[u8], ) -> Result, Error> { - let mode = aead_type_to_mode(alg)?; - if nonce.len() != 12 { - return Err(Error::AeadInvalidNonce); + // only chacha20poly1305 is supported + if !matches!(alg, AeadAlgorithm::ChaCha20Poly1305) { + return Err(Error::UnknownAeadAlgorithm); } - let cipher = match Aead::new(mode, key) { - Ok(c) => c, - Err(_) => return Err(Error::CryptoLibraryError(format!("Invalid configuration"))), - }; + let iv = <&[u8; 12]>::try_from(nonce).map_err(|_| Error::AeadInvalidNonce)?; + + // TODO: instead, use key conversion from the libcrux-chacha20poly1305 crate, when available, + let key = <&[u8; 32]>::try_from(key).map_err(|_| todo!())?; + let mut msg_ctx: Vec = vec![0; msg.len() + 16]; + libcrux_chacha20poly1305::encrypt(key, msg, &mut msg_ctx, aad, iv) + .map_err(|_| Error::CryptoLibraryError("Invalid configuration".into()))?; - cipher - .encrypt_combined(&msg, &nonce, &aad) - .map_err(|e| Error::CryptoLibraryError(format!("AEAD encrypt error: {:?}", e))) + Ok(msg_ctx) } fn aead_open( @@ -121,37 +152,49 @@ impl HpkeCrypto for HpkeEvercrypt { aad: &[u8], cipher_txt: &[u8], ) -> Result, Error> { - let mode = aead_type_to_mode(alg)?; - let cipher = match Aead::new(mode, key) { - Ok(c) => c, - Err(_) => { - return Err(Error::CryptoLibraryError(format!( - "Invalid configuration or unsupported algorithm {:?}", - mode - ))) - } - }; + // only chacha20poly1305 is supported + if !matches!(alg, AeadAlgorithm::ChaCha20Poly1305) { + return Err(Error::UnknownAeadAlgorithm); + } + if cipher_txt.len() < 16 { + return Err(todo!()); + } + + let boundary = cipher_txt.len() - 16; + + let mut ptext = vec![0; boundary]; + + let iv = <&[u8; 12]>::try_from(nonce).map_err(|_| Error::AeadInvalidNonce)?; - cipher - .decrypt_combined(&cipher_txt, &nonce, &aad) - .map_err(|e| Error::CryptoLibraryError(format!("AEAD decryption error: {:?}", e))) + // TODO: instead, use key conversion from the libcrux-chacha20poly1305 crate, when available, + let key = <&[u8; 32]>::try_from(key).map_err(|_| todo!())?; + libcrux_chacha20poly1305::decrypt(key, &mut ptext, cipher_txt, aad, iv).map_err( + |e| match e { + libcrux_chacha20poly1305::AeadError::InvalidCiphertext => { + Error::CryptoLibraryError(format!("AEAD decryption error: {:?}", e)) + } + _ => Error::CryptoLibraryError("Invalid configuration".into()), + }, + )?; + + Ok(ptext) } - type HpkePrng = HpkeEvercryptPrng; + type HpkePrng = HpkeLibcruxPrng; fn prng() -> Self::HpkePrng { #[cfg(feature = "deterministic-prng")] { let mut fake_rng = vec![0u8; 256]; - rand_chacha::ChaCha20Rng::from_entropy().fill_bytes(&mut fake_rng); - HpkeEvercryptPrng { + rand_chacha_old::ChaCha20Rng::from_entropy().fill_bytes(&mut fake_rng); + HpkeLibcruxPrng { fake_rng, - rng: RwLock::new(rand_chacha::ChaCha20Rng::from_entropy()), + rng: RwLock::new(rand_chacha_old::ChaCha20Rng::from_entropy()), } } #[cfg(not(feature = "deterministic-prng"))] - HpkeEvercryptPrng { - rng: RwLock::new(rand_chacha::ChaCha20Rng::from_entropy()), + HpkeLibcruxPrng { + rng: RwLock::new(rand_chacha_old::ChaCha20Rng::from_entropy()), } } @@ -162,6 +205,7 @@ impl HpkeCrypto for HpkeEvercrypt { /// Returns an error if the KEM algorithm is not supported by this crypto provider. fn supports_kem(alg: KemAlgorithm) -> Result<(), Error> { + // XXX: do we support DhKemP256? match alg { KemAlgorithm::DhKem25519 | KemAlgorithm::DhKemP256 => Ok(()), _ => Err(Error::UnknownKemAlgorithm), @@ -171,22 +215,14 @@ impl HpkeCrypto for HpkeEvercrypt { /// Returns an error if the AEAD algorithm is not supported by this crypto provider. fn supports_aead(alg: AeadAlgorithm) -> Result<(), Error> { match alg { - AeadAlgorithm::Aes128Gcm | AeadAlgorithm::Aes256Gcm => aes_support(), + // Don't support Aes + AeadAlgorithm::Aes128Gcm | AeadAlgorithm::Aes256Gcm => Err(Error::UnknownAeadAlgorithm), AeadAlgorithm::ChaCha20Poly1305 | AeadAlgorithm::HpkeExport => Ok(()), } } } -#[cfg(all(target_arch = "x86_64", not(target_os = "macos")))] -fn aes_support() -> Result<(), Error> { - Ok(()) -} - -#[cfg(any(not(target_arch = "x86_64"), target_os = "macos"))] -fn aes_support() -> Result<(), Error> { - Err(Error::UnknownAeadAlgorithm) -} - +/* /// Prepend 0x04 for uncompressed NIST curve points. #[inline(always)] fn nist_format_uncompressed(mut pk: Vec) -> Vec { @@ -195,27 +231,30 @@ fn nist_format_uncompressed(mut pk: Vec) -> Vec { tmp.append(&mut pk); tmp } +*/ #[inline(always)] -fn kem_key_type_to_mode(alg: KemAlgorithm) -> Result { +fn kem_key_type_to_mode(alg: KemAlgorithm) -> Result { match alg { - KemAlgorithm::DhKem25519 => Ok(EcdhMode::X25519), - KemAlgorithm::DhKemP256 => Ok(EcdhMode::P256), + KemAlgorithm::DhKem25519 => Ok(libcrux_kem::Algorithm::X25519), + // XXX: is this correct? + KemAlgorithm::DhKemP256 => Ok(libcrux_kem::Algorithm::Secp256r1), _ => Err(Error::UnknownKemAlgorithm), } } +// TODO: is this correct? #[inline(always)] -fn aead_type_to_mode(alg: AeadAlgorithm) -> Result { +fn kem_key_type_to_ecdh_alg(alg: KemAlgorithm) -> Result { match alg { - AeadAlgorithm::Aes128Gcm => Ok(AeadMode::Aes128Gcm), - AeadAlgorithm::Aes256Gcm => Ok(AeadMode::Aes256Gcm), - AeadAlgorithm::ChaCha20Poly1305 => Ok(AeadMode::Chacha20Poly1305), - _ => Err(Error::UnknownAeadAlgorithm), + KemAlgorithm::DhKem25519 => Ok(libcrux_ecdh::Algorithm::X25519), + // XXX: do we support this? + KemAlgorithm::DhKemP256 => Ok(libcrux_ecdh::Algorithm::P256), + _ => Err(Error::UnknownKemAlgorithm), } } -impl RngCore for HpkeEvercryptPrng { +impl RngCore for HpkeLibcruxPrng { fn next_u32(&mut self) -> u32 { let mut rng = self.rng.write().unwrap(); rng.next_u32() @@ -231,25 +270,25 @@ impl RngCore for HpkeEvercryptPrng { rng.fill_bytes(dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_old::Error> { let mut rng = self.rng.write().unwrap(); rng.try_fill_bytes(dest) } } -impl CryptoRng for HpkeEvercryptPrng {} +impl CryptoRng for HpkeLibcruxPrng {} -impl HpkeTestRng for HpkeEvercryptPrng { +impl HpkeTestRng for HpkeLibcruxPrng { #[cfg(feature = "deterministic-prng")] - fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { + fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_old::Error> { // Here we fake our randomness for testing. if dest.len() > self.fake_rng.len() { - return Err(rand::Error::new(Error::InsufficientRandomness)); + return Err(rand_old::Error::new(Error::InsufficientRandomness)); } dest.clone_from_slice(&self.fake_rng.split_off(self.fake_rng.len() - dest.len())); Ok(()) } #[cfg(not(feature = "deterministic-prng"))] - fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { + fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_old::Error> { self.rng.write().unwrap().try_fill_bytes(dest) } @@ -261,7 +300,7 @@ impl HpkeTestRng for HpkeEvercryptPrng { fn seed(&mut self, _: &[u8]) {} } -impl Display for HpkeEvercrypt { +impl Display for HpkeLibcrux { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", Self::name()) } From 0d76c01dfb431205137994e78e799d98fffae993 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 15:01:54 +0200 Subject: [PATCH 05/56] formatting --- libcrux_provider/benches/bench_p256.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/libcrux_provider/benches/bench_p256.rs b/libcrux_provider/benches/bench_p256.rs index 0a85136..5b7286e 100644 --- a/libcrux_provider/benches/bench_p256.rs +++ b/libcrux_provider/benches/bench_p256.rs @@ -6,11 +6,9 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("P256 Derive"), |b| { b.iter_batched( || { - let sk = HpkeEvercrypt::kem_key_gen( - KemAlgorithm::DhKemP256, - &mut HpkeEvercrypt::prng(), - ) - .unwrap(); + let sk = + HpkeEvercrypt::kem_key_gen(KemAlgorithm::DhKemP256, &mut HpkeEvercrypt::prng()) + .unwrap(); let pk = HpkeEvercrypt::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); (sk.clone(), pk.clone()) }, @@ -23,11 +21,9 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("P256 Derive Base"), |b| { b.iter_batched( || { - let sk = HpkeEvercrypt::kem_key_gen( - KemAlgorithm::DhKemP256, - &mut HpkeEvercrypt::prng(), - ) - .unwrap(); + let sk = + HpkeEvercrypt::kem_key_gen(KemAlgorithm::DhKemP256, &mut HpkeEvercrypt::prng()) + .unwrap(); sk.clone() }, |sk| { From 2b9e49d68e5bd02974a5d0b4fdc736b98c435be4 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 17:29:27 +0200 Subject: [PATCH 06/56] clarify documentation --- traits/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traits/src/lib.rs b/traits/src/lib.rs index 90d684b..189265d 100644 --- a/traits/src/lib.rs +++ b/traits/src/lib.rs @@ -66,7 +66,7 @@ pub trait HpkeCrypto: core::fmt::Debug + Send + Sync { /// KEM Derive with base fn kem_derive_base(alg: KemAlgorithm, sk: &[u8]) -> Result, Error>; - /// KEM Key generation + /// KEM secret key generation fn kem_key_gen(alg: KemAlgorithm, prng: &mut Self::HpkePrng) -> Result, Error>; /// Validate a secret key for its correctness. From 88737dff67b7b8c1312b323d6032ae3bdd6c746c Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 17:34:43 +0200 Subject: [PATCH 07/56] update rand dependency, traits, and provider --- Cargo.toml | 5 +- libcrux_provider/Cargo.toml | 3 - libcrux_provider/benches/bench_hkdf.rs | 22 ++++-- libcrux_provider/benches/bench_p256.rs | 12 +-- libcrux_provider/benches/bench_x25519.rs | 24 +++--- libcrux_provider/src/lib.rs | 94 ++++++++---------------- src/lib.rs | 5 +- tests/test_hpke.rs | 2 +- traits/Cargo.toml | 2 +- traits/src/lib.rs | 6 +- 10 files changed, 73 insertions(+), 102 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e88d682..354b53a 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ serde = { version = "1.0", features = ["derive"], optional = true } tls_codec = { version = "0.4.1-pre.1", features = ["derive"], optional = true } zeroize = { version = "1.5", features = ["zeroize_derive"] } hpke-rs-crypto = { version = "0.2.0", path = "./traits" } +rand_core = { version = "0.9" } [features] default = [] @@ -35,8 +36,8 @@ hpke-rs = { path = ".", features = ["hpke-test", "hazmat"] } hpke-rs-rust-crypto = { version = "0.2.0", path = "./rust_crypto_provider", features = [ "deterministic-prng", ] } -# hpke-rs-evercrypt = { version = "0.1.3-pre.1", path = "./evercrypt_provider", features = ["deterministic-prng"] } -rand = { version = "0.8" } +hpke-rs-libcrux = { version = "0.2.0-pre.1", path = "./libcrux_provider", features = ["deterministic-prng"] } +rand = { version = "0.9" } pretty_env_logger = "0.5" criterion = { version = "0.5", features = ["html_reports"] } diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index 3f89adc..f205b2c 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -20,9 +20,6 @@ libcrux-ed25519 = { version = "0.0.2", features=["rand"] } rand = { version = "0.9" } rand_core = { version = "0.9" } rand_chacha = { version = "0.9" } -rand_old = { version = "0.8", package = "rand"} -rand_core_old = { version = "0.6", package = "rand_core" } -rand_chacha_old = { version = "0.3.1", package = "rand_chacha"} [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } diff --git a/libcrux_provider/benches/bench_hkdf.rs b/libcrux_provider/benches/bench_hkdf.rs index 0f28b75..83f0621 100644 --- a/libcrux_provider/benches/bench_hkdf.rs +++ b/libcrux_provider/benches/bench_hkdf.rs @@ -1,20 +1,25 @@ use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use hpke_rs_crypto::{types::*, HpkeCrypto, RngCore}; -use hpke_rs_evercrypt::*; +use hpke_rs_libcrux::*; use rand::rngs::OsRng; +use rand::TryRngCore; + fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("HKDF SHA256 Extract"), |b| { b.iter_batched( || { + let mut rng = OsRng; + let mut rng_mut = rng.unwrap_mut(); + let mut salt = vec![0u8; 77]; let mut ikm = vec![0u8; 32]; - OsRng.fill_bytes(&mut salt); - OsRng.fill_bytes(&mut ikm); + rng_mut.fill_bytes(&mut salt); + rng_mut.fill_bytes(&mut ikm); (salt.clone(), ikm.clone()) }, |(salt, ikm)| { - let _ = HpkeEvercrypt::kdf_extract(KdfAlgorithm::HkdfSha256, &salt, &ikm); + let _ = HpkeLibcrux::kdf_extract(KdfAlgorithm::HkdfSha256, &salt, &ikm); }, BatchSize::SmallInput, ) @@ -22,14 +27,17 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("HKDF SHA256 Expand"), |b| { b.iter_batched( || { + let mut rng = OsRng; + let mut rng_mut = rng.unwrap_mut(); + let mut info = vec![0u8; 77]; let mut prk = vec![0u8; 32]; - OsRng.fill_bytes(&mut info); - OsRng.fill_bytes(&mut prk); + rng_mut.fill_bytes(&mut info); + rng_mut.fill_bytes(&mut prk); (prk.clone(), info.clone()) }, |(prk, info)| { - let _ = HpkeEvercrypt::kdf_expand(KdfAlgorithm::HkdfSha256, &prk, &info, 32); + let _ = HpkeLibcrux::kdf_expand(KdfAlgorithm::HkdfSha256, &prk, &info, 32); }, BatchSize::SmallInput, ) diff --git a/libcrux_provider/benches/bench_p256.rs b/libcrux_provider/benches/bench_p256.rs index 5b7286e..b9ab025 100644 --- a/libcrux_provider/benches/bench_p256.rs +++ b/libcrux_provider/benches/bench_p256.rs @@ -1,19 +1,19 @@ use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use hpke_rs_crypto::{types::KemAlgorithm, HpkeCrypto}; -use hpke_rs_evercrypt::*; +use hpke_rs_libcrux::*; fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("P256 Derive"), |b| { b.iter_batched( || { let sk = - HpkeEvercrypt::kem_key_gen(KemAlgorithm::DhKemP256, &mut HpkeEvercrypt::prng()) + HpkeLibcrux::kem_key_gen(KemAlgorithm::DhKemP256, &mut HpkeLibcrux::prng()) .unwrap(); - let pk = HpkeEvercrypt::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); + let pk = HpkeLibcrux::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); (sk.clone(), pk.clone()) }, |(sk, pk)| { - let _ = HpkeEvercrypt::kem_derive(KemAlgorithm::DhKemP256, &pk, &sk); + let _ = HpkeLibcrux::kem_derive(KemAlgorithm::DhKemP256, &pk, &sk); }, BatchSize::SmallInput, ) @@ -22,12 +22,12 @@ fn criterion_benchmark(c: &mut Criterion) { b.iter_batched( || { let sk = - HpkeEvercrypt::kem_key_gen(KemAlgorithm::DhKemP256, &mut HpkeEvercrypt::prng()) + HpkeLibcrux::kem_key_gen(KemAlgorithm::DhKemP256, &mut HpkeLibcrux::prng()) .unwrap(); sk.clone() }, |sk| { - let _pk = HpkeEvercrypt::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); + let _pk = HpkeLibcrux::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); }, BatchSize::SmallInput, ) diff --git a/libcrux_provider/benches/bench_x25519.rs b/libcrux_provider/benches/bench_x25519.rs index ad4eb5d..73b48b3 100644 --- a/libcrux_provider/benches/bench_x25519.rs +++ b/libcrux_provider/benches/bench_x25519.rs @@ -1,21 +1,19 @@ use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use hpke_rs_crypto::{types::*, HpkeCrypto}; -use hpke_rs_evercrypt::*; +use hpke_rs_libcrux::*; fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("x25519 Derive"), |b| { b.iter_batched( || { - let sk = HpkeEvercrypt::kem_key_gen( - KemAlgorithm::DhKem25519, - &mut HpkeEvercrypt::prng(), - ) - .unwrap(); - let pk = HpkeEvercrypt::kem_derive_base(KemAlgorithm::DhKem25519, &sk).unwrap(); + let sk = + HpkeLibcrux::kem_key_gen(KemAlgorithm::DhKem25519, &mut HpkeLibcrux::prng()) + .unwrap(); + let pk = HpkeLibcrux::kem_derive_base(KemAlgorithm::DhKem25519, &sk).unwrap(); (sk.clone(), pk.clone()) }, |(sk, pk)| { - let _ = HpkeEvercrypt::kem_derive(KemAlgorithm::DhKem25519, &pk, &sk); + let _ = HpkeLibcrux::kem_derive(KemAlgorithm::DhKem25519, &pk, &sk); }, BatchSize::SmallInput, ) @@ -23,15 +21,13 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("x25519 Derive Base"), |b| { b.iter_batched( || { - let sk = HpkeEvercrypt::kem_key_gen( - KemAlgorithm::DhKem25519, - &mut HpkeEvercrypt::prng(), - ) - .unwrap(); + let sk = + HpkeLibcrux::kem_key_gen(KemAlgorithm::DhKem25519, &mut HpkeLibcrux::prng()) + .unwrap(); sk.clone() }, |sk| { - let _pk = HpkeEvercrypt::kem_derive_base(KemAlgorithm::DhKem25519, &sk).unwrap(); + let _pk = HpkeLibcrux::kem_derive_base(KemAlgorithm::DhKem25519, &sk).unwrap(); }, BatchSize::SmallInput, ) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 0645d5a..0ff43ab 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -5,9 +5,10 @@ use std::{fmt::Display, sync::RwLock}; use hpke_rs_crypto::{ error::Error, types::{AeadAlgorithm, KdfAlgorithm, KemAlgorithm}, - HpkeCrypto, HpkeTestRng, + CryptoRng, HpkeCrypto, HpkeTestRng, }; -use rand_old::{CryptoRng, RngCore, SeedableRng}; + +use rand::SeedableRng; /// The Libcrux HPKE Provider #[derive(Debug)] @@ -17,7 +18,7 @@ pub struct HpkeLibcrux {} pub struct HpkeLibcruxPrng { #[cfg(feature = "deterministic-prng")] fake_rng: Vec, - rng: RwLock, + rng: RwLock, } impl HpkeCrypto for HpkeLibcrux { @@ -68,53 +69,29 @@ impl HpkeCrypto for HpkeLibcrux { libcrux_ecdh::derive(alg, pk, sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive error: {:?}", e))) - /* - .map(|mut p| { - if emode == EcdhMode::P256 { - // We only want the x-coordinate here but evercrypt gives us the entire point - p.truncate(32); - p - } else { - p - } - }) - */ } fn kem_derive_base(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { let alg = kem_key_type_to_ecdh_alg(alg)?; - todo!() - - /* - ecdh_derive_base(mode, sk) - .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive base error: {:?}", e))) - .map(|p| { - if evercrypt_mode == EcdhMode::P256 { - nist_format_uncompressed(p) - } else { - p - } - }) - */ + libcrux_ecdh::secret_to_public(alg, sk) + .map_err(|_| todo!()) } fn kem_key_gen(alg: KemAlgorithm, _: &mut Self::HpkePrng) -> Result, Error> { - let mode = kem_key_type_to_mode(alg)?; + let alg = kem_key_type_to_ecdh_alg(alg)?; use rand::TryRngCore; let mut rng = rand::rngs::OsRng; - let (pk, sk) = libcrux_kem::key_gen(mode, &mut rng.unwrap_mut()) - .map_err(|e| Error::CryptoLibraryError(format!("ECDH key gen error: {:?}", e)))?; // return both keys as single vec - todo!() + libcrux_ecdh::generate_secret(alg, &mut rng.unwrap_mut()) + .map_err(|e| Error::CryptoLibraryError(format!("ECDH key gen error: {:?}", e))) } fn kem_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { + match alg { - //KemAlgorithm::DhKemP256 => p256_validate_sk(&sk) - // XXX: do we support this? KemAlgorithm::DhKemP256 => libcrux_ecdh::p256::validate_scalar_slice(&sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH invalid sk error: {:?}", e))) .map(|sk| sk.0.to_vec()), @@ -185,16 +162,19 @@ impl HpkeCrypto for HpkeLibcrux { fn prng() -> Self::HpkePrng { #[cfg(feature = "deterministic-prng")] { + use rand::TryRngCore; let mut fake_rng = vec![0u8; 256]; - rand_chacha_old::ChaCha20Rng::from_entropy().fill_bytes(&mut fake_rng); + rand_chacha::ChaCha20Rng::from_os_rng() + .try_fill_bytes(&mut fake_rng) + .unwrap(); HpkeLibcruxPrng { fake_rng, - rng: RwLock::new(rand_chacha_old::ChaCha20Rng::from_entropy()), + rng: RwLock::new(rand_chacha::ChaCha20Rng::from_os_rng()), } } #[cfg(not(feature = "deterministic-prng"))] HpkeLibcruxPrng { - rng: RwLock::new(rand_chacha_old::ChaCha20Rng::from_entropy()), + rng: RwLock::new(rand_chacha::ChaCha20Rng::from_os_rng()), } } @@ -205,7 +185,6 @@ impl HpkeCrypto for HpkeLibcrux { /// Returns an error if the KEM algorithm is not supported by this crypto provider. fn supports_kem(alg: KemAlgorithm) -> Result<(), Error> { - // XXX: do we support DhKemP256? match alg { KemAlgorithm::DhKem25519 | KemAlgorithm::DhKemP256 => Ok(()), _ => Err(Error::UnknownKemAlgorithm), @@ -233,63 +212,48 @@ fn nist_format_uncompressed(mut pk: Vec) -> Vec { } */ -#[inline(always)] -fn kem_key_type_to_mode(alg: KemAlgorithm) -> Result { - match alg { - KemAlgorithm::DhKem25519 => Ok(libcrux_kem::Algorithm::X25519), - // XXX: is this correct? - KemAlgorithm::DhKemP256 => Ok(libcrux_kem::Algorithm::Secp256r1), - _ => Err(Error::UnknownKemAlgorithm), - } -} - -// TODO: is this correct? #[inline(always)] fn kem_key_type_to_ecdh_alg(alg: KemAlgorithm) -> Result { match alg { KemAlgorithm::DhKem25519 => Ok(libcrux_ecdh::Algorithm::X25519), - // XXX: do we support this? KemAlgorithm::DhKemP256 => Ok(libcrux_ecdh::Algorithm::P256), _ => Err(Error::UnknownKemAlgorithm), } } -impl RngCore for HpkeLibcruxPrng { + +impl hpke_rs_crypto::RngCore for HpkeLibcruxPrng { fn next_u32(&mut self) -> u32 { - let mut rng = self.rng.write().unwrap(); - rng.next_u32() + self.rng.write().unwrap().next_u32() } fn next_u64(&mut self) -> u64 { - let mut rng = self.rng.write().unwrap(); - rng.next_u64() + self.rng.write().unwrap().next_u64() } fn fill_bytes(&mut self, dest: &mut [u8]) { - let mut rng = self.rng.write().unwrap(); - rng.fill_bytes(dest) - } - - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_old::Error> { - let mut rng = self.rng.write().unwrap(); - rng.try_fill_bytes(dest) + self.rng.write().unwrap().fill_bytes(dest) } } impl CryptoRng for HpkeLibcruxPrng {} impl HpkeTestRng for HpkeLibcruxPrng { + type Error = Error; + #[cfg(feature = "deterministic-prng")] - fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_old::Error> { + fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { // Here we fake our randomness for testing. if dest.len() > self.fake_rng.len() { - return Err(rand_old::Error::new(Error::InsufficientRandomness)); + return Err(Error::InsufficientRandomness); } dest.clone_from_slice(&self.fake_rng.split_off(self.fake_rng.len() - dest.len())); Ok(()) } #[cfg(not(feature = "deterministic-prng"))] - fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_old::Error> { - self.rng.write().unwrap().try_fill_bytes(dest) + fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + use rand_core::TryRngCore; + self.try_fill_bytes(dest) + .map_err(|_| Error::InsufficientRandomness) } #[cfg(feature = "deterministic-prng")] diff --git a/src/lib.rs b/src/lib.rs index 6517298..c7a89e2 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,13 +23,14 @@ use alloc::{ #[cfg(feature = "hpke-test-prng")] use hpke_rs_crypto::HpkeTestRng; -#[cfg(not(feature = "hpke-test-prng"))] -use hpke_rs_crypto::RngCore; use hpke_rs_crypto::{ types::{AeadAlgorithm, KdfAlgorithm, KemAlgorithm}, HpkeCrypto, }; use prelude::kdf::{labeled_expand, labeled_extract}; +#[cfg(not(feature = "hpke-test-prng"))] +use rand_core::TryRngCore; + #[cfg(feature = "serialization")] pub(crate) use serde::{Deserialize, Serialize}; use zeroize::Zeroize; diff --git a/tests/test_hpke.rs b/tests/test_hpke.rs index db95b94..eec3c41 100644 --- a/tests/test_hpke.rs +++ b/tests/test_hpke.rs @@ -7,7 +7,7 @@ use hpke_rs_crypto::{ types::{AeadAlgorithm, KdfAlgorithm, KemAlgorithm}, HpkeCrypto, RngCore, }; -// use hpke_rs_evercrypt::HpkeEvercrypt; +use hpke_rs_libcrux::HpkeLibcrux; use hpke_rs_rust_crypto::HpkeRustCrypto; use lazy_static::lazy_static; diff --git a/traits/Cargo.toml b/traits/Cargo.toml index 424c19c..42993f6 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/franziskuskiefer/hpke-rs" [dependencies] serde = { version = "1.0", features = ["derive"], optional = true } -rand_core = { version = "0.6.4" } +rand_core = { version = "0.9" } [features] serde = ["dep:serde"] diff --git a/traits/src/lib.rs b/traits/src/lib.rs index 189265d..3cdba56 100644 --- a/traits/src/lib.rs +++ b/traits/src/lib.rs @@ -127,10 +127,14 @@ pub trait HpkeCrypto: core::fmt::Debug + Send + Sync { } } + /// PRNG extension for testing that is supposed to return pre-configured bytes. pub trait HpkeTestRng { + + // Error type to replace rand::Error (which is no longer available as of version 0.9) + type Error: core::fmt::Debug + core::fmt::Display; /// Like [`RngCore::try_fill_bytes`] but the result is expected to be known. - fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error>; + fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error>; /// Set the randomness state of this test PRNG. fn seed(&mut self, seed: &[u8]); From 77a63056926160345fe8548efbed280c854c660c Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 17:59:45 +0200 Subject: [PATCH 08/56] documentation --- libcrux_provider/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 0ff43ab..cf2bb7a 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -84,7 +84,6 @@ impl HpkeCrypto for HpkeLibcrux { use rand::TryRngCore; let mut rng = rand::rngs::OsRng; - // return both keys as single vec libcrux_ecdh::generate_secret(alg, &mut rng.unwrap_mut()) .map_err(|e| Error::CryptoLibraryError(format!("ECDH key gen error: {:?}", e))) } From 453cbea137fb050764f267fd6c1ab7bd298f1d49 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 18:03:35 +0200 Subject: [PATCH 09/56] use provided prng --- libcrux_provider/src/lib.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index cf2bb7a..4d35543 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -78,18 +78,14 @@ impl HpkeCrypto for HpkeLibcrux { .map_err(|_| todo!()) } - fn kem_key_gen(alg: KemAlgorithm, _: &mut Self::HpkePrng) -> Result, Error> { + fn kem_key_gen(alg: KemAlgorithm, prng: &mut Self::HpkePrng) -> Result, Error> { let alg = kem_key_type_to_ecdh_alg(alg)?; - use rand::TryRngCore; - let mut rng = rand::rngs::OsRng; - - libcrux_ecdh::generate_secret(alg, &mut rng.unwrap_mut()) + libcrux_ecdh::generate_secret(alg, prng) .map_err(|e| Error::CryptoLibraryError(format!("ECDH key gen error: {:?}", e))) } fn kem_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { - match alg { KemAlgorithm::DhKemP256 => libcrux_ecdh::p256::validate_scalar_slice(&sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH invalid sk error: {:?}", e))) @@ -220,7 +216,6 @@ fn kem_key_type_to_ecdh_alg(alg: KemAlgorithm) -> Result u32 { self.rng.write().unwrap().next_u32() From 92f78ebbd40ad0bca852d7f1033b5ca7df20e56a Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 18:03:46 +0200 Subject: [PATCH 10/56] formatting --- libcrux_provider/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 4d35543..97d71a6 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -74,8 +74,7 @@ impl HpkeCrypto for HpkeLibcrux { fn kem_derive_base(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { let alg = kem_key_type_to_ecdh_alg(alg)?; - libcrux_ecdh::secret_to_public(alg, sk) - .map_err(|_| todo!()) + libcrux_ecdh::secret_to_public(alg, sk).map_err(|_| todo!()) } fn kem_key_gen(alg: KemAlgorithm, prng: &mut Self::HpkePrng) -> Result, Error> { From 91b8ca5399d47e73433afa46b946adfb7aedaff1 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Thu, 10 Apr 2025 18:09:56 +0200 Subject: [PATCH 11/56] add todo for HpkeExport --- libcrux_provider/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 97d71a6..7166aa8 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -190,7 +190,9 @@ impl HpkeCrypto for HpkeLibcrux { match alg { // Don't support Aes AeadAlgorithm::Aes128Gcm | AeadAlgorithm::Aes256Gcm => Err(Error::UnknownAeadAlgorithm), - AeadAlgorithm::ChaCha20Poly1305 | AeadAlgorithm::HpkeExport => Ok(()), + AeadAlgorithm::ChaCha20Poly1305 => Ok(()), + // TODO: should this be supported? + AeadAlgorithm::HpkeExport => todo!(), } } } From 89432d12dafb5d90174589518f53abc877fa01a2 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Fri, 11 Apr 2025 14:14:37 +0200 Subject: [PATCH 12/56] fixup tests and providers --- Cargo.toml | 6 ++++-- libcrux_provider/Cargo.toml | 2 +- libcrux_provider/src/lib.rs | 23 +++++++++++++++----- rust_crypto_provider/Cargo.toml | 1 + rust_crypto_provider/src/lib.rs | 29 ++++++++++++++++++++++--- src/test_aead.rs | 38 ++++++++++++++++----------------- src/test_kdf.rs | 7 +++--- tests/test_hpke.rs | 32 +++++++++++++-------------- tests/test_hpke_kat.rs | 10 ++++----- traits/src/lib.rs | 2 +- 10 files changed, 95 insertions(+), 55 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 354b53a..a8ff007 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ std = [] serialization = ["serde", "tls_codec", "tls_codec/serde", "std"] hazmat = [] hpke-test = ["std"] -hpke-test-prng = [] # ⚠️ Enable testing PRNG - DO NOT USE +hpke-test-prng = [] # ⚠️ Enable testing PRNG - DO NOT USE [dev-dependencies] hpke-rs-crypto = { version = "0.2.0", path = "./traits", features = ["std"] } @@ -36,7 +36,9 @@ hpke-rs = { path = ".", features = ["hpke-test", "hazmat"] } hpke-rs-rust-crypto = { version = "0.2.0", path = "./rust_crypto_provider", features = [ "deterministic-prng", ] } -hpke-rs-libcrux = { version = "0.2.0-pre.1", path = "./libcrux_provider", features = ["deterministic-prng"] } +hpke-rs-libcrux = { version = "0.2.0-alpha.1", path = "./libcrux_provider", features = [ + "deterministic-prng", +] } rand = { version = "0.9" } pretty_env_logger = "0.5" criterion = { version = "0.5", features = ["html_reports"] } diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index f205b2c..9f2a311 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hpke-rs-libcrux" -version = "0.2.0-pre.1" +version = "0.2.0-alpha.1" authors = ["Franziskus Kiefer "] edition = "2021" license = "MPL-2.0" diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 7166aa8..b3ed48b 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -69,12 +69,28 @@ impl HpkeCrypto for HpkeLibcrux { libcrux_ecdh::derive(alg, pk, sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive error: {:?}", e))) + .map(|mut p| { + if alg == libcrux_ecdh::Algorithm::P256 { + p.truncate(32); + p + } else { + p + } + }) } fn kem_derive_base(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { let alg = kem_key_type_to_ecdh_alg(alg)?; - libcrux_ecdh::secret_to_public(alg, sk).map_err(|_| todo!()) + libcrux_ecdh::secret_to_public(alg, sk) + .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive base error: {:?}", e))) + .map(|p| { + if alg == libcrux_ecdh::Algorithm::P256 { + nist_format_uncompressed(p) + } else { + p + } + }) } fn kem_key_gen(alg: KemAlgorithm, prng: &mut Self::HpkePrng) -> Result, Error> { @@ -191,13 +207,11 @@ impl HpkeCrypto for HpkeLibcrux { // Don't support Aes AeadAlgorithm::Aes128Gcm | AeadAlgorithm::Aes256Gcm => Err(Error::UnknownAeadAlgorithm), AeadAlgorithm::ChaCha20Poly1305 => Ok(()), - // TODO: should this be supported? - AeadAlgorithm::HpkeExport => todo!(), + AeadAlgorithm::HpkeExport => Ok(()), } } } -/* /// Prepend 0x04 for uncompressed NIST curve points. #[inline(always)] fn nist_format_uncompressed(mut pk: Vec) -> Vec { @@ -206,7 +220,6 @@ fn nist_format_uncompressed(mut pk: Vec) -> Vec { tmp.append(&mut pk); tmp } -*/ #[inline(always)] fn kem_key_type_to_ecdh_alg(alg: KemAlgorithm) -> Result { diff --git a/rust_crypto_provider/Cargo.toml b/rust_crypto_provider/Cargo.toml index 1a0b293..118d37d 100644 --- a/rust_crypto_provider/Cargo.toml +++ b/rust_crypto_provider/Cargo.toml @@ -30,6 +30,7 @@ chacha20poly1305 = { version = "0.10", default-features = false, features = [ aes-gcm = { version = "0.10", default-features = false, features = ["aes"] } # Randomness rand_core = { version = "0.6", features = ["getrandom"] } +rand_old = { version = "0.8", package = "rand" } rand_chacha = { version = "0.3", default-features = false } [dev-dependencies] diff --git a/rust_crypto_provider/src/lib.rs b/rust_crypto_provider/src/lib.rs index 6559708..afd9245 100644 --- a/rust_crypto_provider/src/lib.rs +++ b/rust_crypto_provider/src/lib.rs @@ -232,7 +232,10 @@ impl HpkeCrypto for HpkeRustCrypto { } } -impl RngCore for HpkeRustCryptoPrng { +// We need to implement the old and new traits here because the crytpo uses the +// old one. + +impl rand_old::RngCore for HpkeRustCryptoPrng { fn next_u32(&mut self) -> u32 { self.rng.next_u32() } @@ -250,11 +253,29 @@ impl RngCore for HpkeRustCryptoPrng { } } +impl rand_old::CryptoRng for HpkeRustCryptoPrng {} + +use rand_old::RngCore as _; + +impl RngCore for HpkeRustCryptoPrng { + fn next_u32(&mut self) -> u32 { + self.rng.next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.rng.next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.rng.fill_bytes(dest); + } +} + impl CryptoRng for HpkeRustCryptoPrng {} impl HpkeTestRng for HpkeRustCryptoPrng { #[cfg(feature = "deterministic-prng")] - fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { + fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_old::Error> { // Here we fake our randomness for testing. if dest.len() > self.fake_rng.len() { return Err(rand_core::Error::new(Error::InsufficientRandomness)); @@ -268,12 +289,14 @@ impl HpkeTestRng for HpkeRustCryptoPrng { self.fake_rng = seed.to_vec(); } #[cfg(not(feature = "deterministic-prng"))] - fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { + fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_old::Error> { self.rng.try_fill_bytes(dest) } #[cfg(not(feature = "deterministic-prng"))] fn seed(&mut self, _: &[u8]) {} + + type Error = rand_old::Error; } impl Display for HpkeRustCrypto { diff --git a/src/test_aead.rs b/src/test_aead.rs index 33b4c4d..f375c70 100644 --- a/src/test_aead.rs +++ b/src/test_aead.rs @@ -1,20 +1,20 @@ -use hpke_rs_crypto::{types::AeadAlgorithm, HpkeCrypto}; -use hpke_rs_rust_crypto::HpkeRustCrypto; +// use hpke_rs_crypto::{types::AeadAlgorithm, HpkeCrypto}; +// use hpke_rs_rust_crypto::HpkeRustCrypto; -#[test] -fn test_aes_gcm_128_self() { - let key = [ - 0x5b, 0x96, 0x04, 0xfe, 0x14, 0xea, 0xdb, 0xa9, 0x31, 0xb0, 0xcc, 0xf3, 0x48, 0x43, 0xda, - 0xb9, - ]; - let nonce = [ - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - ]; - let aad = [0x03, 0x04, 0x05]; - let msg = b"test message"; - let ctxt = - HpkeRustCrypto::aead_seal(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, msg).unwrap(); - let ptxt = - HpkeRustCrypto::aead_open(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, &ctxt).unwrap(); - assert_eq!(&ptxt, msg); -} +// #[test] +// fn test_aes_gcm_128_self() { +// let key = [ +// 0x5b, 0x96, 0x04, 0xfe, 0x14, 0xea, 0xdb, 0xa9, 0x31, 0xb0, 0xcc, 0xf3, 0x48, 0x43, 0xda, +// 0xb9, +// ]; +// let nonce = [ +// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, +// ]; +// let aad = [0x03, 0x04, 0x05]; +// let msg = b"test message"; +// let ctxt = +// HpkeRustCrypto::aead_seal(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, msg).unwrap(); +// let ptxt = +// HpkeRustCrypto::aead_open(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, &ctxt).unwrap(); +// assert_eq!(&ptxt, msg); +// } diff --git a/src/test_kdf.rs b/src/test_kdf.rs index 635f70d..0768e58 100755 --- a/src/test_kdf.rs +++ b/src/test_kdf.rs @@ -1,5 +1,6 @@ use hpke_rs_crypto::{types::KdfAlgorithm, HpkeCrypto}; -use hpke_rs_rust_crypto::HpkeRustCrypto; +// use hpke_rs_rust_crypto::HpkeRustCrypto; +use hpke_rs_libcrux::HpkeLibcrux; use crate::test_util::hex_to_bytes; @@ -16,8 +17,8 @@ fn test_hkdf_sha256() { "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865", ); - let prk = HpkeRustCrypto::kdf_extract(KdfAlgorithm::HkdfSha256, &salt, &ikm); - let okm = HpkeRustCrypto::kdf_expand(KdfAlgorithm::HkdfSha256, &prk, &info, len) + let prk = HpkeLibcrux::kdf_extract(KdfAlgorithm::HkdfSha256, &salt, &ikm); + let okm = HpkeLibcrux::kdf_expand(KdfAlgorithm::HkdfSha256, &prk, &info, len) .expect("Error expanding with HKDF"); assert_eq!(&expected_prk, &prk); diff --git a/tests/test_hpke.rs b/tests/test_hpke.rs index eec3c41..64b9485 100644 --- a/tests/test_hpke.rs +++ b/tests/test_hpke.rs @@ -273,14 +273,14 @@ generate_test_case!( AeadAlgorithm::ChaCha20Poly1305, HpkeRustCrypto ); -// generate_test_case!( -// base_dhkemp256_hkdfsha256_chacha20poly1305_evercrypt, -// HpkeMode::Base, -// KemAlgorithm::DhKemP256, -// KdfAlgorithm::HkdfSha256, -// AeadAlgorithm::ChaCha20Poly1305, -// HpkeEvercrypt -// ); +generate_test_case!( + base_dhkemp256_hkdfsha256_chacha20poly1305_libcrux, + HpkeMode::Base, + KemAlgorithm::DhKemP256, + KdfAlgorithm::HkdfSha256, + AeadAlgorithm::ChaCha20Poly1305, + HpkeLibcrux +); generate_test_case!( base_dhkem25519_hkdfsha256_chacha20poly1305, HpkeMode::Base, @@ -289,14 +289,14 @@ generate_test_case!( AeadAlgorithm::ChaCha20Poly1305, HpkeRustCrypto ); -// generate_test_case!( -// base_dhkem25519_hkdfsha256_chacha20poly1305_evercrypt, -// HpkeMode::Base, -// KemAlgorithm::DhKem25519, -// KdfAlgorithm::HkdfSha256, -// AeadAlgorithm::ChaCha20Poly1305, -// HpkeEvercrypt -// ); +generate_test_case!( + base_dhkem25519_hkdfsha256_chacha20poly1305_libcrux, + HpkeMode::Base, + KemAlgorithm::DhKem25519, + KdfAlgorithm::HkdfSha256, + AeadAlgorithm::ChaCha20Poly1305, + HpkeLibcrux +); generate_test_case!( base_dhkemp256_hkdfsha384_chacha20poly1305, HpkeMode::Base, diff --git a/tests/test_hpke_kat.rs b/tests/test_hpke_kat.rs index 3a62ced..33ef6d2 100755 --- a/tests/test_hpke_kat.rs +++ b/tests/test_hpke_kat.rs @@ -1,6 +1,5 @@ extern crate hpke_rs as hpke; -// use hpke_rs_evercrypt::HpkeEvercrypt; use hpke_rs_rust_crypto::HpkeRustCrypto; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use serde::{self, Deserialize, Serialize}; @@ -12,6 +11,7 @@ use std::time::Instant; use hpke::prelude::*; use hpke::test_util::{hex_to_bytes, hex_to_bytes_option, vec_to_option_slice}; use hpke_rs_crypto::{types::*, HpkeCrypto}; +use hpke_rs_libcrux::HpkeLibcrux; #[derive(Serialize, Deserialize, Debug, Clone)] #[allow(non_snake_case)] @@ -294,10 +294,10 @@ fn test_kat() { let time = now.elapsed(); log::info!("Test vectors with Rust Crypto took: {}s", time.as_secs()); - // let now = Instant::now(); - // kat::(tests); - // let time = now.elapsed(); - // log::info!("Test vectors with Evercrypt took: {}s", time.as_secs()); + let now = Instant::now(); + kat::(tests); + let time = now.elapsed(); + log::info!("Test vectors with Evercrypt took: {}s", time.as_secs()); } } diff --git a/traits/src/lib.rs b/traits/src/lib.rs index 3cdba56..e374e99 100644 --- a/traits/src/lib.rs +++ b/traits/src/lib.rs @@ -133,7 +133,7 @@ pub trait HpkeTestRng { // Error type to replace rand::Error (which is no longer available as of version 0.9) type Error: core::fmt::Debug + core::fmt::Display; - /// Like [`RngCore::try_fill_bytes`] but the result is expected to be known. + /// Like [`TryRngCore::try_fill_bytes`] but the result is expected to be known. fn try_fill_test_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error>; /// Set the randomness state of this test PRNG. From d9de0817b9a5e2b4a9b3068d0da5d757255d073a Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 14 Apr 2025 08:26:18 +0200 Subject: [PATCH 13/56] wip: add xwing-06; bug in p256 --- Cargo.toml | 9 +++-- benches/bench.rs | 21 +++++----- benches/manual_benches.rs | 13 +++--- libcrux_provider/Cargo.toml | 6 +-- libcrux_provider/src/lib.rs | 70 +++++++++++++++++++++++++++++---- rust_crypto_provider/Cargo.toml | 2 +- rust_crypto_provider/src/lib.rs | 61 ++++++++++++++++++++-------- src/dh_kem.rs | 26 ++++++------ src/kem.rs | 52 ++++++++++++++++++------ src/lib.rs | 15 ++++--- tests/test_hpke.rs | 9 +++++ traits/Cargo.toml | 2 +- traits/src/error.rs | 6 +++ traits/src/lib.rs | 34 +++++++++++----- traits/src/types.rs | 11 +++++- 15 files changed, 247 insertions(+), 90 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a8ff007..21bf9b9 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hpke-rs" -version = "0.2.1-pre.1" +version = "0.2.1-alpha.1" authors = ["Franziskus Kiefer "] edition = "2021" license = "MPL-2.0" @@ -15,8 +15,9 @@ log = "0.4" serde = { version = "1.0", features = ["derive"], optional = true } tls_codec = { version = "0.4.1-pre.1", features = ["derive"], optional = true } zeroize = { version = "1.5", features = ["zeroize_derive"] } -hpke-rs-crypto = { version = "0.2.0", path = "./traits" } +hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "./traits" } rand_core = { version = "0.9" } +libcrux-sha3 = { version = "0.0.2" } [features] default = [] @@ -27,7 +28,9 @@ hpke-test = ["std"] hpke-test-prng = [] # ⚠️ Enable testing PRNG - DO NOT USE [dev-dependencies] -hpke-rs-crypto = { version = "0.2.0", path = "./traits", features = ["std"] } +hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "./traits", features = [ + "std", +] } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } lazy_static = "1.4" diff --git a/benches/bench.rs b/benches/bench.rs index c82d1b4..a25839e 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -4,9 +4,8 @@ use hpke_rs_crypto::{ types::{AeadAlgorithm, KdfAlgorithm, KemAlgorithm}, HpkeCrypto, RngCore, }; -// use hpke_rs_evercrypt::*; +use hpke_rs_libcrux::HpkeLibcrux; use hpke_rs_rust_crypto::*; -use rand::rngs::OsRng; const MODES: [Mode; 4] = [ HpkeMode::Base, @@ -127,9 +126,9 @@ fn benchmark(c: &mut Criterion) { ) .unwrap(); let mut aad = vec![0u8; AEAD_AAD]; - OsRng.fill_bytes(&mut aad); + rand::rng().fill_bytes(&mut aad); let mut ptxt = vec![0u8; AEAD_PAYLOAD]; - OsRng.fill_bytes(&mut ptxt); + rand::rng().fill_bytes(&mut ptxt); (context, aad, ptxt) }, |(mut context, aad, ptxt)| { @@ -153,9 +152,9 @@ fn benchmark(c: &mut Criterion) { ) .unwrap(); let mut aad = vec![0u8; AEAD_AAD]; - OsRng.fill_bytes(&mut aad); + rand::rng().fill_bytes(&mut aad); let mut ptxt = vec![0u8; AEAD_PAYLOAD]; - OsRng.fill_bytes(&mut ptxt); + rand::rng().fill_bytes(&mut ptxt); let ctxt = sender_context.seal(&aad, &ptxt).unwrap(); let context = hpke @@ -186,9 +185,9 @@ fn benchmark(c: &mut Criterion) { hpke_mode, kem_mode, kdf_mode, aead_mode, ); let mut aad = vec![0u8; AEAD_AAD]; - OsRng.fill_bytes(&mut aad); + rand::rng().fill_bytes(&mut aad); let mut ptxt = vec![0u8; AEAD_PAYLOAD]; - OsRng.fill_bytes(&mut ptxt); + rand::rng().fill_bytes(&mut ptxt); (hpke, aad, ptxt) }, |(mut hpke, aad, ptxt)| { @@ -226,9 +225,9 @@ fn benchmark(c: &mut Criterion) { ) .unwrap(); let mut aad = vec![0u8; AEAD_AAD]; - OsRng.fill_bytes(&mut aad); + rand::rng().fill_bytes(&mut aad); let mut ptxt = vec![0u8; AEAD_PAYLOAD]; - OsRng.fill_bytes(&mut ptxt); + rand::rng().fill_bytes(&mut ptxt); let ctxt = sender_context.seal(&aad, &ptxt).unwrap(); (hpke, aad, ctxt, enc) @@ -259,7 +258,7 @@ fn benchmark(c: &mut Criterion) { criterion_group!( benches, - // benchmark::, + benchmark::, benchmark::, ); criterion_main!(benches); diff --git a/benches/manual_benches.rs b/benches/manual_benches.rs index 4210cf8..a30fa06 100644 --- a/benches/manual_benches.rs +++ b/benches/manual_benches.rs @@ -5,9 +5,8 @@ use hpke_rs_crypto::{ types::{AeadAlgorithm, KdfAlgorithm, KemAlgorithm}, HpkeCrypto, RngCore, }; -// use hpke_rs_evercrypt::*; +use hpke_rs_libcrux::HpkeLibcrux; use hpke_rs_rust_crypto::*; -use rand::rngs::OsRng; fn duration(d: Duration) -> f64 { ((d.as_secs() as f64) + (d.subsec_nanos() as f64 * 1e-9)) * 1000000f64 @@ -143,9 +142,9 @@ fn benchmark() { ) .unwrap(); let mut aad = vec![0u8; AEAD_AAD]; - OsRng.fill_bytes(&mut aad); + rand::rng().fill_bytes(&mut aad); let mut ptxt = vec![0u8; AEAD_PAYLOAD]; - OsRng.fill_bytes(&mut ptxt); + rand::rng().fill_bytes(&mut ptxt); let mut ctxts = Vec::with_capacity((AEAD_PAYLOAD + 16) * ITERATIONS); let start = Instant::now(); @@ -190,9 +189,9 @@ fn benchmark() { assert_eq!(ptxts[0], ptxt); let mut aad = vec![0u8; AEAD_AAD]; - OsRng.fill_bytes(&mut aad); + rand::rng().fill_bytes(&mut aad); let mut ptxt = vec![0u8; AEAD_PAYLOAD]; - OsRng.fill_bytes(&mut ptxt); + rand::rng().fill_bytes(&mut ptxt); let mut enc = Vec::::new(); let mut ctxt = Vec::::new(); @@ -253,6 +252,6 @@ fn benchmark() { } fn main() { - // benchmark::(); + benchmark::(); benchmark::(); } diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index 9f2a311..74ed7ba 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -10,12 +10,12 @@ readme = "Readme.md" repository = "https://github.com/cryspen/hpke-rs" [dependencies] -hpke-rs-crypto = { version = "0.2.0", path = "../traits" } +hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "../traits" } libcrux-ecdh = { version = "0.0.2" } libcrux-hkdf = { version = "0.0.2" } -libcrux-kem = { version = "0.0.2" } +libcrux-kem = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "franziskus/kem-derand" } libcrux-chacha20poly1305 = { version = "0.0.2" } -libcrux-ed25519 = { version = "0.0.2", features=["rand"] } +libcrux-ed25519 = { version = "0.0.2", features = ["rand"] } # Randomness rand = { version = "0.9" } rand_core = { version = "0.9" } diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index b3ed48b..5d89f3e 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -64,7 +64,7 @@ impl HpkeCrypto for HpkeLibcrux { }) } - fn kem_derive(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error> { + fn dh(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error> { let alg = kem_key_type_to_ecdh_alg(alg)?; libcrux_ecdh::derive(alg, pk, sk) @@ -79,7 +79,7 @@ impl HpkeCrypto for HpkeLibcrux { }) } - fn kem_derive_base(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { + fn secret_to_public(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { let alg = kem_key_type_to_ecdh_alg(alg)?; libcrux_ecdh::secret_to_public(alg, sk) @@ -93,14 +93,51 @@ impl HpkeCrypto for HpkeLibcrux { }) } - fn kem_key_gen(alg: KemAlgorithm, prng: &mut Self::HpkePrng) -> Result, Error> { - let alg = kem_key_type_to_ecdh_alg(alg)?; + fn kem_key_gen( + alg: KemAlgorithm, + prng: &mut Self::HpkePrng, + ) -> Result<(Vec, Vec), Error> { + let alg = kem_key_type_to_libcrux_alg(alg)?; + + libcrux_kem::key_gen(alg, prng) + .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e))) + .map(|(sk, pk)| (pk.encode(), sk.encode())) + } + + fn kem_key_gen_derand(alg: KemAlgorithm, seed: &[u8]) -> Result<(Vec, Vec), Error> { + let alg = kem_key_type_to_libcrux_alg(alg)?; + + libcrux_kem::key_gen_derand(alg, seed) + .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e))) + .map(|(sk, pk)| (pk.encode(), sk.encode())) + } + + fn kem_encaps( + alg: KemAlgorithm, + pk_r: &[u8], + prng: &mut Self::HpkePrng, + ) -> Result<(Vec, Vec), Error> { + let alg = kem_key_type_to_libcrux_alg(alg)?; + + let pk = + libcrux_kem::PublicKey::decode(alg, pk_r).map_err(|_| Error::KemInvalidPublicKey)?; + pk.encapsulate(prng) + .map_err(|e| Error::CryptoLibraryError(format!("Encaps error {:?}", e))) + .map(|(ss, ct)| (ss.encode(), ct.encode())) + } + + fn kem_decaps(alg: KemAlgorithm, ct: &[u8], sk_r: &[u8]) -> Result, Error> { + let alg = kem_key_type_to_libcrux_alg(alg)?; - libcrux_ecdh::generate_secret(alg, prng) - .map_err(|e| Error::CryptoLibraryError(format!("ECDH key gen error: {:?}", e))) + let ct = libcrux_kem::Ct::decode(alg, ct).map_err(|_| Error::AeadInvalidCiphertext)?; + let sk = + libcrux_kem::PrivateKey::decode(alg, sk_r).map_err(|_| Error::KemInvalidSecretKey)?; + ct.decapsulate(&sk) + .map_err(|e| Error::CryptoLibraryError(format!("Decaps error {:?}", e))) + .map(|ss| ss.encode()) } - fn kem_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { + fn dh_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { match alg { KemAlgorithm::DhKemP256 => libcrux_ecdh::p256::validate_scalar_slice(&sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH invalid sk error: {:?}", e))) @@ -129,6 +166,8 @@ impl HpkeCrypto for HpkeLibcrux { libcrux_chacha20poly1305::encrypt(key, msg, &mut msg_ctx, aad, iv) .map_err(|_| Error::CryptoLibraryError("Invalid configuration".into()))?; + eprintln!("aead key {:x?}", key); + eprintln!("aead seal {:x?}", msg_ctx); Ok(msg_ctx) } @@ -139,6 +178,7 @@ impl HpkeCrypto for HpkeLibcrux { aad: &[u8], cipher_txt: &[u8], ) -> Result, Error> { + eprintln!("aead open {:x?}", cipher_txt); // only chacha20poly1305 is supported if !matches!(alg, AeadAlgorithm::ChaCha20Poly1305) { return Err(Error::UnknownAeadAlgorithm); @@ -153,6 +193,8 @@ impl HpkeCrypto for HpkeLibcrux { let iv = <&[u8; 12]>::try_from(nonce).map_err(|_| Error::AeadInvalidNonce)?; + eprintln!("aead key {:x?}", key); + // TODO: instead, use key conversion from the libcrux-chacha20poly1305 crate, when available, let key = <&[u8; 32]>::try_from(key).map_err(|_| todo!())?; libcrux_chacha20poly1305::decrypt(key, &mut ptext, cipher_txt, aad, iv).map_err( @@ -196,7 +238,9 @@ impl HpkeCrypto for HpkeLibcrux { /// Returns an error if the KEM algorithm is not supported by this crypto provider. fn supports_kem(alg: KemAlgorithm) -> Result<(), Error> { match alg { - KemAlgorithm::DhKem25519 | KemAlgorithm::DhKemP256 => Ok(()), + KemAlgorithm::DhKem25519 | KemAlgorithm::DhKemP256 | KemAlgorithm::XWingDraft06 => { + Ok(()) + } _ => Err(Error::UnknownKemAlgorithm), } } @@ -221,6 +265,16 @@ fn nist_format_uncompressed(mut pk: Vec) -> Vec { tmp } +#[inline(always)] +fn kem_key_type_to_libcrux_alg(alg: KemAlgorithm) -> Result { + match alg { + KemAlgorithm::DhKem25519 => Ok(libcrux_kem::Algorithm::X25519), + KemAlgorithm::DhKemP256 => Ok(libcrux_kem::Algorithm::Secp256r1), + KemAlgorithm::XWingDraft06 => Ok(libcrux_kem::Algorithm::XWingKemDraft06), + _ => Err(Error::UnknownKemAlgorithm), + } +} + #[inline(always)] fn kem_key_type_to_ecdh_alg(alg: KemAlgorithm) -> Result { match alg { diff --git a/rust_crypto_provider/Cargo.toml b/rust_crypto_provider/Cargo.toml index 118d37d..9919b02 100644 --- a/rust_crypto_provider/Cargo.toml +++ b/rust_crypto_provider/Cargo.toml @@ -10,7 +10,7 @@ readme = "Readme.md" repository = "https://github.com/franziskuskiefer/hpke-rs" [dependencies] -hpke-rs-crypto = { version = "0.2.0", path = "../traits" } +hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "../traits" } # Rust crypto hkdf = { version = "0.12" } sha2 = { version = "0.10", default-features = false } diff --git a/rust_crypto_provider/src/lib.rs b/rust_crypto_provider/src/lib.rs index afd9245..7c496d5 100644 --- a/rust_crypto_provider/src/lib.rs +++ b/rust_crypto_provider/src/lib.rs @@ -66,7 +66,7 @@ impl HpkeCrypto for HpkeRustCrypto { } } - fn kem_derive(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error> { + fn dh(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error> { match alg { KemAlgorithm::DhKem25519 => { if sk.len() != 32 { @@ -107,7 +107,26 @@ impl HpkeCrypto for HpkeRustCrypto { } } - fn kem_derive_base(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { + fn kem_key_gen_derand(_alg: KemAlgorithm, _seed: &[u8]) -> Result<(Vec, Vec), Error> { + // No ciphersuite uses this. + unimplemented!() + } + + fn kem_encaps( + _alg: KemAlgorithm, + _pk_r: &[u8], + _prng: &mut Self::HpkePrng, + ) -> Result<(Vec, Vec), Error> { + // No ciphersuite uses this. + unimplemented!() + } + + fn kem_decaps(_alg: KemAlgorithm, _ct: &[u8], _sk_r: &[u8]) -> Result, Error> { + // No ciphersuite uses this. + unimplemented!() + } + + fn secret_to_public(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { match alg { KemAlgorithm::DhKem25519 => { if sk.len() != 32 { @@ -126,29 +145,39 @@ impl HpkeCrypto for HpkeRustCrypto { let sk = k256SecretKey::from_slice(sk).map_err(|_| Error::KemInvalidSecretKey)?; Ok(sk.public_key().to_encoded_point(false).as_bytes().into()) } - _ => Err(Error::UnknownKemAlgorithm), + _ => Err(Error::UnsupportedKemOperation), } } - fn kem_key_gen(alg: KemAlgorithm, prng: &mut Self::HpkePrng) -> Result, Error> { + fn kem_key_gen( + alg: KemAlgorithm, + prng: &mut Self::HpkePrng, + ) -> Result<(Vec, Vec), Error> { let rng = &mut prng.rng; match alg { - KemAlgorithm::DhKem25519 => Ok(X25519StaticSecret::random_from_rng(&mut *rng) - .to_bytes() - .to_vec()), - KemAlgorithm::DhKemP256 => Ok(p256SecretKey::random(&mut *rng) - .to_bytes() - .as_slice() - .into()), - KemAlgorithm::DhKemK256 => Ok(k256SecretKey::random(&mut *rng) - .to_bytes() - .as_slice() - .into()), + KemAlgorithm::DhKem25519 => { + let sk = X25519StaticSecret::random_from_rng(&mut *rng); + let pk = X25519PublicKey::from(&sk).as_bytes().to_vec(); + let sk = sk.to_bytes().to_vec(); + Ok((pk, sk)) + } + KemAlgorithm::DhKemP256 => { + let sk = p256SecretKey::random(&mut *rng); + let pk = sk.public_key().to_encoded_point(false).as_bytes().into(); + let sk = sk.to_bytes().as_slice().into(); + Ok((pk, sk)) + } + KemAlgorithm::DhKemK256 => { + let sk = k256SecretKey::random(&mut *rng); + let pk = sk.public_key().to_encoded_point(false).as_bytes().into(); + let sk = sk.to_bytes().as_slice().into(); + Ok((pk, sk)) + } _ => Err(Error::UnknownKemAlgorithm), } } - fn kem_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { + fn dh_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { match alg { KemAlgorithm::DhKemP256 => p256SecretKey::from_slice(sk) .map_err(|_| Error::KemInvalidSecretKey) diff --git a/src/dh_kem.rs b/src/dh_kem.rs index 9586f92..85696b7 100755 --- a/src/dh_kem.rs +++ b/src/dh_kem.rs @@ -41,12 +41,12 @@ pub(super) fn deserialize(enc: &[u8]) -> Vec { enc.to_vec() } +/// Return (private, public) pub(super) fn key_gen( alg: KemAlgorithm, prng: &mut Crypto::HpkePrng, ) -> Result<(Vec, Vec), Error> { - let sk = Crypto::kem_key_gen(alg, prng)?; - let pk = Crypto::kem_derive_base(alg, &sk)?; + let (pk, sk) = Crypto::kem_key_gen(alg, prng)?; Ok((sk, pk)) } @@ -81,7 +81,7 @@ pub(super) fn derive_key_pair( alg.private_key_len(), ); if let Ok(sk) = &candidate { - if let Ok(sk) = Crypto::kem_validate_sk(alg, sk) { + if let Ok(sk) = Crypto::dh_validate_sk(alg, sk) { break sk; } } @@ -98,7 +98,7 @@ pub(super) fn derive_key_pair( panic!("This should be unreachable. Only x25519, P256, and K256 KEMs are implemented") } }; - Ok((Crypto::kem_derive_base(alg, &sk)?, sk)) + Ok((Crypto::secret_to_public(alg, &sk)?, sk)) } pub(super) fn encaps( @@ -109,7 +109,7 @@ pub(super) fn encaps( ) -> Result<(Vec, Vec), Error> { debug_assert_eq!(randomness.len(), alg.private_key_len()); let (pk_e, sk_e) = derive_key_pair::(alg, suite_id, randomness)?; - let dh_pk = Crypto::kem_derive(alg, pk_r, &sk_e)?; + let dh_pk = Crypto::dh(alg, pk_r, &sk_e)?; let enc = serialize(&pk_e); let pk_rm = serialize(pk_r); @@ -126,9 +126,9 @@ pub(super) fn decaps( suite_id: &[u8], ) -> Result, Error> { let pk_e = deserialize(enc); - let dh_pk = Crypto::kem_derive(alg, &pk_e, sk_r)?; + let dh_pk = Crypto::dh(alg, &pk_e, sk_r)?; - let pk_rm = serialize(&Crypto::kem_derive_base(alg, sk_r)?); + let pk_rm = serialize(&Crypto::secret_to_public(alg, sk_r)?); let kem_context = concat(&[enc, &pk_rm]); extract_and_expand::(alg, dh_pk, &kem_context, suite_id) @@ -144,13 +144,13 @@ pub(super) fn auth_encaps( debug_assert_eq!(randomness.len(), alg.private_key_len()); let (pk_e, sk_e) = derive_key_pair::(alg, suite_id, randomness)?; let dh_pk = concat(&[ - &Crypto::kem_derive(alg, pk_r, &sk_e)?, - &Crypto::kem_derive(alg, pk_r, sk_s)?, + &Crypto::dh(alg, pk_r, &sk_e)?, + &Crypto::dh(alg, pk_r, sk_s)?, ]); let enc = serialize(&pk_e); let pk_rm = serialize(pk_r); - let pk_sm = serialize(&Crypto::kem_derive_base(alg, sk_s)?); + let pk_sm = serialize(&Crypto::secret_to_public(alg, sk_s)?); let kem_context = concat(&[&enc, &pk_rm, &pk_sm]); @@ -167,11 +167,11 @@ pub(super) fn auth_decaps( ) -> Result, Error> { let pk_e = deserialize(enc); let dh_pk = concat(&[ - &Crypto::kem_derive(alg, &pk_e, sk_r)?, - &Crypto::kem_derive(alg, pk_s, sk_r)?, + &Crypto::dh(alg, &pk_e, sk_r)?, + &Crypto::dh(alg, pk_s, sk_r)?, ]); - let pk_rm = serialize(&Crypto::kem_derive_base(alg, sk_r)?); + let pk_rm = serialize(&Crypto::secret_to_public(alg, sk_r)?); let pk_sm = serialize(pk_s); let kem_context = concat(&[enc, &pk_rm, &pk_sm]); diff --git a/src/kem.rs b/src/kem.rs index 83db5a1..f3d7ca3 100755 --- a/src/kem.rs +++ b/src/kem.rs @@ -1,9 +1,8 @@ -use alloc::vec::Vec; +use alloc::{vec, vec::Vec}; -use hpke_rs_crypto::{error::Error, types::KemAlgorithm, HpkeCrypto}; +use hpke_rs_crypto::{error::Error, types::KemAlgorithm, HpkeCrypto, RngCore}; -use crate::dh_kem; -use crate::util; +use crate::{dh_kem, util, Hpke}; pub(crate) type PrivateKey = Vec; pub(crate) type PublicKey = Vec; @@ -14,10 +13,10 @@ fn ciphersuite(alg: KemAlgorithm) -> Vec { } pub(crate) fn encaps( - alg: KemAlgorithm, + hpke: &mut Hpke, pk_r: &[u8], - randomness: &[u8], ) -> Result<(Vec, Vec), Error> { + let alg = hpke.kem_id; match alg { KemAlgorithm::DhKemP256 | KemAlgorithm::DhKemK256 @@ -25,8 +24,12 @@ pub(crate) fn encaps( | KemAlgorithm::DhKemP521 | KemAlgorithm::DhKem25519 | KemAlgorithm::DhKem448 => { - dh_kem::encaps::(alg, pk_r, &ciphersuite(alg), randomness) + let randomness = hpke + .random(alg.private_key_len()) + .map_err(|_| Error::InsufficientRandomness)?; + dh_kem::encaps::(alg, pk_r, &ciphersuite(alg), &randomness) } + KemAlgorithm::XWingDraft06 => Crypto::kem_encaps(alg, pk_r, hpke.rng()), } } @@ -42,15 +45,16 @@ pub(crate) fn decaps( | KemAlgorithm::DhKemP521 | KemAlgorithm::DhKem25519 | KemAlgorithm::DhKem448 => dh_kem::decaps::(alg, enc, sk_r, &ciphersuite(alg)), + KemAlgorithm::XWingDraft06 => Crypto::kem_decaps(alg, enc, sk_r), } } pub(crate) fn auth_encaps( - alg: KemAlgorithm, + hpke: &mut Hpke, pk_r: &[u8], sk_s: &[u8], - randomness: &[u8], ) -> Result<(Vec, Vec), Error> { + let alg = hpke.kem_id; match alg { KemAlgorithm::DhKemP256 | KemAlgorithm::DhKemK256 @@ -58,8 +62,12 @@ pub(crate) fn auth_encaps( | KemAlgorithm::DhKemP521 | KemAlgorithm::DhKem25519 | KemAlgorithm::DhKem448 => { - dh_kem::auth_encaps::(alg, pk_r, sk_s, &ciphersuite(alg), randomness) + let randomness = hpke + .random(alg.private_key_len()) + .map_err(|_| Error::InsufficientRandomness)?; + dh_kem::auth_encaps::(alg, pk_r, sk_s, &ciphersuite(alg), &randomness) } + KemAlgorithm::XWingDraft06 => Err(Error::UnsupportedKemOperation), } } @@ -78,20 +86,30 @@ pub(crate) fn auth_decaps( | KemAlgorithm::DhKem448 => { dh_kem::auth_decaps::(alg, enc, sk_r, pk_s, &ciphersuite(alg)) } + KemAlgorithm::XWingDraft06 => Err(Error::UnsupportedKemOperation), } } +/// Returns (private, public) pub(crate) fn key_gen( alg: KemAlgorithm, prng: &mut Crypto::HpkePrng, ) -> Result<(Vec, Vec), Error> { match alg { + // For ECDH based keys, we generate a completely fresh key. KemAlgorithm::DhKemP256 | KemAlgorithm::DhKemK256 | KemAlgorithm::DhKemP384 | KemAlgorithm::DhKemP521 | KemAlgorithm::DhKem25519 | KemAlgorithm::DhKem448 => dh_kem::key_gen::(alg, prng), + KemAlgorithm::XWingDraft06 => { + // For XWing we use the derive key pair function. + let mut seed = vec![0u8; alg.private_key_len()]; + prng.fill_bytes(&mut seed); + let (pk, sk) = derive_key_pair::(alg, &seed)?; + Ok((sk, pk)) + } } } @@ -102,5 +120,17 @@ pub(crate) fn derive_key_pair( alg: KemAlgorithm, ikm: &[u8], ) -> Result<(PublicKey, PrivateKey), Error> { - dh_kem::derive_key_pair::(alg, &ciphersuite(alg), ikm) + match alg { + KemAlgorithm::DhKemP256 + | KemAlgorithm::DhKemK256 + | KemAlgorithm::DhKemP384 + | KemAlgorithm::DhKemP521 + | KemAlgorithm::DhKem25519 + | KemAlgorithm::DhKem448 => dh_kem::derive_key_pair::(alg, &ciphersuite(alg), ikm), + KemAlgorithm::XWingDraft06 => { + let seed = libcrux_sha3::shake256::<32>(ikm); + let kp = Crypto::kem_key_gen_derand(alg, &seed)?; + Ok(kp) + } + } } diff --git a/src/lib.rs b/src/lib.rs index c7a89e2..bb328a6 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,7 @@ use hpke_rs_crypto::{ HpkeCrypto, }; use prelude::kdf::{labeled_expand, labeled_extract}; + #[cfg(not(feature = "hpke-test-prng"))] use rand_core::TryRngCore; @@ -407,17 +408,14 @@ impl Hpke { psk_id: Option<&[u8]>, sk_s: Option<&HpkePrivateKey>, ) -> Result<(EncapsulatedSecret, Context), HpkeError> { - let randomness = self.random(self.kem_id.private_key_len())?; let (zz, enc) = match self.mode { - Mode::Base | Mode::Psk => { - kem::encaps::(self.kem_id, pk_r.value.as_slice(), &randomness)? - } + Mode::Base | Mode::Psk => kem::encaps::(self, pk_r.value.as_slice())?, Mode::Auth | Mode::AuthPsk => { let sk_s = match sk_s { Some(s) => &s.value, None => return Err(HpkeError::InvalidInput), }; - kem::auth_encaps::(self.kem_id, pk_r.value.as_slice(), sk_s, &randomness)? + kem::auth_encaps::(self, pk_r.value.as_slice(), sk_s)? } }; Ok(( @@ -711,6 +709,11 @@ impl Hpke { Ok(out) } + + /// Get the rng. + pub(crate) fn rng(&mut self) -> &mut Crypto::HpkePrng { + &mut self.prng + } } impl HpkeKeyPair { @@ -1000,6 +1003,8 @@ impl From for HpkeError { hpke_rs_crypto::error::Error::InsufficientRandomness => { HpkeError::InsufficientRandomness } + hpke_rs_crypto::error::Error::UnsupportedKemOperation => HpkeError::InvalidConfig, + hpke_rs_crypto::error::Error::KemInvalidCiphertext => HpkeError::InvalidInput, } } } diff --git a/tests/test_hpke.rs b/tests/test_hpke.rs index 64b9485..431f853 100644 --- a/tests/test_hpke.rs +++ b/tests/test_hpke.rs @@ -43,6 +43,7 @@ macro_rules! generate_test_case { ($name:ident, $hpke_mode:expr, $kem_mode:expr, $kdf_mode:expr, $aead_mode:expr, $provider:ident) => { #[test] fn $name() { + let _ = pretty_env_logger::try_init(); let mut hpke = Hpke::<$provider>::new($hpke_mode, $kem_mode, $kdf_mode, $aead_mode); println!("Self test {}", hpke); @@ -297,6 +298,14 @@ generate_test_case!( AeadAlgorithm::ChaCha20Poly1305, HpkeLibcrux ); +generate_test_case!( + base_xwingdraft06_hkdfsha256_chacha20poly1305_libcrux, + HpkeMode::Base, + KemAlgorithm::XWingDraft06, + KdfAlgorithm::HkdfSha256, + AeadAlgorithm::ChaCha20Poly1305, + HpkeLibcrux +); generate_test_case!( base_dhkemp256_hkdfsha384_chacha20poly1305, HpkeMode::Base, diff --git a/traits/Cargo.toml b/traits/Cargo.toml index 42993f6..e1d920e 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hpke-rs-crypto" -version = "0.2.0" +version = "0.3.0-alpha.1" authors = ["Franziskus Kiefer "] edition = "2021" license = "MPL-2.0" diff --git a/traits/src/error.rs b/traits/src/error.rs index 14edd80..0a71317 100644 --- a/traits/src/error.rs +++ b/traits/src/error.rs @@ -20,9 +20,15 @@ pub enum Error { /// Invalid public key for the KEM. KemInvalidPublicKey, + /// Invalid ciphertext for the KEM. + KemInvalidCiphertext, + /// Unknown or unsupported KEM algorithm, UnknownKemAlgorithm, + /// Unsupported operation for KEM algorithm. + UnsupportedKemOperation, + /// Unknown or unsupported AEAD algorithm. UnknownAeadAlgorithm, diff --git a/traits/src/lib.rs b/traits/src/lib.rs index e374e99..4ba7111 100644 --- a/traits/src/lib.rs +++ b/traits/src/lib.rs @@ -60,17 +60,35 @@ pub trait HpkeCrypto: core::fmt::Debug + Send + Sync { output_size: usize, ) -> Result, Error>; - /// KEM Derive - fn kem_derive(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error>; + /// Diffie-Hellman + fn dh(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error>; - /// KEM Derive with base - fn kem_derive_base(alg: KemAlgorithm, sk: &[u8]) -> Result, Error>; + /// Diffie-Hellman with the base (generate public key for secret key `sk`). + fn secret_to_public(alg: KemAlgorithm, sk: &[u8]) -> Result, Error>; - /// KEM secret key generation - fn kem_key_gen(alg: KemAlgorithm, prng: &mut Self::HpkePrng) -> Result, Error>; + /// KEM key pair generation (encapsulation key, decapsulation key). + fn kem_key_gen( + alg: KemAlgorithm, + prng: &mut Self::HpkePrng, + ) -> Result<(Vec, Vec), Error>; + + /// KEM key pair generation (encapsulation key, decapsulation key) based + /// on the `seed`. + fn kem_key_gen_derand(alg: KemAlgorithm, seed: &[u8]) -> Result<(Vec, Vec), Error>; + + /// KEM encapsulation to `pk_r` (shared secret, ciphertext). + fn kem_encaps( + alg: KemAlgorithm, + pk_r: &[u8], + prng: &mut Self::HpkePrng, + ) -> Result<(Vec, Vec), Error>; + + /// KEM decapsulation with `sk_r`. + /// Returns the shared secret. + fn kem_decaps(alg: KemAlgorithm, ct: &[u8], sk_r: &[u8]) -> Result, Error>; /// Validate a secret key for its correctness. - fn kem_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error>; + fn dh_validate_sk(alg: KemAlgorithm, sk: &[u8]) -> Result, Error>; /// AEAD encrypt. fn aead_seal( @@ -127,10 +145,8 @@ pub trait HpkeCrypto: core::fmt::Debug + Send + Sync { } } - /// PRNG extension for testing that is supposed to return pre-configured bytes. pub trait HpkeTestRng { - // Error type to replace rand::Error (which is no longer available as of version 0.9) type Error: core::fmt::Debug + core::fmt::Display; /// Like [`TryRngCore::try_fill_bytes`] but the result is expected to be known. diff --git a/traits/src/types.rs b/traits/src/types.rs index 1ec6175..e960636 100644 --- a/traits/src/types.rs +++ b/traits/src/types.rs @@ -29,6 +29,9 @@ pub enum KemAlgorithm { /// DH KEM on x448 DhKem448 = 0x0021, + + /// X-WING + XWingDraft06 = 0x004D, } impl core::fmt::Display for KemAlgorithm { @@ -47,6 +50,7 @@ impl core::convert::TryFrom for KemAlgorithm { 0x0016 => Ok(KemAlgorithm::DhKemK256), 0x0020 => Ok(KemAlgorithm::DhKem25519), 0x0021 => Ok(KemAlgorithm::DhKem448), + 0x004D => Ok(KemAlgorithm::XWingDraft06), _ => Err(Self::Error::UnknownKemAlgorithm), } } @@ -54,7 +58,7 @@ impl core::convert::TryFrom for KemAlgorithm { impl KemAlgorithm { /// Get the length of the private key for the KEM in bytes. - pub fn private_key_len(&self) -> usize { + pub const fn private_key_len(&self) -> usize { match self { KemAlgorithm::DhKemP256 => 32, KemAlgorithm::DhKemP384 => 48, @@ -62,11 +66,12 @@ impl KemAlgorithm { KemAlgorithm::DhKemK256 => 32, KemAlgorithm::DhKem25519 => 32, KemAlgorithm::DhKem448 => 56, + KemAlgorithm::XWingDraft06 => 32, } } /// Get the length of the shared secret for the KEM in bytes. - pub fn shared_secret_len(&self) -> usize { + pub const fn shared_secret_len(&self) -> usize { match self { KemAlgorithm::DhKemP256 => 32, KemAlgorithm::DhKemP384 => 48, @@ -74,6 +79,7 @@ impl KemAlgorithm { KemAlgorithm::DhKemK256 => 32, KemAlgorithm::DhKem25519 => 32, KemAlgorithm::DhKem448 => 64, + KemAlgorithm::XWingDraft06 => 32, } } } @@ -204,6 +210,7 @@ impl From for KdfAlgorithm { KemAlgorithm::DhKemK256 => KdfAlgorithm::HkdfSha256, KemAlgorithm::DhKem25519 => KdfAlgorithm::HkdfSha256, KemAlgorithm::DhKem448 => KdfAlgorithm::HkdfSha512, + KemAlgorithm::XWingDraft06 => KdfAlgorithm::HkdfSha512, } } } From d9e5fb7d04fce7e6836dcad012568203347debb6 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 12:33:01 +0200 Subject: [PATCH 14/56] generate pk and sk separately in `kem_key_gen()` --- libcrux_provider/src/lib.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 5d89f3e..3ce5ddc 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -97,11 +97,13 @@ impl HpkeCrypto for HpkeLibcrux { alg: KemAlgorithm, prng: &mut Self::HpkePrng, ) -> Result<(Vec, Vec), Error> { - let alg = kem_key_type_to_libcrux_alg(alg)?; + let ecdh_alg = kem_key_type_to_ecdh_alg(alg)?; + let sk = libcrux_ecdh::generate_secret(ecdh_alg, prng) + .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e)))?; - libcrux_kem::key_gen(alg, prng) - .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e))) - .map(|(sk, pk)| (pk.encode(), sk.encode())) + let pk = Self::secret_to_public(alg, &sk)?; + + Ok((pk, sk)) } fn kem_key_gen_derand(alg: KemAlgorithm, seed: &[u8]) -> Result<(Vec, Vec), Error> { From d98e874d7d1d82a8efa70819178714023b536906 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 12:38:06 +0200 Subject: [PATCH 15/56] documentation --- libcrux_provider/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 3ce5ddc..ddef26a 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -93,11 +93,14 @@ impl HpkeCrypto for HpkeLibcrux { }) } + + /// Only works for DH algorithms for now. fn kem_key_gen( alg: KemAlgorithm, prng: &mut Self::HpkePrng, ) -> Result<(Vec, Vec), Error> { let ecdh_alg = kem_key_type_to_ecdh_alg(alg)?; + // Only works for DH now let sk = libcrux_ecdh::generate_secret(ecdh_alg, prng) .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e)))?; From 853a5cd474f884e182497305b33685b66bcb6a02 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 13:41:34 +0200 Subject: [PATCH 16/56] support XWingKemDraft06 in `kem_key_gen()` --- libcrux_provider/src/lib.rs | 45 +++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index ddef26a..3ea347c 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -82,31 +82,30 @@ impl HpkeCrypto for HpkeLibcrux { fn secret_to_public(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { let alg = kem_key_type_to_ecdh_alg(alg)?; - libcrux_ecdh::secret_to_public(alg, sk) - .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive base error: {:?}", e))) - .map(|p| { - if alg == libcrux_ecdh::Algorithm::P256 { - nist_format_uncompressed(p) - } else { - p - } - }) + kem_ecdh_secret_to_public(alg, sk) } - - /// Only works for DH algorithms for now. fn kem_key_gen( alg: KemAlgorithm, prng: &mut Self::HpkePrng, ) -> Result<(Vec, Vec), Error> { - let ecdh_alg = kem_key_type_to_ecdh_alg(alg)?; - // Only works for DH now - let sk = libcrux_ecdh::generate_secret(ecdh_alg, prng) - .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e)))?; + let libcrux_alg = kem_key_type_to_libcrux_alg(alg)?; + + match libcrux_alg { + libcrux_kem::Algorithm::XWingKemDraft06 => libcrux_kem::key_gen(libcrux_alg, prng) + .map(|(sk, pk)| (pk.encode(), sk.encode())) + .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e))), + _ => { + let ecdh_alg = kem_key_type_to_ecdh_alg(alg)?; + let sk = libcrux_ecdh::generate_secret(ecdh_alg, prng).map_err(|e| { + Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e)) + })?; - let pk = Self::secret_to_public(alg, &sk)?; + let pk = kem_ecdh_secret_to_public(ecdh_alg, &sk)?; - Ok((pk, sk)) + Ok((pk, sk)) + } + } } fn kem_key_gen_derand(alg: KemAlgorithm, seed: &[u8]) -> Result<(Vec, Vec), Error> { @@ -261,6 +260,18 @@ impl HpkeCrypto for HpkeLibcrux { } } +fn kem_ecdh_secret_to_public(alg: libcrux_ecdh::Algorithm, sk: &[u8]) -> Result, Error> { + libcrux_ecdh::secret_to_public(alg, sk) + .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive base error: {:?}", e))) + .map(|p| { + if alg == libcrux_ecdh::Algorithm::P256 { + nist_format_uncompressed(p) + } else { + p + } + }) +} + /// Prepend 0x04 for uncompressed NIST curve points. #[inline(always)] fn nist_format_uncompressed(mut pk: Vec) -> Vec { From 401eda01cc6b001fbb46c9dfaf9d32133267e389 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 13:51:39 +0200 Subject: [PATCH 17/56] add error handling --- libcrux_provider/src/lib.rs | 21 ++++++++++++--------- rust_crypto_provider/src/lib.rs | 6 +++--- src/dh_kem.rs | 4 ++-- src/kdf.rs | 2 +- src/lib.rs | 22 ++++++++++++++++------ src/test_kdf.rs | 3 ++- traits/src/lib.rs | 2 +- 7 files changed, 37 insertions(+), 23 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 3ea347c..fc8e4e4 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -26,17 +26,20 @@ impl HpkeCrypto for HpkeLibcrux { "Libcrux".into() } - fn kdf_extract(alg: KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Vec { + fn kdf_extract(alg: KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Result, Error> { // TODO: error handling match alg { KdfAlgorithm::HkdfSha256 => { - libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha256, salt, ikm).unwrap() + libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha256, salt, ikm) + .map_err(|_| todo!()) } KdfAlgorithm::HkdfSha384 => { - libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha384, salt, ikm).unwrap() + libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha384, salt, ikm) + .map_err(|_| todo!()) } KdfAlgorithm::HkdfSha512 => { - libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha512, salt, ikm).unwrap() + libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha512, salt, ikm) + .map_err(|_| todo!()) } } } @@ -48,20 +51,20 @@ impl HpkeCrypto for HpkeLibcrux { output_size: usize, ) -> Result, Error> { // TODO: error handling - Ok(match alg { + match alg { KdfAlgorithm::HkdfSha256 => { libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha256, prk, info, output_size) - .unwrap() + .map_err(|_| todo!()) } KdfAlgorithm::HkdfSha384 => { libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha384, prk, info, output_size) - .unwrap() + .map_err(|_| todo!()) } KdfAlgorithm::HkdfSha512 => { libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha512, prk, info, output_size) - .unwrap() + .map_err(|_| todo!()) } - }) + } } fn dh(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error> { diff --git a/rust_crypto_provider/src/lib.rs b/rust_crypto_provider/src/lib.rs index 7c496d5..c02509e 100644 --- a/rust_crypto_provider/src/lib.rs +++ b/rust_crypto_provider/src/lib.rs @@ -45,12 +45,12 @@ impl HpkeCrypto for HpkeRustCrypto { "RustCrypto".into() } - fn kdf_extract(alg: KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Vec { - match alg { + fn kdf_extract(alg: KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Result, Error> { + Ok(match alg { KdfAlgorithm::HkdfSha256 => sha256_extract(salt, ikm), KdfAlgorithm::HkdfSha384 => sha384_extract(salt, ikm), KdfAlgorithm::HkdfSha512 => sha512_extract(salt, ikm), - } + }) } fn kdf_expand( diff --git a/src/dh_kem.rs b/src/dh_kem.rs index 85696b7..02be098 100755 --- a/src/dh_kem.rs +++ b/src/dh_kem.rs @@ -16,7 +16,7 @@ fn extract_and_expand( kem_context: &[u8], suite_id: &[u8], ) -> Result, Error> { - let prk = labeled_extract::(alg.into(), &[], suite_id, "eae_prk", &pk); + let prk = labeled_extract::(alg.into(), &[], suite_id, "eae_prk", &pk)?; labeled_expand::( alg.into(), &prk, @@ -55,7 +55,7 @@ pub(super) fn derive_key_pair( suite_id: &[u8], ikm: &[u8], ) -> Result<(PublicKey, PrivateKey), Error> { - let dkp_prk = labeled_extract::(alg.into(), &[], suite_id, "dkp_prk", ikm); + let dkp_prk = labeled_extract::(alg.into(), &[], suite_id, "dkp_prk", ikm)?; let sk = match alg { KemAlgorithm::DhKem25519 => labeled_expand::( diff --git a/src/kdf.rs b/src/kdf.rs index d273070..716862a 100755 --- a/src/kdf.rs +++ b/src/kdf.rs @@ -12,7 +12,7 @@ pub(crate) fn labeled_extract( suite_id: &[u8], label: &str, ikm: &[u8], -) -> Vec { +) -> Result, Error> { let labeled_ikm = concat(&[HPKE_VERSION, suite_id, label.as_bytes(), ikm]); Crypto::kdf_extract(alg, salt, &labeled_ikm) } diff --git a/src/lib.rs b/src/lib.rs index bb328a6..3895739 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -617,11 +617,20 @@ impl Hpke { } #[inline] - fn key_schedule_context(&self, info: &[u8], psk_id: &[u8], suite_id: &[u8]) -> Vec { + fn key_schedule_context( + &self, + info: &[u8], + psk_id: &[u8], + suite_id: &[u8], + ) -> Result, HpkeError> { let psk_id_hash = - labeled_extract::(self.kdf_id, &[0], suite_id, "psk_id_hash", psk_id); - let info_hash = labeled_extract::(self.kdf_id, &[0], suite_id, "info_hash", info); - util::concat(&[&[self.mode as u8], &psk_id_hash, &info_hash]) + labeled_extract::(self.kdf_id, &[0], suite_id, "psk_id_hash", psk_id)?; + let info_hash = labeled_extract::(self.kdf_id, &[0], suite_id, "info_hash", info)?; + Ok(util::concat(&[ + &[self.mode as u8], + &psk_id_hash, + &info_hash, + ])) } /// Creating the Encryption Context @@ -635,9 +644,10 @@ impl Hpke { ) -> Result, HpkeError> { self.verify_psk_inputs(psk, psk_id)?; let suite_id = self.ciphersuite(); - let key_schedule_context = self.key_schedule_context(info, psk_id, &suite_id); + let key_schedule_context = self.key_schedule_context(info, psk_id, &suite_id)?; let secret = - labeled_extract::(self.kdf_id, shared_secret, &suite_id, "secret", psk); + labeled_extract::(self.kdf_id, shared_secret, &suite_id, "secret", psk) + .map_err(|e| HpkeError::CryptoError(format!("Crypto error: {}", e)))?; let key = labeled_expand::( self.kdf_id, diff --git a/src/test_kdf.rs b/src/test_kdf.rs index 0768e58..603ec84 100755 --- a/src/test_kdf.rs +++ b/src/test_kdf.rs @@ -17,7 +17,8 @@ fn test_hkdf_sha256() { "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865", ); - let prk = HpkeLibcrux::kdf_extract(KdfAlgorithm::HkdfSha256, &salt, &ikm); + let prk = HpkeLibcrux::kdf_extract(KdfAlgorithm::HkdfSha256, &salt, &ikm) + .expect("Error extracting with HKDF"); let okm = HpkeLibcrux::kdf_expand(KdfAlgorithm::HkdfSha256, &prk, &info, len) .expect("Error expanding with HKDF"); diff --git a/traits/src/lib.rs b/traits/src/lib.rs index 4ba7111..be668c6 100644 --- a/traits/src/lib.rs +++ b/traits/src/lib.rs @@ -50,7 +50,7 @@ pub trait HpkeCrypto: core::fmt::Debug + Send + Sync { } /// KDF Extract - fn kdf_extract(alg: types::KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Vec; + fn kdf_extract(alg: types::KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Result, Error>; /// KDF Expand fn kdf_expand( From fcbadf3798438cca09272d40a5e4be91bb1ff1e0 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 13:57:26 +0200 Subject: [PATCH 18/56] update benchmarks --- libcrux_provider/benches/bench_p256.rs | 9 ++++----- libcrux_provider/benches/bench_x25519.rs | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libcrux_provider/benches/bench_p256.rs b/libcrux_provider/benches/bench_p256.rs index b9ab025..e67961e 100644 --- a/libcrux_provider/benches/bench_p256.rs +++ b/libcrux_provider/benches/bench_p256.rs @@ -6,14 +6,13 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("P256 Derive"), |b| { b.iter_batched( || { - let sk = + let (pk, sk) = HpkeLibcrux::kem_key_gen(KemAlgorithm::DhKemP256, &mut HpkeLibcrux::prng()) .unwrap(); - let pk = HpkeLibcrux::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); (sk.clone(), pk.clone()) }, |(sk, pk)| { - let _ = HpkeLibcrux::kem_derive(KemAlgorithm::DhKemP256, &pk, &sk); + let _ = HpkeLibcrux::dh(KemAlgorithm::DhKemP256, &pk, &sk); }, BatchSize::SmallInput, ) @@ -21,13 +20,13 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("P256 Derive Base"), |b| { b.iter_batched( || { - let sk = + let (_pk, sk) = HpkeLibcrux::kem_key_gen(KemAlgorithm::DhKemP256, &mut HpkeLibcrux::prng()) .unwrap(); sk.clone() }, |sk| { - let _pk = HpkeLibcrux::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); + let _pk = HpkeLibcrux::secret_to_public(KemAlgorithm::DhKemP256, &sk).unwrap(); }, BatchSize::SmallInput, ) diff --git a/libcrux_provider/benches/bench_x25519.rs b/libcrux_provider/benches/bench_x25519.rs index 73b48b3..e94e6f6 100644 --- a/libcrux_provider/benches/bench_x25519.rs +++ b/libcrux_provider/benches/bench_x25519.rs @@ -6,14 +6,13 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("x25519 Derive"), |b| { b.iter_batched( || { - let sk = + let (pk, sk) = HpkeLibcrux::kem_key_gen(KemAlgorithm::DhKem25519, &mut HpkeLibcrux::prng()) .unwrap(); - let pk = HpkeLibcrux::kem_derive_base(KemAlgorithm::DhKem25519, &sk).unwrap(); (sk.clone(), pk.clone()) }, |(sk, pk)| { - let _ = HpkeLibcrux::kem_derive(KemAlgorithm::DhKem25519, &pk, &sk); + let _ = HpkeLibcrux::dh(KemAlgorithm::DhKem25519, &pk, &sk); }, BatchSize::SmallInput, ) @@ -21,13 +20,13 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("x25519 Derive Base"), |b| { b.iter_batched( || { - let sk = + let (_pk, sk) = HpkeLibcrux::kem_key_gen(KemAlgorithm::DhKem25519, &mut HpkeLibcrux::prng()) .unwrap(); sk.clone() }, |sk| { - let _pk = HpkeLibcrux::kem_derive_base(KemAlgorithm::DhKem25519, &sk).unwrap(); + let _pk = HpkeLibcrux::secret_to_public(KemAlgorithm::DhKem25519, &sk).unwrap(); }, BatchSize::SmallInput, ) From 1224350ee7dfb820495a76df47a1904bf91c91cd Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 14:04:28 +0200 Subject: [PATCH 19/56] update benchmarks --- rust_crypto_provider/Cargo.toml | 2 +- rust_crypto_provider/benches/bench_hkdf.rs | 9 ++++----- rust_crypto_provider/benches/bench_k256.rs | 9 ++++----- rust_crypto_provider/benches/bench_p256.rs | 9 ++++----- rust_crypto_provider/benches/bench_x25519.rs | 9 ++++----- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/rust_crypto_provider/Cargo.toml b/rust_crypto_provider/Cargo.toml index 9919b02..cb49dc0 100644 --- a/rust_crypto_provider/Cargo.toml +++ b/rust_crypto_provider/Cargo.toml @@ -35,7 +35,7 @@ rand_chacha = { version = "0.3", default-features = false } [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } -rand = { version = "0.8" } +rand = { version = "0.9" } [features] deterministic-prng = [ diff --git a/rust_crypto_provider/benches/bench_hkdf.rs b/rust_crypto_provider/benches/bench_hkdf.rs index c865191..08b9b4d 100644 --- a/rust_crypto_provider/benches/bench_hkdf.rs +++ b/rust_crypto_provider/benches/bench_hkdf.rs @@ -1,7 +1,6 @@ use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use hpke_rs_crypto::{types::*, HpkeCrypto, RngCore}; use hpke_rs_rust_crypto::*; -use rand::rngs::OsRng; fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("HKDF SHA256 Extract"), |b| { @@ -9,8 +8,8 @@ fn criterion_benchmark(c: &mut Criterion) { || { let mut salt = vec![0u8; 77]; let mut ikm = vec![0u8; 32]; - OsRng.fill_bytes(&mut salt); - OsRng.fill_bytes(&mut ikm); + rand::rng().fill_bytes(&mut salt); + rand::rng().fill_bytes(&mut ikm); (salt.clone(), ikm.clone()) }, |(salt, ikm)| { @@ -24,8 +23,8 @@ fn criterion_benchmark(c: &mut Criterion) { || { let mut info = vec![0u8; 77]; let mut prk = vec![0u8; 32]; - OsRng.fill_bytes(&mut info); - OsRng.fill_bytes(&mut prk); + rand::rng().fill_bytes(&mut info); + rand::rng().fill_bytes(&mut prk); (prk.clone(), info.clone()) }, |(prk, info)| { diff --git a/rust_crypto_provider/benches/bench_k256.rs b/rust_crypto_provider/benches/bench_k256.rs index aaf5b3a..a50917a 100644 --- a/rust_crypto_provider/benches/bench_k256.rs +++ b/rust_crypto_provider/benches/bench_k256.rs @@ -6,16 +6,15 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("K256 Derive"), |b| { b.iter_batched( || { - let sk = HpkeRustCrypto::kem_key_gen( + let (pk, sk) = HpkeRustCrypto::kem_key_gen( KemAlgorithm::DhKemK256, &mut HpkeRustCrypto::prng(), ) .unwrap(); - let pk = HpkeRustCrypto::kem_derive_base(KemAlgorithm::DhKemK256, &sk).unwrap(); (sk.clone(), pk.clone()) }, |(sk, pk)| { - let _ = HpkeRustCrypto::kem_derive(KemAlgorithm::DhKemK256, &pk, &sk); + let _ = HpkeRustCrypto::dh(KemAlgorithm::DhKemK256, &pk, &sk); }, BatchSize::SmallInput, ) @@ -23,7 +22,7 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("K256 Derive Base"), |b| { b.iter_batched( || { - let sk = HpkeRustCrypto::kem_key_gen( + let (_pk, sk) = HpkeRustCrypto::kem_key_gen( KemAlgorithm::DhKemK256, &mut HpkeRustCrypto::prng(), ) @@ -31,7 +30,7 @@ fn criterion_benchmark(c: &mut Criterion) { sk.clone() }, |sk| { - let _pk = HpkeRustCrypto::kem_derive_base(KemAlgorithm::DhKemK256, &sk).unwrap(); + let _pk = HpkeRustCrypto::secret_to_public(KemAlgorithm::DhKemK256, &sk).unwrap(); }, BatchSize::SmallInput, ) diff --git a/rust_crypto_provider/benches/bench_p256.rs b/rust_crypto_provider/benches/bench_p256.rs index 672cfce..7c8c6f4 100644 --- a/rust_crypto_provider/benches/bench_p256.rs +++ b/rust_crypto_provider/benches/bench_p256.rs @@ -6,16 +6,15 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("P256 Derive"), |b| { b.iter_batched( || { - let sk = HpkeRustCrypto::kem_key_gen( + let (pk, sk) = HpkeRustCrypto::kem_key_gen( KemAlgorithm::DhKemP256, &mut HpkeRustCrypto::prng(), ) .unwrap(); - let pk = HpkeRustCrypto::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); (sk.clone(), pk.clone()) }, |(sk, pk)| { - let _ = HpkeRustCrypto::kem_derive(KemAlgorithm::DhKemP256, &pk, &sk); + let _ = HpkeRustCrypto::dh(KemAlgorithm::DhKemP256, &pk, &sk); }, BatchSize::SmallInput, ) @@ -23,7 +22,7 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("P256 Derive Base"), |b| { b.iter_batched( || { - let sk = HpkeRustCrypto::kem_key_gen( + let (_pk, sk) = HpkeRustCrypto::kem_key_gen( KemAlgorithm::DhKemP256, &mut HpkeRustCrypto::prng(), ) @@ -31,7 +30,7 @@ fn criterion_benchmark(c: &mut Criterion) { sk.clone() }, |sk| { - let _pk = HpkeRustCrypto::kem_derive_base(KemAlgorithm::DhKemP256, &sk).unwrap(); + let _pk = HpkeRustCrypto::secret_to_public(KemAlgorithm::DhKemP256, &sk).unwrap(); }, BatchSize::SmallInput, ) diff --git a/rust_crypto_provider/benches/bench_x25519.rs b/rust_crypto_provider/benches/bench_x25519.rs index 7e93e3e..3e7b98b 100644 --- a/rust_crypto_provider/benches/bench_x25519.rs +++ b/rust_crypto_provider/benches/bench_x25519.rs @@ -6,16 +6,15 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("x25519 Derive"), |b| { b.iter_batched( || { - let sk = HpkeRustCrypto::kem_key_gen( + let (pk, sk) = HpkeRustCrypto::kem_key_gen( KemAlgorithm::DhKem25519, &mut HpkeRustCrypto::prng(), ) .unwrap(); - let pk = HpkeRustCrypto::kem_derive_base(KemAlgorithm::DhKem25519, &sk).unwrap(); (sk.clone(), pk.clone()) }, |(sk, pk)| { - let _ = HpkeRustCrypto::kem_derive(KemAlgorithm::DhKem25519, &pk, &sk); + let _ = HpkeRustCrypto::dh(KemAlgorithm::DhKem25519, &pk, &sk); }, BatchSize::SmallInput, ) @@ -23,7 +22,7 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("x25519 Derive Base"), |b| { b.iter_batched( || { - let sk = HpkeRustCrypto::kem_key_gen( + let (_pk, sk) = HpkeRustCrypto::kem_key_gen( KemAlgorithm::DhKem25519, &mut HpkeRustCrypto::prng(), ) @@ -31,7 +30,7 @@ fn criterion_benchmark(c: &mut Criterion) { sk.clone() }, |sk| { - let _pk = HpkeRustCrypto::kem_derive_base(KemAlgorithm::DhKem25519, &sk).unwrap(); + let _pk = HpkeRustCrypto::secret_to_public(KemAlgorithm::DhKem25519, &sk).unwrap(); }, BatchSize::SmallInput, ) From 681e598c5a485cdafaa7e218b096cb1cc895ba0b Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 14:07:01 +0200 Subject: [PATCH 20/56] more concise way to get rng from `rand` in benchmarks --- libcrux_provider/benches/bench_hkdf.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/libcrux_provider/benches/bench_hkdf.rs b/libcrux_provider/benches/bench_hkdf.rs index 83f0621..007d680 100644 --- a/libcrux_provider/benches/bench_hkdf.rs +++ b/libcrux_provider/benches/bench_hkdf.rs @@ -1,21 +1,15 @@ use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use hpke_rs_crypto::{types::*, HpkeCrypto, RngCore}; use hpke_rs_libcrux::*; -use rand::rngs::OsRng; - -use rand::TryRngCore; fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("HKDF SHA256 Extract"), |b| { b.iter_batched( || { - let mut rng = OsRng; - let mut rng_mut = rng.unwrap_mut(); - let mut salt = vec![0u8; 77]; let mut ikm = vec![0u8; 32]; - rng_mut.fill_bytes(&mut salt); - rng_mut.fill_bytes(&mut ikm); + rand::rng().fill_bytes(&mut salt); + rand::rng().fill_bytes(&mut ikm); (salt.clone(), ikm.clone()) }, |(salt, ikm)| { @@ -27,13 +21,10 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function(&format!("HKDF SHA256 Expand"), |b| { b.iter_batched( || { - let mut rng = OsRng; - let mut rng_mut = rng.unwrap_mut(); - let mut info = vec![0u8; 77]; let mut prk = vec![0u8; 32]; - rng_mut.fill_bytes(&mut info); - rng_mut.fill_bytes(&mut prk); + rand::rng().fill_bytes(&mut info); + rand::rng().fill_bytes(&mut prk); (prk.clone(), info.clone()) }, |(prk, info)| { From 293988d707ed2ee908e5bb51cfec74c79cb7a2ff Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 14:10:20 +0200 Subject: [PATCH 21/56] remove debugging statements --- libcrux_provider/src/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index fc8e4e4..e572ea2 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -173,8 +173,6 @@ impl HpkeCrypto for HpkeLibcrux { libcrux_chacha20poly1305::encrypt(key, msg, &mut msg_ctx, aad, iv) .map_err(|_| Error::CryptoLibraryError("Invalid configuration".into()))?; - eprintln!("aead key {:x?}", key); - eprintln!("aead seal {:x?}", msg_ctx); Ok(msg_ctx) } @@ -185,7 +183,6 @@ impl HpkeCrypto for HpkeLibcrux { aad: &[u8], cipher_txt: &[u8], ) -> Result, Error> { - eprintln!("aead open {:x?}", cipher_txt); // only chacha20poly1305 is supported if !matches!(alg, AeadAlgorithm::ChaCha20Poly1305) { return Err(Error::UnknownAeadAlgorithm); @@ -200,8 +197,6 @@ impl HpkeCrypto for HpkeLibcrux { let iv = <&[u8; 12]>::try_from(nonce).map_err(|_| Error::AeadInvalidNonce)?; - eprintln!("aead key {:x?}", key); - // TODO: instead, use key conversion from the libcrux-chacha20poly1305 crate, when available, let key = <&[u8; 32]>::try_from(key).map_err(|_| todo!())?; libcrux_chacha20poly1305::decrypt(key, &mut ptext, cipher_txt, aad, iv).map_err( From a3d706eed437ebb39dfa271adf05e8e36e6374b0 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 14:24:27 +0200 Subject: [PATCH 22/56] wrap sha algorithm conversion --- libcrux_provider/src/lib.rs | 41 ++++++++++++------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index e572ea2..7d0a89b 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -28,20 +28,8 @@ impl HpkeCrypto for HpkeLibcrux { fn kdf_extract(alg: KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Result, Error> { // TODO: error handling - match alg { - KdfAlgorithm::HkdfSha256 => { - libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha256, salt, ikm) - .map_err(|_| todo!()) - } - KdfAlgorithm::HkdfSha384 => { - libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha384, salt, ikm) - .map_err(|_| todo!()) - } - KdfAlgorithm::HkdfSha512 => { - libcrux_hkdf::extract(libcrux_hkdf::Algorithm::Sha512, salt, ikm) - .map_err(|_| todo!()) - } - } + let alg = kdf_algorithm_to_libcrux_hkdf_algorithm(alg); + libcrux_hkdf::extract(alg, salt, ikm).map_err(|_| todo!()) } fn kdf_expand( @@ -51,20 +39,8 @@ impl HpkeCrypto for HpkeLibcrux { output_size: usize, ) -> Result, Error> { // TODO: error handling - match alg { - KdfAlgorithm::HkdfSha256 => { - libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha256, prk, info, output_size) - .map_err(|_| todo!()) - } - KdfAlgorithm::HkdfSha384 => { - libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha384, prk, info, output_size) - .map_err(|_| todo!()) - } - KdfAlgorithm::HkdfSha512 => { - libcrux_hkdf::expand(libcrux_hkdf::Algorithm::Sha512, prk, info, output_size) - .map_err(|_| todo!()) - } - } + let alg = kdf_algorithm_to_libcrux_hkdf_algorithm(alg); + libcrux_hkdf::expand(alg, prk, info, output_size).map_err(|_| todo!()) } fn dh(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error> { @@ -279,6 +255,15 @@ fn nist_format_uncompressed(mut pk: Vec) -> Vec { tmp } +#[inline(always)] +fn kdf_algorithm_to_libcrux_hkdf_algorithm(alg: KdfAlgorithm) -> libcrux_hkdf::Algorithm { + match alg { + KdfAlgorithm::HkdfSha256 => libcrux_hkdf::Algorithm::Sha256, + KdfAlgorithm::HkdfSha384 => libcrux_hkdf::Algorithm::Sha384, + KdfAlgorithm::HkdfSha512 => libcrux_hkdf::Algorithm::Sha512, + } +} + #[inline(always)] fn kem_key_type_to_libcrux_alg(alg: KemAlgorithm) -> Result { match alg { From 07e54d2cbed9023d3afaf1842bfe86e8f22fd4a1 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 14:25:26 +0200 Subject: [PATCH 23/56] error handling --- libcrux_provider/src/lib.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 7d0a89b..b74f8f2 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -27,9 +27,9 @@ impl HpkeCrypto for HpkeLibcrux { } fn kdf_extract(alg: KdfAlgorithm, salt: &[u8], ikm: &[u8]) -> Result, Error> { - // TODO: error handling let alg = kdf_algorithm_to_libcrux_hkdf_algorithm(alg); - libcrux_hkdf::extract(alg, salt, ikm).map_err(|_| todo!()) + libcrux_hkdf::extract(alg, salt, ikm) + .map_err(|e| Error::CryptoLibraryError(format!("KDF extract error: {:?}", e))) } fn kdf_expand( @@ -38,9 +38,9 @@ impl HpkeCrypto for HpkeLibcrux { info: &[u8], output_size: usize, ) -> Result, Error> { - // TODO: error handling let alg = kdf_algorithm_to_libcrux_hkdf_algorithm(alg); - libcrux_hkdf::expand(alg, prk, info, output_size).map_err(|_| todo!()) + libcrux_hkdf::expand(alg, prk, info, output_size) + .map_err(|e| Error::CryptoLibraryError(format!("KDF expand error: {:?}", e))) } fn dh(alg: KemAlgorithm, pk: &[u8], sk: &[u8]) -> Result, Error> { @@ -144,7 +144,9 @@ impl HpkeCrypto for HpkeLibcrux { let iv = <&[u8; 12]>::try_from(nonce).map_err(|_| Error::AeadInvalidNonce)?; // TODO: instead, use key conversion from the libcrux-chacha20poly1305 crate, when available, - let key = <&[u8; 32]>::try_from(key).map_err(|_| todo!())?; + let key = <&[u8; 32]>::try_from(key) + .map_err(|_| Error::CryptoLibraryError("AEAD invalid key length".into()))?; + let mut msg_ctx: Vec = vec![0; msg.len() + 16]; libcrux_chacha20poly1305::encrypt(key, msg, &mut msg_ctx, aad, iv) .map_err(|_| Error::CryptoLibraryError("Invalid configuration".into()))?; @@ -164,7 +166,8 @@ impl HpkeCrypto for HpkeLibcrux { return Err(Error::UnknownAeadAlgorithm); } if cipher_txt.len() < 16 { - return Err(todo!()); + // TODO: is this the correct error type? + return Err(Error::AeadInvalidCiphertext); } let boundary = cipher_txt.len() - 16; @@ -174,7 +177,8 @@ impl HpkeCrypto for HpkeLibcrux { let iv = <&[u8; 12]>::try_from(nonce).map_err(|_| Error::AeadInvalidNonce)?; // TODO: instead, use key conversion from the libcrux-chacha20poly1305 crate, when available, - let key = <&[u8; 32]>::try_from(key).map_err(|_| todo!())?; + let key = <&[u8; 32]>::try_from(key) + .map_err(|_| Error::CryptoLibraryError("AEAD invalid key length".into()))?; libcrux_chacha20poly1305::decrypt(key, &mut ptext, cipher_txt, aad, iv).map_err( |e| match e { libcrux_chacha20poly1305::AeadError::InvalidCiphertext => { From 1b5b33faa23726099f9ba6d9ece141a31ef900c9 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 14:27:32 +0200 Subject: [PATCH 24/56] fix lints --- benches/bench.rs | 26 +++++++++++++------------- benches/manual_benches.rs | 12 ++++++------ src/util.rs | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index a25839e..804869d 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -80,13 +80,13 @@ fn benchmark(c: &mut Criterion) { (None, None) }; - let mut group = c.benchmark_group(format!("{}", label)); + let mut group = c.benchmark_group(label.to_string()); group.bench_function("Setup Sender", |b| { b.iter(|| { let mut hpke = Hpke::::new(hpke_mode, kem_mode, kdf_mode, aead_mode); hpke.setup_sender( - &pk_rm, + pk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -101,7 +101,7 @@ fn benchmark(c: &mut Criterion) { Hpke::::new(hpke_mode, kem_mode, kdf_mode, aead_mode); hpke.setup_receiver( enc, - &sk_rm, + sk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -111,14 +111,14 @@ fn benchmark(c: &mut Criterion) { }) }); - group.bench_function(&format!("Seal {}({})", AEAD_PAYLOAD, AEAD_AAD), |b| { + group.bench_function(format!("Seal {}({})", AEAD_PAYLOAD, AEAD_AAD), |b| { b.iter_batched( || { let mut hpke = Hpke::::new(hpke_mode, kem_mode, kdf_mode, aead_mode); let (_enc, context) = hpke .setup_sender( - &pk_rm, + pk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -137,14 +137,14 @@ fn benchmark(c: &mut Criterion) { BatchSize::SmallInput, ) }); - group.bench_function(&format!("Open {}({})", AEAD_PAYLOAD, AEAD_AAD), |b| { + group.bench_function(format!("Open {}({})", AEAD_PAYLOAD, AEAD_AAD), |b| { b.iter_batched( || { let mut hpke = Hpke::::new(hpke_mode, kem_mode, kdf_mode, aead_mode); let (enc, mut sender_context) = hpke .setup_sender( - &pk_rm, + pk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -160,7 +160,7 @@ fn benchmark(c: &mut Criterion) { let context = hpke .setup_receiver( &enc, - &sk_rm, + sk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -177,7 +177,7 @@ fn benchmark(c: &mut Criterion) { }); group.bench_function( - &format!("Single-Shot Seal {}({})", AEAD_PAYLOAD, AEAD_AAD), + format!("Single-Shot Seal {}({})", AEAD_PAYLOAD, AEAD_AAD), |b| { b.iter_batched( || { @@ -193,7 +193,7 @@ fn benchmark(c: &mut Criterion) { |(mut hpke, aad, ptxt)| { let _ctxt = hpke .seal( - &pk_rm, + pk_rm, &info, &aad, &ptxt, @@ -208,7 +208,7 @@ fn benchmark(c: &mut Criterion) { }, ); group.bench_function( - &format!("Single-Shot Open {}({})", AEAD_PAYLOAD, AEAD_AAD), + format!("Single-Shot Open {}({})", AEAD_PAYLOAD, AEAD_AAD), |b| { b.iter_batched( || { @@ -217,7 +217,7 @@ fn benchmark(c: &mut Criterion) { ); let (enc, mut sender_context) = hpke .setup_sender( - &pk_rm, + pk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -236,7 +236,7 @@ fn benchmark(c: &mut Criterion) { let _ctxt_out = hpke .open( &enc, - &sk_rm, + sk_rm, &info, &aad, &ctxt, diff --git a/benches/manual_benches.rs b/benches/manual_benches.rs index a30fa06..005d486 100644 --- a/benches/manual_benches.rs +++ b/benches/manual_benches.rs @@ -102,7 +102,7 @@ fn benchmark() { Hpke::::new(hpke_mode, kem_mode, kdf_mode, aead_mode); let _sender = hpke .setup_sender( - &pk_rm, + pk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -120,7 +120,7 @@ fn benchmark() { let _receiver = hpke .setup_receiver( enc, - &sk_rm, + sk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -134,7 +134,7 @@ fn benchmark() { let (enc, mut context) = hpke .setup_sender( - &pk_rm, + pk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -164,7 +164,7 @@ fn benchmark() { let mut context = hpke .setup_receiver( &enc, - &sk_rm, + sk_rm, &info, psk.as_ref().map(Vec::as_ref), psk_id.as_ref().map(Vec::as_ref), @@ -199,7 +199,7 @@ fn benchmark() { for _ in 0..ITERATIONS { let (new_enc, new_ctxt) = hpke .seal( - &pk_rm, + pk_rm, &info, &aad, &ptxt, @@ -226,7 +226,7 @@ fn benchmark() { ptxt_out = hpke .open( &enc, - &sk_rm, + sk_rm, &info, &aad, &ctxt, diff --git a/src/util.rs b/src/util.rs index 5302272..919c330 100755 --- a/src/util.rs +++ b/src/util.rs @@ -18,6 +18,6 @@ fn test_concat() { let expected = "blablaRFCXXXX "; assert_eq!( expected.as_bytes()[..], - concat(&[&a.as_bytes(), &b.as_bytes()])[..] + concat(&[a.as_bytes(), b.as_bytes()])[..] ) } From b590d4251149f0ccb26a959d4c110e33d56d5f19 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 14:42:43 +0200 Subject: [PATCH 25/56] only convert enum types when needed --- libcrux_provider/src/lib.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index b74f8f2..dde4e18 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -68,14 +68,15 @@ impl HpkeCrypto for HpkeLibcrux { alg: KemAlgorithm, prng: &mut Self::HpkePrng, ) -> Result<(Vec, Vec), Error> { - let libcrux_alg = kem_key_type_to_libcrux_alg(alg)?; - - match libcrux_alg { - libcrux_kem::Algorithm::XWingKemDraft06 => libcrux_kem::key_gen(libcrux_alg, prng) - .map(|(sk, pk)| (pk.encode(), sk.encode())) - .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e))), - _ => { - let ecdh_alg = kem_key_type_to_ecdh_alg(alg)?; + match alg { + KemAlgorithm::XWingDraft06 => { + libcrux_kem::key_gen(libcrux_kem::Algorithm::XWingKemDraft06, prng) + .map(|(sk, pk)| (pk.encode(), sk.encode())) + .map_err(|e| Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e))) + } + other_alg => { + // ECDH only + let ecdh_alg = kem_key_type_to_ecdh_alg(other_alg)?; let sk = libcrux_ecdh::generate_secret(ecdh_alg, prng).map_err(|e| { Error::CryptoLibraryError(format!("KEM key gen error: {:?}", e)) })?; From 5f225b56e9e6b54ec2e9bd0a947afbf8a7ec12ff Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 14:44:27 +0200 Subject: [PATCH 26/56] inline internal `secret_to_public` function --- libcrux_provider/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index dde4e18..46ac552 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -239,6 +239,7 @@ impl HpkeCrypto for HpkeLibcrux { } } +#[inline(always)] fn kem_ecdh_secret_to_public(alg: libcrux_ecdh::Algorithm, sk: &[u8]) -> Result, Error> { libcrux_ecdh::secret_to_public(alg, sk) .map_err(|e| Error::CryptoLibraryError(format!("ECDH derive base error: {:?}", e))) From f0e0c29bfb0a03d62cd1573514a685167997504d Mon Sep 17 00:00:00 2001 From: wysiwys Date: Mon, 14 Apr 2025 15:14:57 +0200 Subject: [PATCH 27/56] remove `TODO` --- libcrux_provider/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 46ac552..5fe0fe2 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -167,7 +167,6 @@ impl HpkeCrypto for HpkeLibcrux { return Err(Error::UnknownAeadAlgorithm); } if cipher_txt.len() < 16 { - // TODO: is this the correct error type? return Err(Error::AeadInvalidCiphertext); } From 0e632a56198d55606df3d33f1b81f0820282512f Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 10:07:58 +0200 Subject: [PATCH 28/56] feature-gate rand std features --- Cargo.toml | 4 ++-- rust_crypto_provider/Cargo.toml | 3 ++- traits/Cargo.toml | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 21bf9b9..b1de515 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,12 +16,12 @@ serde = { version = "1.0", features = ["derive"], optional = true } tls_codec = { version = "0.4.1-pre.1", features = ["derive"], optional = true } zeroize = { version = "1.5", features = ["zeroize_derive"] } hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "./traits" } -rand_core = { version = "0.9" } +rand_core = { version = "0.9", default-features = false} libcrux-sha3 = { version = "0.0.2" } [features] default = [] -std = [] +std = ["rand_core/std"] serialization = ["serde", "tls_codec", "tls_codec/serde", "std"] hazmat = [] hpke-test = ["std"] diff --git a/rust_crypto_provider/Cargo.toml b/rust_crypto_provider/Cargo.toml index cb49dc0..17c2740 100644 --- a/rust_crypto_provider/Cargo.toml +++ b/rust_crypto_provider/Cargo.toml @@ -30,7 +30,7 @@ chacha20poly1305 = { version = "0.10", default-features = false, features = [ aes-gcm = { version = "0.10", default-features = false, features = ["aes"] } # Randomness rand_core = { version = "0.6", features = ["getrandom"] } -rand_old = { version = "0.8", package = "rand" } +rand_old = { version = "0.8", package = "rand", default-features = false } rand_chacha = { version = "0.3", default-features = false } [dev-dependencies] @@ -38,6 +38,7 @@ criterion = { version = "0.5", features = ["html_reports"] } rand = { version = "0.9" } [features] +std = ["rand_core/std", "rand_old/std"] deterministic-prng = [ "hpke-rs-crypto/std", "rand_core/std", diff --git a/traits/Cargo.toml b/traits/Cargo.toml index e1d920e..b1812b9 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -11,8 +11,8 @@ repository = "https://github.com/franziskuskiefer/hpke-rs" [dependencies] serde = { version = "1.0", features = ["derive"], optional = true } -rand_core = { version = "0.9" } +rand_core = { version = "0.9", default-features = false } [features] serde = ["dep:serde"] -std = [] +std = ["rand_core/std"] From 524cb3ce81d31e3742f37a119dd90d476f45fd47 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 10:10:46 +0200 Subject: [PATCH 29/56] feature-gate hpke-rs-crypto std feature in hpke-rs --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b1de515..34dc408 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,13 +15,13 @@ log = "0.4" serde = { version = "1.0", features = ["derive"], optional = true } tls_codec = { version = "0.4.1-pre.1", features = ["derive"], optional = true } zeroize = { version = "1.5", features = ["zeroize_derive"] } -hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "./traits" } +hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "./traits", default-features = false } rand_core = { version = "0.9", default-features = false} libcrux-sha3 = { version = "0.0.2" } [features] default = [] -std = ["rand_core/std"] +std = ["rand_core/std", "hpke-rs-crypto/std"] serialization = ["serde", "tls_codec", "tls_codec/serde", "std"] hazmat = [] hpke-test = ["std"] From 4d68e4be5b26c3850e7442aba65103befa679cd0 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 10:22:01 +0200 Subject: [PATCH 30/56] remove unused dependency --- libcrux_provider/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index 74ed7ba..6070b1d 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -15,7 +15,6 @@ libcrux-ecdh = { version = "0.0.2" } libcrux-hkdf = { version = "0.0.2" } libcrux-kem = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "franziskus/kem-derand" } libcrux-chacha20poly1305 = { version = "0.0.2" } -libcrux-ed25519 = { version = "0.0.2", features = ["rand"] } # Randomness rand = { version = "0.9" } rand_core = { version = "0.9" } From cacc7fc9a635083ce04c408565d2c9a97592085c Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 10:22:30 +0200 Subject: [PATCH 31/56] replace documentation link --- libcrux_provider/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index 6070b1d..60d24d0 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -4,7 +4,7 @@ version = "0.2.0-alpha.1" authors = ["Franziskus Kiefer "] edition = "2021" license = "MPL-2.0" -documentation = "https://docs.rs/hpke-rs-evercrypt" +documentation = "https://docs.rs/hpke-rs-libcrux" description = "Crypto backend for HPKE using formally verified code from libcrux." readme = "Readme.md" repository = "https://github.com/cryspen/hpke-rs" From 3f5d823086017868c5a338728409a53329e96676 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 11:49:07 +0200 Subject: [PATCH 32/56] remove commented line --- src/test_kdf.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test_kdf.rs b/src/test_kdf.rs index 603ec84..8ae969d 100755 --- a/src/test_kdf.rs +++ b/src/test_kdf.rs @@ -1,5 +1,4 @@ use hpke_rs_crypto::{types::KdfAlgorithm, HpkeCrypto}; -// use hpke_rs_rust_crypto::HpkeRustCrypto; use hpke_rs_libcrux::HpkeLibcrux; use crate::test_util::hex_to_bytes; From 7316f7a875757d979542da1aee0511fac38d7f37 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 13:06:21 +0200 Subject: [PATCH 33/56] update Cargo.toml --- no-std-support-check/Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/no-std-support-check/Cargo.toml b/no-std-support-check/Cargo.toml index 9884d5c..556863e 100644 --- a/no-std-support-check/Cargo.toml +++ b/no-std-support-check/Cargo.toml @@ -8,8 +8,10 @@ version = "0.0.0" hpke-rs = { path = ".." } hpke-rs-crypto = { path = "../traits" } hpke-rs-rust-crypto = { path = "../rust_crypto_provider" } +hpke-rs-libcrux = { path = "../libcrux_provider" } # the no-std-support-check CI job uses the `thumbv7em-none-eabihf` target # `getrandom` does not support that target out of box so this feature needs to be enabled to avoid a compilation error # (normally this feature should NOT be enabled in a library but this crate is just used for a CI check) -getrandom = { version = "0.2.11", features = ["custom"] } +getrandom_old = { package = "getrandom", version = "0.2.11", features=["custom"] } +getrandom = { version = "0.3.2" } From 1ba1d7313fb23bb59e666d790b9863e815b7d6ed Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 13:06:51 +0200 Subject: [PATCH 34/56] enable custom getrandom backend --- no-std-support-check/.cargo/config.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 no-std-support-check/.cargo/config.toml diff --git a/no-std-support-check/.cargo/config.toml b/no-std-support-check/.cargo/config.toml new file mode 100644 index 0000000..3dbe7b8 --- /dev/null +++ b/no-std-support-check/.cargo/config.toml @@ -0,0 +1,3 @@ +# enable custom backend for getrandom +[target.thumbv7em-none-eabihf] +rustflags = ['--cfg', 'getrandom_backend="custom"'] From cd4157b2d8ffd2fc831ab66f6adabdd71357f2f3 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 13:07:35 +0200 Subject: [PATCH 35/56] support no-std in provider --- libcrux_provider/src/lib.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/libcrux_provider/src/lib.rs b/libcrux_provider/src/lib.rs index 5fe0fe2..f745bd7 100644 --- a/libcrux_provider/src/lib.rs +++ b/libcrux_provider/src/lib.rs @@ -1,6 +1,9 @@ #![doc = include_str!("../Readme.md")] +#![cfg_attr(not(test), no_std)] +extern crate alloc; -use std::{fmt::Display, sync::RwLock}; +use alloc::{string::String, vec::Vec, format}; +use core::fmt::Display; use hpke_rs_crypto::{ error::Error, @@ -8,7 +11,7 @@ use hpke_rs_crypto::{ CryptoRng, HpkeCrypto, HpkeTestRng, }; -use rand::SeedableRng; +use rand_core::SeedableRng; /// The Libcrux HPKE Provider #[derive(Debug)] @@ -18,7 +21,7 @@ pub struct HpkeLibcrux {} pub struct HpkeLibcruxPrng { #[cfg(feature = "deterministic-prng")] fake_rng: Vec, - rng: RwLock, + rng: rand_chacha::ChaCha20Rng, } impl HpkeCrypto for HpkeLibcrux { @@ -148,7 +151,7 @@ impl HpkeCrypto for HpkeLibcrux { let key = <&[u8; 32]>::try_from(key) .map_err(|_| Error::CryptoLibraryError("AEAD invalid key length".into()))?; - let mut msg_ctx: Vec = vec![0; msg.len() + 16]; + let mut msg_ctx: Vec = alloc::vec![0; msg.len() + 16]; libcrux_chacha20poly1305::encrypt(key, msg, &mut msg_ctx, aad, iv) .map_err(|_| Error::CryptoLibraryError("Invalid configuration".into()))?; @@ -172,7 +175,7 @@ impl HpkeCrypto for HpkeLibcrux { let boundary = cipher_txt.len() - 16; - let mut ptext = vec![0; boundary]; + let mut ptext = alloc::vec![0; boundary]; let iv = <&[u8; 12]>::try_from(nonce).map_err(|_| Error::AeadInvalidNonce)?; @@ -197,18 +200,18 @@ impl HpkeCrypto for HpkeLibcrux { #[cfg(feature = "deterministic-prng")] { use rand::TryRngCore; - let mut fake_rng = vec![0u8; 256]; + let mut fake_rng = alloc::vec![0u8; 256]; rand_chacha::ChaCha20Rng::from_os_rng() .try_fill_bytes(&mut fake_rng) .unwrap(); HpkeLibcruxPrng { fake_rng, - rng: RwLock::new(rand_chacha::ChaCha20Rng::from_os_rng()), + rng: rand_chacha::ChaCha20Rng::from_os_rng(), } } #[cfg(not(feature = "deterministic-prng"))] HpkeLibcruxPrng { - rng: RwLock::new(rand_chacha::ChaCha20Rng::from_os_rng()), + rng: rand_chacha::ChaCha20Rng::from_os_rng(), } } @@ -290,15 +293,15 @@ fn kem_key_type_to_ecdh_alg(alg: KemAlgorithm) -> Result u32 { - self.rng.write().unwrap().next_u32() + self.rng.next_u32() } fn next_u64(&mut self) -> u64 { - self.rng.write().unwrap().next_u64() + self.rng.next_u64() } fn fill_bytes(&mut self, dest: &mut [u8]) { - self.rng.write().unwrap().fill_bytes(dest) + self.rng.fill_bytes(dest) } } impl CryptoRng for HpkeLibcruxPrng {} @@ -331,7 +334,7 @@ impl HpkeTestRng for HpkeLibcruxPrng { } impl Display for HpkeLibcrux { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", Self::name()) } } From 10877b64c05a1e65b5d6a570c329ff57dd4008fb Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 13:37:15 +0200 Subject: [PATCH 36/56] no-std rand dependencies (mostly) --- libcrux_provider/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index 60d24d0..1172569 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -16,9 +16,9 @@ libcrux-hkdf = { version = "0.0.2" } libcrux-kem = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "franziskus/kem-derand" } libcrux-chacha20poly1305 = { version = "0.0.2" } # Randomness -rand = { version = "0.9" } -rand_core = { version = "0.9" } -rand_chacha = { version = "0.9" } +rand = { version = "0.9", default-features = false } +rand_core = { version = "0.9", features = ["os_rng"] } +rand_chacha = { version = "0.9", default-features = false } [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } From 7f602600f19994f2711130e413be1b6de767f3f0 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 13:37:34 +0200 Subject: [PATCH 37/56] depend on updated libcrux dependencies in new dev branch --- libcrux_provider/Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index 1172569..4b32572 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -11,10 +11,10 @@ repository = "https://github.com/cryspen/hpke-rs" [dependencies] hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "../traits" } -libcrux-ecdh = { version = "0.0.2" } -libcrux-hkdf = { version = "0.0.2" } -libcrux-kem = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "franziskus/kem-derand" } -libcrux-chacha20poly1305 = { version = "0.0.2" } +libcrux-ecdh = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "wysiwys/kem-derand", default-features = false } +libcrux-hkdf = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "wysiwys/kem-derand" } +libcrux-kem = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "wysiwys/kem-derand", default-features = false } +libcrux-chacha20poly1305 = { version = "0.0.2", git = "https://github.com/cryspen/libcrux", branch = "wysiwys/kem-derand" } # Randomness rand = { version = "0.9", default-features = false } rand_core = { version = "0.9", features = ["os_rng"] } From c9219a19c3437c5e3e166d1fc3fef3f2d01ccdc0 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 14:27:55 +0200 Subject: [PATCH 38/56] documentation --- no-std-support-check/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/no-std-support-check/Cargo.toml b/no-std-support-check/Cargo.toml index 556863e..cad38b9 100644 --- a/no-std-support-check/Cargo.toml +++ b/no-std-support-check/Cargo.toml @@ -11,7 +11,10 @@ hpke-rs-rust-crypto = { path = "../rust_crypto_provider" } hpke-rs-libcrux = { path = "../libcrux_provider" } # the no-std-support-check CI job uses the `thumbv7em-none-eabihf` target -# `getrandom` does not support that target out of box so this feature needs to be enabled to avoid a compilation error +# this version of `getrandom`, required by `hpke-rs-rust-crypto`, does not support that target out of box so this feature needs to be enabled to avoid a compilation error # (normally this feature should NOT be enabled in a library but this crate is just used for a CI check) getrandom_old = { package = "getrandom", version = "0.2.11", features=["custom"] } + +# for the newer version of `getrandom`, which is required by `hpke-rs-libcrux`, the `.cargo/config.toml` needs to contain configuration for a custom backend. +# see https://docs.rs/getrandom/latest/getrandom/#custom-backend getrandom = { version = "0.3.2" } From d00245536378cbbe9384080064c407c68059ddaf Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 15:15:01 +0200 Subject: [PATCH 39/56] update repo links in `Cargo.toml` files --- Cargo.toml | 2 +- rust_crypto_provider/Cargo.toml | 2 +- traits/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 34dc408..0f24aeb 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ license = "MPL-2.0" documentation = "https://docs.rs/hpke-rs" description = "HPKE Implementation" readme = "Readme.md" -repository = "https://github.com/franziskuskiefer/hpke-rs" +repository = "https://github.com/cryspen/hpke-rs" exclude = ["/tests"] [dependencies] diff --git a/rust_crypto_provider/Cargo.toml b/rust_crypto_provider/Cargo.toml index 17c2740..e6ff908 100644 --- a/rust_crypto_provider/Cargo.toml +++ b/rust_crypto_provider/Cargo.toml @@ -7,7 +7,7 @@ license = "MPL-2.0" documentation = "https://docs.rs/hpke-rs-rust-crypto" description = "Crypto backend for HPKE using native Rust crypto." readme = "Readme.md" -repository = "https://github.com/franziskuskiefer/hpke-rs" +repository = "https://github.com/cryspen/hpke-rs" [dependencies] hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "../traits" } diff --git a/traits/Cargo.toml b/traits/Cargo.toml index b1812b9..3be26e2 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -7,7 +7,7 @@ license = "MPL-2.0" documentation = "https://docs.rs/hpke-rs-crypto" description = "Traits and types for HPKE crypto backends" readme = "Readme.md" -repository = "https://github.com/franziskuskiefer/hpke-rs" +repository = "https://github.com/cryspen/hpke-rs" [dependencies] serde = { version = "1.0", features = ["derive"], optional = true } From 323f152d5cb6b9d0c04fd14a6fe507ae45e1d6a2 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Tue, 15 Apr 2025 15:29:18 +0200 Subject: [PATCH 40/56] replace references to evercrypt --- .gitignore | 2 +- Readme.md | 2 +- libcrux_provider/Readme.md | 16 ++++++++-------- publish.sh | 4 ++-- tests/test_hpke_kat.rs | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 2c39f9c..2c828cb 100755 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ Cargo.lock **/*.rs.bk .vscode/ -evercrypt_provider/target +libcrux_provider/target no-std-support-check/target rust_crypto_provider/target traits/target/ diff --git a/Readme.md b/Readme.md index 02c322f..d5e833c 100644 --- a/Readme.md +++ b/Readme.md @@ -50,7 +50,7 @@ Instead it expects an implementation of the [HpkeCrypto] trait. [crate-link]: https://crates.io/crates/hpke-rs [docs-badge]: https://img.shields.io/badge/docs-rs-blue.svg?style=for-the-badge [docs-link]: https://docs.rs/hpke-rs -[evercrypt]: https://github.com/franziskuskiefer/evercrypt-rust +[libcrux]: https://github.com/cryspen/libcrux [hpke (RFC 9180)]: https://www.rfc-editor.org/rfc/rfc9180.html [hpkecrypto]: https://docs.rs/hpke-rs-crypto [rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg?style=for-the-badge diff --git a/libcrux_provider/Readme.md b/libcrux_provider/Readme.md index 0010c4e..4eefce2 100644 --- a/libcrux_provider/Readme.md +++ b/libcrux_provider/Readme.md @@ -1,18 +1,18 @@ -# HPKE Crypto provider using Evercrypt +# HPKE Crypto provider using Libcrux [![crates.io][crate-badge]][crate-link] [![Docs][docs-badge]][docs-link] ![Rust Version][rustc-image] -This crate provides an implementation of the [HpkeCrypto] trait using [Evercrypt]. +This crate provides an implementation of the [HpkeCrypto] trait using [Libcrux]. Please see [hpke-rs] for more details. -[evercrypt]: https://crates.io/crates/evercrypt -[hpkecrypto]: https://github.com/franziskuskiefer/hpke-rs/tree/main/traits +[libcrux]: https://crates.io/crates/libcrux +[hpkecrypto]: https://github.com/cryspen/hpke-rs/tree/main/traits [rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg?style=for-the-badge [docs-badge]: https://img.shields.io/badge/docs-rs-blue.svg?style=for-the-badge -[docs-link]: https://docs.rs/hpke-rs-evercrypt -[crate-badge]: https://img.shields.io/crates/v/hpke-rs-evercrypt.svg?style=for-the-badge -[crate-link]: https://crates.io/crates/hpke-rs-evercrypt -[hpke-rs]: https://github.com/franziskuskiefer/hpke-rs +[docs-link]: https://docs.rs/hpke-rs-libcrux +[crate-badge]: https://img.shields.io/crates/v/hpke-rs-libcrux.svg?style=for-the-badge +[crate-link]: https://crates.io/crates/hpke-rs-libcrux +[hpke-rs]: https://github.com/cryspen/hpke-rs diff --git a/publish.sh b/publish.sh index f517c50..f0ab133 100755 --- a/publish.sh +++ b/publish.sh @@ -6,8 +6,8 @@ set -e # "hpke-rs-crypto cd traits && cargo publish $@ && cd - -# hpke-rs-evercrypt -# cd evercrypt_provider && cargo publish $@ && cd - +# hpke-rs-libcrux +cd libcrux_provider && cargo publish $@ && cd - # hpke-rs-rust-crypto cd rust_crypto_provider && cargo publish $@ && cd - diff --git a/tests/test_hpke_kat.rs b/tests/test_hpke_kat.rs index 33ef6d2..f959c0e 100755 --- a/tests/test_hpke_kat.rs +++ b/tests/test_hpke_kat.rs @@ -297,7 +297,7 @@ fn test_kat() { let now = Instant::now(); kat::(tests); let time = now.elapsed(); - log::info!("Test vectors with Evercrypt took: {}s", time.as_secs()); + log::info!("Test vectors with Libcrux took: {}s", time.as_secs()); } } From 9f571f0bdc464278d9bb5ff93a16e2d6ec2e67ba Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 08:49:52 +0200 Subject: [PATCH 41/56] remove executable permission on files --- Cargo.toml | 0 src/dh_kem.rs | 0 src/kdf.rs | 0 src/kem.rs | 0 src/lib.rs | 0 src/test_kdf.rs | 0 src/util.rs | 0 tests/test_hpke_kat.rs | 0 8 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Cargo.toml mode change 100755 => 100644 src/dh_kem.rs mode change 100755 => 100644 src/kdf.rs mode change 100755 => 100644 src/kem.rs mode change 100755 => 100644 src/lib.rs mode change 100755 => 100644 src/test_kdf.rs mode change 100755 => 100644 src/util.rs mode change 100755 => 100644 tests/test_hpke_kat.rs diff --git a/Cargo.toml b/Cargo.toml old mode 100755 new mode 100644 diff --git a/src/dh_kem.rs b/src/dh_kem.rs old mode 100755 new mode 100644 diff --git a/src/kdf.rs b/src/kdf.rs old mode 100755 new mode 100644 diff --git a/src/kem.rs b/src/kem.rs old mode 100755 new mode 100644 diff --git a/src/lib.rs b/src/lib.rs old mode 100755 new mode 100644 diff --git a/src/test_kdf.rs b/src/test_kdf.rs old mode 100755 new mode 100644 diff --git a/src/util.rs b/src/util.rs old mode 100755 new mode 100644 diff --git a/tests/test_hpke_kat.rs b/tests/test_hpke_kat.rs old mode 100755 new mode 100644 From a838a0a5c06a714e118a724d389fb5769eefd3ee Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 08:59:06 +0200 Subject: [PATCH 42/56] test that libcrux provider does not support these algorithms --- src/test_aead.rs | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/test_aead.rs b/src/test_aead.rs index f375c70..4e2cd53 100644 --- a/src/test_aead.rs +++ b/src/test_aead.rs @@ -1,20 +1,27 @@ -// use hpke_rs_crypto::{types::AeadAlgorithm, HpkeCrypto}; -// use hpke_rs_rust_crypto::HpkeRustCrypto; +use hpke_rs_crypto::{types::AeadAlgorithm, HpkeCrypto}; +use hpke_rs_libcrux::HpkeLibcrux; +use hpke_rs_rust_crypto::HpkeRustCrypto; -// #[test] -// fn test_aes_gcm_128_self() { -// let key = [ -// 0x5b, 0x96, 0x04, 0xfe, 0x14, 0xea, 0xdb, 0xa9, 0x31, 0xb0, 0xcc, 0xf3, 0x48, 0x43, 0xda, -// 0xb9, -// ]; -// let nonce = [ -// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, -// ]; -// let aad = [0x03, 0x04, 0x05]; -// let msg = b"test message"; -// let ctxt = -// HpkeRustCrypto::aead_seal(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, msg).unwrap(); -// let ptxt = -// HpkeRustCrypto::aead_open(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, &ctxt).unwrap(); -// assert_eq!(&ptxt, msg); -// } +#[test] +fn test_aes_gcm_128_self() { + let key = [ + 0x5b, 0x96, 0x04, 0xfe, 0x14, 0xea, 0xdb, 0xa9, 0x31, 0xb0, 0xcc, 0xf3, 0x48, 0x43, 0xda, + 0xb9, + ]; + let nonce = [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + ]; + let aad = [0x03, 0x04, 0x05]; + let msg = b"test message"; + let ctxt = + HpkeRustCrypto::aead_seal(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, msg).unwrap(); + let ptxt = + HpkeRustCrypto::aead_open(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, &ctxt).unwrap(); + assert_eq!(&ptxt, msg); + + // assert error on Libcrux provider + HpkeLibcrux::aead_seal(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, msg) + .expect_err("Unsupported algorithm"); + HpkeLibcrux::aead_open(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, &ctxt) + .expect_err("Unsupported algorithm"); +} From 6e2c5d6c64d7c2865a9a3b612701eb569fded05a Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 09:01:27 +0200 Subject: [PATCH 43/56] add chacha20poly1305 test --- src/test_aead.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/test_aead.rs b/src/test_aead.rs index 4e2cd53..62868b4 100644 --- a/src/test_aead.rs +++ b/src/test_aead.rs @@ -13,6 +13,8 @@ fn test_aes_gcm_128_self() { ]; let aad = [0x03, 0x04, 0x05]; let msg = b"test message"; + + // test rust crypto provider let ctxt = HpkeRustCrypto::aead_seal(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, msg).unwrap(); let ptxt = @@ -25,3 +27,32 @@ fn test_aes_gcm_128_self() { HpkeLibcrux::aead_open(AeadAlgorithm::Aes128Gcm, &key, &nonce, &aad, &ctxt) .expect_err("Unsupported algorithm"); } + +#[test] +fn test_chacha20poly1305_self() { + let key = [ + 0x5b, 0x96, 0x04, 0xfe, 0x14, 0xea, 0xdb, 0xa9, 0x31, 0xb0, 0xcc, 0xf3, 0x48, 0x43, 0xda, + 0xb9, 0x5b, 0x96, 0x04, 0xfe, 0x14, 0xea, 0xdb, 0xa9, 0x31, 0xb0, 0xcc, 0xf3, 0x48, 0x43, + 0xda, 0xb9, + ]; + let nonce = [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + ]; + let aad = [0x03, 0x04, 0x05]; + let msg = b"test message"; + + // test rust crypto provider + let ctxt = HpkeRustCrypto::aead_seal(AeadAlgorithm::ChaCha20Poly1305, &key, &nonce, &aad, msg) + .unwrap(); + let ptxt = + HpkeRustCrypto::aead_open(AeadAlgorithm::ChaCha20Poly1305, &key, &nonce, &aad, &ctxt) + .unwrap(); + assert_eq!(&ptxt, msg); + + // test libcrux provider + let ctxt = + HpkeLibcrux::aead_seal(AeadAlgorithm::ChaCha20Poly1305, &key, &nonce, &aad, msg).unwrap(); + let ptxt = + HpkeLibcrux::aead_open(AeadAlgorithm::ChaCha20Poly1305, &key, &nonce, &aad, &ctxt).unwrap(); + assert_eq!(&ptxt, msg); +} From 3a174471a35931cb008573eeafcffc646892c070 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 09:23:59 +0200 Subject: [PATCH 44/56] add std feature to libcrux provider --- libcrux_provider/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index 4b32572..4f35507 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -25,6 +25,7 @@ criterion = { version = "0.5", features = ["html_reports"] } [features] deterministic-prng = [] # ⚠️ FOR TESTING ONLY. +std = ["rand/std", "rand_chacha/std", "libcrux-ecdh/std", "libcrux-kem/std", "hpke-rs-crypto/std"] [[bench]] name = "bench_hkdf" From 897dadb3f68171484fc29289a30fe97b7783a638 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 14:24:43 +0200 Subject: [PATCH 45/56] depend on `main` branch of libcrux --- libcrux_provider/Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcrux_provider/Cargo.toml b/libcrux_provider/Cargo.toml index 4f35507..173cdc4 100644 --- a/libcrux_provider/Cargo.toml +++ b/libcrux_provider/Cargo.toml @@ -11,10 +11,10 @@ repository = "https://github.com/cryspen/hpke-rs" [dependencies] hpke-rs-crypto = { version = "0.3.0-alpha.1", path = "../traits" } -libcrux-ecdh = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "wysiwys/kem-derand", default-features = false } -libcrux-hkdf = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "wysiwys/kem-derand" } -libcrux-kem = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "wysiwys/kem-derand", default-features = false } -libcrux-chacha20poly1305 = { version = "0.0.2", git = "https://github.com/cryspen/libcrux", branch = "wysiwys/kem-derand" } +libcrux-ecdh = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "main", default-features = false } +libcrux-hkdf = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "main" } +libcrux-kem = { version = "0.0.3-alpha.1", git = "https://github.com/cryspen/libcrux", branch = "main", default-features = false } +libcrux-chacha20poly1305 = { version = "0.0.2", git = "https://github.com/cryspen/libcrux", branch = "main" } # Randomness rand = { version = "0.9", default-features = false } rand_core = { version = "0.9", features = ["os_rng"] } From 3f5df73d7eb6deec315bb5290262cc50d06efa85 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:07:49 +0200 Subject: [PATCH 46/56] fix permissions on `.gitignore` --- .gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 .gitignore diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 From 77295cd84b4a15af38ebc177d99ed82319c8ca81 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:08:08 +0200 Subject: [PATCH 47/56] error handling --- rust_crypto_provider/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust_crypto_provider/src/lib.rs b/rust_crypto_provider/src/lib.rs index c02509e..587651c 100644 --- a/rust_crypto_provider/src/lib.rs +++ b/rust_crypto_provider/src/lib.rs @@ -109,7 +109,7 @@ impl HpkeCrypto for HpkeRustCrypto { fn kem_key_gen_derand(_alg: KemAlgorithm, _seed: &[u8]) -> Result<(Vec, Vec), Error> { // No ciphersuite uses this. - unimplemented!() + return Err(Error::UnsupportedKemOperation); } fn kem_encaps( @@ -118,12 +118,12 @@ impl HpkeCrypto for HpkeRustCrypto { _prng: &mut Self::HpkePrng, ) -> Result<(Vec, Vec), Error> { // No ciphersuite uses this. - unimplemented!() + return Err(Error::UnsupportedKemOperation); } fn kem_decaps(_alg: KemAlgorithm, _ct: &[u8], _sk_r: &[u8]) -> Result, Error> { // No ciphersuite uses this. - unimplemented!() + return Err(Error::UnsupportedKemOperation); } fn secret_to_public(alg: KemAlgorithm, sk: &[u8]) -> Result, Error> { From 75c93ae7a8a868e211c6bd227144238119b91dbb Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:17:54 +0200 Subject: [PATCH 48/56] update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7859e33..f6b484a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.2.1] - Unreleased +- [#72](https://github.com/cryspen/hpke-rs/pull/72): + - add support for X-Wing KEM + - upgrade rand dependency from 0.8 -> 0.9 + - replace Evercrypt provider with Libcrux provider + - redesign `HpkeCrypto` trait to support X-Wing as well as ecdh-based KEM algorithms - [#66](https://github.com/franziskuskiefer/hpke-rs/pull/66): add support for secp256k1 curve. This adds `DhKemK256 = 0x0016` to the `KemAlgorithms` ## [0.2.0] - 2023-12-01 From 4ad195f91650651c16c63531a99e555355a58a99 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:27:12 +0200 Subject: [PATCH 49/56] clarify text --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6b484a..67188f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - add support for X-Wing KEM - upgrade rand dependency from 0.8 -> 0.9 - replace Evercrypt provider with Libcrux provider - - redesign `HpkeCrypto` trait to support X-Wing as well as ecdh-based KEM algorithms + - redesign `HpkeCrypto` trait to support X-Wing - [#66](https://github.com/franziskuskiefer/hpke-rs/pull/66): add support for secp256k1 curve. This adds `DhKemK256 = 0x0016` to the `KemAlgorithms` ## [0.2.0] - 2023-12-01 From 57d091787dd249d6f35219f0febe8cc03bab9cdb Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:35:57 +0200 Subject: [PATCH 50/56] update version and changelog --- rust_crypto_provider/CHANGELOG.md | 3 +++ rust_crypto_provider/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/rust_crypto_provider/CHANGELOG.md b/rust_crypto_provider/CHANGELOG.md index 50d53b2..a627a73 100644 --- a/rust_crypto_provider/CHANGELOG.md +++ b/rust_crypto_provider/CHANGELOG.md @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.1] - Unreleased +- [#72](https://github.com/cryspen/hpke-rs/pull/72): use new hpke-rs-crypto trait API + ## [0.2.0] - 2023-12-01 - [#59](https://github.com/franziskuskiefer/hpke-rs/pull/59): hpke-rs-rust-crypto: make deterministic-prng enable the std feature diff --git a/rust_crypto_provider/Cargo.toml b/rust_crypto_provider/Cargo.toml index e6ff908..439ca56 100644 --- a/rust_crypto_provider/Cargo.toml +++ b/rust_crypto_provider/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hpke-rs-rust-crypto" -version = "0.2.0" +version = "0.2.1-alpha.1" authors = ["Franziskus Kiefer "] edition = "2021" license = "MPL-2.0" From 8fa0bb86bf17d0882d870e3a7b73c40197079be2 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:37:09 +0200 Subject: [PATCH 51/56] minor version --- rust_crypto_provider/CHANGELOG.md | 2 +- rust_crypto_provider/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust_crypto_provider/CHANGELOG.md b/rust_crypto_provider/CHANGELOG.md index a627a73..a3fba77 100644 --- a/rust_crypto_provider/CHANGELOG.md +++ b/rust_crypto_provider/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1] - Unreleased +## [0.3.0] - Unreleased - [#72](https://github.com/cryspen/hpke-rs/pull/72): use new hpke-rs-crypto trait API ## [0.2.0] - 2023-12-01 diff --git a/rust_crypto_provider/Cargo.toml b/rust_crypto_provider/Cargo.toml index 439ca56..98c36c0 100644 --- a/rust_crypto_provider/Cargo.toml +++ b/rust_crypto_provider/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hpke-rs-rust-crypto" -version = "0.2.1-alpha.1" +version = "0.3.0-alpha.1" authors = ["Franziskus Kiefer "] edition = "2021" license = "MPL-2.0" From 2d1e833e7076d7347ea3684dfbc922cf5184696d Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:41:06 +0200 Subject: [PATCH 52/56] more changelog updates --- CHANGELOG.md | 1 - rust_crypto_provider/CHANGELOG.md | 4 +++- traits/CHANGELOG.md | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67188f7..c64d5d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - add support for X-Wing KEM - upgrade rand dependency from 0.8 -> 0.9 - replace Evercrypt provider with Libcrux provider - - redesign `HpkeCrypto` trait to support X-Wing - [#66](https://github.com/franziskuskiefer/hpke-rs/pull/66): add support for secp256k1 curve. This adds `DhKemK256 = 0x0016` to the `KemAlgorithms` ## [0.2.0] - 2023-12-01 diff --git a/rust_crypto_provider/CHANGELOG.md b/rust_crypto_provider/CHANGELOG.md index a3fba77..b1cccba 100644 --- a/rust_crypto_provider/CHANGELOG.md +++ b/rust_crypto_provider/CHANGELOG.md @@ -6,7 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.3.0] - Unreleased -- [#72](https://github.com/cryspen/hpke-rs/pull/72): use new hpke-rs-crypto trait API +- [#72](https://github.com/cryspen/hpke-rs/pull/72): + - use new hpke-rs-crypto trait API + - upgrade rand dependency from 0.8 -> 0.9 ## [0.2.0] - 2023-12-01 diff --git a/traits/CHANGELOG.md b/traits/CHANGELOG.md index 51c0a4c..2a58cfd 100644 --- a/traits/CHANGELOG.md +++ b/traits/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0] - Unreleased +- [#72](https://github.com/cryspen/hpke-rs/pull/72): + - redesign `HpkeCrypto` trait to support X-Wing KEM + - upgrade rand dependency from 0.8 -> 0.9 + ## [0.2.0] - 2023-12-01 - [#53](https://github.com/franziskuskiefer/hpke-rs/pull/53): rm getrandom dep From d575b2bbe5bc8a915d0d63f39624c00baefb8333 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:45:52 +0200 Subject: [PATCH 53/56] update version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 0f24aeb..277c1e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ serde = { version = "1.0", features = ["derive"] } lazy_static = "1.4" rayon = "1.5" hpke-rs = { path = ".", features = ["hpke-test", "hazmat"] } -hpke-rs-rust-crypto = { version = "0.2.0", path = "./rust_crypto_provider", features = [ +hpke-rs-rust-crypto = { version = "0.3.0-alpha.1", path = "./rust_crypto_provider", features = [ "deterministic-prng", ] } hpke-rs-libcrux = { version = "0.2.0-alpha.1", path = "./libcrux_provider", features = [ From 5d93351f7bc9c7c3dea926f00ef1e52cc334c6a2 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:49:00 +0200 Subject: [PATCH 54/56] reset changelog for new crate --- libcrux_provider/CHANGELOG.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libcrux_provider/CHANGELOG.md b/libcrux_provider/CHANGELOG.md index 449b591..eb77875 100644 --- a/libcrux_provider/CHANGELOG.md +++ b/libcrux_provider/CHANGELOG.md @@ -4,12 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.1.3] - 2023-03-04 - -### Changed -- [#37](https://github.com/franziskuskiefer/hpke-rs/pull/37): correct error type for aead_type_to_mode - -## 0.1.2 (2022-02-24) +## 0.1.0 - Unreleased * initial release From 6c9ae940b39e26c3ec691f153906c8d556ad5c3b Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 16:54:48 +0200 Subject: [PATCH 55/56] formatting --- rust_crypto_provider/CHANGELOG.md | 1 + traits/CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/rust_crypto_provider/CHANGELOG.md b/rust_crypto_provider/CHANGELOG.md index b1cccba..44671fe 100644 --- a/rust_crypto_provider/CHANGELOG.md +++ b/rust_crypto_provider/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.3.0] - Unreleased + - [#72](https://github.com/cryspen/hpke-rs/pull/72): - use new hpke-rs-crypto trait API - upgrade rand dependency from 0.8 -> 0.9 diff --git a/traits/CHANGELOG.md b/traits/CHANGELOG.md index 2a58cfd..c978599 100644 --- a/traits/CHANGELOG.md +++ b/traits/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.3.0] - Unreleased + - [#72](https://github.com/cryspen/hpke-rs/pull/72): - redesign `HpkeCrypto` trait to support X-Wing KEM - upgrade rand dependency from 0.8 -> 0.9 From 7688297e81712d76ca152c877fd9df10da4249b3 Mon Sep 17 00:00:00 2001 From: wysiwys Date: Wed, 16 Apr 2025 17:01:18 +0200 Subject: [PATCH 56/56] remove unimplemented item --- rust_crypto_provider/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/rust_crypto_provider/CHANGELOG.md b/rust_crypto_provider/CHANGELOG.md index 44671fe..1db13b6 100644 --- a/rust_crypto_provider/CHANGELOG.md +++ b/rust_crypto_provider/CHANGELOG.md @@ -9,7 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#72](https://github.com/cryspen/hpke-rs/pull/72): - use new hpke-rs-crypto trait API - - upgrade rand dependency from 0.8 -> 0.9 ## [0.2.0] - 2023-12-01