Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb55e9f5b5 | ||
|
|
e944f9db3b | ||
|
|
f3f4fef0e9 | ||
|
|
23aa7813e7 | ||
|
|
0473d9db68 | ||
|
|
f0531f0812 | ||
|
|
c93884aca3 | ||
|
|
40769f7eca | ||
|
|
1b67086028 | ||
|
|
68cc7d3709 | ||
|
|
59e3fedb21 | ||
|
|
8da56845b8 | ||
|
|
c0162ec8d9 |
+12
-12
@@ -4,7 +4,7 @@ on:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [opened, repoened, synchronize]
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
cargo-audit:
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cache cargo-audit
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/.crates.toml
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
run: cargo install cargo-audit
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run cargo audit
|
||||
run: cargo audit -D warnings
|
||||
@@ -43,11 +43,11 @@ jobs:
|
||||
- --features serde
|
||||
toolchain:
|
||||
- stable
|
||||
- 1.65.0
|
||||
- 1.83.0
|
||||
name: test
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install ${{ matrix.toolchain }} toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -99,8 +99,8 @@ jobs:
|
||||
- --features danger
|
||||
- --features serde
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: hecrj/setup-rust-action@v1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: hecrj/setup-rust-action@v2
|
||||
- run: rustup target add ${{ matrix.target }}
|
||||
- run: cargo build --verbose --target=${{ matrix.target }} --no-default-features ${{ matrix.frontend_feature }} ${{ matrix.backend_feature }}
|
||||
|
||||
@@ -110,7 +110,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install stable toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -140,7 +140,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install nightly toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -161,7 +161,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/.crates.toml
|
||||
@@ -170,10 +170,10 @@ jobs:
|
||||
key: taplo
|
||||
|
||||
- name: Install Taplo
|
||||
run: cargo install taplo-cli
|
||||
run: cargo install taplo-cli --locked
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Taplo
|
||||
run: taplo fmt --check
|
||||
|
||||
@@ -10,9 +10,10 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
rust: [stable]
|
||||
|
||||
steps:
|
||||
- uses: hecrj/setup-rust-action@v1
|
||||
- uses: hecrj/setup-rust-action@v2
|
||||
with:
|
||||
rust-version: ${{ matrix.rust }}
|
||||
- uses: actions/checkout@master
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
+10
-6
@@ -8,16 +8,16 @@ license = "MIT"
|
||||
name = "voprf"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/facebook/voprf/"
|
||||
rust-version = "1.65"
|
||||
version = "0.5.0-pre.6"
|
||||
rust-version = "1.83"
|
||||
version = "0.6.0-pre.0"
|
||||
|
||||
[features]
|
||||
alloc = []
|
||||
danger = []
|
||||
default = ["ristretto255-ciphersuite", "dep:serde"]
|
||||
ristretto255 = ["dep:curve25519-dalek", "generic-array/more_lengths"]
|
||||
ristretto255 = ["dep:curve25519-dalek"]
|
||||
ristretto255-ciphersuite = ["ristretto255", "dep:sha2"]
|
||||
serde = ["generic-array/serde", "dep:serde"]
|
||||
serde = ["curve25519-dalek?/serde", "generic-array/serde", "dep:serde"]
|
||||
std = ["alloc"]
|
||||
|
||||
[dependencies]
|
||||
@@ -33,7 +33,7 @@ elliptic-curve = { version = "0.13", features = [
|
||||
"sec1",
|
||||
"voprf",
|
||||
] }
|
||||
generic-array = "0.14"
|
||||
generic-array = "1"
|
||||
rand_core = { version = "0.6", default-features = false }
|
||||
serde = { version = "1", default-features = false, features = [
|
||||
"derive",
|
||||
@@ -43,7 +43,7 @@ subtle = { version = "2.3", default-features = false }
|
||||
zeroize = { version = "1.5", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
generic-array = { version = "0.14", features = ["more_lengths"] }
|
||||
generic-array = { version = "1" }
|
||||
hex = "0.4"
|
||||
p256 = { version = "0.13", default-features = false, features = [
|
||||
"hash2curve",
|
||||
@@ -53,6 +53,10 @@ p384 = { version = "0.13", default-features = false, features = [
|
||||
"hash2curve",
|
||||
"voprf",
|
||||
] }
|
||||
p521 = { version = "0.13.3", default-features = false, features = [
|
||||
"hash2curve",
|
||||
"voprf",
|
||||
] }
|
||||
proptest = "1"
|
||||
rand = "0.8"
|
||||
regex = "1"
|
||||
|
||||
@@ -3,7 +3,7 @@ An implementation of a (verifiable) oblivious pseudorandom function (VOPRF)
|
||||
|
||||
A VOPRF is a verifiable oblivious pseudorandom function, a protocol between a client and a server. The regular (non-verifiable) OPRF is also supported in this implementation.
|
||||
|
||||
This implementation is based on the [Internet Draft for VOPRF](https://github.com/cfrg/draft-irtf-cfrg-voprf).
|
||||
This implementation is based on [RFC 9497](https://www.rfc-editor.org/rfc/rfc9497).
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
@@ -16,7 +16,7 @@ Installation
|
||||
Add the following line to the dependencies of your `Cargo.toml`:
|
||||
|
||||
```
|
||||
voprf = "0.5.0-pre.6"
|
||||
voprf = "0.6.0-pre.0"
|
||||
```
|
||||
|
||||
### Minimum Supported Rust Version
|
||||
|
||||
+4
-3
@@ -12,6 +12,7 @@ use digest::core_api::BlockSizeUser;
|
||||
use digest::{FixedOutput, HashMarker, OutputSizeUser};
|
||||
use elliptic_curve::VoprfParameters;
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, U256};
|
||||
use generic_array::ArrayLength;
|
||||
|
||||
use crate::Group;
|
||||
|
||||
@@ -19,10 +20,10 @@ use crate::Group;
|
||||
pub trait CipherSuite
|
||||
where
|
||||
<Self::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<Self::Hash as BlockSizeUser>::BlockSize>,
|
||||
ArrayLength + IsLess<U256> + IsLessOrEqual<<Self::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
/// The ciphersuite identifier as dictated by
|
||||
/// <https://datatracker.ietf.org/doc/draft-irtf-cfrg-voprf/>
|
||||
/// <https://www.rfc-editor.org/rfc/rfc9497>
|
||||
const ID: &'static str;
|
||||
|
||||
/// A finite cyclic group along with a point representation that allows some
|
||||
@@ -39,7 +40,7 @@ where
|
||||
T: Group,
|
||||
T::Hash: BlockSizeUser + Default + FixedOutput + HashMarker,
|
||||
<T::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<T::Hash as BlockSizeUser>::BlockSize>,
|
||||
ArrayLength + IsLess<U256> + IsLessOrEqual<<T::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
const ID: &'static str = T::ID;
|
||||
|
||||
|
||||
+30
-83
@@ -12,10 +12,9 @@ use core::convert::TryFrom;
|
||||
use core::ops::Add;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::{Digest, Output, OutputSizeUser};
|
||||
use generic_array::sequence::Concat;
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, Unsigned, U2, U256, U9};
|
||||
use generic_array::typenum::{IsLess, Unsigned, U2, U256, U9};
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use subtle::ConstantTimeEq;
|
||||
@@ -79,10 +78,7 @@ impl Mode {
|
||||
pub struct BlindedElement<CS: CipherSuite>(
|
||||
#[cfg_attr(feature = "serde", serde(with = "Element::<CS::Group>"))]
|
||||
pub(crate) <CS::Group as Group>::Elem,
|
||||
)
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>;
|
||||
);
|
||||
|
||||
/// The server's response to the [BlindedElement] message from a client (either
|
||||
/// verifiable or not) to a server (either verifiable or not).
|
||||
@@ -96,10 +92,7 @@ where
|
||||
pub struct EvaluationElement<CS: CipherSuite>(
|
||||
#[cfg_attr(feature = "serde", serde(with = "Element::<CS::Group>"))]
|
||||
pub(crate) <CS::Group as Group>::Elem,
|
||||
)
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>;
|
||||
);
|
||||
|
||||
/// Contains prepared [`EvaluationElement`]s by a server batch evaluate
|
||||
/// preparation.
|
||||
@@ -110,10 +103,7 @@ where
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
)]
|
||||
pub struct PreparedEvaluationElement<CS: CipherSuite>(pub(crate) EvaluationElement<CS>)
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>;
|
||||
pub struct PreparedEvaluationElement<CS: CipherSuite>(pub(crate) EvaluationElement<CS>);
|
||||
|
||||
/// A proof produced by a server that the OPRF output matches against a server
|
||||
/// public key.
|
||||
@@ -124,11 +114,7 @@ where
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
)]
|
||||
pub struct Proof<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct Proof<CS: CipherSuite> {
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
pub(crate) c_scalar: <CS::Group as Group>::Scalar,
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
@@ -147,15 +133,11 @@ pub(crate) fn generate_proof<CS: CipherSuite, R: RngCore + CryptoRng>(
|
||||
k: <CS::Group as Group>::Scalar,
|
||||
a: <CS::Group as Group>::Elem,
|
||||
b: <CS::Group as Group>::Elem,
|
||||
cs: impl Iterator<Item = <CS::Group as Group>::Elem> + ExactSizeIterator,
|
||||
ds: impl Iterator<Item = <CS::Group as Group>::Elem> + ExactSizeIterator,
|
||||
cs: impl ExactSizeIterator<Item = <CS::Group as Group>::Elem>,
|
||||
ds: impl ExactSizeIterator<Item = <CS::Group as Group>::Elem>,
|
||||
mode: Mode,
|
||||
) -> Result<Proof<CS>>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
// https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-11.html#section-2.2.1
|
||||
) -> Result<Proof<CS>> {
|
||||
// https://www.rfc-editor.org/rfc/rfc9497#section-2.2.1
|
||||
|
||||
let (m, z) = compute_composites::<CS, _, _>(Some(k), b, cs, ds, mode)?;
|
||||
|
||||
@@ -209,16 +191,12 @@ where
|
||||
pub(crate) fn verify_proof<CS: CipherSuite>(
|
||||
a: <CS::Group as Group>::Elem,
|
||||
b: <CS::Group as Group>::Elem,
|
||||
cs: impl Iterator<Item = <CS::Group as Group>::Elem> + ExactSizeIterator,
|
||||
ds: impl Iterator<Item = <CS::Group as Group>::Elem> + ExactSizeIterator,
|
||||
cs: impl ExactSizeIterator<Item = <CS::Group as Group>::Elem>,
|
||||
ds: impl ExactSizeIterator<Item = <CS::Group as Group>::Elem>,
|
||||
proof: &Proof<CS>,
|
||||
mode: Mode,
|
||||
) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
// https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-11.html#section-2.2.2
|
||||
) -> Result<()> {
|
||||
// https://www.rfc-editor.org/rfc/rfc9497#section-2.2.2
|
||||
let (m, z) = compute_composites::<CS, _, _>(None, b, cs, ds, mode)?;
|
||||
let t2 = (a * &proof.s_scalar) + &(b * &proof.c_scalar);
|
||||
let t3 = (m * &proof.s_scalar) + &(z * &proof.c_scalar);
|
||||
@@ -282,12 +260,8 @@ fn compute_composites<
|
||||
c_slice: IC,
|
||||
d_slice: ID,
|
||||
mode: Mode,
|
||||
) -> Result<ComputeCompositesResult<CS>>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
// https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-11.html#section-2.2.1
|
||||
) -> Result<ComputeCompositesResult<CS>> {
|
||||
// https://www.rfc-editor.org/rfc/rfc9497#section-2.2.1
|
||||
|
||||
let elem_len = <CS::Group as Group>::ElemLen::U16.to_be_bytes();
|
||||
|
||||
@@ -309,7 +283,7 @@ where
|
||||
.chain_update(seed_dst.i2osp_2())
|
||||
.chain_update_multi(&seed_dst.as_dst())
|
||||
.finalize();
|
||||
let seed_len = i2osp_2_array(&seed);
|
||||
let seed_len = i2osp_2_array::<<CS::Hash as OutputSizeUser>::OutputSize>();
|
||||
|
||||
let mut m = CS::Group::identity_elem();
|
||||
let mut z = CS::Group::identity_elem();
|
||||
@@ -362,11 +336,7 @@ pub(crate) fn derive_key_internal<CS: CipherSuite>(
|
||||
seed: &[u8],
|
||||
info: &[u8],
|
||||
mode: Mode,
|
||||
) -> Result<<CS::Group as Group>::Scalar, Error>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Result<<CS::Group as Group>::Scalar, Error> {
|
||||
let dst = Dst::new::<CS, _, _>(STR_DERIVE_KEYPAIR, mode);
|
||||
|
||||
let info_len = i2osp_2(info.len()).map_err(|_| Error::DeriveKeyPair)?;
|
||||
@@ -400,11 +370,7 @@ pub fn derive_key<CS: CipherSuite>(
|
||||
seed: &[u8],
|
||||
info: &[u8],
|
||||
mode: Mode,
|
||||
) -> Result<<CS::Group as Group>::Scalar, Error>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Result<<CS::Group as Group>::Scalar, Error> {
|
||||
derive_key_internal::<CS>(seed, info, mode)
|
||||
}
|
||||
|
||||
@@ -418,11 +384,7 @@ pub(crate) fn derive_keypair<CS: CipherSuite>(
|
||||
seed: &[u8],
|
||||
info: &[u8],
|
||||
mode: Mode,
|
||||
) -> Result<DeriveKeypairResult<CS>, Error>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Result<DeriveKeypairResult<CS>, Error> {
|
||||
let sk_s = derive_key_internal::<CS>(seed, info, mode)?;
|
||||
let pk_s = CS::Group::base_elem() * &sk_s;
|
||||
|
||||
@@ -438,11 +400,7 @@ pub(crate) fn deterministic_blind_unchecked<CS: CipherSuite>(
|
||||
input: &[u8],
|
||||
blind: &<CS::Group as Group>::Scalar,
|
||||
mode: Mode,
|
||||
) -> Result<<CS::Group as Group>::Elem>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Result<<CS::Group as Group>::Elem> {
|
||||
let hashed_point = hash_to_group::<CS>(input, mode)?;
|
||||
Ok(hashed_point * blind)
|
||||
}
|
||||
@@ -451,11 +409,7 @@ where
|
||||
pub(crate) fn hash_to_group<CS: CipherSuite>(
|
||||
input: &[u8],
|
||||
mode: Mode,
|
||||
) -> Result<<CS::Group as Group>::Elem>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Result<<CS::Group as Group>::Elem> {
|
||||
let dst = Dst::new::<CS, _, _>(STR_HASH_TO_GROUP, mode);
|
||||
CS::Group::hash_to_curve::<CS::Hash>(&[input], &dst.as_dst()).map_err(|_| Error::Input)
|
||||
}
|
||||
@@ -466,11 +420,7 @@ pub(crate) fn server_evaluate_hash_input<CS: CipherSuite>(
|
||||
input: &[u8],
|
||||
info: Option<&[u8]>,
|
||||
issued_element: GenericArray<u8, <<CS as CipherSuite>::Group as Group>::ElemLen>,
|
||||
) -> Result<Output<CS::Hash>>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Result<Output<CS::Hash>> {
|
||||
// OPRF & VOPRF
|
||||
// hashInput = I2OSP(len(input), 2) || input ||
|
||||
// I2OSP(len(issuedElement), 2) || issuedElement ||
|
||||
@@ -492,28 +442,27 @@ where
|
||||
.chain_update(info.as_ref());
|
||||
}
|
||||
Ok(hash
|
||||
.chain_update(i2osp_2(issued_element.as_ref().len()).map_err(|_| Error::Input)?)
|
||||
.chain_update(i2osp_2(issued_element.as_slice().len()).map_err(|_| Error::Input)?)
|
||||
.chain_update(issued_element)
|
||||
.chain_update(STR_FINALIZE)
|
||||
.finalize())
|
||||
}
|
||||
|
||||
pub(crate) struct Dst<L: ArrayLength<u8>> {
|
||||
pub(crate) struct Dst<L: ArrayLength> {
|
||||
dst_1: GenericArray<u8, L>,
|
||||
dst_2: &'static str,
|
||||
}
|
||||
|
||||
impl<L: ArrayLength<u8>> Dst<L> {
|
||||
pub(crate) fn new<CS: CipherSuite, T, TL: ArrayLength<u8>>(par_1: T, mode: Mode) -> Self
|
||||
impl<L: ArrayLength> Dst<L> {
|
||||
pub(crate) fn new<CS, T, TL>(par_1: T, mode: Mode) -> Self
|
||||
where
|
||||
CS: CipherSuite,
|
||||
T: Into<GenericArray<u8, TL>>,
|
||||
TL: Add<U9, Output = L>,
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
TL: ArrayLength + Add<U9, Output = L>,
|
||||
{
|
||||
let par_1 = par_1.into();
|
||||
// Generates the contextString parameter as defined in
|
||||
// <https://datatracker.ietf.org/doc/draft-irtf-cfrg-voprf/>
|
||||
// <https://www.rfc-editor.org/rfc/rfc9497#section-3.1>
|
||||
let par_2 = GenericArray::from(STR_OPRF)
|
||||
.concat([mode.to_u8()].into())
|
||||
.concat([b'-'].into());
|
||||
@@ -569,8 +518,6 @@ pub(crate) fn i2osp_2(input: usize) -> Result<[u8; 2], InternalError> {
|
||||
.map_err(|_| InternalError::I2osp)
|
||||
}
|
||||
|
||||
pub(crate) fn i2osp_2_array<L: ArrayLength<u8> + IsLess<U256>>(
|
||||
_: &GenericArray<u8, L>,
|
||||
) -> GenericArray<u8, U2> {
|
||||
pub(crate) fn i2osp_2_array<L: ArrayLength + IsLess<U256>>() -> GenericArray<u8, U2> {
|
||||
L::U16.to_be_bytes().into()
|
||||
}
|
||||
|
||||
+2
-5
@@ -8,13 +8,11 @@
|
||||
|
||||
//! Errors which are produced during an execution of the protocol
|
||||
|
||||
use displaydoc::Display;
|
||||
|
||||
/// [`Result`](core::result::Result) shorthand that uses [`Error`].
|
||||
pub type Result<T, E = Error> = core::result::Result<T, E>;
|
||||
|
||||
/// Represents an error in the manipulation of internal cryptographic data
|
||||
#[derive(Clone, Copy, Debug, Display, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Copy, Debug, displaydoc::Display, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub enum Error {
|
||||
/// Size of info is longer then [`u16::MAX`].
|
||||
Info,
|
||||
@@ -41,5 +39,4 @@ pub enum InternalError {
|
||||
I2osp,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl std::error::Error for Error {}
|
||||
impl core::error::Error for Error {}
|
||||
|
||||
@@ -6,39 +6,53 @@
|
||||
// of this source tree. You may select, at your option, one of the above-listed
|
||||
// licenses.
|
||||
|
||||
use core::ops::Add;
|
||||
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::{FixedOutput, HashMarker};
|
||||
use elliptic_curve::group::cofactor::CofactorGroup;
|
||||
use elliptic_curve::hash2curve::{ExpandMsgXmd, FromOkm, GroupDigest};
|
||||
use elliptic_curve::sec1::{FromEncodedPoint, ModulusSize, ToEncodedPoint};
|
||||
use elliptic_curve::{
|
||||
AffinePoint, Field, FieldBytesSize, Group as _, ProjectivePoint, PublicKey, Scalar, SecretKey,
|
||||
AffinePoint, Field, FieldBytes, FieldBytesSize, Group as _, ProjectivePoint, PublicKey, Scalar,
|
||||
SecretKey,
|
||||
};
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, U256};
|
||||
use generic_array::GenericArray;
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, Sum, U256};
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
|
||||
use super::Group;
|
||||
use crate::{Error, InternalError, Result};
|
||||
|
||||
type ElemLen<C> = <ScalarLen<C> as ModulusSize>::CompressedPointSize;
|
||||
type ScalarLen<C> = FieldBytesSize<C>;
|
||||
|
||||
impl<C> Group for C
|
||||
where
|
||||
C: GroupDigest,
|
||||
ProjectivePoint<Self>: CofactorGroup + ToEncodedPoint<Self>,
|
||||
FieldBytesSize<Self>: ModulusSize,
|
||||
ScalarLen<Self>: ModulusSize,
|
||||
ScalarLen<Self>: ArrayLength,
|
||||
AffinePoint<Self>: FromEncodedPoint<Self> + ToEncodedPoint<Self>,
|
||||
Scalar<Self>: FromOkm,
|
||||
// `VoprfClientLen`, `PoprfClientLen`, `VoprfServerLen`, `PoprfServerLen`
|
||||
ScalarLen<Self>: Add<ElemLen<Self>>,
|
||||
Sum<ScalarLen<Self>, ElemLen<Self>>: ArrayLength,
|
||||
// `ProofLen`
|
||||
ScalarLen<Self>: Add<ScalarLen<Self>>,
|
||||
Sum<ScalarLen<Self>, ScalarLen<Self>>: ArrayLength,
|
||||
ElemLen<Self>: ArrayLength,
|
||||
{
|
||||
type Elem = ProjectivePoint<Self>;
|
||||
|
||||
type ElemLen = <FieldBytesSize<Self> as ModulusSize>::CompressedPointSize;
|
||||
type ElemLen = ElemLen<Self>;
|
||||
|
||||
type Scalar = Scalar<Self>;
|
||||
|
||||
type ScalarLen = FieldBytesSize<Self>;
|
||||
type ScalarLen = ScalarLen<Self>;
|
||||
|
||||
// Implements the `hash_to_curve()` function from
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|
||||
// https://www.rfc-editor.org/rfc/rfc9380.html#section-3
|
||||
fn hash_to_curve<H>(input: &[&[u8]], dst: &[&[u8]]) -> Result<Self::Elem, InternalError>
|
||||
where
|
||||
H: BlockSizeUser + Default + FixedOutput + HashMarker,
|
||||
@@ -97,7 +111,10 @@ where
|
||||
}
|
||||
|
||||
fn serialize_scalar(scalar: Self::Scalar) -> GenericArray<u8, Self::ScalarLen> {
|
||||
scalar.into()
|
||||
let bytes: FieldBytes<Self> = scalar.into();
|
||||
let mut result = GenericArray::<u8, Self::ScalarLen>::default();
|
||||
result.as_mut_slice().copy_from_slice(bytes.as_ref());
|
||||
result
|
||||
}
|
||||
|
||||
fn deserialize_scalar(scalar_bits: &[u8]) -> Result<Self::Scalar> {
|
||||
|
||||
+13
-5
@@ -16,7 +16,7 @@ use core::ops::{Add, Mul, Sub};
|
||||
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::{FixedOutput, HashMarker};
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, U256};
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, Sum, U256};
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
#[cfg(feature = "ristretto255")]
|
||||
@@ -27,8 +27,16 @@ use zeroize::Zeroize;
|
||||
use crate::{InternalError, Result};
|
||||
|
||||
/// A prime-order subgroup of a base field (EC, prime-order field ...). This
|
||||
/// subgroup is noted additively — as in the draft RFC — in this trait.
|
||||
pub trait Group {
|
||||
/// subgroup is noted additively — as in the RFC — in this trait.
|
||||
pub trait Group
|
||||
where
|
||||
// `VoprfClientLen`, `PoprfClientLen`, `VoprfServerLen`, `PoprfServerLen`
|
||||
Self::ScalarLen: Add<Self::ElemLen>,
|
||||
Sum<Self::ScalarLen, Self::ElemLen>: ArrayLength,
|
||||
// `ProofLen`
|
||||
Self::ScalarLen: Add<Self::ScalarLen>,
|
||||
Sum<Self::ScalarLen, Self::ScalarLen>: ArrayLength,
|
||||
{
|
||||
/// The type of group elements
|
||||
type Elem: ConstantTimeEq
|
||||
+ Copy
|
||||
@@ -37,7 +45,7 @@ pub trait Group {
|
||||
+ for<'a> Mul<&'a Self::Scalar, Output = Self::Elem>;
|
||||
|
||||
/// The byte length necessary to represent group elements
|
||||
type ElemLen: ArrayLength<u8> + 'static;
|
||||
type ElemLen: ArrayLength + 'static;
|
||||
|
||||
/// The type of base field scalars
|
||||
type Scalar: ConstantTimeEq
|
||||
@@ -48,7 +56,7 @@ pub trait Group {
|
||||
+ for<'a> Sub<&'a Self::Scalar, Output = Self::Scalar>;
|
||||
|
||||
/// The byte length necessary to represent scalars
|
||||
type ScalarLen: ArrayLength<u8> + 'static;
|
||||
type ScalarLen: ArrayLength + 'static;
|
||||
|
||||
/// Transforms a password and domain separation tag (DST) into a curve point
|
||||
///
|
||||
|
||||
@@ -44,7 +44,7 @@ impl Group for Ristretto255 {
|
||||
type ScalarLen = U32;
|
||||
|
||||
// Implements the `hash_to_ristretto255()` function from
|
||||
// https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-10.txt
|
||||
// https://www.rfc-editor.org/rfc/rfc9380.html#appendix-B
|
||||
fn hash_to_curve<H>(input: &[&[u8]], dst: &[&[u8]]) -> Result<Self::Elem, InternalError>
|
||||
where
|
||||
H: BlockSizeUser + Default + FixedOutput + HashMarker,
|
||||
@@ -59,7 +59,7 @@ impl Group for Ristretto255 {
|
||||
}
|
||||
|
||||
// Implements the `HashToScalar()` function from
|
||||
// https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-07.html#section-4.1
|
||||
// https://www.rfc-editor.org/rfc/rfc9497#section-4.1
|
||||
fn hash_to_scalar<H>(input: &[&[u8]], dst: &[&[u8]]) -> Result<Self::Scalar, InternalError>
|
||||
where
|
||||
H: BlockSizeUser + Default + FixedOutput + HashMarker,
|
||||
@@ -96,9 +96,10 @@ impl Group for Ristretto255 {
|
||||
|
||||
fn random_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
|
||||
loop {
|
||||
let scalar = Scalar::random(rng);
|
||||
let mut scalar_bytes = [0u8; 32];
|
||||
rng.fill_bytes(&mut scalar_bytes);
|
||||
|
||||
if scalar != Scalar::ZERO {
|
||||
if let Ok(scalar) = Self::deserialize_scalar(&scalar_bytes) {
|
||||
break scalar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ use crate::{Error, Group, Result};
|
||||
fn test_group_properties() -> Result<()> {
|
||||
use p256::NistP256;
|
||||
use p384::NistP384;
|
||||
use p521::NistP521;
|
||||
|
||||
#[cfg(feature = "ristretto255")]
|
||||
{
|
||||
@@ -32,6 +33,9 @@ fn test_group_properties() -> Result<()> {
|
||||
test_identity_element_error::<NistP384>()?;
|
||||
test_zero_scalar_error::<NistP384>()?;
|
||||
|
||||
test_identity_element_error::<NistP521>()?;
|
||||
test_zero_scalar_error::<NistP521>()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -9,9 +9,7 @@
|
||||
//! An implementation of a verifiable oblivious pseudorandom function (VOPRF)
|
||||
//!
|
||||
//! Note: This implementation is in sync with
|
||||
//! [draft-irtf-cfrg-voprf-19](https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html),
|
||||
//! but this specification is subject to change, until the final version
|
||||
//! published by the IETF.
|
||||
//! [RFC 9497](https://www.rfc-editor.org/rfc/rfc9497).
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
@@ -512,7 +510,7 @@
|
||||
//! and [PoprfClient] are used, and that each of the functions accept an
|
||||
//! additional (and optional) info parameter which represents the public input.
|
||||
//! See
|
||||
//! <https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-11.html#name-poprf-public-input>
|
||||
//! <https://www.rfc-editor.org/rfc/rfc9497#name-poprf-public-input>
|
||||
//! for more detailed information on how this public input should be used.
|
||||
//!
|
||||
//! # Features
|
||||
|
||||
+23
-64
@@ -11,9 +11,8 @@
|
||||
use core::iter::{self, Map};
|
||||
|
||||
use derive_where::derive_where;
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::{Digest, Output, OutputSizeUser};
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, Unsigned, U256};
|
||||
use digest::{Digest, Output};
|
||||
use generic_array::typenum::Unsigned;
|
||||
use generic_array::GenericArray;
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
|
||||
@@ -44,11 +43,7 @@ use crate::{CipherSuite, Error, Group, Result};
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
)]
|
||||
pub struct OprfClient<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct OprfClient<CS: CipherSuite> {
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
pub(crate) blind: <CS::Group as Group>::Scalar,
|
||||
}
|
||||
@@ -62,11 +57,7 @@ where
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
)]
|
||||
pub struct OprfServer<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct OprfServer<CS: CipherSuite> {
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
pub(crate) sk: <CS::Group as Group>::Scalar,
|
||||
}
|
||||
@@ -76,11 +67,7 @@ where
|
||||
// =================== //
|
||||
/////////////////////////
|
||||
|
||||
impl<CS: CipherSuite> OprfClient<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> OprfClient<CS> {
|
||||
/// Computes the first step for the multiplicative blinding version of
|
||||
/// DH-OPRF.
|
||||
///
|
||||
@@ -154,11 +141,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> OprfServer<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> OprfServer<CS> {
|
||||
/// Produces a new instance of a [OprfServer] using a supplied RNG
|
||||
///
|
||||
/// # Errors
|
||||
@@ -194,7 +177,7 @@ where
|
||||
Ok(Self { sk })
|
||||
}
|
||||
|
||||
// Only used for tests
|
||||
/// Only used for tests
|
||||
#[cfg(test)]
|
||||
pub fn get_private_key(&self) -> <CS::Group as Group>::Scalar {
|
||||
self.sk
|
||||
@@ -231,11 +214,7 @@ where
|
||||
|
||||
/// Contains the fields that are returned by a non-verifiable client blind
|
||||
#[derive_where(Debug; <CS::Group as Group>::Scalar, <CS::Group as Group>::Elem)]
|
||||
pub struct OprfClientBlindResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct OprfClientBlindResult<CS: CipherSuite> {
|
||||
/// The state to be persisted on the client
|
||||
pub state: OprfClient<CS>,
|
||||
/// The message to send to the server
|
||||
@@ -261,11 +240,7 @@ fn finalize_after_unblind<
|
||||
>(
|
||||
inputs_and_unblinded_elements: IE,
|
||||
_unused: &'a [u8],
|
||||
) -> FinalizeAfterUnblindResult<CS, I, IE>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> FinalizeAfterUnblindResult<'a, CS, I, IE> {
|
||||
inputs_and_unblinded_elements.map(|(input, unblinded_element)| {
|
||||
let elem_len = <CS::Group as Group>::ElemLen::U16.to_be_bytes();
|
||||
|
||||
@@ -303,11 +278,7 @@ mod tests {
|
||||
key: <CS::Group as Group>::Scalar,
|
||||
info: &[u8],
|
||||
mode: Mode,
|
||||
) -> Output<CS::Hash>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Output<CS::Hash> {
|
||||
let dst = Dst::new::<CS, _, _>(STR_HASH_TO_GROUP, mode);
|
||||
let point = CS::Group::hash_to_curve::<CS::Hash>(&[input], &dst.as_dst()).unwrap();
|
||||
|
||||
@@ -319,11 +290,7 @@ mod tests {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn base_retrieval<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn base_retrieval<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = OprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -334,11 +301,7 @@ mod tests {
|
||||
assert_eq!(client_finalize_result, res2);
|
||||
}
|
||||
|
||||
fn base_inversion_unsalted<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn base_inversion_unsalted<CS: CipherSuite>() {
|
||||
let mut rng = OsRng;
|
||||
let mut input = [0u8; 64];
|
||||
rng.fill_bytes(&mut input);
|
||||
@@ -358,11 +321,7 @@ mod tests {
|
||||
assert_eq!(client_finalize_result, res2);
|
||||
}
|
||||
|
||||
fn server_evaluate<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn server_evaluate<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = OprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -386,11 +345,7 @@ mod tests {
|
||||
assert!(client_finalize != server_evaluate);
|
||||
}
|
||||
|
||||
fn zeroize_oprf_client<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn zeroize_oprf_client<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = OprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -404,11 +359,7 @@ mod tests {
|
||||
assert!(message.serialize().iter().all(|&x| x == 0));
|
||||
}
|
||||
|
||||
fn zeroize_oprf_server<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn zeroize_oprf_server<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = OprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -427,6 +378,7 @@ mod tests {
|
||||
fn test_functionality() -> Result<()> {
|
||||
use p256::NistP256;
|
||||
use p384::NistP384;
|
||||
use p521::NistP521;
|
||||
|
||||
#[cfg(feature = "ristretto255")]
|
||||
{
|
||||
@@ -454,6 +406,13 @@ mod tests {
|
||||
zeroize_oprf_client::<NistP384>();
|
||||
zeroize_oprf_server::<NistP384>();
|
||||
|
||||
base_retrieval::<NistP521>();
|
||||
base_inversion_unsalted::<NistP521>();
|
||||
server_evaluate::<NistP521>();
|
||||
|
||||
zeroize_oprf_client::<NistP521>();
|
||||
zeroize_oprf_server::<NistP521>();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+38
-116
@@ -13,10 +13,9 @@ use alloc::vec::Vec;
|
||||
use core::iter::{self, Map, Repeat, Zip};
|
||||
|
||||
use derive_where::derive_where;
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::{Digest, Output, OutputSizeUser};
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, Unsigned, U256};
|
||||
use generic_array::GenericArray;
|
||||
use generic_array::typenum::Unsigned;
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
|
||||
use crate::common::{
|
||||
@@ -42,11 +41,7 @@ use crate::{CipherSuite, Error, Group, Result};
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
)]
|
||||
pub struct PoprfClient<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct PoprfClient<CS: CipherSuite> {
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
pub(crate) blind: <CS::Group as Group>::Scalar,
|
||||
#[cfg_attr(feature = "serde", serde(with = "Element::<CS::Group>"))]
|
||||
@@ -62,11 +57,7 @@ where
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
)]
|
||||
pub struct PoprfServer<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct PoprfServer<CS: CipherSuite> {
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
pub(crate) sk: <CS::Group as Group>::Scalar,
|
||||
#[cfg_attr(feature = "serde", serde(with = "Element::<CS::Group>"))]
|
||||
@@ -78,11 +69,7 @@ where
|
||||
// =================== //
|
||||
/////////////////////////
|
||||
|
||||
impl<CS: CipherSuite> PoprfClient<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> PoprfClient<CS> {
|
||||
/// Computes the first step for the multiplicative blinding version of
|
||||
/// DH-OPRF.
|
||||
///
|
||||
@@ -145,7 +132,10 @@ where
|
||||
proof: &Proof<CS>,
|
||||
pk: <CS::Group as Group>::Elem,
|
||||
info: Option<&[u8]>,
|
||||
) -> Result<Output<CS::Hash>> {
|
||||
) -> Result<Output<CS::Hash>>
|
||||
where
|
||||
<<CS as CipherSuite>::Hash as OutputSizeUser>::OutputSize: ArrayLength,
|
||||
{
|
||||
let clients = core::array::from_ref(self);
|
||||
let messages = core::array::from_ref(evaluation_element);
|
||||
|
||||
@@ -180,6 +170,7 @@ where
|
||||
<&'a IC as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
&'a IM: 'a + IntoIterator<Item = &'a EvaluationElement<CS>>,
|
||||
<&'a IM as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
<<CS as CipherSuite>::Hash as OutputSizeUser>::OutputSize: ArrayLength,
|
||||
{
|
||||
let unblinded_elements = poprf_unblind(clients, messages, pk, proof, info)?;
|
||||
|
||||
@@ -193,11 +184,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> PoprfServer<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> PoprfServer<CS> {
|
||||
/// Produces a new instance of a [PoprfServer] using a supplied RNG
|
||||
///
|
||||
/// # Errors
|
||||
@@ -235,7 +222,7 @@ where
|
||||
Ok(Self { sk, pk })
|
||||
}
|
||||
|
||||
// Only used for tests
|
||||
/// Only used for tests
|
||||
#[cfg(test)]
|
||||
pub fn get_private_key(&self) -> <CS::Group as Group>::Scalar {
|
||||
self.sk
|
||||
@@ -427,11 +414,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> BlindedElement<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> BlindedElement<CS> {
|
||||
/// Creates a [BlindedElement] from a raw group element.
|
||||
///
|
||||
/// # Caution
|
||||
@@ -450,11 +433,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> EvaluationElement<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> EvaluationElement<CS> {
|
||||
/// Creates an [EvaluationElement] from a raw group element.
|
||||
///
|
||||
/// # Caution
|
||||
@@ -480,11 +459,7 @@ where
|
||||
|
||||
/// Contains the fields that are returned by a verifiable client blind
|
||||
#[derive_where(Debug; <CS::Group as Group>::Scalar, <CS::Group as Group>::Elem)]
|
||||
pub struct PoprfClientBlindResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct PoprfClientBlindResult<CS: CipherSuite> {
|
||||
/// The state to be persisted on the client
|
||||
pub state: PoprfClient<CS>,
|
||||
/// The message to send to the server
|
||||
@@ -497,11 +472,7 @@ pub type PoprfClientBatchFinalizeResult<'a, CS, II, IC, IM> =
|
||||
|
||||
/// Contains the fields that are returned by a verifiable server evaluate
|
||||
#[derive_where(Debug; <CS::Group as Group>::Scalar, <CS::Group as Group>::Elem)]
|
||||
pub struct PoprfServerEvaluateResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct PoprfServerEvaluateResult<CS: CipherSuite> {
|
||||
/// The message to send to the client
|
||||
pub message: EvaluationElement<CS>,
|
||||
/// The proof for the client to verify
|
||||
@@ -511,11 +482,7 @@ where
|
||||
/// Contains the fields that are returned by a verifiable server batch evaluate
|
||||
#[derive_where(Debug; <CS::Group as Group>::Scalar, <CS::Group as Group>::Elem)]
|
||||
#[cfg(feature = "alloc")]
|
||||
pub struct PoprfServerBatchEvaluateResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct PoprfServerBatchEvaluateResult<CS: CipherSuite> {
|
||||
/// The messages to send to the client
|
||||
pub messages: Vec<EvaluationElement<CS>>,
|
||||
/// The proof for the client to verify
|
||||
@@ -545,19 +512,12 @@ pub type PoprfServerBatchEvaluatePreparedEvaluationElements<CS, I> = Map<
|
||||
pub struct PoprfPreparedTweak<CS: CipherSuite>(
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
<CS::Group as Group>::Scalar,
|
||||
)
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>;
|
||||
);
|
||||
|
||||
/// Contains the fields that are returned by a partially verifiable server batch
|
||||
/// evaluate prepare
|
||||
#[derive_where(Debug; I, <CS::Group as Group>::Scalar)]
|
||||
pub struct PoprfServerBatchEvaluatePrepareResult<CS: CipherSuite, I>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct PoprfServerBatchEvaluatePrepareResult<CS: CipherSuite, I> {
|
||||
/// Prepared [`EvaluationElement`].
|
||||
pub prepared_evaluation_elements: PoprfServerBatchEvaluatePreparedEvaluationElements<CS, I>,
|
||||
/// Prepared tweak.
|
||||
@@ -576,8 +536,6 @@ pub type PoprfServerBatchEvaluateFinishedMessages<'a, CS, I> = Map<
|
||||
#[derive_where(Debug; <&'a I as IntoIterator>::IntoIter, <CS::Group as Group>::Scalar)]
|
||||
pub struct PoprfServerBatchEvaluateFinishResult<'a, CS: 'a + CipherSuite, I>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
&'a I: IntoIterator<Item = &'a PreparedEvaluationElement<CS>>,
|
||||
{
|
||||
/// The [`EvaluationElement`]s to send to the client
|
||||
@@ -598,11 +556,7 @@ where
|
||||
fn compute_tweaked_key<CS: CipherSuite>(
|
||||
pk: <CS::Group as Group>::Elem,
|
||||
info: Option<&[u8]>,
|
||||
) -> Result<<CS::Group as Group>::Elem>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Result<<CS::Group as Group>::Elem> {
|
||||
// None for info is treated the same as empty bytes
|
||||
let info = info.unwrap_or_default();
|
||||
|
||||
@@ -636,11 +590,7 @@ where
|
||||
fn compute_tweak<CS: CipherSuite>(
|
||||
sk: <CS::Group as Group>::Scalar,
|
||||
info: Option<&[u8]>,
|
||||
) -> Result<<CS::Group as Group>::Scalar>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Result<<CS::Group as Group>::Scalar> {
|
||||
// None for info is treated the same as empty bytes
|
||||
let info = info.unwrap_or_default();
|
||||
|
||||
@@ -691,8 +641,6 @@ fn poprf_unblind<'a, CS: 'a + CipherSuite, IC, IM>(
|
||||
info: Option<&[u8]>,
|
||||
) -> Result<PoprfUnblindResult<'a, CS, IC, IM>>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
&'a IC: 'a + IntoIterator<Item = &'a PoprfClient<CS>>,
|
||||
<&'a IC as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
&'a IM: 'a + IntoIterator<Item = &'a EvaluationElement<CS>>,
|
||||
@@ -720,7 +668,7 @@ where
|
||||
)?;
|
||||
|
||||
Ok(blinds
|
||||
.zip(messages.into_iter())
|
||||
.zip(messages)
|
||||
.map(|(blind, x)| x.0 * &CS::Group::invert_scalar(blind)))
|
||||
}
|
||||
|
||||
@@ -728,7 +676,7 @@ type FinalizeAfterUnblindResult<'a, CS, IE, II> = Map<
|
||||
Zip<Zip<IE, II>, Repeat<&'a [u8]>>,
|
||||
fn(
|
||||
((<<CS as CipherSuite>::Group as Group>::Elem, &[u8]), &[u8]),
|
||||
) -> Result<GenericArray<u8, <<CS as CipherSuite>::Hash as OutputSizeUser>::OutputSize>>,
|
||||
) -> Result<Output<<CS as CipherSuite>::Hash>>,
|
||||
>;
|
||||
|
||||
/// Can only fail with [`Error::Batch`] and returned values can only fail with
|
||||
@@ -744,8 +692,7 @@ fn finalize_after_unblind<
|
||||
info: Option<&'a [u8]>,
|
||||
) -> Result<FinalizeAfterUnblindResult<'a, CS, IE, II>>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
<<CS as CipherSuite>::Hash as OutputSizeUser>::OutputSize: ArrayLength,
|
||||
{
|
||||
if unblinded_elements.len() != inputs.len() {
|
||||
return Err(Error::Batch);
|
||||
@@ -784,11 +731,8 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::ops::Add;
|
||||
use core::ptr;
|
||||
|
||||
use generic_array::typenum::Sum;
|
||||
use generic_array::ArrayLength;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use super::*;
|
||||
@@ -800,11 +744,7 @@ mod tests {
|
||||
key: <CS::Group as Group>::Scalar,
|
||||
info: &[u8],
|
||||
mode: Mode,
|
||||
) -> Output<CS::Hash>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Output<CS::Hash> {
|
||||
let t = compute_tweak::<CS>(key, Some(info)).unwrap();
|
||||
|
||||
let dst = Dst::new::<CS, _, _>(STR_HASH_TO_GROUP, mode);
|
||||
@@ -820,11 +760,7 @@ mod tests {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn verifiable_retrieval<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn verifiable_retrieval<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let info = b"info";
|
||||
let mut rng = OsRng;
|
||||
@@ -847,11 +783,7 @@ mod tests {
|
||||
assert_eq!(client_finalize_result, res2);
|
||||
}
|
||||
|
||||
fn verifiable_bad_public_key<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn verifiable_bad_public_key<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let info = b"info";
|
||||
let mut rng = OsRng;
|
||||
@@ -875,11 +807,7 @@ mod tests {
|
||||
assert!(client_finalize_result.is_err());
|
||||
}
|
||||
|
||||
fn verifiable_server_evaluate<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn verifiable_server_evaluate<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let info = Some(b"info".as_slice());
|
||||
let mut rng = OsRng;
|
||||
@@ -912,13 +840,7 @@ mod tests {
|
||||
assert!(client_finalize != server_evaluate);
|
||||
}
|
||||
|
||||
fn zeroize_verifiable_client<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
|
||||
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ElemLen>: ArrayLength<u8>,
|
||||
{
|
||||
fn zeroize_verifiable_client<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = PoprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -932,15 +854,7 @@ mod tests {
|
||||
assert!(message.serialize().iter().all(|&x| x == 0));
|
||||
}
|
||||
|
||||
fn zeroize_verifiable_server<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
|
||||
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ElemLen>: ArrayLength<u8>,
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ScalarLen>,
|
||||
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ScalarLen>: ArrayLength<u8>,
|
||||
{
|
||||
fn zeroize_verifiable_server<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let info = b"info";
|
||||
let mut rng = OsRng;
|
||||
@@ -967,6 +881,7 @@ mod tests {
|
||||
fn test_functionality() -> Result<()> {
|
||||
use p256::NistP256;
|
||||
use p384::NistP384;
|
||||
use p521::NistP521;
|
||||
|
||||
#[cfg(feature = "ristretto255")]
|
||||
{
|
||||
@@ -994,6 +909,13 @@ mod tests {
|
||||
zeroize_verifiable_client::<NistP384>();
|
||||
zeroize_verifiable_server::<NistP384>();
|
||||
|
||||
verifiable_retrieval::<NistP521>();
|
||||
verifiable_bad_public_key::<NistP521>();
|
||||
verifiable_server_evaluate::<NistP521>();
|
||||
|
||||
zeroize_verifiable_client::<NistP521>();
|
||||
zeroize_verifiable_server::<NistP521>();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+19
-78
@@ -9,13 +9,9 @@
|
||||
//! Handles the serialization of each of the components used in the VOPRF
|
||||
//! protocol
|
||||
|
||||
use core::ops::Add;
|
||||
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::OutputSizeUser;
|
||||
use generic_array::sequence::Concat;
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, Sum, Unsigned, U256};
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use generic_array::typenum::{Sum, Unsigned};
|
||||
use generic_array::GenericArray;
|
||||
|
||||
use crate::{
|
||||
BlindedElement, CipherSuite, Error, EvaluationElement, Group, OprfClient, OprfServer,
|
||||
@@ -30,11 +26,7 @@ use crate::{
|
||||
/// Length of [`OprfClient`] in bytes for serialization.
|
||||
pub type OprfClientLen<CS> = <<CS as CipherSuite>::Group as Group>::ScalarLen;
|
||||
|
||||
impl<CS: CipherSuite> OprfClient<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> OprfClient<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, OprfClientLen<CS>> {
|
||||
CS::Group::serialize_scalar(self.blind)
|
||||
@@ -57,17 +49,9 @@ pub type VoprfClientLen<CS> = Sum<
|
||||
<<CS as CipherSuite>::Group as Group>::ElemLen,
|
||||
>;
|
||||
|
||||
impl<CS: CipherSuite> VoprfClient<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> VoprfClient<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, VoprfClientLen<CS>>
|
||||
where
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
|
||||
VoprfClientLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
pub fn serialize(&self) -> GenericArray<u8, VoprfClientLen<CS>> {
|
||||
<CS::Group as Group>::serialize_scalar(self.blind)
|
||||
.concat(<CS::Group as Group>::serialize_elem(self.blinded_element))
|
||||
}
|
||||
@@ -93,17 +77,9 @@ pub type PoprfClientLen<CS> = Sum<
|
||||
<<CS as CipherSuite>::Group as Group>::ElemLen,
|
||||
>;
|
||||
|
||||
impl<CS: CipherSuite> PoprfClient<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> PoprfClient<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, PoprfClientLen<CS>>
|
||||
where
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
|
||||
PoprfClientLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
pub fn serialize(&self) -> GenericArray<u8, PoprfClientLen<CS>> {
|
||||
<CS::Group as Group>::serialize_scalar(self.blind)
|
||||
.concat(<CS::Group as Group>::serialize_elem(self.blinded_element))
|
||||
}
|
||||
@@ -126,11 +102,7 @@ where
|
||||
/// Length of [`OprfServer`] in bytes for serialization.
|
||||
pub type OprfServerLen<CS> = <<CS as CipherSuite>::Group as Group>::ScalarLen;
|
||||
|
||||
impl<CS: CipherSuite> OprfServer<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> OprfServer<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, OprfServerLen<CS>> {
|
||||
CS::Group::serialize_scalar(self.sk)
|
||||
@@ -153,17 +125,9 @@ pub type VoprfServerLen<CS> = Sum<
|
||||
<<CS as CipherSuite>::Group as Group>::ElemLen,
|
||||
>;
|
||||
|
||||
impl<CS: CipherSuite> VoprfServer<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> VoprfServer<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, VoprfServerLen<CS>>
|
||||
where
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
|
||||
VoprfServerLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
pub fn serialize(&self) -> GenericArray<u8, VoprfServerLen<CS>> {
|
||||
CS::Group::serialize_scalar(self.sk).concat(CS::Group::serialize_elem(self.pk))
|
||||
}
|
||||
|
||||
@@ -185,17 +149,9 @@ pub type PoprfServerLen<CS> = Sum<
|
||||
<<CS as CipherSuite>::Group as Group>::ElemLen,
|
||||
>;
|
||||
|
||||
impl<CS: CipherSuite> PoprfServer<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> PoprfServer<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, PoprfServerLen<CS>>
|
||||
where
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
|
||||
PoprfServerLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
pub fn serialize(&self) -> GenericArray<u8, PoprfServerLen<CS>> {
|
||||
CS::Group::serialize_scalar(self.sk).concat(CS::Group::serialize_elem(self.pk))
|
||||
}
|
||||
|
||||
@@ -217,17 +173,9 @@ pub type ProofLen<CS> = Sum<
|
||||
<<CS as CipherSuite>::Group as Group>::ScalarLen,
|
||||
>;
|
||||
|
||||
impl<CS: CipherSuite> Proof<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> Proof<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, ProofLen<CS>>
|
||||
where
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ScalarLen>,
|
||||
ProofLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
pub fn serialize(&self) -> GenericArray<u8, ProofLen<CS>> {
|
||||
CS::Group::serialize_scalar(self.c_scalar)
|
||||
.concat(CS::Group::serialize_scalar(self.s_scalar))
|
||||
}
|
||||
@@ -247,11 +195,7 @@ where
|
||||
/// Length of [`BlindedElement`] in bytes for serialization.
|
||||
pub type BlindedElementLen<CS> = <<CS as CipherSuite>::Group as Group>::ElemLen;
|
||||
|
||||
impl<CS: CipherSuite> BlindedElement<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> BlindedElement<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, BlindedElementLen<CS>> {
|
||||
CS::Group::serialize_elem(self.0)
|
||||
@@ -271,11 +215,7 @@ where
|
||||
/// Length of [`EvaluationElement`] in bytes for serialization.
|
||||
pub type EvaluationElementLen<CS> = <<CS as CipherSuite>::Group as Group>::ElemLen;
|
||||
|
||||
impl<CS: CipherSuite> EvaluationElement<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> EvaluationElement<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, EvaluationElementLen<CS>> {
|
||||
CS::Group::serialize_elem(self.0)
|
||||
@@ -307,11 +247,11 @@ fn deserialize_scalar<G: Group>(input: &mut &[u8]) -> Result<G::Scalar> {
|
||||
}
|
||||
|
||||
trait SliceExt {
|
||||
fn take_ext(self: &mut &Self, take: usize) -> Option<&Self>;
|
||||
fn take_ext<'a>(self: &mut &'a Self, take: usize) -> Option<&'a Self>;
|
||||
}
|
||||
|
||||
impl<T> SliceExt for [T] {
|
||||
fn take_ext(self: &mut &Self, take: usize) -> Option<&Self> {
|
||||
fn take_ext<'a>(self: &mut &'a Self, take: usize) -> Option<&'a Self> {
|
||||
if take > self.len() {
|
||||
return None;
|
||||
}
|
||||
@@ -391,6 +331,7 @@ mod test {
|
||||
|
||||
let _ = $item::<p256::NistP256>::deserialize(&$bytes[..]);
|
||||
let _ = $item::<p384::NistP384>::deserialize(&$bytes[..]);
|
||||
let _ = $item::<p521::NistP521>::deserialize(&$bytes[..]);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+61
-171
@@ -7,24 +7,21 @@
|
||||
// licenses.
|
||||
|
||||
//! The VOPRF test vectors taken from:
|
||||
//! https://github.com/cfrg/draft-irtf-cfrg-voprf/blob/draft-irtf-cfrg-voprf-19/draft-irtf-cfrg-voprf.md
|
||||
//! https://www.rfc-editor.org/rfc/rfc9497#appendix-A
|
||||
|
||||
pub(crate) const VECTORS: &str = r#"
|
||||
## ristretto255-SHA512
|
||||
A.1. ristretto255-SHA512
|
||||
|
||||
### OPRF Mode
|
||||
A.1.1. OPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
skSm = 5ebcea5ee37023ccb9fc2d2019f9d7737be85591ae8652ffa9ef0f4d37063
|
||||
b0e
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.1.1.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
|
||||
6706
|
||||
@@ -35,11 +32,9 @@ d8cc917ea0869c7e
|
||||
Output = 527759c3d9366f277d8c6020418d96bb393ba2afb20ff90df23fb770826
|
||||
4e2f3ab9135e3bd69955851de4b1f9fe8a0973396719b7912ba9ee8aa7d0b5e24bcf
|
||||
6
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.1.1.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
|
||||
6706
|
||||
@@ -50,11 +45,9 @@ EvaluationElement = b4cbf5a4f1eeda5a63ce7b77c7d23f461db3fcab0dd28e4e
|
||||
Output = f4a74c9c592497375e796aa837e907b1a045d34306a749db9f34221f7e7
|
||||
50cb4f2a6413a6bf6fa5e19ba6348eb673934a722a7ede2e7621306d18951e7cf2c7
|
||||
3
|
||||
~~~
|
||||
|
||||
### VOPRF Mode
|
||||
A.1.2. VOPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -62,11 +55,9 @@ skSm = e6f73f344b79b379f1a0dd37e07ff62e38d9f71345ce62ae3a9bc60b04ccd
|
||||
909
|
||||
pkSm = c803e2cc6b05fc15064549b5920659ca4a77b2cca6f04f6b357009335476a
|
||||
d4e
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.1.2.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
|
||||
6706
|
||||
@@ -81,11 +72,9 @@ ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d98
|
||||
Output = b58cfbe118e0cb94d79b5fd6a6dafb98764dff49c14e1770b566e42402d
|
||||
a1a7da4d8527693914139caee5bd03903af43a491351d23b430948dd50cde10d32b3
|
||||
c
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.1.2.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
|
||||
6706
|
||||
@@ -100,11 +89,9 @@ ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d98
|
||||
Output = 8a9a2f3c7f085b65933594309041fc1898d42d0858e59f90814ae90571a
|
||||
6df60356f4610bf816f27afdd84f47719e480906d27ecd994985890e5f539e7ea74b
|
||||
6
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.1.2.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
|
||||
6706,222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0
|
||||
@@ -123,11 +110,9 @@ Output = b58cfbe118e0cb94d79b5fd6a6dafb98764dff49c14e1770b566e42402d
|
||||
a1a7da4d8527693914139caee5bd03903af43a491351d23b430948dd50cde10d32b3
|
||||
c,8a9a2f3c7f085b65933594309041fc1898d42d0858e59f90814ae90571a6df6035
|
||||
6f4610bf816f27afdd84f47719e480906d27ecd994985890e5f539e7ea74b6
|
||||
~~~
|
||||
|
||||
### POPRF Mode
|
||||
A.1.3. POPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -135,11 +120,9 @@ skSm = 145c79c108538421ac164ecbe131942136d5570b16d8bf41a24d4337da981
|
||||
e07
|
||||
pkSm = c647bef38497bc6ec077c22af65b696efa43bff3b4a1975a3e8e0a1c5a79d
|
||||
631
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.1.3.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Info = 7465737420696e666f
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
|
||||
@@ -155,11 +138,9 @@ ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d98
|
||||
Output = ca688351e88afb1d841fde4401c79efebb2eb75e7998fa9737bd5a82a15
|
||||
2406d38bd29f680504e54fd4587eddcf2f37a2617ac2fbd2993f7bdf45442ace7d22
|
||||
1
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.1.3.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
|
||||
@@ -175,11 +156,9 @@ ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d98
|
||||
Output = 7c6557b276a137922a0bcfc2aa2b35dd78322bd500235eb6d6b6f91bc5b
|
||||
56a52de2d65612d503236b321f5d0bebcbc52b64b92e426f29c9b8b69f52de98ae50
|
||||
7
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.1.3.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
|
||||
@@ -199,23 +178,19 @@ Output = ca688351e88afb1d841fde4401c79efebb2eb75e7998fa9737bd5a82a15
|
||||
2406d38bd29f680504e54fd4587eddcf2f37a2617ac2fbd2993f7bdf45442ace7d22
|
||||
1,7c6557b276a137922a0bcfc2aa2b35dd78322bd500235eb6d6b6f91bc5b56a52de
|
||||
2d65612d503236b321f5d0bebcbc52b64b92e426f29c9b8b69f52de98ae507
|
||||
~~~
|
||||
|
||||
## decaf448-SHAKE256
|
||||
A.2. decaf448-SHAKE256
|
||||
|
||||
### OPRF Mode
|
||||
A.2.1. OPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
skSm = e8b1375371fd11ebeb224f832dcc16d371b4188951c438f751425699ed29e
|
||||
cc80c6c13e558ccd67634fd82eac94aa8d1f0d7fee990695d1e
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.2.1.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
|
||||
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
|
||||
@@ -226,11 +201,9 @@ EvaluationElement = 50ce4e60eed006e22e7027454b5a4b8319eb2bc8ced609eb
|
||||
Output = 37d3f7922d9388a15b561de5829bbf654c4089ede89c0ce0f3f85bcdba0
|
||||
9e382ce0ab3507e021f9e79706a1798ffeac68ebd5cf62e5eb9838c7068351d97ae3
|
||||
7
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.2.1.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
|
||||
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
|
||||
@@ -241,11 +214,9 @@ EvaluationElement = 162e9fa6e9d527c3cd734a31bf122a34dbd5bcb7bb23651f
|
||||
Output = a2a652290055cb0f6f8637a249ee45e32ef4667db0b4c80c0a70d2a6416
|
||||
4d01525cfdad5d870a694ec77972b9b6ec5d2596a5223e5336913f945101f0137f55
|
||||
e
|
||||
~~~
|
||||
|
||||
### VOPRF Mode
|
||||
A.2.2. VOPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -253,11 +224,9 @@ skSm = e3c01519a076a326a0eb566343e9b21c115fa18e6e85577ddbe890b33104f
|
||||
cc2835ddfb14a928dc3f5d79b936e17c76b99e0bf6a1680930e
|
||||
pkSm = 945fc518c47695cf65217ace04b86ac5e4cbe26ca649d52854bb16c494ce0
|
||||
9069d6add96b20d4b0ae311a87c9a73e3a146b525763ab2f955
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.2.2.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
|
||||
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
|
||||
@@ -274,11 +243,9 @@ ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0
|
||||
Output = e2ac40b634f36cccd8262b285adff7c9dcc19cd308564a5f4e581d1a853
|
||||
5773b86fa4fc9f2203c370763695c5093aea4a7aedec4488b1340ba3bf663a23098c
|
||||
1
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.2.2.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
|
||||
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
|
||||
@@ -295,11 +262,9 @@ ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0
|
||||
Output = 862952380e07ec840d9f6e6f909c5a25d16c3dacb586d89a181b4aa7380
|
||||
c959baa8c480fe8e6c64e089d68ea7aeeb5817bd524d7577905b5bab487690048c94
|
||||
1
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.2.2.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
|
||||
3833a26e9388336361686ff1f83df55046504dfecad8549ba112,b1b748135d405ce
|
||||
@@ -323,11 +288,9 @@ Output = e2ac40b634f36cccd8262b285adff7c9dcc19cd308564a5f4e581d1a853
|
||||
5773b86fa4fc9f2203c370763695c5093aea4a7aedec4488b1340ba3bf663a23098c
|
||||
1,862952380e07ec840d9f6e6f909c5a25d16c3dacb586d89a181b4aa7380c959baa
|
||||
8c480fe8e6c64e089d68ea7aeeb5817bd524d7577905b5bab487690048c941
|
||||
~~~
|
||||
|
||||
### POPRF Mode
|
||||
A.2.3. POPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -335,11 +298,9 @@ skSm = 792a10dcbd3ba4a52a054f6f39186623208695301e7adb9634b74709ab22d
|
||||
e402990eb143fd7c67ac66be75e0609705ecea800992aac8e19
|
||||
pkSm = 6c9d12723a5bbcf305522cc04b4a34d9ced2e12831826018ea7b5dcf54526
|
||||
47ad262113059bf0f6e4354319951b9d513c74f29cb0eec38c1
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.2.3.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Info = 7465737420696e666f
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
|
||||
@@ -357,11 +318,9 @@ ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0
|
||||
Output = 4423f6dcc1740688ea201de57d76824d59cd6b859e1f9884b7eebc49b0b
|
||||
971358cf9cb075df1536a8ea31bcf55c3e31c2ba9cfa8efe54448d17091daeb9924e
|
||||
d
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.2.3.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
|
||||
@@ -379,11 +338,9 @@ ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0
|
||||
Output = 8691905500510843902c44bdd9730ab9dc3925aa58ff9dd42765a2baf63
|
||||
3126de0c3adb93bef5652f38e5827b6396e87643960163a560fc4ac9738c8de4e4a8
|
||||
d
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.2.3.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
|
||||
@@ -408,23 +365,19 @@ Output = 4423f6dcc1740688ea201de57d76824d59cd6b859e1f9884b7eebc49b0b
|
||||
971358cf9cb075df1536a8ea31bcf55c3e31c2ba9cfa8efe54448d17091daeb9924e
|
||||
d,8691905500510843902c44bdd9730ab9dc3925aa58ff9dd42765a2baf633126de0
|
||||
c3adb93bef5652f38e5827b6396e87643960163a560fc4ac9738c8de4e4a8d
|
||||
~~~
|
||||
|
||||
## P256-SHA256
|
||||
A.3. P256-SHA256
|
||||
|
||||
### OPRF Mode
|
||||
A.3.1. OPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
skSm = 159749d750713afe245d2d39ccfaae8381c53ce92d098a9375ee70739c7ac
|
||||
0bf
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.3.1.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
d364
|
||||
@@ -434,11 +387,9 @@ EvaluationElement = 030de02ffec47a1fd53efcdd1c6faf5bdc270912b8749e78
|
||||
3c7ca75bb412958832
|
||||
Output = a0b34de5fa4c5b6da07e72af73cc507cceeb48981b97b7285fc375345fe
|
||||
495dd
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.3.1.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
d364
|
||||
@@ -448,11 +399,9 @@ EvaluationElement = 03a0395fe3828f2476ffcd1f4fe540e5a8489322d398be3c
|
||||
4e5a869db7fcb7c52c
|
||||
Output = c748ca6dd327f0ce85f4ae3a8cd6d4d5390bbb804c9e12dcf94f853fece
|
||||
3dcce
|
||||
~~~
|
||||
|
||||
### VOPRF Mode
|
||||
A.3.2. VOPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -460,11 +409,9 @@ skSm = ca5d94c8807817669a51b196c34c1b7f8442fde4334a7121ae4736364312f
|
||||
ca6
|
||||
pkSm = 03e17e70604bcabe198882c0a1f27a92441e774224ed9c702e51dd17038b1
|
||||
02462
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.3.2.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
d364
|
||||
@@ -478,11 +425,9 @@ ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698c
|
||||
e45c405d1348b7b1
|
||||
Output = 0412e8f78b02c415ab3a288e228978376f99927767ff37c5718d420010a
|
||||
645a1
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.3.2.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
d364
|
||||
@@ -496,11 +441,9 @@ ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698c
|
||||
e45c405d1348b7b1
|
||||
Output = 771e10dcd6bcd3664e23b8f2a710cfaaa8357747c4a8cbba03133967b5c
|
||||
24f18
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.3.2.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
d364,f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b
|
||||
@@ -518,11 +461,9 @@ ProofRandomScalar = 350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba
|
||||
Output = 0412e8f78b02c415ab3a288e228978376f99927767ff37c5718d420010a
|
||||
645a1,771e10dcd6bcd3664e23b8f2a710cfaaa8357747c4a8cbba03133967b5c24f
|
||||
18
|
||||
~~~
|
||||
|
||||
### POPRF Mode
|
||||
A.3.3. POPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -530,11 +471,9 @@ skSm = 6ad2173efa689ef2c27772566ad7ff6e2d59b3b196f00219451fb2c89ee4d
|
||||
ae2
|
||||
pkSm = 030d7ff077fddeec965db14b794f0cc1ba9019b04a2f4fcc1fa525dedf72e
|
||||
2a3e3
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.3.3.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Info = 7465737420696e666f
|
||||
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
@@ -549,11 +488,9 @@ ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698c
|
||||
e45c405d1348b7b1
|
||||
Output = 193a92520bd8fd1f37accb918040a57108daa110dc4f659abe212636d24
|
||||
5c592
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.3.3.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
@@ -568,11 +505,9 @@ ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698c
|
||||
e45c405d1348b7b1
|
||||
Output = 1e6d164cfd835d88a31401623549bf6b9b306628ef03a7962921d62bc5f
|
||||
fce8c
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.3.3.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
@@ -591,23 +526,19 @@ ProofRandomScalar = 350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba
|
||||
Output = 193a92520bd8fd1f37accb918040a57108daa110dc4f659abe212636d24
|
||||
5c592,1e6d164cfd835d88a31401623549bf6b9b306628ef03a7962921d62bc5ffce
|
||||
8c
|
||||
~~~
|
||||
|
||||
## P384-SHA384
|
||||
A.4. P384-SHA384
|
||||
|
||||
### OPRF Mode
|
||||
A.4.1. OPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
skSm = dfe7ddc41a4646901184f2b432616c8ba6d452f9bcd0c4f75a5150ef2b2ed
|
||||
02ef40b8b92f60ae591bcabd72a6518f188
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.4.1.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
|
||||
889d89dbfa691d1cde91517fa222ed7ad364
|
||||
@@ -617,11 +548,9 @@ EvaluationElement = 03af2a4fc94770d7a7bf3187ca9cc4faf3732049eded2442
|
||||
ee50fbddda58b70ae2999366f72498cdbc43e6f2fc184afe30
|
||||
Output = ed84ad3f31a552f0456e58935fcc0a3039db42e7f356dcb32aa6d487b6b
|
||||
815a07d5813641fb1398c03ddab5763874357
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.4.1.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
|
||||
889d89dbfa691d1cde91517fa222ed7ad364
|
||||
@@ -631,11 +560,9 @@ EvaluationElement = 034e9b9a2960b536f2ef47d8608b21597ba400d5abfa1825
|
||||
fd21c36b75f927f396bf3716c96129d1fa4a77fa1d479c8d7b
|
||||
Output = dd4f29da869ab9355d60617b60da0991e22aaab243a3460601e48b07585
|
||||
9d1c526d36597326f1b985778f781a1682e75
|
||||
~~~
|
||||
|
||||
### VOPRF Mode
|
||||
A.4.2. VOPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -643,11 +570,9 @@ skSm = 051646b9e6e7a71ae27c1e1d0b87b4381db6d3595eeeb1adb41579adbf992
|
||||
f4278f9016eafc944edaa2b43183581779d
|
||||
pkSm = 031d689686c611991b55f1a1d8f4305ccd6cb719446f660a30db61b7aa87b
|
||||
46acf59b7c0d4a9077b3da21c25dd482229a0
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.4.2.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
|
||||
889d89dbfa691d1cde91517fa222ed7ad364
|
||||
@@ -662,11 +587,9 @@ ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62
|
||||
c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
|
||||
Output = 3333230886b562ffb8329a8be08fea8025755372817ec969d114d1203d0
|
||||
26b4a622beab60220bf19078bca35a529b35c
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.4.2.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
|
||||
889d89dbfa691d1cde91517fa222ed7ad364
|
||||
@@ -681,11 +604,9 @@ ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62
|
||||
c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
|
||||
Output = b91c70ea3d4d62ba922eb8a7d03809a441e1c3c7af915cbc2226f485213
|
||||
e895942cd0f8580e6d99f82221e66c40d274f
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.4.2.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
|
||||
889d89dbfa691d1cde91517fa222ed7ad364,803d955f0e073a04aa5d92b3fb739f5
|
||||
@@ -706,11 +627,9 @@ eca27405420cdf3d63cb3aef005f40ba51943c8026877963
|
||||
Output = 3333230886b562ffb8329a8be08fea8025755372817ec969d114d1203d0
|
||||
26b4a622beab60220bf19078bca35a529b35c,b91c70ea3d4d62ba922eb8a7d03809
|
||||
a441e1c3c7af915cbc2226f485213e895942cd0f8580e6d99f82221e66c40d274f
|
||||
~~~
|
||||
|
||||
### POPRF Mode
|
||||
A.4.3. POPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -718,11 +637,9 @@ skSm = 5b2690d6954b8fbb159f19935d64133f12770c00b68422559c65431942d72
|
||||
1ff79d47d7a75906c30b7818ec0f38b7fb2
|
||||
pkSm = 02f00f0f1de81e5d6cf18140d4926ffdc9b1898c48dc49657ae36eb1e45de
|
||||
b8b951aaf1f10c82d2eaa6d02aafa3f10d2b6
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.4.3.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Info = 7465737420696e666f
|
||||
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
|
||||
@@ -738,11 +655,9 @@ ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62
|
||||
c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
|
||||
Output = 0188653cfec38119a6c7dd7948b0f0720460b4310e40824e048bf82a165
|
||||
27303ed449a08caf84272c3bbc972ede797df
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.4.3.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
|
||||
@@ -758,11 +673,9 @@ ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62
|
||||
c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
|
||||
Output = ff2a527a21cc43b251a567382677f078c6e356336aec069dea8ba369953
|
||||
43ca3b33bb5d6cf15be4d31a7e6d75b30d3f5
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.4.3.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
|
||||
@@ -784,24 +697,20 @@ eca27405420cdf3d63cb3aef005f40ba51943c8026877963
|
||||
Output = 0188653cfec38119a6c7dd7948b0f0720460b4310e40824e048bf82a165
|
||||
27303ed449a08caf84272c3bbc972ede797df,ff2a527a21cc43b251a567382677f0
|
||||
78c6e356336aec069dea8ba36995343ca3b33bb5d6cf15be4d31a7e6d75b30d3f5
|
||||
~~~
|
||||
|
||||
## P521-SHA512
|
||||
A.5. P521-SHA512
|
||||
|
||||
### OPRF Mode
|
||||
A.5.1. OPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
skSm = 0153441b8faedb0340439036d6aed06d1217b34c42f17f8db4c5cc610a4a9
|
||||
55d698a688831b16d0dc7713a1aa3611ec60703bffc7dc9c84e3ed673b3dbe1d5fcc
|
||||
ea6
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.5.1.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
|
||||
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
@@ -815,11 +724,9 @@ EvaluationElement = 030166371cf827cb2fb9b581f97907121a16e2dc5d8b10ce
|
||||
Output = 26232de6fff83f812adadadb6cc05d7bbeee5dca043dbb16b03488abb99
|
||||
81d0a1ef4351fad52dbd7e759649af393348f7b9717566c19a6b8856284d69375c80
|
||||
9
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.5.1.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
|
||||
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
@@ -833,11 +740,9 @@ af5640cbb2d9620a6e
|
||||
Output = ad1f76ef939042175e007738906ac0336bbd1d51e287ebaa66901abdd32
|
||||
4ea3ffa40bfc5a68e7939c2845e0fd37a5a6e76dadb9907c6cc8579629757fd4d04b
|
||||
a
|
||||
~~~
|
||||
|
||||
### VOPRF Mode
|
||||
A.5.2. VOPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -847,11 +752,9 @@ skSm = 015c7fc1b4a0b1390925bae915bd9f3d72009d44d9241b962428aad5d13f2
|
||||
pkSm = 0301505d646f6e4c9102451eb39730c4ba1c4087618641edbdba4a60896b0
|
||||
7fd0c9414ce553cbf25b81dfcca50a8f6724ab7a2bc4d0cf736967a287bb6084cc06
|
||||
78ac0
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.5.2.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
|
||||
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
@@ -872,11 +775,9 @@ e45c405d1348b7b1
|
||||
Output = 5e003d9b2fb540b3d4bab5fedd154912246da1ee5e557afd8f56415faa1
|
||||
a0fadff6517da802ee254437e4f60907b4cda146e7ba19e249eef7be405549f62954
|
||||
b
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.5.2.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
|
||||
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
@@ -897,11 +798,9 @@ e45c405d1348b7b1
|
||||
Output = fa15eebba81ecf40954f7135cb76f69ef22c6bae394d1a4362f9b03066b
|
||||
54b6604d39f2e53369ca6762a3d9787e230e832aa85955af40ecb8deebb009a8cf47
|
||||
4
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.5.2.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
|
||||
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
|
||||
@@ -929,11 +828,9 @@ Output = 5e003d9b2fb540b3d4bab5fedd154912246da1ee5e557afd8f56415faa1
|
||||
a0fadff6517da802ee254437e4f60907b4cda146e7ba19e249eef7be405549f62954
|
||||
b,fa15eebba81ecf40954f7135cb76f69ef22c6bae394d1a4362f9b03066b54b6604
|
||||
d39f2e53369ca6762a3d9787e230e832aa85955af40ecb8deebb009a8cf474
|
||||
~~~
|
||||
|
||||
### POPRF Mode
|
||||
A.5.3. POPRF Mode
|
||||
|
||||
~~~
|
||||
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
|
||||
3a3
|
||||
KeyInfo = 74657374206b6579
|
||||
@@ -943,11 +840,9 @@ b27
|
||||
pkSm = 0301de8ceb9ffe9237b1bba87c320ea0bebcfc3447fe6f278065c6c69886d
|
||||
692d1126b79b6844f829940ace9b52a5e26882cf7cbc9e57503d4cca3cd834584729
|
||||
f812a
|
||||
~~~
|
||||
|
||||
#### Test Vector 1, Batch Size 1
|
||||
A.5.3.1. Test Vector 1, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 00
|
||||
Info = 7465737420696e666f
|
||||
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
|
||||
@@ -969,11 +864,9 @@ e45c405d1348b7b1
|
||||
Output = 808ae5b87662eaaf0b39151dd85991b94c96ef214cb14a68bf5c1439548
|
||||
82d330da8953a80eea20788e552bc8bbbfff3100e89f9d6e341197b122c46a208733
|
||||
b
|
||||
~~~
|
||||
|
||||
#### Test Vector 2, Batch Size 1
|
||||
A.5.3.2. Test Vector 2, Batch Size 1
|
||||
|
||||
~~~
|
||||
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
|
||||
@@ -995,11 +888,9 @@ e45c405d1348b7b1
|
||||
Output = 27032e24b1a52a82ab7f4646f3c5df0f070f499db98b9c5df33972bd5af
|
||||
5762c3638afae7912a6c1acdb1ae2ab2fa670bd5486c645a0e55412e08d33a4a0d6e
|
||||
3
|
||||
~~~
|
||||
|
||||
#### Test Vector 3, Batch Size 2
|
||||
A.5.3.3. Test Vector 3, Batch Size 2
|
||||
|
||||
~~~
|
||||
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
|
||||
Info = 7465737420696e666f
|
||||
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
|
||||
@@ -1028,5 +919,4 @@ Output = 808ae5b87662eaaf0b39151dd85991b94c96ef214cb14a68bf5c1439548
|
||||
82d330da8953a80eea20788e552bc8bbbfff3100e89f9d6e341197b122c46a208733
|
||||
b,27032e24b1a52a82ab7f4646f3c5df0f070f499db98b9c5df33972bd5af5762c36
|
||||
38afae7912a6c1acdb1ae2ab2fa670bd5486c645a0e55412e08d33a4a0d6e3
|
||||
~~~
|
||||
"#;
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ pub(crate) fn rfc_to_json(input: &str) -> String {
|
||||
}
|
||||
|
||||
fn parse_ciphersuites(input: &str) -> String {
|
||||
let re = regex::Regex::new(r"\n## (?P<ciphersuite>.+?)\n").unwrap();
|
||||
let re = regex::Regex::new(r"\nA\.\d\. (?P<ciphersuite>.+?)\n\n").unwrap();
|
||||
let mut ciphersuites = vec![];
|
||||
|
||||
let chunks: Vec<&str> = re.split(input).collect();
|
||||
@@ -34,7 +34,7 @@ fn parse_ciphersuites(input: &str) -> String {
|
||||
}
|
||||
|
||||
fn parse_modes(input: &str) -> String {
|
||||
let re = regex::Regex::new(r"### (?P<mode>.*+) Mode").unwrap();
|
||||
let re = regex::Regex::new(r"A\.\d.\d\. (?P<mode>.*?) Mode").unwrap();
|
||||
let mut modes = vec![];
|
||||
|
||||
let chunks: Vec<&str> = re.split(input).collect();
|
||||
@@ -53,7 +53,7 @@ fn parse_modes(input: &str) -> String {
|
||||
}
|
||||
|
||||
fn parse_vectors(input: &str) -> String {
|
||||
let re = regex::Regex::new(r"Test Vector.*+\n").unwrap();
|
||||
let re = regex::Regex::new(r"A\.\d.\d\.\d\. Test Vector.*+\n").unwrap();
|
||||
let mut vectors = vec![];
|
||||
|
||||
let chunks: Vec<&str> = re.split(input).collect();
|
||||
|
||||
@@ -9,12 +9,7 @@
|
||||
use alloc::string::String;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use core::ops::Add;
|
||||
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::OutputSizeUser;
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, Sum, U256};
|
||||
use generic_array::ArrayLength;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::tests::mock_rng::CycleRng;
|
||||
@@ -89,6 +84,7 @@ macro_rules! json_to_test_vectors {
|
||||
fn test_vectors() -> Result<()> {
|
||||
use p256::NistP256;
|
||||
use p384::NistP384;
|
||||
use p521::NistP521;
|
||||
|
||||
let rfc: Value = serde_json::from_str(rfc_to_json(super::cfrg_vectors::VECTORS).as_str())
|
||||
.expect("Could not parse json");
|
||||
@@ -188,14 +184,37 @@ fn test_vectors() -> Result<()> {
|
||||
test_poprf_finalize::<NistP384>(&p384_poprf_tvs)?;
|
||||
test_poprf_evaluate::<NistP384>(&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::<NistP521>(&p521_oprf_tvs)?;
|
||||
test_oprf_blind::<NistP521>(&p521_oprf_tvs)?;
|
||||
test_oprf_blind_evaluate::<NistP521>(&p521_oprf_tvs)?;
|
||||
test_oprf_finalize::<NistP521>(&p521_oprf_tvs)?;
|
||||
test_oprf_evaluate::<NistP521>(&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::<NistP521>(&p521_voprf_tvs)?;
|
||||
test_voprf_blind::<NistP521>(&p521_voprf_tvs)?;
|
||||
test_voprf_blind_evaluate::<NistP521>(&p521_voprf_tvs)?;
|
||||
test_voprf_finalize::<NistP521>(&p521_voprf_tvs)?;
|
||||
test_voprf_evaluate::<NistP521>(&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::<NistP521>(&p521_poprf_tvs)?;
|
||||
test_poprf_blind::<NistP521>(&p521_poprf_tvs)?;
|
||||
test_poprf_blind_evaluate::<NistP521>(&p521_poprf_tvs)?;
|
||||
test_poprf_finalize::<NistP521>(&p521_poprf_tvs)?;
|
||||
test_poprf_evaluate::<NistP521>(&p521_poprf_tvs)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_oprf_seed_to_key<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_oprf_seed_to_key<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
let server = OprfServer::<CS>::new_from_seed(¶meters.seed, ¶meters.key_info)?;
|
||||
|
||||
@@ -207,11 +226,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_voprf_seed_to_key<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_voprf_seed_to_key<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
let server = VoprfServer::<CS>::new_from_seed(¶meters.seed, ¶meters.key_info)?;
|
||||
|
||||
@@ -227,11 +242,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_poprf_seed_to_key<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_poprf_seed_to_key<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
let server = PoprfServer::<CS>::new_from_seed(¶meters.seed, ¶meters.key_info)?;
|
||||
|
||||
@@ -248,11 +259,7 @@ where
|
||||
}
|
||||
|
||||
// Tests input -> blind, blinded_element
|
||||
fn test_oprf_blind<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_oprf_blind<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let blind = CS::Group::deserialize_scalar(¶meters.blind[i])?;
|
||||
@@ -273,11 +280,7 @@ where
|
||||
}
|
||||
|
||||
// Tests input -> blind, blinded_element
|
||||
fn test_voprf_blind<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_voprf_blind<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let blind = CS::Group::deserialize_scalar(¶meters.blind[i])?;
|
||||
@@ -298,11 +301,7 @@ where
|
||||
}
|
||||
|
||||
// Tests input -> blind, blinded_element
|
||||
fn test_poprf_blind<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_poprf_blind<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let blind = CS::Group::deserialize_scalar(¶meters.blind[i])?;
|
||||
@@ -323,11 +322,7 @@ where
|
||||
}
|
||||
|
||||
// Tests sksm, blinded_element -> evaluation_element
|
||||
fn test_oprf_blind_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_oprf_blind_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let server = OprfServer::<CS>::new_with_key(¶meters.sksm)?;
|
||||
@@ -344,13 +339,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_voprf_blind_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ScalarLen>,
|
||||
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ScalarLen>: ArrayLength<u8>,
|
||||
{
|
||||
fn test_voprf_blind_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
let mut rng = CycleRng::new(parameters.proof_random_scalar.clone());
|
||||
let server = VoprfServer::<CS>::new_with_key(¶meters.sksm)?;
|
||||
@@ -376,13 +365,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_poprf_blind_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ScalarLen>,
|
||||
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ScalarLen>: ArrayLength<u8>,
|
||||
{
|
||||
fn test_poprf_blind_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
let mut rng = CycleRng::new(parameters.proof_random_scalar.clone());
|
||||
let server = PoprfServer::<CS>::new_with_key(¶meters.sksm)?;
|
||||
@@ -418,11 +401,7 @@ where
|
||||
}
|
||||
|
||||
// Tests input, blind, evaluation_element -> output
|
||||
fn test_oprf_finalize<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_oprf_finalize<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let client =
|
||||
@@ -439,11 +418,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_voprf_finalize<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_voprf_finalize<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
let mut clients = vec![];
|
||||
for i in 0..parameters.input.len() {
|
||||
@@ -478,11 +453,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_poprf_finalize<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_poprf_finalize<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
let mut clients = vec![];
|
||||
for i in 0..parameters.input.len() {
|
||||
@@ -516,11 +487,7 @@ where
|
||||
}
|
||||
|
||||
// Tests input, sksm -> output
|
||||
fn test_oprf_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_oprf_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let server = OprfServer::<CS>::new_with_key(¶meters.sksm)?;
|
||||
@@ -533,11 +500,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_voprf_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_voprf_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let server = VoprfServer::<CS>::new_with_key(¶meters.sksm)?;
|
||||
@@ -550,11 +513,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_poprf_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn test_poprf_evaluate<CS: CipherSuite>(tvs: &[VOPRFTestVectorParameters]) -> Result<()> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let server = PoprfServer::<CS>::new_with_key(¶meters.sksm)?;
|
||||
|
||||
+33
-101
@@ -13,9 +13,8 @@ use alloc::vec::Vec;
|
||||
use core::iter::{self, Map, Repeat, Zip};
|
||||
|
||||
use derive_where::derive_where;
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::{Digest, Output, OutputSizeUser};
|
||||
use generic_array::typenum::{IsLess, IsLessOrEqual, Unsigned, U256};
|
||||
use digest::{Digest, Output};
|
||||
use generic_array::typenum::Unsigned;
|
||||
use generic_array::GenericArray;
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
|
||||
@@ -42,11 +41,7 @@ use crate::{CipherSuite, Error, Group, Result};
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
)]
|
||||
pub struct VoprfClient<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct VoprfClient<CS: CipherSuite> {
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
pub(crate) blind: <CS::Group as Group>::Scalar,
|
||||
#[cfg_attr(feature = "serde", serde(with = "Element::<CS::Group>"))]
|
||||
@@ -62,11 +57,7 @@ where
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
)]
|
||||
pub struct VoprfServer<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct VoprfServer<CS: CipherSuite> {
|
||||
#[cfg_attr(feature = "serde", serde(with = "Scalar::<CS::Group>"))]
|
||||
pub(crate) sk: <CS::Group as Group>::Scalar,
|
||||
#[cfg_attr(feature = "serde", serde(with = "Element::<CS::Group>"))]
|
||||
@@ -78,11 +69,7 @@ where
|
||||
// =================== //
|
||||
/////////////////////////
|
||||
|
||||
impl<CS: CipherSuite> VoprfClient<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> VoprfClient<CS> {
|
||||
/// Computes the first step for the multiplicative blinding version of
|
||||
/// DH-OPRF.
|
||||
///
|
||||
@@ -161,7 +148,7 @@ where
|
||||
///
|
||||
/// The resulting messages can each fail individually with [`Error::Input`]
|
||||
/// if the `input` is empty or longer then [`u16::MAX`].
|
||||
pub fn batch_finalize<'a, I: 'a, II, IC, IM>(
|
||||
pub fn batch_finalize<'a, I, II, IC, IM>(
|
||||
inputs: &'a II,
|
||||
clients: &'a IC,
|
||||
messages: &'a IM,
|
||||
@@ -170,7 +157,7 @@ where
|
||||
) -> Result<VoprfClientBatchFinalizeResult<'a, CS, I, II, IC, IM>>
|
||||
where
|
||||
CS: 'a,
|
||||
I: AsRef<[u8]>,
|
||||
I: 'a + AsRef<[u8]>,
|
||||
&'a II: 'a + IntoIterator<Item = I>,
|
||||
<&'a II as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
&'a IC: 'a + IntoIterator<Item = &'a VoprfClient<CS>>,
|
||||
@@ -197,18 +184,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// Only used for test functions
|
||||
/// Only used for test functions
|
||||
#[cfg(test)]
|
||||
pub fn get_blind(&self) -> <CS::Group as Group>::Scalar {
|
||||
self.blind
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> VoprfServer<CS>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
impl<CS: CipherSuite> VoprfServer<CS> {
|
||||
/// Produces a new instance of a [VoprfServer] using a supplied RNG
|
||||
///
|
||||
/// # Errors
|
||||
@@ -246,7 +229,7 @@ where
|
||||
Ok(Self { sk, pk })
|
||||
}
|
||||
|
||||
// Only used for tests
|
||||
/// Only used for tests
|
||||
#[cfg(test)]
|
||||
pub fn get_private_key(&self) -> <CS::Group as Group>::Scalar {
|
||||
self.sk
|
||||
@@ -402,11 +385,7 @@ where
|
||||
|
||||
/// Contains the fields that are returned by a verifiable client blind
|
||||
#[derive_where(Debug; <CS::Group as Group>::Scalar, <CS::Group as Group>::Elem)]
|
||||
pub struct VoprfClientBlindResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct VoprfClientBlindResult<CS: CipherSuite> {
|
||||
/// The state to be persisted on the client
|
||||
pub state: VoprfClient<CS>,
|
||||
/// The message to send to the server
|
||||
@@ -423,11 +402,7 @@ pub type VoprfClientBatchFinalizeResult<'a, C, I, II, IC, IM> = FinalizeAfterUnb
|
||||
|
||||
/// Contains the fields that are returned by a verifiable server evaluate
|
||||
#[derive_where(Debug; <CS::Group as Group>::Scalar, <CS::Group as Group>::Elem)]
|
||||
pub struct VoprfServerEvaluateResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct VoprfServerEvaluateResult<CS: CipherSuite> {
|
||||
/// The message to send to the client
|
||||
pub message: EvaluationElement<CS>,
|
||||
/// The proof for the client to verify
|
||||
@@ -437,11 +412,7 @@ where
|
||||
/// Contains the fields that are returned by a verifiable server batch evaluate
|
||||
#[derive_where(Debug; <CS::Group as Group>::Scalar, <CS::Group as Group>::Elem)]
|
||||
#[cfg(feature = "alloc")]
|
||||
pub struct VoprfServerBatchEvaluateResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
pub struct VoprfServerBatchEvaluateResult<CS: CipherSuite> {
|
||||
/// The messages to send to the client
|
||||
pub messages: Vec<EvaluationElement<CS>>,
|
||||
/// The proof for the client to verify
|
||||
@@ -472,8 +443,6 @@ pub type VoprfServerBatchEvaluateFinishedMessages<'a, CS, I> = Map<
|
||||
#[derive_where(Debug; <&'a I as IntoIterator>::IntoIter, <CS::Group as Group>::Scalar)]
|
||||
pub struct VoprfServerBatchEvaluateFinishResult<'a, CS: 'a + CipherSuite, I>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
&'a I: IntoIterator<Item = &'a PreparedEvaluationElement<CS>>,
|
||||
{
|
||||
/// The [`EvaluationElement`]s to send to the client
|
||||
@@ -511,8 +480,6 @@ fn verifiable_unblind<'a, CS: 'a + CipherSuite, IC, IM>(
|
||||
proof: &Proof<CS>,
|
||||
) -> Result<VoprfUnblindResult<'a, CS, IC, IM>>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
&'a IC: 'a + IntoIterator<Item = &'a VoprfClient<CS>>,
|
||||
<&'a IC as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
&'a IM: 'a + IntoIterator<Item = &'a EvaluationElement<CS>>,
|
||||
@@ -537,7 +504,7 @@ where
|
||||
)?;
|
||||
|
||||
Ok(blinds
|
||||
.zip(messages.into_iter())
|
||||
.zip(messages)
|
||||
.map(|(blind, x)| x.0 * &CS::Group::invert_scalar(blind)))
|
||||
}
|
||||
|
||||
@@ -554,11 +521,7 @@ fn finalize_after_unblind<
|
||||
IE: 'a + Iterator<Item = (I, <CS::Group as Group>::Elem)>,
|
||||
>(
|
||||
inputs_and_unblinded_elements: IE,
|
||||
) -> FinalizeAfterUnblindResult<'a, CS, I, IE>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> FinalizeAfterUnblindResult<'a, CS, I, IE> {
|
||||
inputs_and_unblinded_elements.map(|(input, unblinded_element)| {
|
||||
let elem_len = <CS::Group as Group>::ElemLen::U16.to_be_bytes();
|
||||
|
||||
@@ -583,13 +546,10 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::ops::Add;
|
||||
use core::ptr;
|
||||
|
||||
use ::alloc::vec;
|
||||
use ::alloc::vec::Vec;
|
||||
use generic_array::typenum::Sum;
|
||||
use generic_array::ArrayLength;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use super::*;
|
||||
@@ -600,11 +560,7 @@ mod tests {
|
||||
input: &[u8],
|
||||
key: <CS::Group as Group>::Scalar,
|
||||
mode: Mode,
|
||||
) -> Output<CS::Hash>
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
) -> Output<CS::Hash> {
|
||||
let dst = Dst::new::<CS, _, _>(STR_HASH_TO_GROUP, mode);
|
||||
let point = CS::Group::hash_to_curve::<CS::Hash>(&[input], &dst.as_dst()).unwrap();
|
||||
|
||||
@@ -616,11 +572,7 @@ mod tests {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn verifiable_retrieval<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn verifiable_retrieval<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = VoprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -639,11 +591,7 @@ mod tests {
|
||||
assert_eq!(client_finalize_result, res2);
|
||||
}
|
||||
|
||||
fn verifiable_batch_retrieval<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn verifiable_batch_retrieval<CS: CipherSuite>() {
|
||||
let mut rng = OsRng;
|
||||
let mut inputs = vec![];
|
||||
let mut client_states = vec![];
|
||||
@@ -687,11 +635,7 @@ mod tests {
|
||||
assert_eq!(client_finalize_result, res2);
|
||||
}
|
||||
|
||||
fn verifiable_batch_bad_public_key<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn verifiable_batch_bad_public_key<CS: CipherSuite>() {
|
||||
let mut rng = OsRng;
|
||||
let mut inputs = vec![];
|
||||
let mut client_states = vec![];
|
||||
@@ -727,11 +671,7 @@ mod tests {
|
||||
assert!(client_finalize_result.is_err());
|
||||
}
|
||||
|
||||
fn verifiable_bad_public_key<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn verifiable_bad_public_key<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = VoprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -751,11 +691,7 @@ mod tests {
|
||||
assert!(client_finalize_result.is_err());
|
||||
}
|
||||
|
||||
fn verifiable_server_evaluate<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
{
|
||||
fn verifiable_server_evaluate<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = VoprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -784,13 +720,7 @@ mod tests {
|
||||
assert!(client_finalize != server_evaluate);
|
||||
}
|
||||
|
||||
fn zeroize_voprf_client<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
|
||||
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ElemLen>: ArrayLength<u8>,
|
||||
{
|
||||
fn zeroize_voprf_client<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = VoprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -804,15 +734,7 @@ mod tests {
|
||||
assert!(message.serialize().iter().all(|&x| x == 0));
|
||||
}
|
||||
|
||||
fn zeroize_voprf_server<CS: CipherSuite>()
|
||||
where
|
||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ElemLen>,
|
||||
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ElemLen>: ArrayLength<u8>,
|
||||
<CS::Group as Group>::ScalarLen: Add<<CS::Group as Group>::ScalarLen>,
|
||||
Sum<<CS::Group as Group>::ScalarLen, <CS::Group as Group>::ScalarLen>: ArrayLength<u8>,
|
||||
{
|
||||
fn zeroize_voprf_server<CS: CipherSuite>() {
|
||||
let input = b"input";
|
||||
let mut rng = OsRng;
|
||||
let client_blind_result = VoprfClient::<CS>::blind(input, &mut rng).unwrap();
|
||||
@@ -836,6 +758,7 @@ mod tests {
|
||||
fn test_functionality() -> Result<()> {
|
||||
use p256::NistP256;
|
||||
use p384::NistP384;
|
||||
use p521::NistP521;
|
||||
|
||||
#[cfg(feature = "ristretto255")]
|
||||
{
|
||||
@@ -869,6 +792,15 @@ mod tests {
|
||||
zeroize_voprf_client::<NistP384>();
|
||||
zeroize_voprf_server::<NistP384>();
|
||||
|
||||
verifiable_retrieval::<NistP521>();
|
||||
verifiable_batch_retrieval::<NistP521>();
|
||||
verifiable_bad_public_key::<NistP521>();
|
||||
verifiable_batch_bad_public_key::<NistP521>();
|
||||
verifiable_server_evaluate::<NistP521>();
|
||||
|
||||
zeroize_voprf_client::<NistP521>();
|
||||
zeroize_voprf_server::<NistP521>();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user