Skip to content

Commit

Permalink
Refactor traits that allows implementing different engines for the sa…
Browse files Browse the repository at this point in the history
…me curve cycle (microsoft#263)

* rename Group to Engine

* port tests

* checkpoint

* checkpoint

* compiles

* update benchmarks and tests to use Engine

* rename GroupExt to DlogGroup

* move get_curve_params to Group and rename

* fix doc test; cargo fmt

* inline single trait requirements; fix comments

* cut comment
  • Loading branch information
srinathsetty authored and huitseeker committed Nov 22, 2023
1 parent 0868e27 commit 3e4c8ef
Show file tree
Hide file tree
Showing 40 changed files with 2,097 additions and 2,426 deletions.
65 changes: 30 additions & 35 deletions benches/compressed-snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,28 @@ use core::marker::PhantomData;
use criterion::*;
use ff::PrimeField;
use nova_snark::{
provider::pasta::{PallasEngine, VestaEngine},
traits::{
circuit::{StepCircuit, TrivialCircuit},
snark::RelaxedR1CSSNARKTrait,
Group,
Engine,
},
CompressedSNARK, PublicParams, RecursiveSNARK,
};
use std::time::Duration;

type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
type EE1 = nova_snark::provider::ipa_pc::EvaluationEngine<G1>;
type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine<G2>;
type E1 = PallasEngine;
type E2 = VestaEngine;
type EE1 = nova_snark::provider::ipa_pc::EvaluationEngine<E1>;
type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine<E2>;
// SNARKs without computational commitments
type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK<G1, EE1>;
type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK<G2, EE2>;
type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK<E1, EE1>;
type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK<E2, EE2>;
// SNARKs with computational commitments
type SS1 = nova_snark::spartan::ppsnark::RelaxedR1CSSNARK<G1, EE1>;
type SS2 = nova_snark::spartan::ppsnark::RelaxedR1CSSNARK<G2, EE2>;
type C1 = NonTrivialCircuit<<G1 as Group>::Scalar>;
type C2 = TrivialCircuit<<G2 as Group>::Scalar>;
type SS1 = nova_snark::spartan::ppsnark::RelaxedR1CSSNARK<E1, EE1>;
type SS2 = nova_snark::spartan::ppsnark::RelaxedR1CSSNARK<E2, EE2>;
type C1 = NonTrivialCircuit<<E1 as Engine>::Scalar>;
type C2 = TrivialCircuit<<E2 as Engine>::Scalar>;

// To run these benchmarks, first download `criterion` with `cargo install cargo install cargo-criterion`.
// Then `cargo criterion --bench compressed-snark`. The results are located in `target/criterion/data/<name-of-benchmark>`.
Expand Down Expand Up @@ -66,7 +67,7 @@ fn bench_compressed_snark(c: &mut Criterion) {
let c_secondary = TrivialCircuit::default();

// Produce public parameters
let pp = PublicParams::<G1, G2, C1, C2>::setup(
let pp = PublicParams::<E1, E2, C1, C2>::setup(
&c_primary,
&c_secondary,
&*S1::ck_floor(),
Expand All @@ -78,12 +79,12 @@ fn bench_compressed_snark(c: &mut Criterion) {

// produce a recursive SNARK
let num_steps = 3;
let mut recursive_snark: RecursiveSNARK<G1, G2, C1, C2> = RecursiveSNARK::new(
let mut recursive_snark: RecursiveSNARK<E1, E2, C1, C2> = RecursiveSNARK::new(
&pp,
&c_primary,
&c_secondary,
&[<G1 as Group>::Scalar::from(2u64)],
&[<G2 as Group>::Scalar::from(2u64)],
&[<E1 as Engine>::Scalar::from(2u64)],
&[<E2 as Engine>::Scalar::from(2u64)],
)
.unwrap();

Expand All @@ -95,8 +96,8 @@ fn bench_compressed_snark(c: &mut Criterion) {
let res = recursive_snark.verify(
&pp,
i + 1,
&[<G1 as Group>::Scalar::from(2u64)],
&[<G2 as Group>::Scalar::from(2u64)],
&[<E1 as Engine>::Scalar::from(2u64)],
&[<E2 as Engine>::Scalar::from(2u64)],
);
assert!(res.is_ok());
}
Expand All @@ -123,8 +124,8 @@ fn bench_compressed_snark(c: &mut Criterion) {
.verify(
black_box(&vk),
black_box(num_steps),
black_box(&[<G1 as Group>::Scalar::from(2u64)]),
black_box(&[<G2 as Group>::Scalar::from(2u64)]),
black_box(&[<E1 as Engine>::Scalar::from(2u64)]),
black_box(&[<E2 as Engine>::Scalar::from(2u64)]),
)
.is_ok());
})
Expand Down Expand Up @@ -153,7 +154,7 @@ fn bench_compressed_snark_with_computational_commitments(c: &mut Criterion) {
let c_secondary = TrivialCircuit::default();

// Produce public parameters
let pp = PublicParams::<G1, G2, C1, C2>::setup(
let pp = PublicParams::<E1, E2, C1, C2>::setup(
&c_primary,
&c_secondary,
&*SS1::ck_floor(),
Expand All @@ -164,12 +165,12 @@ fn bench_compressed_snark_with_computational_commitments(c: &mut Criterion) {

// produce a recursive SNARK
let num_steps = 3;
let mut recursive_snark: RecursiveSNARK<G1, G2, C1, C2> = RecursiveSNARK::new(
let mut recursive_snark: RecursiveSNARK<E1, E2, C1, C2> = RecursiveSNARK::new(
&pp,
&c_primary,
&c_secondary,
&[<G1 as Group>::Scalar::from(2u64)],
&[<G2 as Group>::Scalar::from(2u64)],
&[<E1 as Engine>::Scalar::from(2u64)],
&[<E2 as Engine>::Scalar::from(2u64)],
)
.unwrap();

Expand All @@ -181,8 +182,8 @@ fn bench_compressed_snark_with_computational_commitments(c: &mut Criterion) {
let res = recursive_snark.verify(
&pp,
i + 1,
&[<G1 as Group>::Scalar::from(2u64)],
&[<G2 as Group>::Scalar::from(2u64)],
&[<E1 as Engine>::Scalar::from(2u64)],
&[<E2 as Engine>::Scalar::from(2u64)],
);
assert!(res.is_ok());
}
Expand All @@ -209,8 +210,8 @@ fn bench_compressed_snark_with_computational_commitments(c: &mut Criterion) {
.verify(
black_box(&vk),
black_box(num_steps),
black_box(&[<G1 as Group>::Scalar::from(2u64)]),
black_box(&[<G2 as Group>::Scalar::from(2u64)]),
black_box(&[<E1 as Engine>::Scalar::from(2u64)]),
black_box(&[<E2 as Engine>::Scalar::from(2u64)]),
)
.is_ok());
})
Expand All @@ -226,21 +227,15 @@ struct NonTrivialCircuit<F: PrimeField> {
_p: PhantomData<F>,
}

impl<F> NonTrivialCircuit<F>
where
F: PrimeField,
{
impl<F: PrimeField> NonTrivialCircuit<F> {
pub fn new(num_cons: usize) -> Self {
Self {
num_cons,
_p: PhantomData,
}
}
}
impl<F> StepCircuit<F> for NonTrivialCircuit<F>
where
F: PrimeField,
{
impl<F: PrimeField> StepCircuit<F> for NonTrivialCircuit<F> {
fn arity(&self) -> usize {
1
}
Expand Down
23 changes: 9 additions & 14 deletions benches/compute-digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use ff::PrimeField;
use nova_snark::{
provider::pasta::{PallasEngine, VestaEngine},
traits::{
circuit::{StepCircuit, TrivialCircuit},
snark::default_ck_hint,
Group,
Engine,
},
PublicParams,
};

type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
type C1 = NonTrivialCircuit<<G1 as Group>::Scalar>;
type C2 = TrivialCircuit<<G2 as Group>::Scalar>;
type E1 = PallasEngine;
type E2 = VestaEngine;
type C1 = NonTrivialCircuit<<E1 as Engine>::Scalar>;
type C2 = TrivialCircuit<<E2 as Engine>::Scalar>;

criterion_group! {
name = compute_digest;
Expand All @@ -28,7 +29,7 @@ criterion_main!(compute_digest);
fn bench_compute_digest(c: &mut Criterion) {
c.bench_function("compute_digest", |b| {
b.iter(|| {
PublicParams::<G1, G2, C1, C2>::setup(
PublicParams::<E1, E2, C1, C2>::setup(
black_box(&C1::new(10)),
black_box(&C2::default()),
black_box(&*default_ck_hint()),
Expand All @@ -44,21 +45,15 @@ struct NonTrivialCircuit<F: PrimeField> {
_p: PhantomData<F>,
}

impl<F> NonTrivialCircuit<F>
where
F: PrimeField,
{
impl<F: PrimeField> NonTrivialCircuit<F> {
pub fn new(num_cons: usize) -> Self {
Self {
num_cons,
_p: PhantomData,
}
}
}
impl<F> StepCircuit<F> for NonTrivialCircuit<F>
where
F: PrimeField,
{
impl<F: PrimeField> StepCircuit<F> for NonTrivialCircuit<F> {
fn arity(&self) -> usize {
1
}
Expand Down
37 changes: 16 additions & 21 deletions benches/recursive-snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ use core::marker::PhantomData;
use criterion::*;
use ff::PrimeField;
use nova_snark::{
provider::pasta::{PallasEngine, VestaEngine},
traits::{
circuit::{StepCircuit, TrivialCircuit},
snark::default_ck_hint,
Group,
Engine,
},
PublicParams, RecursiveSNARK,
};
use std::time::Duration;

type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
type C1 = NonTrivialCircuit<<G1 as Group>::Scalar>;
type C2 = TrivialCircuit<<G2 as Group>::Scalar>;
type E1 = PallasEngine;
type E2 = VestaEngine;
type C1 = NonTrivialCircuit<<E1 as Engine>::Scalar>;
type C2 = TrivialCircuit<<E2 as Engine>::Scalar>;

// To run these benchmarks, first download `criterion` with `cargo install cargo install cargo-criterion`.
// Then `cargo criterion --bench recursive-snark`. The results are located in `target/criterion/data/<name-of-benchmark>`.
Expand Down Expand Up @@ -57,7 +58,7 @@ fn bench_recursive_snark(c: &mut Criterion) {
let c_secondary = TrivialCircuit::default();

// Produce public parameters
let pp = PublicParams::<G1, G2, C1, C2>::setup(
let pp = PublicParams::<E1, E2, C1, C2>::setup(
&c_primary,
&c_secondary,
&*default_ck_hint(),
Expand All @@ -69,12 +70,12 @@ fn bench_recursive_snark(c: &mut Criterion) {
// the first step is cheaper than other steps owing to the presence of
// a lot of zeros in the satisfying assignment
let num_warmup_steps = 10;
let mut recursive_snark: RecursiveSNARK<G1, G2, C1, C2> = RecursiveSNARK::new(
let mut recursive_snark: RecursiveSNARK<E1, E2, C1, C2> = RecursiveSNARK::new(
&pp,
&c_primary,
&c_secondary,
&[<G1 as Group>::Scalar::from(2u64)],
&[<G2 as Group>::Scalar::from(2u64)],
&[<E1 as Engine>::Scalar::from(2u64)],
&[<E2 as Engine>::Scalar::from(2u64)],
)
.unwrap();

Expand All @@ -86,8 +87,8 @@ fn bench_recursive_snark(c: &mut Criterion) {
let res = recursive_snark.verify(
&pp,
i + 1,
&[<G1 as Group>::Scalar::from(2u64)],
&[<G2 as Group>::Scalar::from(2u64)],
&[<E1 as Engine>::Scalar::from(2u64)],
&[<E2 as Engine>::Scalar::from(2u64)],
);
assert!(res.is_ok());
}
Expand All @@ -112,8 +113,8 @@ fn bench_recursive_snark(c: &mut Criterion) {
.verify(
black_box(&pp),
black_box(num_warmup_steps),
black_box(&[<G1 as Group>::Scalar::from(2u64)]),
black_box(&[<G2 as Group>::Scalar::from(2u64)]),
black_box(&[<E1 as Engine>::Scalar::from(2u64)]),
black_box(&[<E2 as Engine>::Scalar::from(2u64)]),
)
.is_ok());
});
Expand All @@ -128,21 +129,15 @@ struct NonTrivialCircuit<F: PrimeField> {
_p: PhantomData<F>,
}

impl<F> NonTrivialCircuit<F>
where
F: PrimeField,
{
impl<F: PrimeField> NonTrivialCircuit<F> {
pub fn new(num_cons: usize) -> Self {
Self {
num_cons,
_p: PhantomData,
}
}
}
impl<F> StepCircuit<F> for NonTrivialCircuit<F>
where
F: PrimeField,
{
impl<F: PrimeField> StepCircuit<F> for NonTrivialCircuit<F> {
fn arity(&self) -> usize {
1
}
Expand Down
20 changes: 11 additions & 9 deletions benches/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,29 @@
//! This code invokes a hand-written SHA-256 gadget from bellman/bellperson.
//! It also uses code from bellman/bellperson to compare circuit-generated digest with sha2 crate's output
#![allow(non_snake_case)]
type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
use bellpepper::gadgets::{sha256::sha256, Assignment};
use bellpepper_core::{
boolean::{AllocatedBit, Boolean},
num::{AllocatedNum, Num},
ConstraintSystem, SynthesisError,
};
use core::marker::PhantomData;
use core::time::Duration;
use criterion::*;
use ff::{PrimeField, PrimeFieldBits};
use nova_snark::{
provider::pasta::{PallasEngine, VestaEngine},
traits::{
circuit::{StepCircuit, TrivialCircuit},
snark::default_ck_hint,
Group,
Engine,
},
PublicParams, RecursiveSNARK,
};
use sha2::{Digest, Sha256};
use std::marker::PhantomData;

type E1 = PallasEngine;
type E2 = VestaEngine;

#[derive(Clone, Debug)]
struct Sha256Circuit<Scalar: PrimeField> {
Expand Down Expand Up @@ -120,8 +122,8 @@ impl<Scalar: PrimeField + PrimeFieldBits> StepCircuit<Scalar> for Sha256Circuit<
}
}

type C1 = Sha256Circuit<<G1 as Group>::Scalar>;
type C2 = TrivialCircuit<<G2 as Group>::Scalar>;
type C1 = Sha256Circuit<<E1 as Engine>::Scalar>;
type C2 = TrivialCircuit<<E2 as Engine>::Scalar>;

criterion_group! {
name = recursive_snark;
Expand Down Expand Up @@ -156,16 +158,16 @@ fn bench_recursive_snark(c: &mut Criterion) {

// Produce public parameters
let ttc = TrivialCircuit::default();
let pp = PublicParams::<G1, G2, C1, C2>::setup(
let pp = PublicParams::<E1, E2, C1, C2>::setup(
&circuit_primary,
&ttc,
&*default_ck_hint(),
&*default_ck_hint(),
);

let circuit_secondary = TrivialCircuit::default();
let z0_primary = vec![<G1 as Group>::Scalar::from(2u64)];
let z0_secondary = vec![<G2 as Group>::Scalar::from(2u64)];
let z0_primary = vec![<E1 as Engine>::Scalar::from(2u64)];
let z0_secondary = vec![<E2 as Engine>::Scalar::from(2u64)];

group.bench_function("Prove", |b| {
b.iter(|| {
Expand Down
Loading

0 comments on commit 3e4c8ef

Please sign in to comment.