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}