mirror of
https://github.com/arnaucube/sonobe-playground.git
synced 2026-01-14 01:51:29 +01:00
Multifolding transformation
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -3330,6 +3330,7 @@ dependencies = [
|
|||||||
"ark-grumpkin",
|
"ark-grumpkin",
|
||||||
"ark-serialize 0.4.1",
|
"ark-serialize 0.4.1",
|
||||||
"folding-schemes",
|
"folding-schemes",
|
||||||
|
"itertools 0.13.0",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ ark-crypto-primitives = { version = "0.4.0" }
|
|||||||
ark-grumpkin = { version = "0.4.0", features = ["r1cs"] }
|
ark-grumpkin = { version = "0.4.0", features = ["r1cs"] }
|
||||||
ark-groth16 = { version = "0.4.0", features = ["parallel"] }
|
ark-groth16 = { version = "0.4.0", features = ["parallel"] }
|
||||||
ark-serialize = { version = "0.4.0" }
|
ark-serialize = { version = "0.4.0" }
|
||||||
|
itertools = { version = "0.13.0" }
|
||||||
rand = { version = "0.8.5" }
|
rand = { version = "0.8.5" }
|
||||||
sonobe = { git = "https://github.com/privacy-scaling-explorations/sonobe", rev = "f1d82418ba047cf90805f2d0505370246df24d68", package = "folding-schemes" }
|
sonobe = { git = "https://github.com/privacy-scaling-explorations/sonobe", rev = "f1d82418ba047cf90805f2d0505370246df24d68", package = "folding-schemes" }
|
||||||
num-traits = { version = "0.2.15" }
|
num-traits = { version = "0.2.15" }
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as G1};
|
use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as G1};
|
||||||
use ark_crypto_primitives::sponge::poseidon::PoseidonConfig;
|
use ark_crypto_primitives::sponge::poseidon::PoseidonConfig;
|
||||||
use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2};
|
use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2};
|
||||||
|
use itertools::Itertools;
|
||||||
use sonobe::{
|
use sonobe::{
|
||||||
commitment::{kzg::KZG, pedersen::Pedersen},
|
commitment::{kzg::KZG, pedersen::Pedersen},
|
||||||
folding::{hypernova::HyperNova, nova::Nova},
|
folding::{hypernova::HyperNova, nova::Nova},
|
||||||
frontend::circom::CircomFCircuit,
|
frontend::circom::CircomFCircuit,
|
||||||
transcript::poseidon::poseidon_canonical_config,
|
transcript::poseidon::poseidon_canonical_config,
|
||||||
FoldingScheme,
|
FoldingScheme, MultiFolding,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type NovaFolding =
|
pub type NovaFolding =
|
||||||
Nova<G1, GVar, G2, GVar2, CircomFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>, false>;
|
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,
|
G1,
|
||||||
GVar,
|
GVar,
|
||||||
G2,
|
G2,
|
||||||
@@ -19,8 +20,8 @@ pub type HyperNovaFolding = HyperNova<
|
|||||||
CircomFCircuit<Fr>,
|
CircomFCircuit<Fr>,
|
||||||
KZG<'static, Bn254>,
|
KZG<'static, Bn254>,
|
||||||
Pedersen<G2>,
|
Pedersen<G2>,
|
||||||
1,
|
N,
|
||||||
1,
|
M,
|
||||||
false,
|
false,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
@@ -36,8 +37,11 @@ pub trait FoldingSchemeExt: FoldingScheme<G1, G2, CircomFCircuit<Fr>> {
|
|||||||
) -> Self::PreprocessorParam;
|
) -> Self::PreprocessorParam;
|
||||||
|
|
||||||
fn transform_inputs(
|
fn transform_inputs(
|
||||||
|
&self,
|
||||||
full_input: Vec<Vec<Fr>>,
|
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 {
|
impl FoldingSchemeExt for NovaFolding {
|
||||||
@@ -49,16 +53,22 @@ impl FoldingSchemeExt for NovaFolding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transform_inputs(
|
fn transform_inputs(
|
||||||
|
&self,
|
||||||
full_input: Vec<Vec<Fr>>,
|
full_input: Vec<Vec<Fr>>,
|
||||||
) -> impl Iterator<Item = StepInput<Self::MultiCommittedInstanceWithWitness>> {
|
_initial_state: Vec<Fr>,
|
||||||
full_input.into_iter().map(|input| StepInput {
|
_rng: &mut impl rand::RngCore,
|
||||||
|
) -> Vec<StepInput<Self::MultiCommittedInstanceWithWitness>> {
|
||||||
|
full_input
|
||||||
|
.into_iter()
|
||||||
|
.map(|input| StepInput {
|
||||||
external_inputs: input,
|
external_inputs: input,
|
||||||
other_instances: None,
|
other_instances: None,
|
||||||
})
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FoldingSchemeExt for HyperNovaFolding {
|
impl<const N: usize, const M: usize> FoldingSchemeExt for HyperNovaFolding<N, M> {
|
||||||
fn prepreprocess(
|
fn prepreprocess(
|
||||||
poseidon_config: PoseidonConfig<Fr>,
|
poseidon_config: PoseidonConfig<Fr>,
|
||||||
circuit: CircomFCircuit<Fr>,
|
circuit: CircomFCircuit<Fr>,
|
||||||
@@ -67,12 +77,52 @@ impl FoldingSchemeExt for HyperNovaFolding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transform_inputs(
|
fn transform_inputs(
|
||||||
|
&self,
|
||||||
full_input: Vec<Vec<Fr>>,
|
full_input: Vec<Vec<Fr>>,
|
||||||
) -> impl Iterator<Item = StepInput<Self::MultiCommittedInstanceWithWitness>> {
|
initial_state: Vec<Fr>,
|
||||||
full_input.into_iter().map(|input| StepInput {
|
rng: &mut impl rand::RngCore,
|
||||||
external_inputs: input,
|
) -> Vec<StepInput<Self::MultiCommittedInstanceWithWitness>> {
|
||||||
other_instances: Some((vec![], vec![])),
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
20
src/main.rs
20
src/main.rs
@@ -3,7 +3,7 @@ use std::time::Instant;
|
|||||||
use scenario_config::ScenarioConfig;
|
use scenario_config::ScenarioConfig;
|
||||||
|
|
||||||
use crate::folding::{
|
use crate::folding::{
|
||||||
FoldingSchemeExt, HyperNovaFolding, NovaFolding, prepare_folding, verify_folding,
|
prepare_folding, verify_folding, FoldingSchemeExt, HyperNovaFolding, NovaFolding,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod circuit;
|
mod circuit;
|
||||||
@@ -22,14 +22,17 @@ fn measure<T, Action: FnOnce() -> T>(action_name: &str, action: Action) -> T {
|
|||||||
fn scenario<FS: FoldingSchemeExt>(config: ScenarioConfig, rng: &mut impl rand::RngCore) {
|
fn scenario<FS: FoldingSchemeExt>(config: ScenarioConfig, rng: &mut impl rand::RngCore) {
|
||||||
// ============== FOLDING PREPARATION ==========================================================
|
// ============== FOLDING PREPARATION ==========================================================
|
||||||
|
|
||||||
|
let start_state = config.start_ivc_state.clone();
|
||||||
let (mut folding, folding_vp) = measure("Prepare folding", || {
|
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 ======================================================================
|
// ============== FOLDING ======================================================================
|
||||||
|
|
||||||
let input = config.input().to_vec();
|
let input = measure("Transform input", || {
|
||||||
for (i, step_input) in FS::transform_inputs(input).enumerate() {
|
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}"), || {
|
measure(&format!("Prove_step {i}"), || {
|
||||||
folding
|
folding
|
||||||
.prove_step(
|
.prove_step(
|
||||||
@@ -57,9 +60,12 @@ fn main() {
|
|||||||
let mut rng = rand::rngs::OsRng;
|
let mut rng = rand::rngs::OsRng;
|
||||||
let config = ScenarioConfig::new();
|
let config = ScenarioConfig::new();
|
||||||
|
|
||||||
println!("========== Nova folding scheme ==========");
|
println!("========== Nova folding scheme ====================");
|
||||||
scenario::<NovaFolding>(config.clone(), &mut rng);
|
scenario::<NovaFolding>(config.clone(), &mut rng);
|
||||||
|
|
||||||
println!("========== HyperNova folding scheme ==========");
|
println!("========== HyperNova<1,1> folding scheme ==========");
|
||||||
scenario::<HyperNovaFolding>(config, &mut rng);
|
scenario::<HyperNovaFolding<1, 1>>(config.clone(), &mut rng);
|
||||||
|
|
||||||
|
println!("========== HyperNova<2,2> folding scheme ==========");
|
||||||
|
scenario::<HyperNovaFolding<2, 2>>(config, &mut rng);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub struct ScenarioConfig {
|
|||||||
impl ScenarioConfig {
|
impl ScenarioConfig {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
num_steps: 5,
|
num_steps: 6,
|
||||||
start_ivc_state: vec![Fr::zero(); 2],
|
start_ivc_state: vec![Fr::zero(); 2],
|
||||||
circuit: measure("Prepare circuit", create_circuit),
|
circuit: measure("Prepare circuit", create_circuit),
|
||||||
input: measure("Prepare input", prepare_input),
|
input: measure("Prepare input", prepare_input),
|
||||||
|
|||||||
Reference in New Issue
Block a user