@ -17,8 +17,12 @@ type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves ::vesta ::Point ;
type EE1 = nova_snark ::provider ::ipa_pc ::EvaluationEngine < G1 > ;
type EE2 = nova_snark ::provider ::ipa_pc ::EvaluationEngine < G2 > ;
// SNARKs without computational commitments
type S1 = nova_snark ::spartan ::snark ::RelaxedR1CSSNARK < G1 , EE1 > ;
type S2 = nova_snark ::spartan ::snark ::RelaxedR1CSSNARK < G2 , EE2 > ;
// SNARKs with computational commitments
type SS1 = nova_snark ::spartan ::ppsnark ::RelaxedR1CSSNARK < G1 , EE1 > ;
type SS2 = nova_snark ::spartan ::ppsnark ::RelaxedR1CSSNARK < G2 , EE2 > ;
type C1 = NonTrivialTestCircuit < < G1 as Group > ::Scalar > ;
type C2 = TrivialTestCircuit < < G2 as Group > ::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 ::< G1 , G2 , C1 , C2 > ::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 < G1 , G2 , C1 , C2 > = RecursiveSNARK ::new (
& pp ,
& c_primary ,
& c_secondary ,
vec ! [ < G1 as Group > ::Scalar ::from ( 2 u64 ) ] ,
vec ! [ < G2 as Group > ::Scalar ::from ( 2 u64 ) ] ,
) ;
for i in 0 . . num_steps {
let res = recursive_snark . prove_step (
& pp ,
& c_primary ,
& c_secondary ,
vec ! [ < G1 as Group > ::Scalar ::from ( 2 u64 ) ] ,
vec ! [ < G2 as Group > ::Scalar ::from ( 2 u64 ) ] ,
) ;
assert ! ( res . is_ok ( ) ) ;
// verify the recursive snark at each step of recursion
let res = recursive_snark . verify (
& pp ,
i + 1 ,
& [ < G1 as Group > ::Scalar ::from ( 2 u64 ) ] ,
& [ < G2 as Group > ::Scalar ::from ( 2 u64 ) ] ,
) ;
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 ! [ < G1 as Group > ::Scalar ::from ( 2 u64 ) ] ) ,
black_box ( vec ! [ < G2 as Group > ::Scalar ::from ( 2 u64 ) ] ) ,
)
. is_ok ( ) ) ;
} )
} ) ;
group . finish ( ) ;
}
}
#[ derive(Clone, Debug, Default) ]
struct NonTrivialTestCircuit < F : PrimeField > {
num_cons : usize ,