Skip to content

Commit 600b66d

Browse files
authored
Secret split (#59)
1 parent 5f80d47 commit 600b66d

File tree

15 files changed

+227
-46
lines changed

15 files changed

+227
-46
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ std = [
4444
"ark-ec/std",
4545
"ring-proof?/std",
4646
]
47+
secret-split = [ "ark-std/getrandom" ]
4748
full = [
4849
"secp256r1",
4950
"ed25519",

README.md

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ supports customization of scheme parameters.
2121

2222
### Built-In suites
2323

24-
The library includes the following pre-configured suites:
24+
The library conditionally includes the following pre-configured suites (see features section):
2525

2626
- **Ed25519-SHA-512-TAI**: Supports IETF and Pedersen VRFs.
2727
- **Secp256r1-SHA-256-TAI**: Supports IETF and Pedersen VRFs.
@@ -41,21 +41,21 @@ let aux_data = b"optional aux data";
4141
```
4242
#### IETF-VRF
4343

44-
Prove
44+
_Prove_
4545
```rust
4646
use ark_ec_vrfs::ietf::Prover;
4747
let proof = secret.prove(input, output, aux_data);
4848
```
4949

50-
Verify
50+
_Verify_
5151
```rust
5252
use ark_ec_vrfs::ietf::Verifier;
5353
let result = public.verify(input, output, aux_data, &proof);
5454
```
5555

5656
#### Ring-VRF
5757

58-
Ring construction
58+
_Ring construction_
5959
```rust
6060
const RING_SIZE: usize = 100;
6161
let prover_key_index = 3;
@@ -67,33 +67,57 @@ ring[prover_key_index] = public.0;
6767
ring[0] = RingContext::padding_point();
6868
```
6969

70-
Ring context construction
70+
_Ring parameters construction_
7171
```rust
7272
let ring_ctx = RingContext::from_seed(RING_SIZE, b"example seed");
7373
```
7474

75-
Prove
75+
_Prove_
7676
```rust
7777
use ark_ec_vrfs::ring::Prover;
7878
let prover_key = ring_ctx.prover_key(&ring);
7979
let prover = ring_ctx.prover(prover_key, prover_key_index);
8080
let proof = secret.prove(input, output, aux_data, &prover);
8181
```
8282

83-
Verify
83+
_Verify_
8484
```rust
8585
use ark_ec_vrfs::ring::Verifier;
8686
let verifier_key = ring_ctx.verifier_key(&ring);
8787
let verifier = ring_ctx.verifier(verifier_key);
8888
let result = Public::verify(input, output, aux_data, &proof, &verifier);
8989
```
9090

91-
Verifier key from commitment
91+
_Verifier key from commitment_
9292
```rust
9393
let ring_commitment = ring_ctx.verifier_key().commitment();
9494
let verifier_key = ring_ctx.verifier_key_from_commitment(ring_commitment);
9595
```
9696

97+
## Features
98+
99+
- `default`: `std`
100+
- `full`: Enables all features listed below except `secret-split`, `parallel`, `asm`, `rfc-6979`, `test-vectors`.
101+
- `secret-split`: Point scalar multiplication with secret split. Secret scalar is split into the sum
102+
of two scalars, which randomly mutate but retain the same sum. Incurs 2x penalty in some internal
103+
sensible scalar multiplications, but provides side channel defenses.
104+
- `ring`: Ring-VRF for the curves supporting it.
105+
- `rfc-6979`: Support for nonce generation according to RFC-9381 section 5.4.2.1.
106+
- `test-vectors`: Deterministic ring-vrf proof. Useful for reproducible test vectors generation.
107+
108+
### Curves
109+
110+
- `ed25519`
111+
- `jubjub`
112+
- `bandersnatch`
113+
- `baby-jubjub`
114+
- `secp256r1`
115+
116+
### Arkworks optimizations
117+
118+
- `parallel`: Parallel execution where worth using `rayon`.
119+
- `asm`: Assembly implementation of some low level operations.
120+
97121
## License
98122

99-
Distributed under the [MIT License](LICENSE).
123+
Distributed under the [MIT License](./LICENSE).

src/codec.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Points and scalars encoding.
2+
13
use ark_ec::short_weierstrass::SWCurveConfig;
24
use utils::te_sw_map;
35

src/ietf.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ pub trait Verifier<S: IetfSuite> {
9090
impl<S: IetfSuite> Prover<S> for Secret<S> {
9191
fn prove(&self, input: Input<S>, output: Output<S>, ad: impl AsRef<[u8]>) -> Proof<S> {
9292
let k = S::nonce(&self.scalar, input);
93-
let k_b = (S::generator() * k).into_affine();
9493

95-
let k_h = (input.0 * k).into_affine();
94+
let k_b = smul!(S::generator(), k).into_affine();
95+
let k_h = smul!(input.0, k).into_affine();
9696

9797
let c = S::challenge(
9898
&[&self.public.0, &input.0, &output.0, &k_b, &k_h],

src/lib.rs

Lines changed: 118 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! # Elliptic Curve VRFs.
1+
//! # Elliptic Curve VRF-AD
22
//!
33
//! This library provides flexible and efficient implementations of Verifiable
44
//! Random Functions with Additional Data (VRF-AD), a cryptographic construct
@@ -8,22 +8,130 @@
88
//! It leverages the [Arkworks](https://github.com/arkworks-rs) framework and
99
//! supports customization of scheme parameters.
1010
//!
11-
//! Supported VRFs:
11+
//! ### Supported VRFs
12+
//!
1213
//! - **IETF VRF**: Complies with ECVRF described in [RFC9381](https://datatracker.ietf.org/doc/rfc9381).
1314
//! - **Pedersen VRF**: Described in [BCHSV23](https://eprint.iacr.org/2023/002).
1415
//! - **Ring VRF**: A zero-knowledge-based inspired by [BCHSV23](https://eprint.iacr.org/2023/002).
16+
//!
17+
//! ### Schemes Specifications
18+
//!
19+
//! - [VRF Schemes Details](https://github.com/davxy/bandersnatch-vrfs-spec)
20+
//! - [Ring VRF ZK Proof](https://github.com/davxy/ring-proof-spec)
21+
//!
22+
//! ### Built-In suites
23+
//!
24+
//! The library conditionally includes the following pre-configured suites (see features section):
25+
//!
26+
//! - **Ed25519-SHA-512-TAI**: Supports IETF and Pedersen VRFs.
27+
//! - **Secp256r1-SHA-256-TAI**: Supports IETF and Pedersen VRFs.
28+
//! - **Bandersnatch** (_Edwards curve on BLS12-381_): Supports IETF, Pedersen, and Ring VRFs.
29+
//! - **JubJub** (_Edwards curve on BLS12-381_): Supports IETF, Pedersen, and Ring VRFs.
30+
//! - **Baby-JubJub** (_Edwards curve on BN254_): Supports IETF, Pedersen, and Ring VRFs.
31+
//!
32+
//! ### Basic Usage
33+
//!
34+
//! ```rust,ignore
35+
//! use ark_ec_vrfs::suites::bandersnatch::*;
36+
//! let secret = Secret::from_seed(b"example seed");
37+
//! let public = secret.public();
38+
//! let input = Input::new(b"example input").unwrap();
39+
//! let output = secret.output(input);
40+
//! let aux_data = b"optional aux data";
41+
//! ```
42+
//! #### IETF-VRF
43+
//!
44+
//! _Prove_
45+
//! ```rust,ignore
46+
//! use ark_ec_vrfs::ietf::Prover;
47+
//! let proof = secret.prove(input, output, aux_data);
48+
//! ```
49+
//!
50+
//! _Verify_
51+
//! ```rust,ignore
52+
//! use ark_ec_vrfs::ietf::Verifier;
53+
//! let result = public.verify(input, output, aux_data, &proof);
54+
//! ```
55+
//!
56+
//! #### Ring-VRF
57+
//!
58+
//! _Ring construction_
59+
//! ```rust,ignore
60+
//! const RING_SIZE: usize = 100;
61+
//! let prover_key_index = 3;
62+
//! // Construct an example ring with dummy keys
63+
//! let mut ring = (0..RING_SIZE).map(|i| Secret::from_seed(&i.to_le_bytes()).public().0).collect();
64+
//! // Patch the ring with the public key of the prover
65+
//! ring[prover_key_index] = public.0;
66+
//! // Any key can be replaced with the padding point
67+
//! ring[0] = RingContext::padding_point();
68+
//! ```
69+
//!
70+
//! _Ring parameters construction_
71+
//! ```rust,ignore
72+
//! let ring_ctx = RingContext::from_seed(RING_SIZE, b"example seed");
73+
//! ```
74+
//!
75+
//! _Prove_
76+
//! ```rust,ignore
77+
//! use ark_ec_vrfs::ring::Prover;
78+
//! let prover_key = ring_ctx.prover_key(&ring);
79+
//! let prover = ring_ctx.prover(prover_key, prover_key_index);
80+
//! let proof = secret.prove(input, output, aux_data, &prover);
81+
//! ```
82+
//!
83+
//! _Verify_
84+
//! ```rust,ignore
85+
//! use ark_ec_vrfs::ring::Verifier;
86+
//! let verifier_key = ring_ctx.verifier_key(&ring);
87+
//! let verifier = ring_ctx.verifier(verifier_key);
88+
//! let result = Public::verify(input, output, aux_data, &proof, &verifier);
89+
//! ```
90+
//!
91+
//! _Verifier key from commitment_
92+
//! ```rust,ignore
93+
//! let ring_commitment = ring_ctx.verifier_key().commitment();
94+
//! let verifier_key = ring_ctx.verifier_key_from_commitment(ring_commitment);
95+
//! ```
96+
//!
97+
//! ## Features
98+
//!
99+
//! - `default`: `std`
100+
//! - `full`: Enables all features listed below except `secret-split`, `parallel`, `asm`, `rfc-6979`, `test-vectors`.
101+
//! - `secret-split`: Point scalar multiplication with secret split. Secret scalar is split into the sum
102+
//! of two scalars, which randomly mutate but retain the same sum. Incurs 2x penalty in some internal
103+
//! sensible scalar multiplications, but provides side channel defenses.
104+
//! - `ring`: Ring-VRF for the curves supporting it.
105+
//! - `rfc-6979`: Support for nonce generation according to RFC-9381 section 5.4.2.1.
106+
//! - `test-vectors`: Deterministic ring-vrf proof. Useful for reproducible test vectors generation.
107+
//!
108+
//! ### Curves
109+
//!
110+
//! - `ed25519`
111+
//! - `jubjub`
112+
//! - `bandersnatch`
113+
//! - `baby-jubjub`
114+
//! - `secp256r1`
115+
//!
116+
//! ### Arkworks optimizations
117+
//!
118+
//! - `parallel`: Parallel execution where worth using `rayon`.
119+
//! - `asm`: Assembly implementation of some low level operations.
120+
//!
121+
//! ## License
122+
//!
123+
//! Distributed under the [MIT License](./LICENSE).
15124
16125
#![cfg_attr(not(feature = "std"), no_std)]
17126
#![deny(unsafe_code)]
18127

19-
use zeroize::Zeroize;
20-
21128
use ark_ec::{AffineRepr, CurveGroup};
22129
use ark_ff::{One, PrimeField, Zero};
23130
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
24131
use ark_std::vec::Vec;
25132

26133
use digest::Digest;
134+
use zeroize::Zeroize;
27135

28136
pub mod codec;
29137
pub mod ietf;
@@ -37,8 +145,9 @@ pub mod ring;
37145
#[cfg(test)]
38146
mod testing;
39147

40-
// Re-export stuff that may be useful downstream.
41-
#[doc(hidden)]
148+
use codec::Codec;
149+
150+
/// Re-export stuff that may be useful downstream.
42151
pub mod reexports {
43152
pub use ark_ec;
44153
pub use ark_ff;
@@ -47,15 +156,13 @@ pub mod reexports {
47156
}
48157

49158
pub type AffinePoint<S> = <S as Suite>::Affine;
50-
51159
pub type BaseField<S> = <AffinePoint<S> as AffineRepr>::BaseField;
52160
pub type ScalarField<S> = <AffinePoint<S> as AffineRepr>::ScalarField;
53161
pub type CurveConfig<S> = <AffinePoint<S> as AffineRepr>::Config;
54162

55163
pub type HashOutput<S> = digest::Output<<S as Suite>::Hasher>;
56164

57-
pub use codec::Codec;
58-
165+
/// Overarching errors.
59166
#[derive(Debug)]
60167
pub enum Error {
61168
/// Verification error
@@ -242,7 +349,7 @@ impl<S: Suite> Secret<S> {
242349

243350
/// Get the VRF output point relative to input.
244351
pub fn output(&self, input: Input<S>) -> Output<S> {
245-
Output((input.0 * self.scalar).into_affine())
352+
Output(smul!(input.0, self.scalar).into_affine())
246353
}
247354
}
248355

@@ -289,6 +396,7 @@ impl<S: Suite> Output<S> {
289396
}
290397
}
291398

399+
/// Type aliases for the given suite.
292400
#[macro_export]
293401
macro_rules! suite_types {
294402
($suite:ident) => {

src/pedersen.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Pedersen VRF
2+
13
use crate::ietf::IetfSuite;
24
use crate::*;
35

@@ -89,12 +91,17 @@ impl<S: PedersenSuite> Prover<S> for Secret<S> {
8991
let kb = S::nonce(&blinding, input);
9092

9193
// Yb = x*G + b*B
92-
let pk_com = (S::generator() * self.scalar + S::BLINDING_BASE * blinding).into_affine();
94+
let xg = smul!(S::generator(), self.scalar);
95+
let bb = smul!(S::BLINDING_BASE, blinding);
96+
let pk_com = (xg + bb).into_affine();
9397

9498
// R = k*G + kb*B
95-
let r = (S::generator() * k + S::BLINDING_BASE * kb).into_affine();
99+
let kg = smul!(S::generator(), k);
100+
let kbb = smul!(S::BLINDING_BASE, kb);
101+
let r = (kg + kbb).into_affine();
102+
96103
// Ok = k*I
97-
let ok = (input.0 * k).into_affine();
104+
let ok = smul!(input.0, k).into_affine();
98105

99106
// c = Hash(Yb, I, O, R, Ok, ad)
100107
let c = S::challenge(&[&pk_com, &input.0, &output.0, &r, &ok], ad.as_ref());

src/ring.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//! Ring VRF.
2+
//!
3+
//! This module is gated by the `ring` feature.
14
use crate::*;
25
use ark_ec::{
36
pairing::Pairing,
@@ -543,7 +546,7 @@ where
543546
}
544547
}
545548

546-
/// Define type aliases for the given ring suite.
549+
/// Type aliases for the given ring suite.
547550
#[macro_export]
548551
macro_rules! ring_suite_types {
549552
($suite:ident) => {
@@ -734,7 +737,6 @@ pub(crate) mod testing {
734737
while !pks.is_empty() {
735738
let chunk_len = 1 + random_val::<usize>(Some(rng)) % 5;
736739
let chunk = pks.drain(..pks.len().min(chunk_len)).collect::<Vec<_>>();
737-
println!("Appending {} items", chunk.len());
738740
vk_builder.append(&chunk[..], &loader).unwrap();
739741
assert_eq!(vk_builder.free_slots(), pks.len());
740742
}

src/suites/baby_jubjub.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//!
55
//! * `suite_string` = b"Baby-JubJub_SHA-512_TAI".
66
//!
7-
//! - The EC group is the prime subgroup of the Baby-JubJub elliptic curve
7+
//! - The EC group **G** is the prime subgroup of the Baby-JubJub elliptic curve
88
//! as defined by <https://github.com/barryWhiteHat/baby_jubjub>.
99
//! For this group, `fLen` = `qLen` = $32$ and `cofactor` = $8$.
1010
//!
@@ -27,7 +27,7 @@
2727
//! * The string_to_int function decodes from the 32 bytes little endian
2828
//! representation.
2929
//!
30-
//! * The point_to_string function converts a point in <G> to an octet
30+
//! * The point_to_string function converts a point in **G** to an octet
3131
//! string using compressed form. The y coordinate is encoded using
3232
//! int_to_string function and the most significant bit of the last
3333
//! octet is used to keep track of the x's sign. This implies that

0 commit comments

Comments
 (0)