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}