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(¶ms, 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}