From d70fab56b8c744e3489ffb34a945f70ee265e3fc Mon Sep 17 00:00:00 2001 From: UneBaguette <28904802+UneBaguette@users.noreply.github.com> Date: Sun, 28 Jun 2026 11:51:02 +0200 Subject: [PATCH] chore: bump to 0.7.0-pre.0, new ciphersuite impl --- CHANGELOG.md | 3 +- Cargo.toml | 2 +- src/ciphersuite.rs | 21 ++++++++ src/lib.rs | 14 ++---- src/oprf.rs | 32 ++++++------ src/poprf.rs | 32 ++++++------ src/serialization.rs | 6 +-- src/tests/mod.rs | 18 ------- src/tests/test_cfrg_vectors.rs | 92 +++++++++++++++++----------------- src/voprf.rs | 44 ++++++++-------- 10 files changed, 130 insertions(+), 134 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77faa66..3c0a095 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Changelog -## 0.6.0-rc.0 (June 27, 2026) +## 0.7.0-pre.0 (June 28, 2026) * MSRV bumped to 1.87 +* `CipherSuite` no longer has a blanket impl via `VoprfParameters`; use `Suite` instead (breaking change) * Migrated from `elliptic-curve 0.13` to `0.14` * Replaced `generic-array` with `hybrid-array` * Updated `digest` dependency to 0.11 diff --git a/Cargo.toml b/Cargo.toml index 0e48c82..64b0169 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ name = "voprf-vexahub" readme = "README.md" repository = "https://github.com/facebook/voprf/" rust-version = "1.87" -version = "0.6.0-rc.0" +version = "0.7.0-pre.0" [features] alloc = [] diff --git a/src/ciphersuite.rs b/src/ciphersuite.rs index afb5466..d0eb7ef 100644 --- a/src/ciphersuite.rs +++ b/src/ciphersuite.rs @@ -13,6 +13,7 @@ use core::ops::Mul; use digest::block_api::BlockSizeUser; use digest::typenum::{IsLess, IsLessOrEqual, U256}; use digest::{Digest, FixedOutput, HashMarker, OutputSizeUser}; +use hash2curve::OprfParameters; use hybrid_array::ArraySize; use hybrid_array::typenum::{IsGreaterOrEqual, Prod, True, U2}; @@ -37,3 +38,23 @@ where /// transcripts). type Hash: Digest + BlockSizeUser + Default + FixedOutput + HashMarker; } + +/// A generic [`CipherSuite`] implementation for any compatible (Group, Hash) pair +#[allow(dead_code)] +#[derive(Debug)] +pub struct Suite(core::marker::PhantomData<(G, H)>); + +impl CipherSuite for Suite +where + G: Group + OprfParameters, + H: BlockSizeUser + Default + FixedOutput + HashMarker + OutputSizeUser, + ::SecurityLevel: Mul, + ::OutputSize: ArraySize + + IsLess + + IsLessOrEqual<::BlockSize, Output = True> + + IsGreaterOrEqual::SecurityLevel, U2>, Output = True>, +{ + const ID: &'static [u8] = G::ID; + type Group = G; + type Hash = H; +} diff --git a/src/lib.rs b/src/lib.rs index 3ab7ca1..29d232a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -566,21 +566,13 @@ mod voprf; #[cfg(test)] mod tests; +/// A [`CipherSuite`] using P-256 and SHA-256, exposed for doctests. #[cfg(feature = "doctest")] -#[derive(Debug)] -#[doc(hidden)] -pub struct P256CipherSuite; - -#[cfg(feature = "doctest")] -impl CipherSuite for P256CipherSuite { - const ID: &'static [u8] = b"P256-SHA256"; - type Group = p256::NistP256; - type Hash = sha2::Sha256; -} +pub type P256CipherSuite = Suite; // Exports -pub use crate::ciphersuite::CipherSuite; +pub use crate::ciphersuite::{CipherSuite, Suite}; #[cfg(feature = "danger")] pub use crate::common::derive_key; pub use crate::common::{ diff --git a/src/oprf.rs b/src/oprf.rs index 488c93b..0a072c4 100644 --- a/src/oprf.rs +++ b/src/oprf.rs @@ -271,8 +271,8 @@ mod tests { use rand::rngs::SysRng; use super::*; - use crate::Group; use crate::common::{Dst, STR_HASH_TO_GROUP}; + use crate::{Group, Suite}; fn prf( input: &[u8], @@ -393,26 +393,26 @@ mod tests { zeroize_oprf_server::(); } - base_retrieval::(); - base_inversion_unsalted::(); - server_evaluate::(); + base_retrieval::>(); + base_inversion_unsalted::>(); + server_evaluate::>(); - zeroize_oprf_client::(); - zeroize_oprf_server::(); + zeroize_oprf_client::>(); + zeroize_oprf_server::>(); - base_retrieval::(); - base_inversion_unsalted::(); - server_evaluate::(); + base_retrieval::>(); + base_inversion_unsalted::>(); + server_evaluate::>(); - zeroize_oprf_client::(); - zeroize_oprf_server::(); + zeroize_oprf_client::>(); + zeroize_oprf_server::>(); - base_retrieval::(); - base_inversion_unsalted::(); - server_evaluate::(); + base_retrieval::>(); + base_inversion_unsalted::>(); + server_evaluate::>(); - zeroize_oprf_client::(); - zeroize_oprf_server::(); + zeroize_oprf_client::>(); + zeroize_oprf_server::>(); Ok(()) } diff --git a/src/poprf.rs b/src/poprf.rs index 7f12169..9f926fb 100644 --- a/src/poprf.rs +++ b/src/poprf.rs @@ -736,8 +736,8 @@ mod tests { use rand::rngs::SysRng; use super::*; - use crate::Group; use crate::common::STR_HASH_TO_GROUP; + use crate::{Group, Suite}; fn prf( input: &[u8], @@ -895,26 +895,26 @@ mod tests { zeroize_verifiable_server::(); } - verifiable_retrieval::(); - verifiable_bad_public_key::(); - verifiable_server_evaluate::(); + verifiable_retrieval::>(); + verifiable_bad_public_key::>(); + verifiable_server_evaluate::>(); - zeroize_verifiable_client::(); - zeroize_verifiable_server::(); + zeroize_verifiable_client::>(); + zeroize_verifiable_server::>(); - verifiable_retrieval::(); - verifiable_bad_public_key::(); - verifiable_server_evaluate::(); + verifiable_retrieval::>(); + verifiable_bad_public_key::>(); + verifiable_server_evaluate::>(); - zeroize_verifiable_client::(); - zeroize_verifiable_server::(); + zeroize_verifiable_client::>(); + zeroize_verifiable_server::>(); - verifiable_retrieval::(); - verifiable_bad_public_key::(); - verifiable_server_evaluate::(); + verifiable_retrieval::>(); + verifiable_bad_public_key::>(); + verifiable_server_evaluate::>(); - zeroize_verifiable_client::(); - zeroize_verifiable_server::(); + zeroize_verifiable_client::>(); + zeroize_verifiable_server::>(); Ok(()) } diff --git a/src/serialization.rs b/src/serialization.rs index ecaa8d6..167d024 100644 --- a/src/serialization.rs +++ b/src/serialization.rs @@ -328,9 +328,9 @@ mod test { let _ = $item::::deserialize(&$bytes[..]); } - let _ = $item::::deserialize(&$bytes[..]); - let _ = $item::::deserialize(&$bytes[..]); - let _ = $item::::deserialize(&$bytes[..]); + let _ = $item::>::deserialize(&$bytes[..]); + let _ = $item::>::deserialize(&$bytes[..]); + let _ = $item::>::deserialize(&$bytes[..]); }; } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 2208070..71e7089 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -10,21 +10,3 @@ mod cfrg_vectors; mod mock_rng; mod parser; mod test_cfrg_vectors; - -impl crate::CipherSuite for p256::NistP256 { - const ID: &'static [u8] = ::ID; - type Group = p256::NistP256; - type Hash = sha2::Sha256; -} - -impl crate::CipherSuite for p384::NistP384 { - const ID: &'static [u8] = ::ID; - type Group = p384::NistP384; - type Hash = sha2::Sha384; -} - -impl crate::CipherSuite for p521::NistP521 { - const ID: &'static [u8] = ::ID; - type Group = p521::NistP521; - type Hash = sha2::Sha512; -} diff --git a/src/tests/test_cfrg_vectors.rs b/src/tests/test_cfrg_vectors.rs index 99c96aa..bb7cd58 100644 --- a/src/tests/test_cfrg_vectors.rs +++ b/src/tests/test_cfrg_vectors.rs @@ -17,7 +17,7 @@ use crate::tests::parser::*; use crate::{ BlindedElement, CipherSuite, EvaluationElement, Group, OprfClient, OprfServer, PoprfClient, PoprfServer, PoprfServerBatchEvaluateFinishResult, PoprfServerBatchEvaluatePrepareResult, - Proof, Result, VoprfClient, VoprfServer, VoprfServerBatchEvaluateFinishResult, + Proof, Result, Suite, VoprfClient, VoprfServer, VoprfServerBatchEvaluateFinishResult, }; #[derive(Debug)] @@ -133,83 +133,83 @@ fn test_vectors() -> Result<()> { let p256_oprf_tvs = json_to_test_vectors!(rfc, String::from("P256-SHA256"), String::from("OPRF")); assert_ne!(p256_oprf_tvs.len(), 0); - test_oprf_seed_to_key::(&p256_oprf_tvs)?; - test_oprf_blind::(&p256_oprf_tvs)?; - test_oprf_blind_evaluate::(&p256_oprf_tvs)?; - test_oprf_finalize::(&p256_oprf_tvs)?; - test_oprf_evaluate::(&p256_oprf_tvs)?; + test_oprf_seed_to_key::>(&p256_oprf_tvs)?; + test_oprf_blind::>(&p256_oprf_tvs)?; + test_oprf_blind_evaluate::>(&p256_oprf_tvs)?; + test_oprf_finalize::>(&p256_oprf_tvs)?; + test_oprf_evaluate::>(&p256_oprf_tvs)?; let p256_voprf_tvs = json_to_test_vectors!(rfc, String::from("P256-SHA256"), String::from("VOPRF")); assert_ne!(p256_voprf_tvs.len(), 0); - test_voprf_seed_to_key::(&p256_voprf_tvs)?; - test_voprf_blind::(&p256_voprf_tvs)?; - test_voprf_blind_evaluate::(&p256_voprf_tvs)?; - test_voprf_finalize::(&p256_voprf_tvs)?; - test_voprf_evaluate::(&p256_voprf_tvs)?; + test_voprf_seed_to_key::>(&p256_voprf_tvs)?; + test_voprf_blind::>(&p256_voprf_tvs)?; + test_voprf_blind_evaluate::>(&p256_voprf_tvs)?; + test_voprf_finalize::>(&p256_voprf_tvs)?; + test_voprf_evaluate::>(&p256_voprf_tvs)?; let p256_poprf_tvs = json_to_test_vectors!(rfc, String::from("P256-SHA256"), String::from("POPRF")); assert_ne!(p256_poprf_tvs.len(), 0); - test_poprf_seed_to_key::(&p256_poprf_tvs)?; - test_poprf_blind::(&p256_poprf_tvs)?; - test_poprf_blind_evaluate::(&p256_poprf_tvs)?; - test_poprf_finalize::(&p256_poprf_tvs)?; - test_poprf_evaluate::(&p256_poprf_tvs)?; + test_poprf_seed_to_key::>(&p256_poprf_tvs)?; + test_poprf_blind::>(&p256_poprf_tvs)?; + test_poprf_blind_evaluate::>(&p256_poprf_tvs)?; + test_poprf_finalize::>(&p256_poprf_tvs)?; + test_poprf_evaluate::>(&p256_poprf_tvs)?; let p384_oprf_tvs = json_to_test_vectors!(rfc, String::from("P384-SHA384"), String::from("OPRF")); assert_ne!(p384_oprf_tvs.len(), 0); - test_oprf_seed_to_key::(&p384_oprf_tvs)?; - test_oprf_blind::(&p384_oprf_tvs)?; - test_oprf_blind_evaluate::(&p384_oprf_tvs)?; - test_oprf_finalize::(&p384_oprf_tvs)?; - test_oprf_evaluate::(&p384_oprf_tvs)?; + test_oprf_seed_to_key::>(&p384_oprf_tvs)?; + test_oprf_blind::>(&p384_oprf_tvs)?; + test_oprf_blind_evaluate::>(&p384_oprf_tvs)?; + test_oprf_finalize::>(&p384_oprf_tvs)?; + test_oprf_evaluate::>(&p384_oprf_tvs)?; let p384_voprf_tvs = json_to_test_vectors!(rfc, String::from("P384-SHA384"), String::from("VOPRF")); assert_ne!(p384_voprf_tvs.len(), 0); - test_voprf_seed_to_key::(&p384_voprf_tvs)?; - test_voprf_blind::(&p384_voprf_tvs)?; - test_voprf_blind_evaluate::(&p384_voprf_tvs)?; - test_voprf_finalize::(&p384_voprf_tvs)?; - test_voprf_evaluate::(&p384_voprf_tvs)?; + test_voprf_seed_to_key::>(&p384_voprf_tvs)?; + test_voprf_blind::>(&p384_voprf_tvs)?; + test_voprf_blind_evaluate::>(&p384_voprf_tvs)?; + test_voprf_finalize::>(&p384_voprf_tvs)?; + test_voprf_evaluate::>(&p384_voprf_tvs)?; let p384_poprf_tvs = json_to_test_vectors!(rfc, String::from("P384-SHA384"), String::from("POPRF")); assert_ne!(p384_poprf_tvs.len(), 0); - test_poprf_seed_to_key::(&p384_poprf_tvs)?; - test_poprf_blind::(&p384_poprf_tvs)?; - test_poprf_blind_evaluate::(&p384_poprf_tvs)?; - test_poprf_finalize::(&p384_poprf_tvs)?; - test_poprf_evaluate::(&p384_poprf_tvs)?; + test_poprf_seed_to_key::>(&p384_poprf_tvs)?; + test_poprf_blind::>(&p384_poprf_tvs)?; + test_poprf_blind_evaluate::>(&p384_poprf_tvs)?; + test_poprf_finalize::>(&p384_poprf_tvs)?; + test_poprf_evaluate::>(&p384_poprf_tvs)?; let p521_oprf_tvs = json_to_test_vectors!(rfc, String::from("P521-SHA512"), String::from("OPRF")); assert_ne!(p521_oprf_tvs.len(), 0); - test_oprf_seed_to_key::(&p521_oprf_tvs)?; - test_oprf_blind::(&p521_oprf_tvs)?; - test_oprf_blind_evaluate::(&p521_oprf_tvs)?; - test_oprf_finalize::(&p521_oprf_tvs)?; - test_oprf_evaluate::(&p521_oprf_tvs)?; + test_oprf_seed_to_key::>(&p521_oprf_tvs)?; + test_oprf_blind::>(&p521_oprf_tvs)?; + test_oprf_blind_evaluate::>(&p521_oprf_tvs)?; + test_oprf_finalize::>(&p521_oprf_tvs)?; + test_oprf_evaluate::>(&p521_oprf_tvs)?; let p521_voprf_tvs = json_to_test_vectors!(rfc, String::from("P521-SHA512"), String::from("VOPRF")); assert_ne!(p521_voprf_tvs.len(), 0); - test_voprf_seed_to_key::(&p521_voprf_tvs)?; - test_voprf_blind::(&p521_voprf_tvs)?; - test_voprf_blind_evaluate::(&p521_voprf_tvs)?; - test_voprf_finalize::(&p521_voprf_tvs)?; - test_voprf_evaluate::(&p521_voprf_tvs)?; + test_voprf_seed_to_key::>(&p521_voprf_tvs)?; + test_voprf_blind::>(&p521_voprf_tvs)?; + test_voprf_blind_evaluate::>(&p521_voprf_tvs)?; + test_voprf_finalize::>(&p521_voprf_tvs)?; + test_voprf_evaluate::>(&p521_voprf_tvs)?; let p521_poprf_tvs = json_to_test_vectors!(rfc, String::from("P521-SHA512"), String::from("POPRF")); assert_ne!(p521_poprf_tvs.len(), 0); - test_poprf_seed_to_key::(&p521_poprf_tvs)?; - test_poprf_blind::(&p521_poprf_tvs)?; - test_poprf_blind_evaluate::(&p521_poprf_tvs)?; - test_poprf_finalize::(&p521_poprf_tvs)?; - test_poprf_evaluate::(&p521_poprf_tvs)?; + test_poprf_seed_to_key::>(&p521_poprf_tvs)?; + test_poprf_blind::>(&p521_poprf_tvs)?; + test_poprf_blind_evaluate::>(&p521_poprf_tvs)?; + test_poprf_finalize::>(&p521_poprf_tvs)?; + test_poprf_evaluate::>(&p521_poprf_tvs)?; Ok(()) } diff --git a/src/voprf.rs b/src/voprf.rs index ebf43fd..3e46ac1 100644 --- a/src/voprf.rs +++ b/src/voprf.rs @@ -553,8 +553,8 @@ mod tests { use rand::rngs::SysRng; use super::*; - use crate::Group; use crate::common::{Dst, STR_HASH_TO_GROUP}; + use crate::{Group, Suite}; fn prf( input: &[u8], @@ -774,32 +774,32 @@ mod tests { zeroize_voprf_server::(); } - verifiable_retrieval::(); - verifiable_batch_retrieval::(); - verifiable_bad_public_key::(); - verifiable_batch_bad_public_key::(); - verifiable_server_evaluate::(); + verifiable_retrieval::>(); + verifiable_batch_retrieval::>(); + verifiable_bad_public_key::>(); + verifiable_batch_bad_public_key::>(); + verifiable_server_evaluate::>(); - zeroize_voprf_client::(); - zeroize_voprf_server::(); + zeroize_voprf_client::>(); + zeroize_voprf_server::>(); - verifiable_retrieval::(); - verifiable_batch_retrieval::(); - verifiable_bad_public_key::(); - verifiable_batch_bad_public_key::(); - verifiable_server_evaluate::(); + verifiable_retrieval::>(); + verifiable_batch_retrieval::>(); + verifiable_bad_public_key::>(); + verifiable_batch_bad_public_key::>(); + verifiable_server_evaluate::>(); - zeroize_voprf_client::(); - zeroize_voprf_server::(); + zeroize_voprf_client::>(); + zeroize_voprf_server::>(); - verifiable_retrieval::(); - verifiable_batch_retrieval::(); - verifiable_bad_public_key::(); - verifiable_batch_bad_public_key::(); - verifiable_server_evaluate::(); + verifiable_retrieval::>(); + verifiable_batch_retrieval::>(); + verifiable_bad_public_key::>(); + verifiable_batch_bad_public_key::>(); + verifiable_server_evaluate::>(); - zeroize_voprf_client::(); - zeroize_voprf_server::(); + zeroize_voprf_client::>(); + zeroize_voprf_server::>(); Ok(()) }