Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a30d5b7fa8 | ||
|
|
8f20115075 |
+12
-11
@@ -3,8 +3,9 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- v0.4
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, repoened, synchronize]
|
types: [opened, reopened, synchronize]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
cargo-audit:
|
cargo-audit:
|
||||||
@@ -12,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Cache cargo-audit
|
- name: Cache cargo-audit
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/.crates.toml
|
~/.cargo/.crates.toml
|
||||||
@@ -24,7 +25,7 @@ jobs:
|
|||||||
run: cargo install cargo-audit
|
run: cargo install cargo-audit
|
||||||
|
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Run cargo audit
|
- name: Run cargo audit
|
||||||
run: cargo audit -D warnings
|
run: cargo audit -D warnings
|
||||||
@@ -47,7 +48,7 @@ jobs:
|
|||||||
name: test
|
name: test
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install ${{ matrix.toolchain }} toolchain
|
- name: Install ${{ matrix.toolchain }} toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -99,8 +100,8 @@ jobs:
|
|||||||
- --features danger
|
- --features danger
|
||||||
- --features serde
|
- --features serde
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: hecrj/setup-rust-action@v1
|
- uses: hecrj/setup-rust-action@v2
|
||||||
- run: rustup target add ${{ matrix.target }}
|
- run: rustup target add ${{ matrix.target }}
|
||||||
- run: cargo build --verbose --target=${{ matrix.target }} --no-default-features ${{ matrix.frontend_feature }} ${{ matrix.backend_feature }}
|
- run: cargo build --verbose --target=${{ matrix.target }} --no-default-features ${{ matrix.frontend_feature }} ${{ matrix.backend_feature }}
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install stable toolchain
|
- name: Install stable toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -140,7 +141,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install nightly toolchain
|
- name: Install nightly toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -161,7 +162,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Cache
|
- name: Cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/.crates.toml
|
~/.cargo/.crates.toml
|
||||||
@@ -170,10 +171,10 @@ jobs:
|
|||||||
key: taplo
|
key: taplo
|
||||||
|
|
||||||
- name: Install Taplo
|
- name: Install Taplo
|
||||||
run: cargo install taplo-cli
|
run: cargo install taplo-cli --locked
|
||||||
|
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Run Taplo
|
- name: Run Taplo
|
||||||
run: taplo fmt --check
|
run: taplo fmt --check
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
|
rust: [stable]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: hecrj/setup-rust-action@v1
|
- uses: hecrj/setup-rust-action@v2
|
||||||
with:
|
with:
|
||||||
rust-version: ${{ matrix.rust }}
|
rust-version: ${{ matrix.rust }}
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
|
|||||||
@@ -8,3 +8,7 @@ Cargo.lock
|
|||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
# Editors
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|||||||
+4
-19
@@ -1,24 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 0.5.0-pre.5 (June 27, 2023)
|
## 0.4.1 (September 24, 2024)
|
||||||
* Updated curve25519-dalek dependency to 4.0.0-rc.3
|
* Backport all non-protocol-breaking changes from versions 0.5+
|
||||||
|
* Fixes Rust 1.81+ compatibility, compatible with 0.4.0 (draft 11), incompatible with 0.5+ (final RFC)
|
||||||
## 0.5.0-pre.4 (May 20, 2023)
|
* Updated dependencies
|
||||||
* Updated curve25519-dalek dependency to 4.0.0-rc.2
|
|
||||||
|
|
||||||
## 0.5.0-pre.3 (March 4, 2023)
|
|
||||||
* Updated to be in sync with draft-irtf-cfrg-voprf-19
|
|
||||||
* Increased MSRV to 1.65
|
|
||||||
* Updated p256 dependency to v0.13
|
|
||||||
* Added p384 tests
|
|
||||||
|
|
||||||
## 0.5.0-pre.2 (February 3, 2023)
|
|
||||||
* Increased MSRV to 1.60
|
|
||||||
* Updated p256 dependency to v0.12
|
|
||||||
* Updated curve25519-dalek dependency to 4.0.0-rc.1
|
|
||||||
|
|
||||||
## 0.5.0-pre.1 (December 19, 2022)
|
|
||||||
* Updated curve25519-dalek dependency to 4.0.0-pre.5
|
|
||||||
|
|
||||||
## 0.4.0 (September 15, 2022)
|
## 0.4.0 (September 15, 2022)
|
||||||
* Updated to be in sync with draft-irtf-cfrg-voprf-11, with
|
* Updated to be in sync with draft-irtf-cfrg-voprf-11, with
|
||||||
|
|||||||
+8
-4
@@ -9,7 +9,7 @@ name = "voprf"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/facebook/voprf/"
|
repository = "https://github.com/facebook/voprf/"
|
||||||
rust-version = "1.65"
|
rust-version = "1.65"
|
||||||
version = "0.5.0-pre.5"
|
version = "0.4.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
alloc = []
|
alloc = []
|
||||||
@@ -21,7 +21,7 @@ serde = ["generic-array/serde", "dep:serde"]
|
|||||||
std = ["alloc"]
|
std = ["alloc"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
curve25519-dalek = { version = "=4.0.0-rc.3", default-features = false, features = [
|
curve25519-dalek = { version = "4", default-features = false, features = [
|
||||||
"rand_core",
|
"rand_core",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
@@ -39,8 +39,8 @@ serde = { version = "1", default-features = false, features = [
|
|||||||
"derive",
|
"derive",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
sha2 = { version = "0.10", default-features = false, optional = true }
|
sha2 = { version = "0.10", default-features = false, optional = true }
|
||||||
subtle = { version = "2.3", default-features = false }
|
subtle = { version = "2.6", default-features = false }
|
||||||
zeroize = { version = "1.5", default-features = false }
|
zeroize = { version = "1.8", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
generic-array = { version = "0.14", features = ["more_lengths"] }
|
generic-array = { version = "0.14", features = ["more_lengths"] }
|
||||||
@@ -53,6 +53,10 @@ p384 = { version = "0.13", default-features = false, features = [
|
|||||||
"hash2curve",
|
"hash2curve",
|
||||||
"voprf",
|
"voprf",
|
||||||
] }
|
] }
|
||||||
|
p521 = { version = "0.13.3", default-features = false, features = [
|
||||||
|
"hash2curve",
|
||||||
|
"voprf",
|
||||||
|
] }
|
||||||
proptest = "1"
|
proptest = "1"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# voprf 
|
# voprf 
|
||||||
An implementation of a (verifiable) oblivious pseudorandom function (VOPRF)
|
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.
|
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.
|
||||||
@@ -16,7 +16,7 @@ Installation
|
|||||||
Add the following line to the dependencies of your `Cargo.toml`:
|
Add the following line to the dependencies of your `Cargo.toml`:
|
||||||
|
|
||||||
```
|
```
|
||||||
voprf = "0.5.0-pre.4"
|
voprf = "0.4.1"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Minimum Supported Rust Version
|
### Minimum Supported Rust Version
|
||||||
|
|||||||
+23
-17
@@ -35,7 +35,7 @@ pub(crate) const STR_DERIVE_KEYPAIR: [u8; 13] = *b"DeriveKeyPair";
|
|||||||
pub(crate) const STR_COMPOSITE: [u8; 9] = *b"Composite";
|
pub(crate) const STR_COMPOSITE: [u8; 9] = *b"Composite";
|
||||||
pub(crate) const STR_CHALLENGE: [u8; 9] = *b"Challenge";
|
pub(crate) const STR_CHALLENGE: [u8; 9] = *b"Challenge";
|
||||||
pub(crate) const STR_INFO: [u8; 4] = *b"Info";
|
pub(crate) const STR_INFO: [u8; 4] = *b"Info";
|
||||||
pub(crate) const STR_OPRF: [u8; 7] = *b"OPRFV1-";
|
pub(crate) const STR_VOPRF: [u8; 8] = *b"VOPRF10-";
|
||||||
pub(crate) const STR_HASH_TO_SCALAR: [u8; 13] = *b"HashToScalar-";
|
pub(crate) const STR_HASH_TO_SCALAR: [u8; 13] = *b"HashToScalar-";
|
||||||
pub(crate) const STR_HASH_TO_GROUP: [u8; 12] = *b"HashToGroup-";
|
pub(crate) const STR_HASH_TO_GROUP: [u8; 12] = *b"HashToGroup-";
|
||||||
|
|
||||||
@@ -147,8 +147,8 @@ pub(crate) fn generate_proof<CS: CipherSuite, R: RngCore + CryptoRng>(
|
|||||||
k: <CS::Group as Group>::Scalar,
|
k: <CS::Group as Group>::Scalar,
|
||||||
a: <CS::Group as Group>::Elem,
|
a: <CS::Group as Group>::Elem,
|
||||||
b: <CS::Group as Group>::Elem,
|
b: <CS::Group as Group>::Elem,
|
||||||
cs: impl Iterator<Item = <CS::Group as Group>::Elem> + ExactSizeIterator,
|
cs: impl ExactSizeIterator<Item = <CS::Group as Group>::Elem>,
|
||||||
ds: impl Iterator<Item = <CS::Group as Group>::Elem> + ExactSizeIterator,
|
ds: impl ExactSizeIterator<Item = <CS::Group as Group>::Elem>,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
) -> Result<Proof<CS>>
|
) -> Result<Proof<CS>>
|
||||||
where
|
where
|
||||||
@@ -209,8 +209,8 @@ where
|
|||||||
pub(crate) fn verify_proof<CS: CipherSuite>(
|
pub(crate) fn verify_proof<CS: CipherSuite>(
|
||||||
a: <CS::Group as Group>::Elem,
|
a: <CS::Group as Group>::Elem,
|
||||||
b: <CS::Group as Group>::Elem,
|
b: <CS::Group as Group>::Elem,
|
||||||
cs: impl Iterator<Item = <CS::Group as Group>::Elem> + ExactSizeIterator,
|
cs: impl ExactSizeIterator<Item = <CS::Group as Group>::Elem>,
|
||||||
ds: impl Iterator<Item = <CS::Group as Group>::Elem> + ExactSizeIterator,
|
ds: impl ExactSizeIterator<Item = <CS::Group as Group>::Elem>,
|
||||||
proof: &Proof<CS>,
|
proof: &Proof<CS>,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
) -> Result<()>
|
) -> Result<()>
|
||||||
@@ -500,29 +500,37 @@ where
|
|||||||
|
|
||||||
pub(crate) struct Dst<L: ArrayLength<u8>> {
|
pub(crate) struct Dst<L: ArrayLength<u8>> {
|
||||||
dst_1: GenericArray<u8, L>,
|
dst_1: GenericArray<u8, L>,
|
||||||
dst_2: &'static str,
|
dst_2: [u8; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L: ArrayLength<u8>> Dst<L> {
|
impl<L: ArrayLength<u8>> Dst<L> {
|
||||||
pub(crate) fn new<CS: CipherSuite, T, TL: ArrayLength<u8>>(par_1: T, mode: Mode) -> Self
|
pub(crate) fn new<CS: CipherSuite, T, TL>(par_1: T, mode: Mode) -> Self
|
||||||
where
|
where
|
||||||
T: Into<GenericArray<u8, TL>>,
|
T: Into<GenericArray<u8, TL>>,
|
||||||
TL: Add<U9, Output = L>,
|
TL: ArrayLength<u8> + Add<U9, Output = L>,
|
||||||
<CS::Hash as OutputSizeUser>::OutputSize:
|
<CS::Hash as OutputSizeUser>::OutputSize:
|
||||||
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
|
||||||
{
|
{
|
||||||
let par_1 = par_1.into();
|
let par_1 = par_1.into();
|
||||||
// Generates the contextString parameter as defined in
|
// Generates the contextString parameter as defined in
|
||||||
// <https://datatracker.ietf.org/doc/draft-irtf-cfrg-voprf/>
|
// <https://datatracker.ietf.org/doc/draft-irtf-cfrg-voprf/>
|
||||||
let par_2 = GenericArray::from(STR_OPRF)
|
let par_2 = GenericArray::from(STR_VOPRF).concat([mode.to_u8()].into());
|
||||||
.concat([mode.to_u8()].into())
|
|
||||||
.concat([b'-'].into());
|
// See <https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-11.html#section-4.1>
|
||||||
|
let cs_id_u16: u16 = match CS::ID {
|
||||||
|
"ristretto255-SHA512" => 0x0001,
|
||||||
|
"decaf448-SHAKE256" => 0x0002,
|
||||||
|
"P256-SHA256" => 0x0003,
|
||||||
|
"P384-SHA384" => 0x0004,
|
||||||
|
"P521-SHA512" => 0x0005,
|
||||||
|
_ => panic!("Incompatible ciphersuite: {}", CS::ID),
|
||||||
|
};
|
||||||
|
|
||||||
let dst_1 = par_1.concat(par_2);
|
let dst_1 = par_1.concat(par_2);
|
||||||
let dst_2 = CS::ID;
|
let dst_2 = cs_id_u16.to_be_bytes();
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
L::USIZE + dst_2.len() <= u16::MAX.into(),
|
L::USIZE + 2 <= u16::MAX.into(),
|
||||||
"constructed DST longer then {}",
|
"constructed DST longer then {}",
|
||||||
u16::MAX
|
u16::MAX
|
||||||
);
|
);
|
||||||
@@ -531,13 +539,11 @@ impl<L: ArrayLength<u8>> Dst<L> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn as_dst(&self) -> [&[u8]; 2] {
|
pub(crate) fn as_dst(&self) -> [&[u8]; 2] {
|
||||||
[&self.dst_1, self.dst_2.as_bytes()]
|
[&self.dst_1, &self.dst_2]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn i2osp_2(&self) -> [u8; 2] {
|
pub(crate) fn i2osp_2(&self) -> [u8; 2] {
|
||||||
u16::try_from(L::USIZE + self.dst_2.len())
|
u16::try_from(L::USIZE + 2).unwrap().to_be_bytes()
|
||||||
.unwrap()
|
|
||||||
.to_be_bytes()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use crate::{Error, Group, Result};
|
|||||||
fn test_group_properties() -> Result<()> {
|
fn test_group_properties() -> Result<()> {
|
||||||
use p256::NistP256;
|
use p256::NistP256;
|
||||||
use p384::NistP384;
|
use p384::NistP384;
|
||||||
|
use p521::NistP521;
|
||||||
|
|
||||||
#[cfg(feature = "ristretto255")]
|
#[cfg(feature = "ristretto255")]
|
||||||
{
|
{
|
||||||
@@ -32,6 +33,9 @@ fn test_group_properties() -> Result<()> {
|
|||||||
test_identity_element_error::<NistP384>()?;
|
test_identity_element_error::<NistP384>()?;
|
||||||
test_zero_scalar_error::<NistP384>()?;
|
test_zero_scalar_error::<NistP384>()?;
|
||||||
|
|
||||||
|
test_identity_element_error::<NistP521>()?;
|
||||||
|
test_zero_scalar_error::<NistP521>()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
//! An implementation of a verifiable oblivious pseudorandom function (VOPRF)
|
//! An implementation of a verifiable oblivious pseudorandom function (VOPRF)
|
||||||
//!
|
//!
|
||||||
//! Note: This implementation is in sync with
|
//! Note: This implementation is in sync with
|
||||||
//! [draft-irtf-cfrg-voprf-19](https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html),
|
//! [draft-irtf-cfrg-voprf-11](https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-11.html),
|
||||||
//! but this specification is subject to change, until the final version
|
//! but this specification is subject to change, until the final version
|
||||||
//! published by the IETF.
|
//! published by the IETF.
|
||||||
//!
|
//!
|
||||||
|
|||||||
@@ -427,6 +427,7 @@ mod tests {
|
|||||||
fn test_functionality() -> Result<()> {
|
fn test_functionality() -> Result<()> {
|
||||||
use p256::NistP256;
|
use p256::NistP256;
|
||||||
use p384::NistP384;
|
use p384::NistP384;
|
||||||
|
use p521::NistP521;
|
||||||
|
|
||||||
#[cfg(feature = "ristretto255")]
|
#[cfg(feature = "ristretto255")]
|
||||||
{
|
{
|
||||||
@@ -454,6 +455,13 @@ mod tests {
|
|||||||
zeroize_oprf_client::<NistP384>();
|
zeroize_oprf_client::<NistP384>();
|
||||||
zeroize_oprf_server::<NistP384>();
|
zeroize_oprf_server::<NistP384>();
|
||||||
|
|
||||||
|
base_retrieval::<NistP521>();
|
||||||
|
base_inversion_unsalted::<NistP521>();
|
||||||
|
server_evaluate::<NistP521>();
|
||||||
|
|
||||||
|
zeroize_oprf_client::<NistP521>();
|
||||||
|
zeroize_oprf_server::<NistP521>();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -720,7 +720,7 @@ where
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(blinds
|
Ok(blinds
|
||||||
.zip(messages.into_iter())
|
.zip(messages)
|
||||||
.map(|(blind, x)| x.0 * &CS::Group::invert_scalar(blind)))
|
.map(|(blind, x)| x.0 * &CS::Group::invert_scalar(blind)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,6 +967,7 @@ mod tests {
|
|||||||
fn test_functionality() -> Result<()> {
|
fn test_functionality() -> Result<()> {
|
||||||
use p256::NistP256;
|
use p256::NistP256;
|
||||||
use p384::NistP384;
|
use p384::NistP384;
|
||||||
|
use p521::NistP521;
|
||||||
|
|
||||||
#[cfg(feature = "ristretto255")]
|
#[cfg(feature = "ristretto255")]
|
||||||
{
|
{
|
||||||
@@ -994,6 +995,13 @@ mod tests {
|
|||||||
zeroize_verifiable_client::<NistP384>();
|
zeroize_verifiable_client::<NistP384>();
|
||||||
zeroize_verifiable_server::<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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,11 +307,11 @@ fn deserialize_scalar<G: Group>(input: &mut &[u8]) -> Result<G::Scalar> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait SliceExt {
|
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] {
|
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() {
|
if take > self.len() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -391,6 +391,7 @@ mod test {
|
|||||||
|
|
||||||
let _ = $item::<p256::NistP256>::deserialize(&$bytes[..]);
|
let _ = $item::<p256::NistP256>::deserialize(&$bytes[..]);
|
||||||
let _ = $item::<p384::NistP384>::deserialize(&$bytes[..]);
|
let _ = $item::<p384::NistP384>::deserialize(&$bytes[..]);
|
||||||
|
let _ = $item::<p521::NistP521>::deserialize(&$bytes[..]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+895
-892
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -15,7 +15,7 @@ pub(crate) fn rfc_to_json(input: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ciphersuites(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"## OPRF\((?P<ciphersuite>.+?)\)").unwrap();
|
||||||
let mut ciphersuites = vec![];
|
let mut ciphersuites = vec![];
|
||||||
|
|
||||||
let chunks: Vec<&str> = re.split(input).collect();
|
let chunks: Vec<&str> = re.split(input).collect();
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ macro_rules! json_to_test_vectors {
|
|||||||
fn test_vectors() -> Result<()> {
|
fn test_vectors() -> Result<()> {
|
||||||
use p256::NistP256;
|
use p256::NistP256;
|
||||||
use p384::NistP384;
|
use p384::NistP384;
|
||||||
|
use p521::NistP521;
|
||||||
|
|
||||||
let rfc: Value = serde_json::from_str(rfc_to_json(super::cfrg_vectors::VECTORS).as_str())
|
let rfc: Value = serde_json::from_str(rfc_to_json(super::cfrg_vectors::VECTORS).as_str())
|
||||||
.expect("Could not parse json");
|
.expect("Could not parse json");
|
||||||
@@ -99,7 +100,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
|
|
||||||
let ristretto_oprf_tvs = json_to_test_vectors!(
|
let ristretto_oprf_tvs = json_to_test_vectors!(
|
||||||
rfc,
|
rfc,
|
||||||
String::from("ristretto255-SHA512"),
|
String::from("ristretto255, SHA-512"),
|
||||||
String::from("OPRF")
|
String::from("OPRF")
|
||||||
);
|
);
|
||||||
assert_ne!(ristretto_oprf_tvs.len(), 0);
|
assert_ne!(ristretto_oprf_tvs.len(), 0);
|
||||||
@@ -111,7 +112,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
|
|
||||||
let ristretto_voprf_tvs = json_to_test_vectors!(
|
let ristretto_voprf_tvs = json_to_test_vectors!(
|
||||||
rfc,
|
rfc,
|
||||||
String::from("ristretto255-SHA512"),
|
String::from("ristretto255, SHA-512"),
|
||||||
String::from("VOPRF")
|
String::from("VOPRF")
|
||||||
);
|
);
|
||||||
assert_ne!(ristretto_voprf_tvs.len(), 0);
|
assert_ne!(ristretto_voprf_tvs.len(), 0);
|
||||||
@@ -123,7 +124,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
|
|
||||||
let ristretto_poprf_tvs = json_to_test_vectors!(
|
let ristretto_poprf_tvs = json_to_test_vectors!(
|
||||||
rfc,
|
rfc,
|
||||||
String::from("ristretto255-SHA512"),
|
String::from("ristretto255, SHA-512"),
|
||||||
String::from("POPRF")
|
String::from("POPRF")
|
||||||
);
|
);
|
||||||
assert_ne!(ristretto_poprf_tvs.len(), 0);
|
assert_ne!(ristretto_poprf_tvs.len(), 0);
|
||||||
@@ -135,7 +136,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let p256_oprf_tvs =
|
let p256_oprf_tvs =
|
||||||
json_to_test_vectors!(rfc, String::from("P256-SHA256"), String::from("OPRF"));
|
json_to_test_vectors!(rfc, String::from("P-256, SHA-256"), String::from("OPRF"));
|
||||||
assert_ne!(p256_oprf_tvs.len(), 0);
|
assert_ne!(p256_oprf_tvs.len(), 0);
|
||||||
test_oprf_seed_to_key::<NistP256>(&p256_oprf_tvs)?;
|
test_oprf_seed_to_key::<NistP256>(&p256_oprf_tvs)?;
|
||||||
test_oprf_blind::<NistP256>(&p256_oprf_tvs)?;
|
test_oprf_blind::<NistP256>(&p256_oprf_tvs)?;
|
||||||
@@ -144,7 +145,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
test_oprf_evaluate::<NistP256>(&p256_oprf_tvs)?;
|
test_oprf_evaluate::<NistP256>(&p256_oprf_tvs)?;
|
||||||
|
|
||||||
let p256_voprf_tvs =
|
let p256_voprf_tvs =
|
||||||
json_to_test_vectors!(rfc, String::from("P256-SHA256"), String::from("VOPRF"));
|
json_to_test_vectors!(rfc, String::from("P-256, SHA-256"), String::from("VOPRF"));
|
||||||
assert_ne!(p256_voprf_tvs.len(), 0);
|
assert_ne!(p256_voprf_tvs.len(), 0);
|
||||||
test_voprf_seed_to_key::<NistP256>(&p256_voprf_tvs)?;
|
test_voprf_seed_to_key::<NistP256>(&p256_voprf_tvs)?;
|
||||||
test_voprf_blind::<NistP256>(&p256_voprf_tvs)?;
|
test_voprf_blind::<NistP256>(&p256_voprf_tvs)?;
|
||||||
@@ -153,7 +154,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
test_voprf_evaluate::<NistP256>(&p256_voprf_tvs)?;
|
test_voprf_evaluate::<NistP256>(&p256_voprf_tvs)?;
|
||||||
|
|
||||||
let p256_poprf_tvs =
|
let p256_poprf_tvs =
|
||||||
json_to_test_vectors!(rfc, String::from("P256-SHA256"), String::from("POPRF"));
|
json_to_test_vectors!(rfc, String::from("P-256, SHA-256"), String::from("POPRF"));
|
||||||
assert_ne!(p256_poprf_tvs.len(), 0);
|
assert_ne!(p256_poprf_tvs.len(), 0);
|
||||||
test_poprf_seed_to_key::<NistP256>(&p256_poprf_tvs)?;
|
test_poprf_seed_to_key::<NistP256>(&p256_poprf_tvs)?;
|
||||||
test_poprf_blind::<NistP256>(&p256_poprf_tvs)?;
|
test_poprf_blind::<NistP256>(&p256_poprf_tvs)?;
|
||||||
@@ -162,7 +163,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
test_poprf_evaluate::<NistP256>(&p256_poprf_tvs)?;
|
test_poprf_evaluate::<NistP256>(&p256_poprf_tvs)?;
|
||||||
|
|
||||||
let p384_oprf_tvs =
|
let p384_oprf_tvs =
|
||||||
json_to_test_vectors!(rfc, String::from("P384-SHA384"), String::from("OPRF"));
|
json_to_test_vectors!(rfc, String::from("P-384, SHA-384"), String::from("OPRF"));
|
||||||
assert_ne!(p384_oprf_tvs.len(), 0);
|
assert_ne!(p384_oprf_tvs.len(), 0);
|
||||||
test_oprf_seed_to_key::<NistP384>(&p384_oprf_tvs)?;
|
test_oprf_seed_to_key::<NistP384>(&p384_oprf_tvs)?;
|
||||||
test_oprf_blind::<NistP384>(&p384_oprf_tvs)?;
|
test_oprf_blind::<NistP384>(&p384_oprf_tvs)?;
|
||||||
@@ -171,7 +172,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
test_oprf_evaluate::<NistP384>(&p384_oprf_tvs)?;
|
test_oprf_evaluate::<NistP384>(&p384_oprf_tvs)?;
|
||||||
|
|
||||||
let p384_voprf_tvs =
|
let p384_voprf_tvs =
|
||||||
json_to_test_vectors!(rfc, String::from("P384-SHA384"), String::from("VOPRF"));
|
json_to_test_vectors!(rfc, String::from("P-384, SHA-384"), String::from("VOPRF"));
|
||||||
assert_ne!(p384_voprf_tvs.len(), 0);
|
assert_ne!(p384_voprf_tvs.len(), 0);
|
||||||
test_voprf_seed_to_key::<NistP384>(&p384_voprf_tvs)?;
|
test_voprf_seed_to_key::<NistP384>(&p384_voprf_tvs)?;
|
||||||
test_voprf_blind::<NistP384>(&p384_voprf_tvs)?;
|
test_voprf_blind::<NistP384>(&p384_voprf_tvs)?;
|
||||||
@@ -180,7 +181,7 @@ fn test_vectors() -> Result<()> {
|
|||||||
test_voprf_evaluate::<NistP384>(&p384_voprf_tvs)?;
|
test_voprf_evaluate::<NistP384>(&p384_voprf_tvs)?;
|
||||||
|
|
||||||
let p384_poprf_tvs =
|
let p384_poprf_tvs =
|
||||||
json_to_test_vectors!(rfc, String::from("P384-SHA384"), String::from("POPRF"));
|
json_to_test_vectors!(rfc, String::from("P-384, SHA-384"), String::from("POPRF"));
|
||||||
assert_ne!(p384_poprf_tvs.len(), 0);
|
assert_ne!(p384_poprf_tvs.len(), 0);
|
||||||
test_poprf_seed_to_key::<NistP384>(&p384_poprf_tvs)?;
|
test_poprf_seed_to_key::<NistP384>(&p384_poprf_tvs)?;
|
||||||
test_poprf_blind::<NistP384>(&p384_poprf_tvs)?;
|
test_poprf_blind::<NistP384>(&p384_poprf_tvs)?;
|
||||||
@@ -188,6 +189,33 @@ fn test_vectors() -> Result<()> {
|
|||||||
test_poprf_finalize::<NistP384>(&p384_poprf_tvs)?;
|
test_poprf_finalize::<NistP384>(&p384_poprf_tvs)?;
|
||||||
test_poprf_evaluate::<NistP384>(&p384_poprf_tvs)?;
|
test_poprf_evaluate::<NistP384>(&p384_poprf_tvs)?;
|
||||||
|
|
||||||
|
let p521_oprf_tvs =
|
||||||
|
json_to_test_vectors!(rfc, String::from("P-521, SHA-512"), 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("P-521, SHA-512"), 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("P-521, SHA-512"), 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -161,7 +161,7 @@ where
|
|||||||
///
|
///
|
||||||
/// The resulting messages can each fail individually with [`Error::Input`]
|
/// The resulting messages can each fail individually with [`Error::Input`]
|
||||||
/// if the `input` is empty or longer then [`u16::MAX`].
|
/// 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,
|
inputs: &'a II,
|
||||||
clients: &'a IC,
|
clients: &'a IC,
|
||||||
messages: &'a IM,
|
messages: &'a IM,
|
||||||
@@ -170,7 +170,7 @@ where
|
|||||||
) -> Result<VoprfClientBatchFinalizeResult<'a, CS, I, II, IC, IM>>
|
) -> Result<VoprfClientBatchFinalizeResult<'a, CS, I, II, IC, IM>>
|
||||||
where
|
where
|
||||||
CS: 'a,
|
CS: 'a,
|
||||||
I: AsRef<[u8]>,
|
I: 'a + AsRef<[u8]>,
|
||||||
&'a II: 'a + IntoIterator<Item = I>,
|
&'a II: 'a + IntoIterator<Item = I>,
|
||||||
<&'a II as IntoIterator>::IntoIter: ExactSizeIterator,
|
<&'a II as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||||
&'a IC: 'a + IntoIterator<Item = &'a VoprfClient<CS>>,
|
&'a IC: 'a + IntoIterator<Item = &'a VoprfClient<CS>>,
|
||||||
@@ -537,7 +537,7 @@ where
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(blinds
|
Ok(blinds
|
||||||
.zip(messages.into_iter())
|
.zip(messages)
|
||||||
.map(|(blind, x)| x.0 * &CS::Group::invert_scalar(blind)))
|
.map(|(blind, x)| x.0 * &CS::Group::invert_scalar(blind)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,6 +836,7 @@ mod tests {
|
|||||||
fn test_functionality() -> Result<()> {
|
fn test_functionality() -> Result<()> {
|
||||||
use p256::NistP256;
|
use p256::NistP256;
|
||||||
use p384::NistP384;
|
use p384::NistP384;
|
||||||
|
use p521::NistP521;
|
||||||
|
|
||||||
#[cfg(feature = "ristretto255")]
|
#[cfg(feature = "ristretto255")]
|
||||||
{
|
{
|
||||||
@@ -869,6 +870,15 @@ mod tests {
|
|||||||
zeroize_voprf_client::<NistP384>();
|
zeroize_voprf_client::<NistP384>();
|
||||||
zeroize_voprf_server::<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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user