Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bbf8fbfb5
|
||
|
|
1451f937ca
|
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 1.0.0-rc.1 (July 3, 2026)
|
||||||
|
|
||||||
|
* Reject trailing bytes in all `deserialize` methods
|
||||||
|
* Reject identity element in `deterministic_blind_unchecked` to prevent blinding bypass
|
||||||
|
* Added roundtrip, trailing bytes, truncated, and empty input tests for serialization
|
||||||
|
|
||||||
|
## 1.0.0-rc.0 (July 2, 2026)
|
||||||
|
|
||||||
|
* Added missing license in Cargo manifest
|
||||||
|
* Implement `zeroize` feature for `digest`, `hybrid-array` and `sha2`
|
||||||
|
* Replaced license appendix in files while keeping original copyright
|
||||||
|
|
||||||
## 1.0.0-pre.1 (July 2, 2026)
|
## 1.0.0-pre.1 (July 2, 2026)
|
||||||
|
|
||||||
* Simplified ciphersuite trait
|
* Simplified ciphersuite trait
|
||||||
|
|||||||
+11
-11
@@ -4,12 +4,12 @@ categories = ["no-std", "algorithms", "cryptography"]
|
|||||||
description = "An implementation of a verifiable oblivious pseudorandom function (VOPRF)"
|
description = "An implementation of a verifiable oblivious pseudorandom function (VOPRF)"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
keywords = ["oprf", "voprf", "cryptography", "oblivious-prf"]
|
keywords = ["oprf", "voprf", "cryptography", "oblivious-prf"]
|
||||||
license = "MIT"
|
license = "MIT OR Apache-2.0"
|
||||||
name = "voprf-vx"
|
name = "voprf-vx"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/vexahub/voprf-vx/"
|
repository = "https://github.com/vexahub/voprf-vx/"
|
||||||
rust-version = "1.87"
|
rust-version = "1.87"
|
||||||
version = "1.0.0-pre.1"
|
version = "1.0.0-rc.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
alloc = []
|
alloc = []
|
||||||
@@ -22,35 +22,35 @@ serde = ["curve25519-dalek?/serde", "hybrid-array/serde", "dep:serde"]
|
|||||||
std = ["alloc"]
|
std = ["alloc"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
curve25519-dalek = { version = "5.0.0-rc", default-features = false, features = ["rand_core", "zeroize"], optional = true }
|
curve25519-dalek = { version = "5.0.0-rc.1", default-features = false, features = ["rand_core", "zeroize"], optional = true }
|
||||||
derive-where = { version = "1", features = ["zeroize-on-drop"] }
|
derive-where = { version = "1", features = ["zeroize-on-drop"] }
|
||||||
digest = "0.11"
|
digest = { version = "0.11", features = ["zeroize"] }
|
||||||
displaydoc = { version = "0.2", default-features = false }
|
displaydoc = { version = "0.2", default-features = false }
|
||||||
elliptic-curve = { version = "0.14", features = [
|
elliptic-curve = { version = "0.14", features = [
|
||||||
"sec1",
|
"sec1",
|
||||||
] }
|
] }
|
||||||
hash2curve = "0.14"
|
hash2curve = "0.14"
|
||||||
hybrid-array = "0.4"
|
hybrid-array = { version = "0.4", features = ["zeroize"] }
|
||||||
rand_core = { version = "0.10", default-features = false, features = [] }
|
rand_core = { version = "0.10", default-features = false }
|
||||||
serde = { version = "1", default-features = false, features = [
|
serde = { version = "1", default-features = false, features = [
|
||||||
"derive",
|
"derive",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
sha2 = { version = "0.11", default-features = false, optional = true }
|
sha2 = { version = "0.11", default-features = false, features = ["zeroize"], optional = true }
|
||||||
p256 = { version = "0.14.0-rc", default-features = false, features = ["hash2curve", "oprf"], optional = true }
|
p256 = { version = "0.14.0-rc.15", default-features = false, features = ["hash2curve", "oprf"], optional = true }
|
||||||
subtle = { version = "2.6", default-features = false }
|
subtle = { version = "2.6", default-features = false }
|
||||||
zeroize = { version = "1.5", default-features = false }
|
zeroize = { version = "1.5", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
p256 = { version = "0.14.0-rc", default-features = false, features = [
|
p256 = { version = "0.14.0-rc.15", default-features = false, features = [
|
||||||
"hash2curve",
|
"hash2curve",
|
||||||
"oprf",
|
"oprf",
|
||||||
] }
|
] }
|
||||||
p384 = { version = "0.14.0-rc", default-features = false, features = [
|
p384 = { version = "0.14.0-rc.15", default-features = false, features = [
|
||||||
"hash2curve",
|
"hash2curve",
|
||||||
"oprf",
|
"oprf",
|
||||||
] }
|
] }
|
||||||
p521 = { version = "0.14.0-rc", default-features = false, features = [
|
p521 = { version = "0.14.0-rc.15", default-features = false, features = [
|
||||||
"hash2curve",
|
"hash2curve",
|
||||||
"oprf",
|
"oprf",
|
||||||
] }
|
] }
|
||||||
|
|||||||
@@ -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 = { package = "voprf-vx", version = "1.0.0-pre.0" }
|
voprf = { package = "voprf-vx", version = "1.0.0-rc.1" }
|
||||||
```
|
```
|
||||||
|
|
||||||
### Minimum Supported Rust Version
|
### Minimum Supported Rust Version
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Defines the CipherSuite trait to specify the underlying primitives for VOPRF
|
//! Defines the CipherSuite trait to specify the underlying primitives for VOPRF
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Common functionality between multiple OPRF modes.
|
//! Common functionality between multiple OPRF modes.
|
||||||
|
|
||||||
@@ -401,6 +397,12 @@ pub(crate) fn deterministic_blind_unchecked<CS: CipherSuite>(
|
|||||||
mode: Mode,
|
mode: Mode,
|
||||||
) -> Result<<CS::Group as Group>::Elem> {
|
) -> Result<<CS::Group as Group>::Elem> {
|
||||||
let hashed_point = hash_to_group::<CS>(input, mode)?;
|
let hashed_point = hash_to_group::<CS>(input, mode)?;
|
||||||
|
|
||||||
|
// Identity element would nullify blinding, revealing the input.
|
||||||
|
if CS::Group::is_identity_elem(hashed_point).into() {
|
||||||
|
return Err(Error::Input);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(hashed_point * blind)
|
Ok(hashed_point * blind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Errors which are produced during an execution of the protocol
|
//! Errors which are produced during an execution of the protocol
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
use core::ops::{Add, Mul};
|
use core::ops::{Add, Mul};
|
||||||
use digest::block_api::BlockSizeUser;
|
use digest::block_api::BlockSizeUser;
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Defines the Group trait to specify the underlying prime order group
|
//! Defines the Group trait to specify the underlying prime order group
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
use core::num::NonZeroU16;
|
use core::num::NonZeroU16;
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Includes a series of tests for the group implementations
|
//! Includes a series of tests for the group implementations
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! An implementation of a verifiable oblivious pseudorandom function (VOPRF)
|
//! An implementation of a verifiable oblivious pseudorandom function (VOPRF)
|
||||||
//!
|
//!
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Contains the main OPRF API
|
//! Contains the main OPRF API
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Contains the main POPRF API
|
//! Contains the main POPRF API
|
||||||
|
|
||||||
|
|||||||
+172
-9
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Handles the serialization of each of the components used in the VOPRF
|
//! Handles the serialization of each of the components used in the VOPRF
|
||||||
//! protocol
|
//! protocol
|
||||||
@@ -38,6 +34,10 @@ impl<CS: CipherSuite> OprfClient<CS> {
|
|||||||
pub fn deserialize(mut input: &[u8]) -> Result<Self> {
|
pub fn deserialize(mut input: &[u8]) -> Result<Self> {
|
||||||
let blind = deserialize_scalar::<CS::Group>(&mut input)?;
|
let blind = deserialize_scalar::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self { blind })
|
Ok(Self { blind })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,6 +63,10 @@ impl<CS: CipherSuite> VoprfClient<CS> {
|
|||||||
let blind = deserialize_scalar::<CS::Group>(&mut input)?;
|
let blind = deserialize_scalar::<CS::Group>(&mut input)?;
|
||||||
let blinded_element = deserialize_elem::<CS::Group>(&mut input)?;
|
let blinded_element = deserialize_elem::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
blind,
|
blind,
|
||||||
blinded_element,
|
blinded_element,
|
||||||
@@ -91,6 +95,10 @@ impl<CS: CipherSuite> PoprfClient<CS> {
|
|||||||
let blind = deserialize_scalar::<CS::Group>(&mut input)?;
|
let blind = deserialize_scalar::<CS::Group>(&mut input)?;
|
||||||
let blinded_element = deserialize_elem::<CS::Group>(&mut input)?;
|
let blinded_element = deserialize_elem::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
blind,
|
blind,
|
||||||
blinded_element,
|
blinded_element,
|
||||||
@@ -114,6 +122,10 @@ impl<CS: CipherSuite> OprfServer<CS> {
|
|||||||
pub fn deserialize(mut input: &[u8]) -> Result<Self> {
|
pub fn deserialize(mut input: &[u8]) -> Result<Self> {
|
||||||
let sk = deserialize_scalar::<CS::Group>(&mut input)?;
|
let sk = deserialize_scalar::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self { sk })
|
Ok(Self { sk })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,6 +150,10 @@ impl<CS: CipherSuite> VoprfServer<CS> {
|
|||||||
let sk = deserialize_scalar::<CS::Group>(&mut input)?;
|
let sk = deserialize_scalar::<CS::Group>(&mut input)?;
|
||||||
let pk = deserialize_elem::<CS::Group>(&mut input)?;
|
let pk = deserialize_elem::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self { sk, pk })
|
Ok(Self { sk, pk })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,6 +178,10 @@ impl<CS: CipherSuite> PoprfServer<CS> {
|
|||||||
let sk = deserialize_scalar::<CS::Group>(&mut input)?;
|
let sk = deserialize_scalar::<CS::Group>(&mut input)?;
|
||||||
let pk = deserialize_elem::<CS::Group>(&mut input)?;
|
let pk = deserialize_elem::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self { sk, pk })
|
Ok(Self { sk, pk })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,6 +207,10 @@ impl<CS: CipherSuite> Proof<CS> {
|
|||||||
let c_scalar = deserialize_scalar::<CS::Group>(&mut input)?;
|
let c_scalar = deserialize_scalar::<CS::Group>(&mut input)?;
|
||||||
let s_scalar = deserialize_scalar::<CS::Group>(&mut input)?;
|
let s_scalar = deserialize_scalar::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Proof { c_scalar, s_scalar })
|
Ok(Proof { c_scalar, s_scalar })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,6 +231,10 @@ impl<CS: CipherSuite> BlindedElement<CS> {
|
|||||||
pub fn deserialize(mut input: &[u8]) -> Result<Self> {
|
pub fn deserialize(mut input: &[u8]) -> Result<Self> {
|
||||||
let value = deserialize_elem::<CS::Group>(&mut input)?;
|
let value = deserialize_elem::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self(value))
|
Ok(Self(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,6 +255,10 @@ impl<CS: CipherSuite> EvaluationElement<CS> {
|
|||||||
pub fn deserialize(mut input: &[u8]) -> Result<Self> {
|
pub fn deserialize(mut input: &[u8]) -> Result<Self> {
|
||||||
let value = deserialize_elem::<CS::Group>(&mut input)?;
|
let value = deserialize_elem::<CS::Group>(&mut input)?;
|
||||||
|
|
||||||
|
if !input.is_empty() {
|
||||||
|
return Err(Error::Deserialization);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self(value))
|
Ok(Self(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -321,6 +353,7 @@ mod test {
|
|||||||
VoprfClient, VoprfServer,
|
VoprfClient, VoprfServer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Fuzz: no panics on arbitrary input
|
||||||
macro_rules! test_deserialize {
|
macro_rules! test_deserialize {
|
||||||
($item:ident, $bytes:ident) => {
|
($item:ident, $bytes:ident) => {
|
||||||
#[cfg(feature = "ristretto255")]
|
#[cfg(feature = "ristretto255")]
|
||||||
@@ -328,12 +361,43 @@ mod test {
|
|||||||
let _ = $item::<crate::Ristretto255>::deserialize(&$bytes[..]);
|
let _ = $item::<crate::Ristretto255>::deserialize(&$bytes[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
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[..]);
|
let _ = $item::<::p521::NistP521>::deserialize(&$bytes[..]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Roundtrip: serialize to deserialize == original
|
||||||
|
macro_rules! test_roundtrip {
|
||||||
|
($item:ident, $cs:ty, $constructor:expr) => {{
|
||||||
|
let original = $constructor;
|
||||||
|
let bytes = original.serialize();
|
||||||
|
let recovered = $item::<$cs>::deserialize(&bytes).expect("roundtrip deserialize");
|
||||||
|
assert_eq!(original.serialize(), recovered.serialize());
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trailing bytes: valid serialization + extra byte must fail
|
||||||
|
macro_rules! test_trailing {
|
||||||
|
($item:ident, $cs:ty, $constructor:expr) => {{
|
||||||
|
let original = $constructor;
|
||||||
|
let bytes = original.serialize();
|
||||||
|
let mut extended = bytes.to_vec();
|
||||||
|
extended.push(0x00);
|
||||||
|
assert!($item::<$cs>::deserialize(&extended).is_err());
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncated: valid serialization minus one byte must fail
|
||||||
|
macro_rules! test_truncated {
|
||||||
|
($item:ident, $cs:ty, $constructor:expr) => {{
|
||||||
|
let original = $constructor;
|
||||||
|
let bytes = original.serialize();
|
||||||
|
let truncated = &bytes[..bytes.len() - 1];
|
||||||
|
assert!($item::<$cs>::deserialize(truncated).is_err());
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
proptest! {
|
proptest! {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nocrash_oprf_client(bytes in vec(any::<u8>(), 0..200)) {
|
fn test_nocrash_oprf_client(bytes in vec(any::<u8>(), 0..200)) {
|
||||||
@@ -381,4 +445,103 @@ mod test {
|
|||||||
test_deserialize!(Proof, bytes);
|
test_deserialize!(Proof, bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! structured_tests {
|
||||||
|
($cs:ty, $mod:ident) => {
|
||||||
|
mod $mod {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use rand::rngs::SysRng;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn roundtrip_oprf_client() {
|
||||||
|
let client = OprfClient::<$cs>::blind(b"input", &mut SysRng)
|
||||||
|
.expect("blind")
|
||||||
|
.state;
|
||||||
|
test_roundtrip!(OprfClient, $cs, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn roundtrip_oprf_server() {
|
||||||
|
let server = OprfServer::<$cs>::new(&mut SysRng).expect("new");
|
||||||
|
test_roundtrip!(OprfServer, $cs, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn roundtrip_voprf_client() {
|
||||||
|
let client = VoprfClient::<$cs>::blind(b"input", &mut SysRng)
|
||||||
|
.expect("blind")
|
||||||
|
.state;
|
||||||
|
test_roundtrip!(VoprfClient, $cs, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn roundtrip_voprf_server() {
|
||||||
|
let server = VoprfServer::<$cs>::new(&mut SysRng).expect("new");
|
||||||
|
test_roundtrip!(VoprfServer, $cs, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn roundtrip_poprf_client() {
|
||||||
|
let client = PoprfClient::<$cs>::blind(b"input", &mut SysRng)
|
||||||
|
.expect("blind")
|
||||||
|
.state;
|
||||||
|
test_roundtrip!(PoprfClient, $cs, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn roundtrip_poprf_server() {
|
||||||
|
let server = PoprfServer::<$cs>::new(&mut SysRng).expect("new");
|
||||||
|
test_roundtrip!(PoprfServer, $cs, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn trailing_oprf_client() {
|
||||||
|
let client = OprfClient::<$cs>::blind(b"input", &mut SysRng)
|
||||||
|
.expect("blind")
|
||||||
|
.state;
|
||||||
|
test_trailing!(OprfClient, $cs, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn trailing_oprf_server() {
|
||||||
|
let server = OprfServer::<$cs>::new(&mut SysRng).expect("new");
|
||||||
|
test_trailing!(OprfServer, $cs, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn truncated_oprf_client() {
|
||||||
|
let client = OprfClient::<$cs>::blind(b"input", &mut SysRng)
|
||||||
|
.expect("blind")
|
||||||
|
.state;
|
||||||
|
test_truncated!(OprfClient, $cs, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn truncated_oprf_server() {
|
||||||
|
let server = OprfServer::<$cs>::new(&mut SysRng).expect("new");
|
||||||
|
test_truncated!(OprfServer, $cs, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_input_fails() {
|
||||||
|
assert!(OprfClient::<$cs>::deserialize(&[]).is_err());
|
||||||
|
assert!(OprfServer::<$cs>::deserialize(&[]).is_err());
|
||||||
|
assert!(VoprfClient::<$cs>::deserialize(&[]).is_err());
|
||||||
|
assert!(VoprfServer::<$cs>::deserialize(&[]).is_err());
|
||||||
|
assert!(PoprfClient::<$cs>::deserialize(&[]).is_err());
|
||||||
|
assert!(PoprfServer::<$cs>::deserialize(&[]).is_err());
|
||||||
|
assert!(BlindedElement::<$cs>::deserialize(&[]).is_err());
|
||||||
|
assert!(EvaluationElement::<$cs>::deserialize(&[]).is_err());
|
||||||
|
assert!(Proof::<$cs>::deserialize(&[]).is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ristretto255")]
|
||||||
|
structured_tests!(crate::Ristretto255, ristretto255);
|
||||||
|
structured_tests!(::p256::NistP256, p256);
|
||||||
|
structured_tests!(::p384::NistP384, p384);
|
||||||
|
structured_tests!(::p521::NistP521, p521);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! The VOPRF test vectors taken from:
|
//! The VOPRF test vectors taken from:
|
||||||
//! https://www.rfc-editor.org/rfc/rfc9497#appendix-A
|
//! https://www.rfc-editor.org/rfc/rfc9497#appendix-A
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
mod cfrg_vectors;
|
mod cfrg_vectors;
|
||||||
mod mock_rng;
|
mod mock_rng;
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
|
|||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
// Copyright (c) VexaHub and contributors.
|
||||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
//
|
|
||||||
// This source code is dual-licensed under either the MIT license found in the
|
|
||||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
|
||||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
|
||||||
// of this source tree. You may select, at your option, one of the above-listed
|
|
||||||
// licenses.
|
|
||||||
|
|
||||||
//! Contains the main VOPRF API
|
//! Contains the main VOPRF API
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user