arnaucube
arnaucube/NovaPublic Self-hosted repository
Nova/benches/recursive-snark.rs
benches/recursive-snark.rsRaw
  1#![allow(non_snake_case)]
  2
  3extern crate flate2;
  4
  5//use flate2::{write::ZlibEncoder, Compression};
  6use nova_snark::{
  7  traits::{Group, StepCircuit},
  8  PublicParams, RecursiveSNARK,
  9};
 10
 11type G1 = pasta_curves::pallas::Point;
 12type G2 = pasta_curves::vesta::Point;
 13
 14use bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError};
 15use core::marker::PhantomData;
 16use criterion::*;
 17use ff::PrimeField;
 18use std::time::Duration;
 19
 20fn recursive_snark_benchmark(c: &mut Criterion) {
 21  let num_samples = 10;
 22  for num_steps in 1..10 {
 23    bench_recursive_snark(c, num_samples, num_steps);
 24  }
 25}
 26
 27fn set_duration() -> Criterion {
 28  Criterion::default().warm_up_time(Duration::from_millis(3000))
 29}
 30
 31criterion_group! {
 32name = recursive_snark;
 33config = set_duration();
 34targets = recursive_snark_benchmark
 35}
 36
 37criterion_main!(recursive_snark);
 38
 39fn bench_recursive_snark(c: &mut Criterion, num_samples: usize, num_steps: usize) {
 40  let mut group = c.benchmark_group(format!("RecursiveSNARK-NumSteps-{}", num_steps));
 41  group.sample_size(num_samples);
 42  // Produce public parameters
 43  let pp = PublicParams::<
 44    G1,
 45    G2,
 46    TrivialTestCircuit<<G1 as Group>::Scalar>,
 47    TrivialTestCircuit<<G2 as Group>::Scalar>,
 48  >::setup(
 49    TrivialTestCircuit {
 50      _p: Default::default(),
 51    },
 52    TrivialTestCircuit {
 53      _p: Default::default(),
 54    },
 55  );
 56  // Bench time to produce a recursive SNARK
 57  group.bench_function("Prove", |b| {
 58    b.iter(|| {
 59      // produce a recursive SNARK
 60      assert!(RecursiveSNARK::prove(
 61        black_box(&pp),
 62        black_box(num_steps),
 63        black_box(<G1 as Group>::Scalar::zero()),
 64        black_box(<G2 as Group>::Scalar::zero()),
 65      )
 66      .is_ok());
 67    })
 68  });
 69  let res = RecursiveSNARK::prove(
 70    &pp,
 71    num_steps,
 72    <G1 as Group>::Scalar::zero(),
 73    <G2 as Group>::Scalar::zero(),
 74  );
 75  assert!(res.is_ok());
 76  let recursive_snark = res.unwrap();
 77
 78  // TODO: Output the proof size
 79  // Benchmark the verification time
 80  let name = "Verify";
 81  group.bench_function(name, |b| {
 82    b.iter(|| {
 83      assert!(black_box(&recursive_snark)
 84        .verify(
 85          black_box(&pp),
 86          black_box(num_steps),
 87          black_box(<G1 as Group>::Scalar::zero()),
 88          black_box(<G2 as Group>::Scalar::zero()),
 89        )
 90        .is_ok());
 91    });
 92  });
 93  group.finish();
 94}
 95
 96#[derive(Clone, Debug)]
 97struct TrivialTestCircuit<F: PrimeField> {
 98  _p: PhantomData<F>,
 99}
100
101impl<F> StepCircuit<F> for TrivialTestCircuit<F>
102where
103  F: PrimeField,
104{
105  fn synthesize<CS: ConstraintSystem<F>>(
106    &self,
107    _cs: &mut CS,
108    z: AllocatedNum<F>,
109  ) -> Result<AllocatedNum<F>, SynthesisError> {
110    Ok(z)
111  }
112
113  fn compute(&self, z: &F) -> F {
114    *z
115  }
116}