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
 13use bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError};
 14use core::marker::PhantomData;
 15use criterion::*;
 16use ff::PrimeField;
 17use std::time::Duration;
 18
 19fn compressed_snark_benchmark(c: &mut Criterion) {
 20  let num_samples = 10;
 21  let num_steps = 3;
 22  bench_compressed_snark(c, num_samples, num_steps);
 23}
 24
 25fn set_duration() -> Criterion {
 26  Criterion::default().warm_up_time(Duration::from_millis(3000))
 27}
 28
 29criterion_group! {
 30name = compressed_snark;
 31config = set_duration();
 32targets = compressed_snark_benchmark
 33}
 34
 35criterion_main!(compressed_snark);
 36
 37fn bench_compressed_snark(c: &mut Criterion, num_samples: usize, num_steps: usize) {
 38  let mut group = c.benchmark_group("CompressedSNARK");
 39  group.sample_size(num_samples);
 40  // Produce public parameters
 41  let pp = PublicParams::<
 42    G1,
 43    G2,
 44    TrivialTestCircuit<<G1 as Group>::Scalar>,
 45    TrivialTestCircuit<<G2 as Group>::Scalar>,
 46  >::setup(
 47    TrivialTestCircuit {
 48      _p: Default::default(),
 49    },
 50    TrivialTestCircuit {
 51      _p: Default::default(),
 52    },
 53  );
 54
 55  // produce a recursive SNARK
 56  let res = RecursiveSNARK::prove(
 57    &pp,
 58    num_steps,
 59    <G1 as Group>::Scalar::zero(),
 60    <G2 as Group>::Scalar::zero(),
 61  );
 62  assert!(res.is_ok());
 63  let recursive_snark = res.unwrap();
 64  // Bench time to produce a compressed SNARK
 65  group.bench_function("Prove", |b| {
 66    b.iter(|| {
 67      assert!(CompressedSNARK::<_, _, _, _, S1, S2>::prove(
 68        black_box(&pp),
 69        black_box(&recursive_snark)
 70      )
 71      .is_ok());
 72    })
 73  });
 74  let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &recursive_snark);
 75  assert!(res.is_ok());
 76  let compressed_snark = res.unwrap();
 77
 78  // Benchmark the verification time
 79  let name = "Verify";
 80  group.bench_function(name, |b| {
 81    b.iter(|| {
 82      assert!(black_box(&compressed_snark)
 83        .verify(
 84          black_box(&pp),
 85          black_box(num_steps),
 86          black_box(<G1 as Group>::Scalar::zero()),
 87          black_box(<G2 as Group>::Scalar::zero()),
 88        )
 89        .is_ok());
 90    })
 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}