diff --git a/README.md b/README.md new file mode 100644 index 0000000..82a9b80 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# fold-babyjubjubs + +Repo folding BabyJubJub EdDSA signatures using [arkeddsa](https://github.com/kilic/arkeddsa), showcasing usage of [Sonobe](https://github.com/privacy-scaling-explorations/sonobe) with [Arkworks](https://github.com/arkworks-rs). + +The main idea is to prove $z_n = F(F(...~F(F(F(z_0)))))$, where $n$ is the number of BabyJubJub EdDSA signature verifications ($F$) that we compute. Proving this in a 'normal' R1CS circuit for a large $n$ would be too costly, but with folding we can manage to prove it in a reasonable time span. + +For more info about Sonobe, check out [Sonobe's docs](https://privacy-scaling-explorations.github.io/sonobe-docs). + +

+ +

+ + +### Usage + +- `cargo test --release -- --nocapture` diff --git a/src/fold_babyjubjubs.rs b/src/fold_babyjubjubs.rs new file mode 100644 index 0000000..a35cdf0 --- /dev/null +++ b/src/fold_babyjubjubs.rs @@ -0,0 +1,93 @@ +#[cfg(test)] +mod tests { + use ark_bn254::{constraints::GVar, Fr, G1Projective as G1}; + use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2}; + use std::time::Instant; + + use arkeddsa::ed_on_bn254_twist::{constraints::EdwardsVar, EdwardsProjective}; + + use folding_schemes::{ + commitment::pedersen::Pedersen, + folding::nova::{Nova, PreprocessorParam}, + frontend::FCircuit, + transcript::poseidon::poseidon_canonical_config, + FoldingScheme, + }; + + use crate::fcircuit::{tests::gen_signatures, FoldSigsStepCircuit}; + + #[test] + fn test_full_flow() { + // 5 recursive steps, 10 signature verifications per step + full_flow::<5, 10>(); + // 5 recursive steps, 50 signature verifications per step + full_flow::<5, 50>(); + } + + fn full_flow() { + 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); + + let mut rng = rand::rngs::OsRng; + let poseidon_config = poseidon_canonical_config::(); + + let pks_sigs = + gen_signatures::(&mut rng, &poseidon_config, N_STEPS); + + // set the initial state + let z_0: Vec = vec![0_u8; 1] + .iter() + .map(|v| Fr::from(*v)) + .collect::>(); + + type FC = FoldSigsStepCircuit; + let f_circuit = FC::::new(poseidon_config.clone()).unwrap(); + + // define type aliases for the FoldingScheme (FS) and Decider (D), to avoid writting the + // whole type each time + pub type FS = + Nova, Pedersen, Pedersen, false>; + + // prepare the Nova prover & verifier params + let nova_preprocess_params = + PreprocessorParam::new(poseidon_config.clone(), f_circuit.clone()); + let start = Instant::now(); + let nova_params = + FS::::preprocess(&mut rng, &nova_preprocess_params).unwrap(); + println!("Nova params generated: {:?}", start.elapsed()); + + // initialize the folding scheme engine, in our case we use Nova + let mut nova = FS::::init(&nova_params, f_circuit, z_0.clone()).unwrap(); + + // run n steps of the folding iteration + let start_full = Instant::now(); + for i in 0..N_STEPS { + let start = Instant::now(); + nova.prove_step(rng, pks_sigs[i].clone(), None).unwrap(); + println!("Nova::prove_step {}: {:?}", nova.i, start.elapsed()); + } + let t = start_full.elapsed(); + println!("Nova's all {} steps time: {:?}", N_STEPS, t); + println!( + "N_STEPS={}, SIGS_PER_STEP={}. Total sigs = {}", + N_STEPS, + SIGS_PER_STEP, + N_STEPS * SIGS_PER_STEP + ); + println!( + "SIGS PER SECOND: {:?}", + (N_STEPS * SIGS_PER_STEP) as f64 / t.as_secs_f64() + ); + println!( + "TIME FOR EACH SIG: {:?} ms", + t / (N_STEPS * SIGS_PER_STEP) as u32 + ); + + // verify the last IVC proof + let ivc_proof = nova.ivc_proof(); + FS::::verify( + nova_params.1.clone(), // Nova's verifier params + ivc_proof, + ) + .unwrap(); + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..33adc14 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,7 @@ +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(clippy::upper_case_acronyms)] + +mod fcircuit; +mod fold_babyjubjubs;