arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/folding-schemes/src/folding/mod.rs
folding-schemes/src/folding/mod.rsRaw
  1pub mod circuits;
  2pub mod hypernova;
  3pub mod nova;
  4pub mod protogalaxy;
  5pub mod traits;
  6
  7#[cfg(test)]
  8pub mod tests {
  9    use ark_ec::CurveGroup;
 10    use ark_ff::PrimeField;
 11    use ark_pallas::{constraints::GVar as GVar1, Fr, Projective as G1};
 12    use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
 13    use ark_vesta::{constraints::GVar as GVar2, Projective as G2};
 14    use std::io::Write;
 15
 16    use crate::commitment::pedersen::Pedersen;
 17    use crate::folding::{
 18        hypernova::HyperNova,
 19        nova::{Nova, PreprocessorParam as NovaPreprocessorParam},
 20        protogalaxy::ProtoGalaxy,
 21    };
 22    use crate::frontend::utils::CubicFCircuit;
 23    use crate::frontend::FCircuit;
 24    use crate::transcript::poseidon::poseidon_canonical_config;
 25    use crate::Error;
 26    use crate::FoldingScheme;
 27
 28    /// tests the IVC proofs and its serializers for the 3 implemented IVCs: Nova, HyperNova and
 29    /// ProtoGalaxy.
 30    #[test]
 31    fn test_serialize_ivc_nova_hypernova_protogalaxy() {
 32        let poseidon_config = poseidon_canonical_config::<Fr>();
 33        type FC = CubicFCircuit<Fr>;
 34        let f_circuit = FC::new(()).unwrap();
 35
 36        // test Nova
 37        type N = Nova<G1, GVar1, G2, GVar2, FC, Pedersen<G1>, Pedersen<G2>, false>;
 38        let prep_param = NovaPreprocessorParam::new(poseidon_config.clone(), f_circuit);
 39        test_serialize_ivc_opt::<G1, G2, FC, N>("nova".to_string(), prep_param.clone()).unwrap();
 40
 41        // test HyperNova
 42        type HN = HyperNova<
 43            G1,
 44            GVar1,
 45            G2,
 46            GVar2,
 47            FC,
 48            Pedersen<G1>,
 49            Pedersen<G2>,
 50            1, // mu
 51            1, // nu
 52            false,
 53        >;
 54        test_serialize_ivc_opt::<G1, G2, FC, HN>("hypernova".to_string(), prep_param).unwrap();
 55
 56        // test ProtoGalaxy
 57        type P = ProtoGalaxy<G1, GVar1, G2, GVar2, FC, Pedersen<G1>, Pedersen<G2>>;
 58        let prep_param = (poseidon_config, f_circuit);
 59        test_serialize_ivc_opt::<G1, G2, FC, P>("protogalaxy".to_string(), prep_param).unwrap();
 60    }
 61
 62    fn test_serialize_ivc_opt<
 63        C1: CurveGroup,
 64        C2: CurveGroup,
 65        FC: FCircuit<C1::ScalarField, Params = ()>,
 66        FS: FoldingScheme<C1, C2, FC>,
 67    >(
 68        name: String,
 69        prep_param: FS::PreprocessorParam,
 70    ) -> Result<(), Error>
 71    where
 72        C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
 73        C2::BaseField: PrimeField,
 74        FC: FCircuit<C1::ScalarField>,
 75    {
 76        let mut rng = ark_std::test_rng();
 77        let F_circuit = FC::new(())?;
 78
 79        let fs_params = FS::preprocess(&mut rng, &prep_param)?;
 80
 81        let z_0 = vec![C1::ScalarField::from(3_u32)];
 82        let mut fs = FS::init(&fs_params, F_circuit, z_0.clone()).unwrap();
 83
 84        // perform multiple IVC steps (internally folding)
 85        let num_steps: usize = 3;
 86        for _ in 0..num_steps {
 87            fs.prove_step(&mut rng, vec![], None).unwrap();
 88        }
 89
 90        // verify the IVCProof
 91        let ivc_proof: FS::IVCProof = fs.ivc_proof();
 92        FS::verify(fs_params.1.clone(), ivc_proof.clone()).unwrap();
 93
 94        // serialize the IVCProof and store it in a file
 95        let mut writer = vec![];
 96        assert!(ivc_proof.serialize_compressed(&mut writer).is_ok());
 97
 98        let mut file = std::fs::OpenOptions::new()
 99            .create(true)
100            .write(true)
101            .open(format!("./ivc_proof-{}.serialized", name))
102            .unwrap();
103        file.write_all(&writer).unwrap();
104
105        // read the IVCProof from the file deserializing it
106        let bytes = std::fs::read(format!("./ivc_proof-{}.serialized", name)).unwrap();
107        let deserialized_ivc_proof =
108            FS::IVCProof::deserialize_compressed(bytes.as_slice()).unwrap();
109        // verify deserialized IVCProof
110        FS::verify(fs_params.1.clone(), deserialized_ivc_proof.clone()).unwrap();
111
112        // build the FS from the given IVCProof, FC::Params, ProverParams and VerifierParams
113        let mut new_fs = FS::from_ivc_proof(deserialized_ivc_proof, (), fs_params.clone()).unwrap();
114
115        // serialize the Nova params
116        let mut fs_pp_serialized = vec![];
117        fs_params
118            .0
119            .serialize_compressed(&mut fs_pp_serialized)
120            .unwrap();
121        let mut fs_vp_serialized = vec![];
122        fs_params
123            .1
124            .serialize_compressed(&mut fs_vp_serialized)
125            .unwrap();
126
127        // deserialize the Nova params. This would be done by the client reading from a file
128        let _fs_pp_deserialized = FS::pp_deserialize_with_mode(
129            &mut fs_pp_serialized.as_slice(),
130            ark_serialize::Compress::Yes,
131            ark_serialize::Validate::Yes,
132            (), // FCircuit's Params
133        )
134        .unwrap();
135
136        // perform several IVC steps on both the original FS instance and the recovered from the
137        // serialization new FS instance
138        let num_steps: usize = 3;
139        for _ in 0..num_steps {
140            new_fs.prove_step(&mut rng, vec![], None).unwrap();
141            fs.prove_step(&mut rng, vec![], None).unwrap();
142        }
143
144        // check that the IVCProofs from both FS instances are equal
145        assert_eq!(new_fs.ivc_proof(), fs.ivc_proof());
146
147        let fs_vp_deserialized = FS::vp_deserialize_with_mode(
148            &mut fs_vp_serialized.as_slice(),
149            ark_serialize::Compress::Yes,
150            ark_serialize::Validate::Yes,
151            (), // fcircuit_params
152        )
153        .unwrap();
154
155        // get the IVCProof
156        let ivc_proof: FS::IVCProof = new_fs.ivc_proof();
157
158        // serialize IVCProof
159        let mut ivc_proof_serialized = vec![];
160        assert!(ivc_proof
161            .serialize_compressed(&mut ivc_proof_serialized)
162            .is_ok());
163        // deserialize IVCProof
164        let ivc_proof_deserialized =
165            FS::IVCProof::deserialize_compressed(ivc_proof_serialized.as_slice()).unwrap();
166
167        // verify the last IVCProof from the recovered from serialization FS
168        FS::verify(fs_vp_deserialized.clone(), ivc_proof_deserialized).unwrap();
169
170        Ok(())
171    }
172}