Browse Source

Multifolding transformation

main
Piotr Mikołajczyk 6 months ago
parent
commit
23b0dc36ec
No known key found for this signature in database GPG Key ID: 7ADA31326DE28EC7
5 changed files with 82 additions and 24 deletions
  1. +1
    -0
      Cargo.lock
  2. +1
    -0
      Cargo.toml
  3. +66
    -16
      src/folding.rs
  4. +13
    -7
      src/main.rs
  5. +1
    -1
      src/scenario_config.rs

+ 1
- 0
Cargo.lock

@ -3330,6 +3330,7 @@ dependencies = [
"ark-grumpkin",
"ark-serialize 0.4.1",
"folding-schemes",
"itertools 0.13.0",
"num-traits",
"rand 0.8.5",
]

+ 1
- 0
Cargo.toml

@ -10,6 +10,7 @@ ark-crypto-primitives = { version = "0.4.0" }
ark-grumpkin = { version = "0.4.0", features = ["r1cs"] }
ark-groth16 = { version = "0.4.0", features = ["parallel"] }
ark-serialize = { version = "0.4.0" }
itertools = { version = "0.13.0" }
rand = { version = "0.8.5" }
sonobe = { git = "https://github.com/privacy-scaling-explorations/sonobe", rev = "f1d82418ba047cf90805f2d0505370246df24d68", package = "folding-schemes" }
num-traits = { version = "0.2.15" }

+ 66
- 16
src/folding.rs

