Browse Source

add folding logic using Sonobe

main
arnaucube 5 months ago
parent
commit
4dfb278142
3 changed files with 116 additions and 0 deletions
  1. +16
    -0
      README.md
  2. +93
    -0
      src/fold_babyjubjubs.rs
  3. +7
    -0
      src/lib.rs

+ 16
- 0
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).
<p align="center">
<img src="https://privacy-scaling-explorations.github.io/sonobe-docs/imgs/folding-main-idea-diagram.png" style="width:70%;" />
</p>
### Usage
- `cargo test --release -- --nocapture`

+ 93
- 0
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<const N_STEPS: usize, const SIGS_PER_STEP: usize>() {
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::<Fr>();
let pks_sigs =
gen_signatures::<rand::rngs::OsRng, SIGS_PER_STEP>(&mut rng, &poseidon_config, N_STEPS);
// set the initial state
let z_0: Vec<Fr> = vec![0_u8; 1]
.iter()
.map(|v| Fr::from(*v))
.collect::<Vec<Fr>>();
type FC<const S: usize> = FoldSigsStepCircuit<Fr, EdwardsProjective, EdwardsVar, S>;
let f_circuit = FC::<SIGS_PER_STEP>::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<const S: usize> =
Nova<G1, GVar, G2, GVar2, FC<S>, Pedersen<G1>, Pedersen<G2>, 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::<SIGS_PER_STEP>::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::<SIGS_PER_STEP>::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::<SIGS_PER_STEP>::verify(
nova_params.1.clone(), // Nova's verifier params
ivc_proof,
)
.unwrap();
}
}

+ 7
- 0
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;

Loading…
Cancel
Save