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