@ -1,17 +1,18 @@
use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as G1};
use ark_crypto_primitives::sponge::poseidon::PoseidonConfig;
use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2};
use itertools::Itertools;
use sonobe::{
commitment::{kzg::KZG, pedersen::Pedersen},
folding::{hypernova::HyperNova, nova::Nova},
frontend::circom::CircomFCircuit,
transcript::poseidon::poseidon_canonical_config,
FoldingScheme,
FoldingScheme, MultiFolding,
};
pub type NovaFolding =
Nova<G1, GVar, G2, GVar2, CircomFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>, false>;
pub type HyperNovaFolding = HyperNova<
pub type HyperNovaFolding<const N: usize, const M: usize> = HyperNova<
G1,
GVar,
G2,
@ -19,8 +20,8 @@ pub type HyperNovaFolding = HyperNova<
CircomFCircuit<Fr>,
KZG<'static, Bn254>,
Pedersen<G2>,
1,
1,
N,
M,
false,
>;
@ -36,8 +37,11 @@ pub trait FoldingSchemeExt: FoldingScheme> {
) -> Self::PreprocessorParam;
fn transform_inputs(
&self,
full_input: Vec<Vec<Fr>>,
) -> impl Iterator<Item = StepInput<Self::MultiCommittedInstanceWithWitness>>;
initial_state: Vec<Fr>,
rng: &mut impl rand::RngCore,
) -> Vec<StepInput<Self::MultiCommittedInstanceWithWitness>>;
}
impl FoldingSchemeExt for NovaFolding {
@ -49,16 +53,22 @@ impl FoldingSchemeExt for NovaFolding {
}
fn transform_inputs(
&self,
full_input: Vec<Vec<Fr>>,
) -> impl Iterator<Item = StepInput<Self::MultiCommittedInstanceWithWitness>> {
full_input.into_iter().map(|input| StepInput {
external_inputs: input,
other_instances: None,
})
_initial_state: Vec<Fr>,
_rng: &mut impl rand::RngCore,
) -> Vec<StepInput<Self::MultiCommittedInstanceWithWitness>> {
full_input
.into_iter()
.map(|input| StepInput {
external_inputs: input,
other_instances: None,
})
.collect()
}
}
impl FoldingSchemeExt for HyperNovaFolding {
impl<const N: usize, const M: usize> FoldingSchemeExt for HyperNovaFolding<N, M> {
fn prepreprocess(
poseidon_config: PoseidonConfig<Fr>,
circuit: CircomFCircuit<Fr>,
@ -67,12 +77,52 @@ impl FoldingSchemeExt for HyperNovaFolding {
}
fn transform_inputs(
&self,
full_input: Vec<Vec<Fr>>,
) -> impl Iterator<Item = StepInput<Self::MultiCommittedInstanceWithWitness>> {
full_input.into_iter().map(|input| StepInput {
external_inputs: input,
other_instances: Some((vec![], vec![])),
})
initial_state: Vec<Fr>,
rng: &mut impl rand::RngCore,
) -> Vec<StepInput<Self::MultiCommittedInstanceWithWitness>> {
full_input
.into_iter()
.chunks(M + N - 1)
.into_iter()
.map(|chunk| {
let chunk = chunk.collect::<Vec<_>>();
let (running, rest) = chunk.split_at(M - 1);
let (incoming, [single]) = rest.split_at(N - 1) else {
panic!("Invalid input chunk size");
};
let lcccs = running
.iter()
.map(|instance| {
self.new_running_instance(
&mut *rng,
initial_state.clone(),
instance.clone(),
)
.expect("Failed to create running instance")
})
.collect();
let cccs = incoming
.iter()
.map(|instance| {
self.new_incoming_instance(
&mut *rng,
initial_state.clone(),
instance.clone(),
)
.expect("Failed to create incoming instance")
})
.collect();
StepInput {
external_inputs: single.clone(),
other_instances: Some((lcccs, cccs)),
}
})
.collect()
}
}

+ 13
- 7
src/main.rs

@ -3,7 +3,7 @@ use std::time::Instant;
use scenario_config::ScenarioConfig;
use crate::folding::{
FoldingSchemeExt, HyperNovaFolding, NovaFolding, prepare_folding, verify_folding,
prepare_folding, verify_folding, FoldingSchemeExt, HyperNovaFolding, NovaFolding,
};
mod circuit;
@ -22,14 +22,17 @@ fn measure T>(action_name: &str, action: Action) -> T {
fn scenario<FS: FoldingSchemeExt>(config: ScenarioConfig, rng: &mut impl rand::RngCore) {
// ============== FOLDING PREPARATION ==========================================================
let start_state = config.start_ivc_state.clone();
let (mut folding, folding_vp) = measure("Prepare folding", || {
prepare_folding::<FS>(&config.circuit, config.start_ivc_state.clone(), rng)
prepare_folding::<FS>(&config.circuit, start_state.clone(), rng)
});
// ============== FOLDING ======================================================================
let input = config.input().to_vec();
for (i, step_input) in FS::transform_inputs(input).enumerate() {
let input = measure("Transform input", || {
folding.transform_inputs(config.input().to_vec(), start_state.clone(), &mut *rng)
});
for (i, step_input) in input.into_iter().enumerate() {
measure(&format!("Prove_step {i}"), || {
folding
.prove_step(
@ -57,9 +60,12 @@ fn main() {
let mut rng = rand::rngs::OsRng;
let config = ScenarioConfig::new();
println!("========== Nova folding scheme ==========");
println!("========== Nova folding scheme ====================");
scenario::<NovaFolding>(config.clone(), &mut rng);
println!("========== HyperNova folding scheme ==========");
scenario::<HyperNovaFolding>(config, &mut rng);
println!("========== HyperNova<1,1> folding scheme ==========");
scenario::<HyperNovaFolding<1, 1>>(config.clone(), &mut rng);
println!("========== HyperNova<2,2> folding scheme ==========");
scenario::<HyperNovaFolding<2, 2>>(config, &mut rng);
}

+ 1
- 1
src/scenario_config.rs

@ -15,7 +15,7 @@ pub struct ScenarioConfig {
impl ScenarioConfig {
pub fn new() -> Self {
Self {
num_steps: 5,
num_steps: 6,
start_ivc_state: vec![Fr::zero(); 2],
circuit: measure("Prepare circuit", create_circuit),
input: measure("Prepare input", prepare_input),

Loading…
Cancel
Save