arnaucube
arnaucube/NovaPublic Self-hosted repository
Nova/benches/recursive-snark.rs
benches/recursive-snark.rsRaw
  1#![allow(non_snake_case)]
  2
  3use criterion::*;
  4use nova_snark::{
  5  traits::{circuit::TrivialTestCircuit, Group},
  6  PublicParams, RecursiveSNARK,
  7};
  8use std::time::Duration;
  9
 10type G1 = pasta_curves::pallas::Point;
 11type G2 = pasta_curves::vesta::Point;
 12type C1 = TrivialTestCircuit<<G1 as Group>::Scalar>;
 13type C2 = TrivialTestCircuit<<G2 as Group>::Scalar>;
 14
 15fn recursive_snark_benchmark(c: &mut Criterion) {
 16  let num_samples = 10;
 17  bench_recursive_snark(c, num_samples);
 18}
 19
 20fn set_duration() -> Criterion {
 21  Criterion::default().warm_up_time(Duration::from_millis(3000))
 22}
 23
 24criterion_group! {
 25name = recursive_snark;
 26config = set_duration();
 27targets = recursive_snark_benchmark
 28}
 29
 30criterion_main!(recursive_snark);
 31
 32fn bench_recursive_snark(c: &mut Criterion, num_samples: usize) {
 33  let mut group = c.benchmark_group("RecursiveSNARK".to_string());
 34  group.sample_size(num_samples);
 35
 36  // Produce public parameters
 37  let pp = PublicParams::<G1, G2, C1, C2>::setup(
 38    TrivialTestCircuit::default(),
 39    TrivialTestCircuit::default(),
 40  );
 41
 42  // Bench time to produce a recursive SNARK;
 43  // we execute a certain number of warm-up steps since executing
 44  // the first step is cheaper than other steps owing to the presence of
 45  // a lot of zeros in the satisfying assignment
 46  let num_warmup_steps = 10;
 47  let mut recursive_snark: Option<RecursiveSNARK<G1, G2, C1, C2>> = None;
 48
 49  for i in 0..num_warmup_steps {
 50    let res = RecursiveSNARK::prove_step(
 51      &pp,
 52      recursive_snark,
 53      TrivialTestCircuit::default(),
 54      TrivialTestCircuit::default(),
 55      <G1 as Group>::Scalar::one(),
 56      <G2 as Group>::Scalar::zero(),
 57    );
 58    assert!(res.is_ok());
 59    let recursive_snark_unwrapped = res.unwrap();
 60
 61    // verify the recursive snark at each step of recursion
 62    let res = recursive_snark_unwrapped.verify(
 63      &pp,
 64      i + 1,
 65      <G1 as Group>::Scalar::one(),
 66      <G2 as Group>::Scalar::zero(),
 67    );
 68    assert!(res.is_ok());
 69
 70    // set the running variable for the next iteration
 71    recursive_snark = Some(recursive_snark_unwrapped);
 72  }
 73
 74  group.bench_function("Prove", |b| {
 75    b.iter(|| {
 76      // produce a recursive SNARK for a step of the recursion
 77      assert!(RecursiveSNARK::prove_step(
 78        black_box(&pp),
 79        black_box(recursive_snark.clone()),
 80        black_box(TrivialTestCircuit::default()),
 81        black_box(TrivialTestCircuit::default()),
 82        black_box(<G1 as Group>::Scalar::zero()),
 83        black_box(<G2 as Group>::Scalar::zero()),
 84      )
 85      .is_ok());
 86    })
 87  });
 88
 89  let recursive_snark = recursive_snark.unwrap();
 90
 91  // Benchmark the verification time
 92  let name = "Verify";
 93  group.bench_function(name, |b| {
 94    b.iter(|| {
 95      assert!(black_box(&recursive_snark)
 96        .verify(
 97          black_box(&pp),
 98          black_box(num_warmup_steps),
 99          black_box(<G1 as Group>::Scalar::zero()),
100          black_box(<G2 as Group>::Scalar::zero()),
101        )
102        .is_ok());
103    });
104  });
105  group.finish();
106}