Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ and follow [semantic versioning](https://semver.org/) for our releases.
- [#309](https://github.com/EspressoSystems/jellyfish/pull/309) Reed-Solomon decoder accept FFT domain
- [#320](https://github.com/EspressoSystems/jellyfish/pull/320) Non-native elliptic curve addition in short Weierstrass form
- [#337](https://github.com/EspressoSystems/jellyfish/pull/337) Port VID from another repo
- [#341](https://github.com/EspressoSystems/jellyfish/pull/341) Port VDF from another repo

### Changed

Expand Down
5 changes: 5 additions & 0 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ark-ed-on-bls12-377 = "0.4.0"
ark-ed-on-bls12-381 = "0.4.0"
ark-ed-on-bn254 = "0.4.0"
ark-ff = "0.4.0"
ark-pallas = "0.4.0"
ark-poly = "0.4.0"
ark-serialize = "0.4.0"
ark-std = { version = "0.4.0", default-features = false }
Expand Down Expand Up @@ -84,6 +85,10 @@ harness = false
name = "advz"
harness = false

[[bench]]
name = "minroot"
harness = false

[features]
default = ["parallel"]
std = [
Expand Down
6 changes: 6 additions & 0 deletions primitives/benches/advz.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// Copyright (c) 2022 Espresso Systems (espressosys.com)
// This file is part of the Jellyfish library.

// You should have received a copy of the MIT License
// along with the Jellyfish library. If not, see <https://mit-license.org/>.

#![cfg(feature = "test-srs")]
use ark_bls12_381::Bls12_381;
use ark_bn254::Bn254;
Expand Down
44 changes: 44 additions & 0 deletions primitives/benches/minroot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#[macro_use]
extern crate criterion;
use ark_bls12_381::Fr as Fr381;
use ark_bn254::Fr as Fr254;
use ark_pallas::Fr as PastaFr;
use ark_std::rand::rngs::StdRng;
use criterion::{Criterion, Throughput};
use jf_primitives::vdf::{
minroot::{MinRoot, MinRootElement},
VDF,
};

fn minroot_bench(c: &mut Criterion) {
let mut benchmark_group = c.benchmark_group("MinRoot");
benchmark_group.sample_size(10);
let iterations = 1u64 << 16;

benchmark_group.throughput(Throughput::Elements(iterations));
let pp = MinRoot::<Fr254>::setup::<StdRng>(iterations, None).unwrap();
let input = MinRootElement::<Fr254>::default();
benchmark_group.bench_function("MinRoot_BN254", |b| {
b.iter(|| MinRoot::<Fr254>::eval(&pp, &input).unwrap())
});

let input = MinRootElement::<Fr381>::default();
benchmark_group.bench_function("MinRoot_BLS381", |b| {
b.iter(|| MinRoot::<Fr381>::eval(&pp, &input).unwrap())
});

let input = MinRootElement::<PastaFr>::default();
benchmark_group.bench_function("MinRoot_Pallas", |b| {
b.iter(|| MinRoot::<PastaFr>::eval(&pp, &input).unwrap())
});

benchmark_group.finish();
}

fn bench(c: &mut Criterion) {
minroot_bench(c);
}

criterion_group!(benches, bench);

criterion_main!(benches);
1 change: 1 addition & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub mod reed_solomon_code;
pub mod rescue;
pub mod signatures;
pub mod toeplitz;
pub mod vdf;
pub mod vid;
pub mod vrf;

Expand Down
184 changes: 184 additions & 0 deletions primitives/src/vdf/minroot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// Copyright (c) 2022 Espresso Systems (espressosys.com)
// This file is part of the Jellyfish library.

// You should have received a copy of the MIT License
// along with the Jellyfish library. If not, see <https://mit-license.org/>.
//! Instantiation of the MinRoot Delay function <https://eprint.iacr.org/2022/1626.pdf>.

use crate::{errors::PrimitivesError, vdf::VDF};
use ark_ec::AffineRepr;
use ark_ff::PrimeField;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::{format, vec::Vec};
use core::marker::PhantomData;

/// MinRoot compatible field
pub trait MinRootField: PrimeField {
/// The MinRoot iteration is calculating the cubic root (or fifth-root if
/// modulus % 3 == 1) of a field element. E.g. `EXP_COEF` should be (2 *
/// modulus - 1) / 3 if modulus % 3 != 1.
const EXP_COEF: Self::BigInt;
}

#[derive(
Copy,
Clone,
Debug,
Default,
Eq,
PartialEq,
Ord,
PartialOrd,
CanonicalSerialize,
CanonicalDeserialize,
)]

/// Public parameter for MinRoot DF,
pub struct MinRootPP {
/// Indicates the number of iterations
pub difficulty: u64,
}

/// A minroot element consists of a pair of field elements.
#[derive(
Copy,
Clone,
Debug,
Default,
Eq,
PartialEq,
Ord,
PartialOrd,
CanonicalSerialize,
CanonicalDeserialize,
)]
pub struct MinRootElement<F: MinRootField>(F, F);

impl<F, T> From<T> for MinRootElement<F>
where
T: AffineRepr<BaseField = F>,
F: MinRootField,
{
fn from(value: T) -> Self {
let (x, y) = value.xy().unwrap();
MinRootElement(*x, *y)
}
}

/// Dummy struct for MinRoot delay function.
pub struct MinRoot<F: MinRootField> {
_phantom: PhantomData<F>,
}

impl<F: MinRootField> VDF for MinRoot<F> {
type PublicParameter = MinRootPP;
type Proof = MinRootElement<F>;
type Input = MinRootElement<F>;
type Output = MinRootElement<F>;

fn setup<R: ark_std::rand::CryptoRng + ark_std::rand::RngCore>(
difficulty: u64,
_prng: Option<&mut R>,
) -> Result<Self::PublicParameter, PrimitivesError> {
Ok(MinRootPP { difficulty })
}

fn eval(
pp: &Self::PublicParameter,
input: &Self::Input,
) -> Result<(Self::Output, Self::Proof), PrimitivesError> {
let mut output = *input;
for i in 0..pp.difficulty {
Self::iterate_in_place(&mut output, i)?;
}
Ok((output, output))
}

fn verify(
_pp: &Self::PublicParameter,
_input: &Self::Input,
output: &Self::Output,
proof: &Self::Proof,
) -> Result<(), PrimitivesError> {
if proof == output {
Ok(())
} else {
Err(PrimitivesError::VerificationError(format!(
"Expected: \"{:?}\", found \"{:?}\" instead",
proof, output
)))
}
}
}

impl<F: MinRootField> MinRoot<F> {
#[inline]
fn iterate_in_place(elem: &mut MinRootElement<F>, round: u64) -> Result<(), PrimitivesError> {
let x = elem.0;
elem.0 = (x + elem.1).pow(F::EXP_COEF);
// assert_eq!(elem.0.pow([5u64]), x + elem.1);
elem.1 = x + F::from(round);
Ok(())
}
}

impl MinRootField for ark_bn254::Fr {
// modulus 21888242871839275222246405745257275088548364400416034343698204186575808495617
// modulus % 3 == 1, modulus % 5 == 2
// coef = (4 * modulus - 3) / 5
// coef: 17510594297471420177797124596205820070838691520332827474958563349260646796493
const EXP_COEF: Self::BigInt = ark_ff::BigInt::<4>([
14981214993055009997,
6006880321387387405,
10624953561019755799,
2789598613442376532,
]);
}

impl MinRootField for ark_bls12_381::Fr {
// modulus 52435875175126190479447740508185965837690552500527637822603658699938581184513
// modulus % 3 == 1, modulus % 5 == 3
// coef = (2 * modulus - 1) / 5
// coef: 20974350070050476191779096203274386335076221000211055129041463479975432473805
const EXP_COEF: Self::BigInt = ark_ff::BigInt::<4>([
3689348813023923405,
2413663763415232921,
16233882818423549954,
3341406743785779740,
]);
}

impl MinRootField for ark_pallas::Fr {
// modulus 28948022309329048855892746252171976963363056481941647379679742748393362948097
// modulus % 3 == 1, modulus % 5 == 2
// coef = (4 * modulus - 3) / 5
// coef: 23158417847463239084714197001737581570690445185553317903743794198714690358477
const EXP_COEF: Self::BigInt = ark_ff::BigInt::<4>([
15465117582000704717,
5665212537877281354,
3689348814741910323,
3689348814741910323,
]);
}

#[cfg(test)]
mod test {
use super::{MinRoot, MinRootElement, MinRootField};
use crate::vdf::VDF;
use ark_std::rand::rngs::StdRng;

#[test]
fn test_minroot() {
test_minroot_helper::<ark_bn254::Fr>();
test_minroot_helper::<ark_bls12_381::Fr>();
test_minroot_helper::<ark_pallas::Fr>();
}

fn test_minroot_helper<F: MinRootField>() {
let start = MinRootElement(F::one(), F::one());
let pp = MinRoot::<F>::setup::<StdRng>(100, None).unwrap();
let (output, proof) = MinRoot::<F>::eval(&pp, &start).unwrap();
assert_eq!(output, proof);
assert!(MinRoot::<F>::verify(&pp, &start, &output, &proof).is_ok());
}
}
74 changes: 74 additions & 0 deletions primitives/src/vdf/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) 2022 Espresso Systems (espressosys.com)
// This file is part of the Jellyfish library.

// You should have received a copy of the MIT License
// along with the Jellyfish library. If not, see <https://mit-license.org/>.

//! Trait and implementation for a Verifiable Delay Function (VDF) <https://eprint.iacr.org/2018/601.pdf>.
use crate::errors::PrimitivesError;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::{
fmt::Debug,
rand::{CryptoRng, RngCore},
};

pub mod minroot;

/// A trait for VDF proof, evaluation and verification.
pub trait VDF {
/// Public parameters
type PublicParameter;

/// VDF proof.
type Proof: Debug
+ Clone
+ Send
+ Sync
+ CanonicalSerialize
+ CanonicalDeserialize
+ PartialEq
+ Eq;

/// VDF input.
type Input: Debug
+ Clone
+ Send
+ Sync
+ CanonicalSerialize
+ CanonicalDeserialize
+ PartialEq
+ Eq;

/// VDF output.
type Output: Debug
+ Clone
+ Send
+ Sync
+ CanonicalSerialize
+ CanonicalDeserialize
+ PartialEq
+ Eq;

/// Generates a public parameter from RNG with given difficulty.
/// Concrete instantiations of VDF shall document properly about the
/// correspondence between the difficulty value and the time required
/// for evaluation/proof generation.
fn setup<R: CryptoRng + RngCore>(
difficulty: u64,
prng: Option<&mut R>,
) -> Result<Self::PublicParameter, PrimitivesError>;

/// Computes the VDF output and proof.
fn eval(
pp: &Self::PublicParameter,
input: &Self::Input,
) -> Result<(Self::Output, Self::Proof), PrimitivesError>;

/// Verifies a VDF output given the proof.
fn verify(
pp: &Self::PublicParameter,
input: &Self::Input,
output: &Self::Output,
proof: &Self::Proof,
) -> Result<(), PrimitivesError>;
}
6 changes: 6 additions & 0 deletions primitives/src/vid/advz.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// Copyright (c) 2022 Espresso Systems (espressosys.com)
// This file is part of the Jellyfish library.

// You should have received a copy of the MIT License
// along with the Jellyfish library. If not, see <https://mit-license.org/>.

//! Implementation of Verifiable Information Dispersal (VID) from <https://eprint.iacr.org/2021/1500>.
//!
//! `advz` named for the authors Alhaddad-Duan-Varia-Zhang.
Expand Down
6 changes: 6 additions & 0 deletions primitives/src/vid/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// Copyright (c) 2022 Espresso Systems (espressosys.com)
// This file is part of the Jellyfish library.

// You should have received a copy of the MIT License
// along with the Jellyfish library. If not, see <https://mit-license.org/>.

//! Trait and implementation for a Verifiable Information Retrieval (VID).
/// See <https://arxiv.org/abs/2111.12323> section 1.3--1.4 for intro to VID semantics.
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
Expand Down