fold-babyjubjubs/src/fold_babyjubjubs.rs
src/fold_babyjubjubs.rsRaw
1#[cfg(test)]
2mod tests {
3 use ark_bn254::{Fr, G1Projective as G1};
4 use ark_grumpkin::Projective as G2;
5 use std::time::Instant;
6
7 use arkeddsa::ed_on_bn254_twist::{constraints::EdwardsVar, EdwardsProjective};
8
9 use folding_schemes::{
10 commitment::pedersen::Pedersen,
11 folding::nova::{Nova, PreprocessorParam},
12 frontend::FCircuit,
13 transcript::poseidon::poseidon_canonical_config,
14 FoldingScheme,
15 };
16
17 use crate::fcircuit::{tests::gen_signatures, FoldSigsStepCircuit};
18
19 #[test]
20 fn test_full_flow() {
21 // 5 recursive steps, 10 signature verifications per step
22 full_flow::<5, 10>();
23 // 5 recursive steps, 50 signature verifications per step
24 full_flow::<5, 50>();
25 }
26
27 fn full_flow<const N_STEPS: usize, const SIGS_PER_STEP: usize>() {
28 println!("\nrunning Nova folding scheme on FoldSigsStepCircuit, with N_STEPS={}, SIGS_PER_STEP={}. Total sigs = {}", N_STEPS, SIGS_PER_STEP, N_STEPS* SIGS_PER_STEP);
29
30 let mut rng = rand::rngs::OsRng;
31 let poseidon_config = poseidon_canonical_config::<Fr>();
32
33 let pks_sigs =
34 gen_signatures::<rand::rngs::OsRng, SIGS_PER_STEP>(&mut rng, &poseidon_config, N_STEPS);
35
36 // set the initial state
37 let z_0: Vec<Fr> = vec![0_u8; 1]
38 .iter()
39 .map(|v| Fr::from(*v))
40 .collect::<Vec<Fr>>();
41
42 type FC<const S: usize> = FoldSigsStepCircuit<Fr, EdwardsProjective, EdwardsVar, S>;
43 let f_circuit = FC::<SIGS_PER_STEP>::new(poseidon_config.clone()).unwrap();
44
45 // define type aliases for the FoldingScheme (FS) and Decider (D), to avoid writting the
46 // whole type each time
47 pub type FS<const S: usize> = Nova<G1, G2, FC<S>, Pedersen<G1>, Pedersen<G2>, false>;
48
49 // prepare the Nova prover & verifier params
50 let nova_preprocess_params =
51 PreprocessorParam::new(poseidon_config.clone(), f_circuit.clone());
52 let start = Instant::now();
53 let nova_params =
54 FS::<SIGS_PER_STEP>::preprocess(&mut rng, &nova_preprocess_params).unwrap();
55 println!("Nova params generated: {:?}", start.elapsed());
56
57 // initialize the folding scheme engine, in our case we use Nova
58 let mut nova = FS::<SIGS_PER_STEP>::init(&nova_params, f_circuit, z_0.clone()).unwrap();
59
60 // run n steps of the folding iteration
61 let start_full = Instant::now();
62 for i in 0..N_STEPS {
63 let start = Instant::now();
64 nova.prove_step(rng, pks_sigs[i].clone(), None).unwrap();
65 println!("Nova::prove_step {}: {:?}", nova.i, start.elapsed());
66 }
67 let t = start_full.elapsed();
68 println!("Nova's all {} steps time: {:?}", N_STEPS, t);
69 println!(
70 "N_STEPS={}, SIGS_PER_STEP={}. Total sigs = {}",
71 N_STEPS,
72 SIGS_PER_STEP,
73 N_STEPS * SIGS_PER_STEP
74 );
75 println!(
76 "SIGS PER SECOND: {:?}",
77 (N_STEPS * SIGS_PER_STEP) as f64 / t.as_secs_f64()
78 );
79 println!(
80 "TIME FOR EACH SIG: {:?} ms",
81 t / (N_STEPS * SIGS_PER_STEP) as u32
82 );
83
84 // verify the last IVC proof
85 let ivc_proof = nova.ivc_proof();
86 FS::<SIGS_PER_STEP>::verify(
87 nova_params.1.clone(), // Nova's verifier params
88 ivc_proof,
89 )
90 .unwrap();
91 }
92}