diff --git a/benches/compressed-snark.rs b/benches/compressed-snark.rs index 4effe26..4ea7156 100644 --- a/benches/compressed-snark.rs +++ b/benches/compressed-snark.rs @@ -17,8 +17,12 @@ type G1 = pasta_curves::pallas::Point; type G2 = pasta_curves::vesta::Point; type EE1 = nova_snark::provider::ipa_pc::EvaluationEngine; type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine; +// SNARKs without computational commitments type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK; type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK; +// SNARKs with computational commitments +type SS1 = nova_snark::spartan::ppsnark::RelaxedR1CSSNARK; +type SS2 = nova_snark::spartan::ppsnark::RelaxedR1CSSNARK; type C1 = NonTrivialTestCircuit<::Scalar>; type C2 = TrivialTestCircuit<::Scalar>; @@ -31,13 +35,13 @@ cfg_if::cfg_if! { criterion_group! { name = compressed_snark; config = Criterion::default().warm_up_time(Duration::from_millis(3000)).with_profiler(pprof::criterion::PProfProfiler::new(100, pprof::criterion::Output::Flamegraph(None))); - targets = bench_compressed_snark + targets = bench_compressed_snark, bench_compressed_snark_with_computational_commitments } } else { criterion_group! { name = compressed_snark; config = Criterion::default().warm_up_time(Duration::from_millis(3000)); - targets = bench_compressed_snark + targets = bench_compressed_snark, bench_compressed_snark_with_computational_commitments } } } @@ -129,6 +133,93 @@ fn bench_compressed_snark(c: &mut Criterion) { } } +fn bench_compressed_snark_with_computational_commitments(c: &mut Criterion) { + let num_samples = 10; + let num_cons_verifier_circuit_primary = 9819; + // we vary the number of constraints in the step circuit + for &num_cons_in_augmented_circuit in [9819, 16384, 32768, 65536, 131072, 262144].iter() { + // number of constraints in the step circuit + let num_cons = num_cons_in_augmented_circuit - num_cons_verifier_circuit_primary; + + let mut group = c.benchmark_group(format!( + "CompressedSNARK-Commitments-StepCircuitSize-{num_cons}" + )); + group + .sampling_mode(SamplingMode::Flat) + .sample_size(num_samples); + + let c_primary = NonTrivialTestCircuit::new(num_cons); + let c_secondary = TrivialTestCircuit::default(); + + // Produce public parameters + let pp = PublicParams::::setup(c_primary.clone(), c_secondary.clone()); + + // Produce prover and verifier keys for CompressedSNARK + let (pk, vk) = CompressedSNARK::<_, _, _, _, SS1, SS2>::setup(&pp).unwrap(); + + // produce a recursive SNARK + let num_steps = 3; + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( + &pp, + &c_primary, + &c_secondary, + vec![::Scalar::from(2u64)], + vec![::Scalar::from(2u64)], + ); + + for i in 0..num_steps { + let res = recursive_snark.prove_step( + &pp, + &c_primary, + &c_secondary, + vec![::Scalar::from(2u64)], + vec![::Scalar::from(2u64)], + ); + assert!(res.is_ok()); + + // verify the recursive snark at each step of recursion + let res = recursive_snark.verify( + &pp, + i + 1, + &[::Scalar::from(2u64)], + &[::Scalar::from(2u64)], + ); + assert!(res.is_ok()); + } + + // Bench time to produce a compressed SNARK + group.bench_function("Prove", |b| { + b.iter(|| { + assert!(CompressedSNARK::<_, _, _, _, SS1, SS2>::prove( + black_box(&pp), + black_box(&pk), + black_box(&recursive_snark) + ) + .is_ok()); + }) + }); + let res = CompressedSNARK::<_, _, _, _, SS1, SS2>::prove(&pp, &pk, &recursive_snark); + assert!(res.is_ok()); + let compressed_snark = res.unwrap(); + + // Benchmark the verification time + group.bench_function("Verify", |b| { + b.iter(|| { + assert!(black_box(&compressed_snark) + .verify( + black_box(&vk), + black_box(num_steps), + black_box(vec![::Scalar::from(2u64)]), + black_box(vec![::Scalar::from(2u64)]), + ) + .is_ok()); + }) + }); + + group.finish(); + } +} + #[derive(Clone, Debug, Default)] struct NonTrivialTestCircuit { num_cons: usize,