fold-babyjubjubs/src/fold_babyjubjubs.rs
src/fold_babyjubjubs.rsRaw
1#[cfg(test)]
2mod tests {
3 use ark_bn254::{constraints::GVar, Fr, G1Projective as G1};
4 use ark_grumpkin::{constraints::GVar as GVar2, 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> =
48 Nova<G1, GVar, G2, GVar2, FC<S>, Pedersen<G1>, Pedersen<G2>, false>;
49
50 // prepare the Nova prover & verifier params
51 let nova_preprocess_params =
52 PreprocessorParam::new(poseidon_config.clone(), f_circuit.clone());
53 let start = Instant::now();
54 let nova_params =
55 FS::<SIGS_PER_STEP>::preprocess(&mut rng, &nova_preprocess_params).unwrap();
56 println!("Nova params generated: {:?}", start.elapsed());
57
58 // initialize the folding scheme engine, in our case we use Nova
59 let mut nova = FS::<SIGS_PER_STEP>::init(&nova_params, f_circuit, z_0.clone()).unwrap();
60
61 // run n steps of the folding iteration
62 let start_full = Instant::now();
63 for i in 0..N_STEPS {
64 let start = Instant::now();
65 nova.prove_step(rng, pks_sigs[i].clone(), None).unwrap();
66 println!("Nova::prove_step {}: {:?}", nova.i, start.elapsed());
67 }
68 let t = start_full.elapsed();
69 println!("Nova's all {} steps time: {:?}", N_STEPS, t);
70 println!(
71 "N_STEPS={}, SIGS_PER_STEP={}. Total sigs = {}",
72 N_STEPS,
73 SIGS_PER_STEP,
74 N_STEPS * SIGS_PER_STEP
75 );
76 println!(
77 "SIGS PER SECOND: {:?}",
78 (N_STEPS * SIGS_PER_STEP) as f64 / t.as_secs_f64()
79 );
80 println!(
81 "TIME FOR EACH SIG: {:?} ms",
82 t / (N_STEPS * SIGS_PER_STEP) as u32
83 );
84
85 // verify the last IVC proof
86 let ivc_proof = nova.ivc_proof();
87 FS::<SIGS_PER_STEP>::verify(
88 nova_params.1.clone(), // Nova's verifier params
89 ivc_proof,
90 )
91 .unwrap();
92 }
93}