@@ -17,8 +17,12 @@ type G1 = pasta_curves::pallas::Point;
1717type G2 = pasta_curves:: vesta:: Point ;
1818type EE1 = nova_snark:: provider:: ipa_pc:: EvaluationEngine < G1 > ;
1919type EE2 = nova_snark:: provider:: ipa_pc:: EvaluationEngine < G2 > ;
20+ // SNARKs without computational commitments
2021type S1 = nova_snark:: spartan:: snark:: RelaxedR1CSSNARK < G1 , EE1 > ;
2122type S2 = nova_snark:: spartan:: snark:: RelaxedR1CSSNARK < G2 , EE2 > ;
23+ // SNARKs with computational commitments
24+ type SS1 = nova_snark:: spartan:: ppsnark:: RelaxedR1CSSNARK < G1 , EE1 > ;
25+ type SS2 = nova_snark:: spartan:: ppsnark:: RelaxedR1CSSNARK < G2 , EE2 > ;
2226type C1 = NonTrivialTestCircuit < <G1 as Group >:: Scalar > ;
2327type C2 = TrivialTestCircuit < <G2 as Group >:: Scalar > ;
2428
@@ -31,13 +35,13 @@ cfg_if::cfg_if! {
3135 criterion_group! {
3236 name = compressed_snark;
3337 config = Criterion :: default ( ) . warm_up_time( Duration :: from_millis( 3000 ) ) . with_profiler( pprof:: criterion:: PProfProfiler :: new( 100 , pprof:: criterion:: Output :: Flamegraph ( None ) ) ) ;
34- targets = bench_compressed_snark
38+ targets = bench_compressed_snark, bench_compressed_snark_with_computational_commitments
3539 }
3640 } else {
3741 criterion_group! {
3842 name = compressed_snark;
3943 config = Criterion :: default ( ) . warm_up_time( Duration :: from_millis( 3000 ) ) ;
40- targets = bench_compressed_snark
44+ targets = bench_compressed_snark, bench_compressed_snark_with_computational_commitments
4145 }
4246 }
4347}
@@ -61,7 +65,7 @@ fn bench_compressed_snark(c: &mut Criterion) {
6165 let c_secondary = TrivialTestCircuit :: default ( ) ;
6266
6367 // Produce public parameters
64- let pp = PublicParams :: < G1 , G2 , C1 , C2 > :: setup ( c_primary. clone ( ) , c_secondary. clone ( ) ) ;
68+ let pp = PublicParams :: < G1 , G2 , C1 , C2 > :: setup ( & c_primary, & c_secondary) ;
6569
6670 // Produce prover and verifier keys for CompressedSNARK
6771 let ( pk, vk) = CompressedSNARK :: < _ , _ , _ , _ , S1 , S2 > :: setup ( & pp) . unwrap ( ) ;
@@ -129,6 +133,93 @@ fn bench_compressed_snark(c: &mut Criterion) {
129133 }
130134}
131135
136+ fn bench_compressed_snark_with_computational_commitments ( c : & mut Criterion ) {
137+ let num_samples = 10 ;
138+ let num_cons_verifier_circuit_primary = 9819 ;
139+ // we vary the number of constraints in the step circuit
140+ for & num_cons_in_augmented_circuit in [ 9819 , 16384 , 32768 , 65536 , 131072 , 262144 ] . iter ( ) {
141+ // number of constraints in the step circuit
142+ let num_cons = num_cons_in_augmented_circuit - num_cons_verifier_circuit_primary;
143+
144+ let mut group = c. benchmark_group ( format ! (
145+ "CompressedSNARK-Commitments-StepCircuitSize-{num_cons}"
146+ ) ) ;
147+ group
148+ . sampling_mode ( SamplingMode :: Flat )
149+ . sample_size ( num_samples) ;
150+
151+ let c_primary = NonTrivialTestCircuit :: new ( num_cons) ;
152+ let c_secondary = TrivialTestCircuit :: default ( ) ;
153+
154+ // Produce public parameters
155+ let pp = PublicParams :: < G1 , G2 , C1 , C2 > :: setup ( & c_primary, & c_secondary) ;
156+
157+ // Produce prover and verifier keys for CompressedSNARK
158+ let ( pk, vk) = CompressedSNARK :: < _ , _ , _ , _ , SS1 , SS2 > :: setup ( & pp) . unwrap ( ) ;
159+
160+ // produce a recursive SNARK
161+ let num_steps = 3 ;
162+ let mut recursive_snark: RecursiveSNARK < G1 , G2 , C1 , C2 > = RecursiveSNARK :: new (
163+ & pp,
164+ & c_primary,
165+ & c_secondary,
166+ vec ! [ <G1 as Group >:: Scalar :: from( 2u64 ) ] ,
167+ vec ! [ <G2 as Group >:: Scalar :: from( 2u64 ) ] ,
168+ ) ;
169+
170+ for i in 0 ..num_steps {
171+ let res = recursive_snark. prove_step (
172+ & pp,
173+ & c_primary,
174+ & c_secondary,
175+ vec ! [ <G1 as Group >:: Scalar :: from( 2u64 ) ] ,
176+ vec ! [ <G2 as Group >:: Scalar :: from( 2u64 ) ] ,
177+ ) ;
178+ assert ! ( res. is_ok( ) ) ;
179+
180+ // verify the recursive snark at each step of recursion
181+ let res = recursive_snark. verify (
182+ & pp,
183+ i + 1 ,
184+ & [ <G1 as Group >:: Scalar :: from ( 2u64 ) ] ,
185+ & [ <G2 as Group >:: Scalar :: from ( 2u64 ) ] ,
186+ ) ;
187+ assert ! ( res. is_ok( ) ) ;
188+ }
189+
190+ // Bench time to produce a compressed SNARK
191+ group. bench_function ( "Prove" , |b| {
192+ b. iter ( || {
193+ assert ! ( CompressedSNARK :: <_, _, _, _, SS1 , SS2 >:: prove(
194+ black_box( & pp) ,
195+ black_box( & pk) ,
196+ black_box( & recursive_snark)
197+ )
198+ . is_ok( ) ) ;
199+ } )
200+ } ) ;
201+ let res = CompressedSNARK :: < _ , _ , _ , _ , SS1 , SS2 > :: prove ( & pp, & pk, & recursive_snark) ;
202+ assert ! ( res. is_ok( ) ) ;
203+ let compressed_snark = res. unwrap ( ) ;
204+
205+ // Benchmark the verification time
206+ group. bench_function ( "Verify" , |b| {
207+ b. iter ( || {
208+ assert ! ( black_box( & compressed_snark)
209+ . verify(
210+ black_box( & vk) ,
211+ black_box( num_steps) ,
212+ black_box( vec![ <G1 as Group >:: Scalar :: from( 2u64 ) ] ) ,
213+ black_box( vec![ <G2 as Group >:: Scalar :: from( 2u64 ) ] ) ,
214+ )
215+ . is_ok( ) ) ;
216+ } )
217+ } ) ;
218+
219+ group. finish ( ) ;
220+ }
221+ }
222+
132223#[ derive( Clone , Debug , Default ) ]
133224struct NonTrivialTestCircuit < F : PrimeField > {
134225 num_cons : usize ,
0 commit comments