arnaucube
arnaucube/NovaPublic Self-hosted repository
Nova/benches/compressed-snark.rs
benches/compressed-snark.rsRaw
  1#![allow(non_snake_case)]
  2
  3use nova_snark::{
  4  traits::{Group, StepCircuit},
  5  CompressedSNARK, PublicParams, RecursiveSNARK,
  6};
  7
  8type G1 = pasta_curves::pallas::Point;
  9type G2 = pasta_curves::vesta::Point;
 10type S1 = nova_snark::spartan_with_ipa_pc::RelaxedR1CSSNARK<G1>;
 11type S2 = nova_snark::spartan_with_ipa_pc::RelaxedR1CSSNARK<G2>;
 12
 13#[derive(Clone, Debug)]
 14struct TrivialTestCircuit<F: PrimeField> {
 15  _p: PhantomData<F>,
 16}
 17
 18impl<F> StepCircuit<F> for TrivialTestCircuit<F>
 19where
 20  F: PrimeField,
 21{
 22  fn synthesize<CS: ConstraintSystem<F>>(
 23    &self,
 24    _cs: &mut CS,
 25    z: AllocatedNum<F>,
 26  ) -> Result<AllocatedNum<F>, SynthesisError> {
 27    Ok(z)
 28  }
 29
 30  fn compute(&self, z: &F) -> F {
 31    *z
 32  }
 33}
 34
 35type C1 = TrivialTestCircuit<<G1 as Group>::Scalar>;
 36type C2 = TrivialTestCircuit<<G2 as Group>::Scalar>;
 37
 38use bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError};
 39use core::marker::PhantomData;
 40use criterion::*;
 41use ff::PrimeField;
 42use std::time::Duration;
 43
 44fn compressed_snark_benchmark(c: &mut Criterion) {
 45  let num_samples = 10;
 46  bench_compressed_snark(c, num_samples);
 47}
 48
 49fn set_duration() -> Criterion {
 50  Criterion::default().warm_up_time(Duration::from_millis(3000))
 51}
 52
 53criterion_group! {
 54name = compressed_snark;
 55config = set_duration();
 56targets = compressed_snark_benchmark
 57}
 58
 59criterion_main!(compressed_snark);
 60
 61fn bench_compressed_snark(c: &mut Criterion, num_samples: usize) {
 62  let mut group = c.benchmark_group("CompressedSNARK");
 63  group.sample_size(num_samples);
 64
 65  // Produce public parameters
 66  let pp = PublicParams::<G1, G2, C1, C2>::setup(
 67    TrivialTestCircuit {
 68      _p: Default::default(),
 69    },
 70    TrivialTestCircuit {
 71      _p: Default::default(),
 72    },
 73  );
 74
 75  // produce a recursive SNARK
 76  let num_steps = 3;
 77  let mut recursive_snark: Option<RecursiveSNARK<G1, G2, C1, C2>> = None;
 78
 79  for i in 0..num_steps {
 80    let res = RecursiveSNARK::prove_step(
 81      &pp,
 82      recursive_snark,
 83      TrivialTestCircuit {
 84        _p: Default::default(),
 85      },
 86      TrivialTestCircuit {
 87        _p: Default::default(),
 88      },
 89      <G1 as Group>::Scalar::one(),
 90      <G2 as Group>::Scalar::zero(),
 91    );
 92    assert!(res.is_ok());
 93    let recursive_snark_unwrapped = res.unwrap();
 94
 95    // verify the recursive snark at each step of recursion
 96    let res = recursive_snark_unwrapped.verify(
 97      &pp,
 98      i + 1,
 99      <G1 as Group>::Scalar::one(),
100      <G2 as Group>::Scalar::zero(),
101    );
102    assert!(res.is_ok());
103
104    // set the running variable for the next iteration
105    recursive_snark = Some(recursive_snark_unwrapped);
106  }
107
108  // Bench time to produce a compressed SNARK
109  let recursive_snark = recursive_snark.unwrap();
110  group.bench_function("Prove", |b| {
111    b.iter(|| {
112      assert!(CompressedSNARK::<_, _, _, _, S1, S2>::prove(
113        black_box(&pp),
114        black_box(&recursive_snark)
115      )
116      .is_ok());
117    })
118  });
119  let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &recursive_snark);
120  assert!(res.is_ok());
121  let compressed_snark = res.unwrap();
122
123  // Benchmark the verification time
124  let name = "Verify";
125  group.bench_function(name, |b| {
126    b.iter(|| {
127      assert!(black_box(&compressed_snark)
128        .verify(
129          black_box(&pp),
130          black_box(num_steps),
131          black_box(<G1 as Group>::Scalar::zero()),
132          black_box(<G2 as Group>::Scalar::zero()),
133        )
134        .is_ok());
135    })
136  });
137
138  group.finish();
139}