chore: bump to 1.0.0-pre.0, new name voprf-vx, replace OprfCipherSuite trait with OprfHash type alias #4

Merged
breakingbread merged 3 commits from chore/few-changes-whtevr into master 2026-06-29 11:32:18 +02:00
9 changed files with 86 additions and 88 deletions
+24 -10
View File
@@ -1,20 +1,24 @@
# Changelog
## 0.7.0-pre.0 (June 28, 2026)
## 1.0.0-pre.0 (June 29, 2026)
Forked from [facebook/voprf](https://github.com/facebook/voprf/) at `0.6.0-pre.1`.
* MSRV bumped to 1.87
* Migrated from `elliptic-curve 0.13` to `0.14`
* Replaced `generic-array` with `hybrid-array`
* Updated `digest` dependency to 0.11
* Updated `rand_core` dependency to 0.10
* Updated `rand` dependency to 0.10
* Updated `sha2` dependency to 0.11
* Updated `p256`, `p384`, `p521` dependencies to 0.14.0-rc
* Replaced `generic-array` with `hybrid-array 0.4`
* Updated `digest` to 0.11, `rand_core` to 0.10, `rand` to 0.10, `sha2` to 0.11
* Updated `p256`, `p384`, `p521` to `0.14`
* Replaced `elliptic-curve/hash2curve` feature with standalone `hash2curve 0.14` crate
* Updated `hash_to_scalar` to use `MapToCurve::Length` as OKM length per RFC 9380, replacing the removed `GroupDigest::hash_to_scalar` method
* Updated `random_scalar` to consume exactly `ScalarLen` bytes per attempt, adapting to the new `rand_core 0.10` API
* Added `OkmLen` associated type to `Group` trait
* Removed `VoprfParameters` dependency to be replaced with `OprfParameters` + `GroupDigest`
* Added `SecurityLevel` associated type to `Group` trait for generic hash bounds
* Added `OkmLen` associated type to `Group` trait (`MapToCurve::Length`)
* Updated `hash_to_scalar` to use `MapToCurve::Length` as OKM length per RFC 9380
* Updated `random_scalar` for deterministic byte consumption with `rand_core 0.10`
* Auto-impl `CipherSuite` for any `OprfParameters + Group` type via `OprfHash<T>`
## 0.6.0-pre.1 (April 6, 2026)
* MSRV bumped to 1.85
* Updated rand_core dependency to 0.9
* Updated rand dependency to 0.9
@@ -22,40 +26,50 @@
* Fixed docs issue
## 0.6.0-pre.0 (November 8, 2025)
* MSRV bumped to 1.83
* Updated Ristretto255 random scalar generation
* Updated generic-array to v1
## 0.5.0 (March 6, 2024)
* Just a version bump from v0.5.0-pre.7
## 0.5.0-pre.7 (January 11, 2024)
* Updated to be in sync with RFC 9497
## 0.5.0-pre.6 (July 24, 2023)
* Updated curve25519-dalek dependency to 4
## 0.5.0-pre.5 (June 27, 2023)
* Updated curve25519-dalek dependency to 4.0.0-rc.3
## 0.5.0-pre.4 (May 20, 2023)
* Updated curve25519-dalek dependency to 4.0.0-rc.2
## 0.5.0-pre.3 (March 4, 2023)
* Updated to be in sync with draft-irtf-cfrg-voprf-19
* Increased MSRV to 1.65
* Updated p256 dependency to v0.13
* Added p384 tests
## 0.5.0-pre.2 (February 3, 2023)
* Increased MSRV to 1.60
* Updated p256 dependency to v0.12
* Updated curve25519-dalek dependency to 4.0.0-rc.1
## 0.5.0-pre.1 (December 19, 2022)
* Updated curve25519-dalek dependency to 4.0.0-pre.5
## 0.4.0 (September 15, 2022)
* Updated to be in sync with draft-irtf-cfrg-voprf-11, with
the addition of the POPRF mode
* Adds the evaluate() function to the servers to calculate the output of the OPRF
+1 -1
View File
@@ -7,6 +7,6 @@ We use GitHub issues to track public bugs. Please ensure your description is
clear and has sufficient instructions to be able to reproduce the issue.
## License
By contributing to voprf, you agree that your contributions will be
By contributing to voprf-vx, you agree that your contributions will be
licensed under both the LICENSE-MIT and LICENSE-APACHE files in the root
directory of this source tree.
+5 -5
View File
@@ -1,15 +1,15 @@
[package]
authors = ["Kevin Lewi <[email protected]>"]
authors = ["VexaHub Developers", "Kevin Lewi <[email protected]>"]
categories = ["no-std", "algorithms", "cryptography"]
description = "An implementation of a verifiable oblivious pseudorandom function (VOPRF)"
edition = "2024"
keywords = ["oprf"]
keywords = ["oprf", "voprf", "cryptography", "oblivious-prf"]
license = "MIT"
name = "voprf-vexahub"
name = "voprf-vx"
readme = "README.md"
repository = "https://github.com/facebook/voprf/"
repository = "https://github.com/vexahub/voprf-vx/"
rust-version = "1.87"
version = "0.7.0-pre.0"
version = "1.0.0-pre.0"
[features]
alloc = []
+5 -3
View File
@@ -8,7 +8,7 @@ This implementation is based on [RFC 9497](https://www.rfc-editor.org/rfc/rfc949
Documentation
-------------
The API can be found [here](https://docs.rs/voprf-vexahub/) along with an example for usage.
The API can be found [here](https://docs.rs/voprf-vx/) along with an example for usage.
Installation
------------
@@ -16,7 +16,7 @@ Installation
Add the following line to the dependencies of your `Cargo.toml`:
```
voprf = { package = "voprf-vexahub", version = "0.6.0-rc.0" }
voprf = { package = "voprf-vx", version = "1.0.0-pre.0" }
```
### Minimum Supported Rust Version
@@ -26,7 +26,9 @@ Rust **1.87** or higher.
Contributors
------------
The author of this code is Kevin Lewi ([@kevinlewi](https://github.com/kevinlewi)).
This is a fork of [facebook/voprf](https://github.com/facebook/voprf/) maintained by [VexaHub](https://github.com/vexahub).
The original author is Kevin Lewi ([@kevinlewi](https://github.com/kevinlewi)).
To learn more about contributing to this project, [see this document](./CONTRIBUTING.md).
License
+11 -21
View File
@@ -12,8 +12,8 @@ use crate::Group;
use core::ops::Mul;
use digest::block_api::BlockSizeUser;
use digest::typenum::{IsLess, IsLessOrEqual, U256};
use digest::{Digest, FixedOutput, HashMarker, OutputSizeUser};
use hash2curve::{ExpandMsg, GroupDigest, OprfParameters};
use digest::{FixedOutput, HashMarker, OutputSizeUser};
use hash2curve::{ExpandMsg, GroupDigest, MapToCurve, OprfParameters};
use hybrid_array::ArraySize;
use hybrid_array::typenum::{IsGreaterOrEqual, Prod, True, U2};
@@ -36,34 +36,24 @@ where
/// The main hash function to use (for HKDF computations and hashing
/// transcripts).
type Hash: Digest + BlockSizeUser + Default + FixedOutput + HashMarker;
type Hash: BlockSizeUser + Default + FixedOutput + HashMarker;
}
/// Trait associating a hash to an elliptic curve for OPRF usage.
pub trait OprfCipherSuite: OprfParameters + Group {
type Hash: Digest + BlockSizeUser + Default + FixedOutput + HashMarker + OutputSizeUser;
}
/// The hash function associated with a curve's OPRF `expand_message` implementation.
type OprfHash<T> =
<<T as GroupDigest>::ExpandMsg as ExpandMsg<<T as MapToCurve>::SecurityLevel>>::Hash;
impl<T> OprfCipherSuite for T
where
T: OprfParameters + Group,
<T as GroupDigest>::ExpandMsg: ExpandMsg<<T as Group>::SecurityLevel>,
<<T as GroupDigest>::ExpandMsg as ExpandMsg<<T as Group>::SecurityLevel>>::Hash:
Digest + BlockSizeUser + Default + FixedOutput + HashMarker + OutputSizeUser,
{
type Hash = <<T as GroupDigest>::ExpandMsg as ExpandMsg<<T as Group>::SecurityLevel>>::Hash;
}
impl<T: OprfCipherSuite> CipherSuite for T
impl<T: OprfParameters> CipherSuite for T
where
T: Group,
<T as Group>::SecurityLevel: Mul<U2>,
<<T as OprfCipherSuite>::Hash as OutputSizeUser>::OutputSize: ArraySize
OprfHash<T>: BlockSizeUser + Default + FixedOutput + HashMarker,
<OprfHash<T> as OutputSizeUser>::OutputSize: ArraySize
+ IsLess<U256>
+ IsLessOrEqual<<<T as OprfCipherSuite>::Hash as BlockSizeUser>::BlockSize, Output = True>
+ IsLessOrEqual<<OprfHash<T> as BlockSizeUser>::BlockSize, Output = True>
+ IsGreaterOrEqual<Prod<<T as Group>::SecurityLevel, U2>, Output = True>,
{
const ID: &'static [u8] = T::ID;
type Group = T;
type Hash = <T as OprfCipherSuite>::Hash;
type Hash = OprfHash<T>;
}
+1 -4
View File
@@ -29,7 +29,7 @@ type ScalarLen<C> = FieldBytesSize<C>;
impl<C> Group for C
where
C: GroupDigest + MapToCurve,
C: GroupDigest,
C::SecurityLevel: Mul<U2>,
C::SecurityLevel: ArraySize,
<C::SecurityLevel as Mul<U2>>::Output: ArraySize,
@@ -37,7 +37,6 @@ where
ScalarLen<Self>: ModulusSize,
ScalarLen<Self>: ArraySize,
ScalarLen<Self>: hybrid_array::typenum::NonZero,
Scalar<Self>: elliptic_curve::ops::Reduce<Array<u8, ScalarLen<Self>>>,
Scalar<Self>: elliptic_curve::ops::Reduce<Array<u8, <C as MapToCurve>::Length>>,
AffinePoint<Self>: FromSec1Point<Self> + ToSec1Point<Self>,
// `VoprfClientLen`, `PoprfClientLen`, `VoprfServerLen`, `PoprfServerLen`
@@ -58,8 +57,6 @@ where
type SecurityLevel = C::SecurityLevel;
type OkmLen = <C as MapToCurve>::Length;
// Implements the `hash_to_curve()` function from
// https://www.rfc-editor.org/rfc/rfc9380.html#section-3
fn hash_to_curve<H>(input: &[&[u8]], dst: &[&[u8]]) -> Result<Self::Elem, InternalError> {
-3
View File
@@ -66,9 +66,6 @@ where
/// `expand_message` requirement `len_in_bytes = 2 * k / 8`.
type SecurityLevel: ArraySize;
/// The OKM length for hash_to_scalar (>= ScalarLen, used by hash_to_field).
type OkmLen: ArraySize + hybrid_array::typenum::NonZero;
/// Transforms a password and domain separation tag (DST) into a curve point
///
/// # Errors
+1 -3
View File
@@ -17,7 +17,7 @@ use digest::{FixedOutput, HashMarker};
use hash2curve::{ExpandMsg, ExpandMsgXmd, Expander};
use hybrid_array::Array;
use hybrid_array::typenum::{
IsGreaterOrEqual, IsLess, IsLessOrEqual, Prod, True, U2, U16, U32, U64, U256,
IsGreaterOrEqual, IsLess, IsLessOrEqual, Prod, True, U2, U16, U32, U256,
};
use rand_core::{TryCryptoRng, TryRng};
use subtle::ConstantTimeEq;
@@ -49,8 +49,6 @@ impl Group for Ristretto255 {
type SecurityLevel = U16;
type OkmLen = U64;
// Implements the `hash_to_ristretto255()` function from
// https://www.rfc-editor.org/rfc/rfc9380.html#appendix-B
fn hash_to_curve<H>(input: &[&[u8]], dst: &[&[u8]]) -> Result<Self::Elem, InternalError>
+38 -38
View File
@@ -20,7 +20,7 @@
//! We will use the following choice in this example:
//!
//! ```ignore
//! type CipherSuite = voprf_vexahub::Ristretto255;
//! type CipherSuite = voprf_vx::Ristretto255;
//! ```
//!
//! ## Modes of Operation
@@ -51,12 +51,12 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! use rand::rngs::SysRng;
//! use rand::Rng;
//! use voprf_vexahub::OprfServer;
//! use voprf_vx::OprfServer;
//!
//! let mut server_rng = SysRng;
//! let server = OprfServer::<CipherSuite>::new(&mut server_rng);
@@ -71,12 +71,12 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! use rand::rngs::SysRng;
//! use rand::Rng;
//! use voprf_vexahub::OprfClient;
//! use voprf_vx::OprfClient;
//!
//! let mut client_rng = SysRng;
//! let client_blind_result = OprfClient::<CipherSuite>::blind(b"input", &mut client_rng)
@@ -92,10 +92,10 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::OprfClient;
//! # use voprf_vx::OprfClient;
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -103,7 +103,7 @@
//! # b"input",
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # use voprf_vexahub::OprfServer;
//! # use voprf_vx::OprfServer;
//! # let mut server_rng = SysRng;
//! # let server = OprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! let server_evaluate_result = server.blind_evaluate(&client_blind_result.message);
@@ -117,10 +117,10 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::OprfClient;
//! # use voprf_vx::OprfClient;
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -128,7 +128,7 @@
//! # b"input",
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # use voprf_vexahub::OprfServer;
//! # use voprf_vx::OprfServer;
//! # let mut server_rng = SysRng;
//! # let server = OprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! # let message = server.blind_evaluate(&client_blind_result.message);
@@ -150,10 +150,10 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::OprfClient;
//! # use voprf_vx::OprfClient;
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -161,7 +161,7 @@
//! # b"input",
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # use voprf_vexahub::OprfServer;
//! # use voprf_vx::OprfServer;
//! # let mut server_rng = SysRng;
//! # let server = OprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! # let message = server.blind_evaluate(&client_blind_result.message);
@@ -197,12 +197,12 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! use rand::rngs::SysRng;
//! use rand::Rng;
//! use voprf_vexahub::VoprfServer;
//! use voprf_vx::VoprfServer;
//!
//! let mut server_rng = SysRng;
//! let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
@@ -224,12 +224,12 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! use rand::rngs::SysRng;
//! use rand::Rng;
//! use voprf_vexahub::VoprfClient;
//! use voprf_vx::VoprfClient;
//!
//! let mut client_rng = SysRng;
//! let client_blind_result = VoprfClient::<CipherSuite>::blind(b"input", &mut client_rng)
@@ -246,10 +246,10 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::{VoprfServerEvaluateResult, VoprfClient};
//! # use voprf_vx::{VoprfServerEvaluateResult, VoprfClient};
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -257,7 +257,7 @@
//! # b"input",
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # use voprf_vexahub::VoprfServer;
//! # use voprf_vx::VoprfServer;
//! # let mut server_rng = SysRng;
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! let VoprfServerEvaluateResult { message, proof } =
@@ -273,10 +273,10 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::VoprfClient;
//! # use voprf_vx::VoprfClient;
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -284,7 +284,7 @@
//! # b"input",
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # use voprf_vexahub::VoprfServer;
//! # use voprf_vx::VoprfServer;
//! # let mut server_rng = SysRng;
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! # let server_evaluate_result = server.blind_evaluate(
@@ -314,10 +314,10 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::VoprfClient;
//! # use voprf_vx::VoprfClient;
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -325,7 +325,7 @@
//! # b"input",
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # use voprf_vexahub::VoprfServer;
//! # use voprf_vx::VoprfServer;
//! # let mut server_rng = SysRng;
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! # let server_evaluate_result = server.blind_evaluate(
@@ -368,10 +368,10 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::VoprfClient;
//! # use voprf_vx::VoprfClient;
//! # use rand::{rngs::SysRng, Rng};
//! #
//! let mut client_rng = SysRng;
@@ -392,10 +392,10 @@
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::{VoprfServerBatchEvaluateFinishResult, VoprfClient};
//! # use voprf_vx::{VoprfServerBatchEvaluateFinishResult, VoprfClient};
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -409,7 +409,7 @@
//! # client_states.push(client_blind_result.state);
//! # client_messages.push(client_blind_result.message);
//! # }
//! # use voprf_vexahub::VoprfServer;
//! # use voprf_vx::VoprfServer;
//! let mut server_rng = SysRng;
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! let prepared_evaluation_elements = server.batch_blind_evaluate_prepare(client_messages.iter());
@@ -426,10 +426,10 @@
//! ```
//! # #[cfg(feature = "alloc")] {
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::{VoprfServerBatchEvaluateResult, VoprfClient};
//! # use voprf_vx::{VoprfServerBatchEvaluateResult, VoprfClient};
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -443,7 +443,7 @@
//! # client_states.push(client_blind_result.state);
//! # client_messages.push(client_blind_result.message);
//! # }
//! # use voprf_vexahub::VoprfServer;
//! # use voprf_vx::VoprfServer;
//! let mut server_rng = SysRng;
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! let VoprfServerBatchEvaluateResult { messages, proof } = server
@@ -460,10 +460,10 @@
//! ```
//! # #[cfg(feature = "alloc")] {
//! # #[cfg(feature = "ristretto255")]
//! # type CipherSuite = voprf_vexahub::Ristretto255;
//! # type CipherSuite = voprf_vx::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
//! # use voprf_vexahub::{VoprfServerBatchEvaluateResult, VoprfClient};
//! # use voprf_vx::{VoprfServerBatchEvaluateResult, VoprfClient};
//! # use rand::{rngs::SysRng, Rng};
//! #
//! # let mut client_rng = SysRng;
@@ -477,7 +477,7 @@
//! # client_states.push(client_blind_result.state);
//! # client_messages.push(client_blind_result.message);
//! # }
//! # use voprf_vexahub::VoprfServer;
//! # use voprf_vx::VoprfServer;
//! # let mut server_rng = SysRng;
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! # let VoprfServerBatchEvaluateResult { messages, proof } = server