#![allow(non_snake_case)] use nova_snark::{ traits::{Group, StepCircuit}, CompressedSNARK, PublicParams, RecursiveSNARK, }; type G1 = pasta_curves::pallas::Point; type G2 = pasta_curves::vesta::Point; type S1 = nova_snark::spartan_with_ipa_pc::RelaxedR1CSSNARK; type S2 = nova_snark::spartan_with_ipa_pc::RelaxedR1CSSNARK; use bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError}; use core::marker::PhantomData; use criterion::*; use ff::PrimeField; use std::time::Duration; fn compressed_snark_benchmark(c: &mut Criterion) { let num_samples = 10; let num_steps = 3; bench_compressed_snark(c, num_samples, num_steps); } fn set_duration() -> Criterion { Criterion::default().warm_up_time(Duration::from_millis(3000)) } criterion_group! { name = compressed_snark; config = set_duration(); targets = compressed_snark_benchmark } criterion_main!(compressed_snark); fn bench_compressed_snark(c: &mut Criterion, num_samples: usize, num_steps: usize) { let mut group = c.benchmark_group("CompressedSNARK"); group.sample_size(num_samples); // Produce public parameters let pp = PublicParams::< G1, G2, TrivialTestCircuit<::Scalar>, TrivialTestCircuit<::Scalar>, >::setup( TrivialTestCircuit { _p: Default::default(), }, TrivialTestCircuit { _p: Default::default(), }, ); // produce a recursive SNARK let res = RecursiveSNARK::prove( &pp, num_steps, ::Scalar::zero(), ::Scalar::zero(), ); assert!(res.is_ok()); let recursive_snark = res.unwrap(); // Bench time to produce a compressed SNARK group.bench_function("Prove", |b| { b.iter(|| { assert!(CompressedSNARK::<_, _, _, _, S1, S2>::prove( black_box(&pp), black_box(&recursive_snark) ) .is_ok()); }) }); let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); // Benchmark the verification time let name = "Verify"; group.bench_function(name, |b| { b.iter(|| { assert!(black_box(&compressed_snark) .verify( black_box(&pp), black_box(num_steps), black_box(::Scalar::zero()), black_box(::Scalar::zero()), ) .is_ok()); }) }); group.finish(); } #[derive(Clone, Debug)] struct TrivialTestCircuit { _p: PhantomData, } impl StepCircuit for TrivialTestCircuit where F: PrimeField, { fn synthesize>( &self, _cs: &mut CS, z: AllocatedNum, ) -> Result, SynthesisError> { Ok(z) } fn compute(&self, z: &F) -> F { *z } }