arnaucube
arnaucube/sonobe-playgroundPublic Self-hosted repository
sonobe-playground/src/folding.rs
src/folding.rsRaw
  1use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as G1};
  2use ark_crypto_primitives::sponge::poseidon::PoseidonConfig;
  3use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2};
  4use sonobe::{
  5    commitment::{kzg::KZG, pedersen::Pedersen},
  6    folding::{hypernova::HyperNova, nova::Nova},
  7    frontend::circom::CircomFCircuit,
  8    transcript::poseidon::poseidon_canonical_config,
  9    FoldingScheme,
 10};
 11
 12pub type NovaFolding =
 13    Nova<G1, GVar, G2, GVar2, CircomFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>, false>;
 14pub type HyperNovaFolding = HyperNova<
 15    G1,
 16    GVar,
 17    G2,
 18    GVar2,
 19    CircomFCircuit<Fr>,
 20    KZG<'static, Bn254>,
 21    Pedersen<G2>,
 22    1,
 23    1,
 24    false,
 25>;
 26
 27pub struct StepInput<OtherInstances> {
 28    pub external_inputs: Vec<Fr>,
 29    pub other_instances: Option<OtherInstances>,
 30}
 31
 32pub trait FoldingSchemeExt: FoldingScheme<G1, G2, CircomFCircuit<Fr>> {
 33    fn prepreprocess(
 34        poseidon_config: PoseidonConfig<Fr>,
 35        circuit: CircomFCircuit<Fr>,
 36    ) -> Self::PreprocessorParam;
 37
 38    fn transform_inputs(
 39        full_input: Vec<Vec<Fr>>,
 40    ) -> impl Iterator<Item = StepInput<Self::MultiCommittedInstanceWithWitness>>;
 41}
 42
 43impl FoldingSchemeExt for NovaFolding {
 44    fn prepreprocess(
 45        poseidon_config: PoseidonConfig<Fr>,
 46        circuit: CircomFCircuit<Fr>,
 47    ) -> Self::PreprocessorParam {
 48        Self::PreprocessorParam::new(poseidon_config, circuit)
 49    }
 50
 51    fn transform_inputs(
 52        full_input: Vec<Vec<Fr>>,
 53    ) -> impl Iterator<Item = StepInput<Self::MultiCommittedInstanceWithWitness>> {
 54        full_input.into_iter().map(|input| StepInput {
 55            external_inputs: input,
 56            other_instances: None,
 57        })
 58    }
 59}
 60
 61impl FoldingSchemeExt for HyperNovaFolding {
 62    fn prepreprocess(
 63        poseidon_config: PoseidonConfig<Fr>,
 64        circuit: CircomFCircuit<Fr>,
 65    ) -> Self::PreprocessorParam {
 66        Self::PreprocessorParam::new(poseidon_config, circuit)
 67    }
 68
 69    fn transform_inputs(
 70        full_input: Vec<Vec<Fr>>,
 71    ) -> impl Iterator<Item = StepInput<Self::MultiCommittedInstanceWithWitness>> {
 72        full_input.into_iter().map(|input| StepInput {
 73            external_inputs: input,
 74            other_instances: Some((vec![], vec![])),
 75        })
 76    }
 77}
 78
 79pub fn prepare_folding<FS: FoldingSchemeExt>(
 80    circuit: &CircomFCircuit<Fr>,
 81    start_ivc_state: Vec<Fr>,
 82    rng: &mut impl rand::RngCore,
 83) -> (FS, FS::VerifierParam) {
 84    let preprocess_params = FS::prepreprocess(poseidon_canonical_config::<Fr>(), circuit.clone());
 85    let params =
 86        FS::preprocess(&mut *rng, &preprocess_params).expect("Failed to preprocess folding scheme");
 87    let folding =
 88        FS::init(&params, circuit.clone(), start_ivc_state).expect("Failed to init folding scheme");
 89
 90    (folding, params.1)
 91}
 92
 93pub fn verify_folding<FS: FoldingSchemeExt>(
 94    folding: &FS,
 95    folding_vp: FS::VerifierParam,
 96    start_ivc_state: Vec<Fr>,
 97    num_steps: u32,
 98) {
 99    let (running_instance, incoming_instance, cyclefold_instance) = folding.instances();
100    FS::verify(
101        folding_vp,
102        start_ivc_state,
103        folding.state(),
104        Fr::from(num_steps),
105        running_instance,
106        incoming_instance,
107        cyclefold_instance,
108    )
109    .expect("Failed to verify folded proof");
110}