mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-01-08 15:01:30 +01:00
feat/hypernova serialization (#159)
* feat: implement serialization of hypernova prover and verifier params, proof and public inputs * chore: remove leftover comments * chore: remove timers * chore: improve typing and import naming
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
use ark_crypto_primitives::sponge::Absorb;
|
use ark_crypto_primitives::sponge::Absorb;
|
||||||
use ark_ec::CurveGroup;
|
use ark_ec::CurveGroup;
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
|
use ark_serialize::CanonicalDeserialize;
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
use ark_std::One;
|
use ark_std::One;
|
||||||
use ark_std::Zero;
|
use ark_std::Zero;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -17,7 +19,7 @@ use crate::utils::virtual_polynomial::{build_eq_x_r_vec, VirtualPolynomial};
|
|||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
/// Committed CCS instance
|
/// Committed CCS instance
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, CanonicalSerialize, CanonicalDeserialize)]
|
||||||
pub struct CCCS<C: CurveGroup> {
|
pub struct CCCS<C: CurveGroup> {
|
||||||
// Commitment to witness
|
// Commitment to witness
|
||||||
pub C: C,
|
pub C: C,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use ark_crypto_primitives::sponge::Absorb;
|
|||||||
use ark_ec::{CurveGroup, Group};
|
use ark_ec::{CurveGroup, Group};
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar, ToConstraintFieldGadget};
|
use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar, ToConstraintFieldGadget};
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
use ark_snark::SNARK;
|
use ark_snark::SNARK;
|
||||||
use ark_std::rand::{CryptoRng, RngCore};
|
use ark_std::rand::{CryptoRng, RngCore};
|
||||||
use ark_std::{One, Zero};
|
use ark_std::{One, Zero};
|
||||||
@@ -14,11 +15,12 @@ use crate::commitment::{
|
|||||||
kzg::Proof as KZGProof, pedersen::Params as PedersenParams, CommitmentScheme,
|
kzg::Proof as KZGProof, pedersen::Params as PedersenParams, CommitmentScheme,
|
||||||
};
|
};
|
||||||
use crate::folding::circuits::{nonnative::affine::NonNativeAffineVar, CF2};
|
use crate::folding::circuits::{nonnative::affine::NonNativeAffineVar, CF2};
|
||||||
|
use crate::folding::nova::decider_eth::VerifierParam;
|
||||||
use crate::frontend::FCircuit;
|
use crate::frontend::FCircuit;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use crate::{Decider as DeciderTrait, FoldingScheme};
|
use crate::{Decider as DeciderTrait, FoldingScheme};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize)]
|
||||||
pub struct Proof<C1, CS1, S>
|
pub struct Proof<C1, CS1, S>
|
||||||
where
|
where
|
||||||
C1: CurveGroup,
|
C1: CurveGroup,
|
||||||
@@ -85,8 +87,7 @@ where
|
|||||||
type PreprocessorParam = (FS::ProverParam, FS::VerifierParam);
|
type PreprocessorParam = (FS::ProverParam, FS::VerifierParam);
|
||||||
type ProverParam = (S::ProvingKey, CS1::ProverParams);
|
type ProverParam = (S::ProvingKey, CS1::ProverParams);
|
||||||
type Proof = Proof<C1, CS1, S>;
|
type Proof = Proof<C1, CS1, S>;
|
||||||
/// VerifierParam = (pp_hash, snark::vk, commitment_scheme::vk)
|
type VerifierParam = VerifierParam<C1, CS1::VerifierParams, S::VerifyingKey>;
|
||||||
type VerifierParam = (C1::ScalarField, S::VerifyingKey, CS1::VerifierParams);
|
|
||||||
type PublicInput = Vec<C1::ScalarField>;
|
type PublicInput = Vec<C1::ScalarField>;
|
||||||
type CommittedInstance = ();
|
type CommittedInstance = ();
|
||||||
|
|
||||||
@@ -120,7 +121,12 @@ where
|
|||||||
let pp_hash = hypernova_vp.pp_hash()?;
|
let pp_hash = hypernova_vp.pp_hash()?;
|
||||||
|
|
||||||
let pp = (g16_pk, hypernova_pp.cs_pp);
|
let pp = (g16_pk, hypernova_pp.cs_pp);
|
||||||
let vp = (pp_hash, g16_vk, hypernova_vp.cs_vp);
|
|
||||||
|
let vp = VerifierParam {
|
||||||
|
pp_hash,
|
||||||
|
snark_vp: g16_vk,
|
||||||
|
cs_vp: hypernova_vp.cs_vp,
|
||||||
|
};
|
||||||
Ok((pp, vp))
|
Ok((pp, vp))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +189,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (pp_hash, snark_vk, cs_vk): (C1::ScalarField, S::VerifyingKey, CS1::VerifierParams) =
|
let (pp_hash, snark_vk, cs_vk): (C1::ScalarField, S::VerifyingKey, CS1::VerifierParams) =
|
||||||
vp;
|
(vp.pp_hash, vp.snark_vp, vp.cs_vp);
|
||||||
|
|
||||||
// Note: the NIMFS proof is checked inside the DeciderEthCircuit, which ensures that the
|
// Note: the NIMFS proof is checked inside the DeciderEthCircuit, which ensures that the
|
||||||
// 'proof.U_i1' is correctly computed
|
// 'proof.U_i1' is correctly computed
|
||||||
@@ -223,11 +229,15 @@ pub mod tests {
|
|||||||
use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as Projective};
|
use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as Projective};
|
||||||
use ark_groth16::Groth16;
|
use ark_groth16::Groth16;
|
||||||
use ark_grumpkin::{constraints::GVar as GVar2, Projective as Projective2};
|
use ark_grumpkin::{constraints::GVar as GVar2, Projective as Projective2};
|
||||||
use std::time::Instant;
|
use ark_serialize::{Compress, Validate};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::commitment::{kzg::KZG, pedersen::Pedersen};
|
use crate::commitment::{kzg::KZG, pedersen::Pedersen};
|
||||||
use crate::folding::hypernova::PreprocessorParam;
|
use crate::folding::hypernova::cccs::CCCS;
|
||||||
|
use crate::folding::hypernova::{
|
||||||
|
PreprocessorParam, ProverParams, VerifierParams as HyperNovaVerifierParams,
|
||||||
|
};
|
||||||
|
use crate::folding::nova::decider_eth::VerifierParam;
|
||||||
use crate::frontend::utils::CubicFCircuit;
|
use crate::frontend::utils::CubicFCircuit;
|
||||||
use crate::transcript::poseidon::poseidon_canonical_config;
|
use crate::transcript::poseidon::poseidon_canonical_config;
|
||||||
|
|
||||||
@@ -262,51 +272,225 @@ pub mod tests {
|
|||||||
NU,
|
NU,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
let mut rng = rand::rngs::OsRng;
|
||||||
|
let poseidon_config = poseidon_canonical_config::<Fr>();
|
||||||
|
|
||||||
|
let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
|
||||||
|
let z_0 = vec![Fr::from(3_u32)];
|
||||||
|
|
||||||
|
let prep_param = PreprocessorParam::new(poseidon_config, F_circuit);
|
||||||
|
let hypernova_params = HN::preprocess(&mut rng, &prep_param).unwrap();
|
||||||
|
|
||||||
|
let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap();
|
||||||
|
hypernova
|
||||||
|
.prove_step(&mut rng, vec![], Some((vec![], vec![])))
|
||||||
|
.unwrap();
|
||||||
|
hypernova
|
||||||
|
.prove_step(&mut rng, vec![], Some((vec![], vec![])))
|
||||||
|
.unwrap(); // do a 2nd step
|
||||||
|
|
||||||
|
// prepare the Decider prover & verifier params
|
||||||
|
let (decider_pp, decider_vp) =
|
||||||
|
D::preprocess(&mut rng, hypernova_params, hypernova.clone()).unwrap();
|
||||||
|
|
||||||
|
// decider proof generation
|
||||||
|
let proof = D::prove(rng, decider_pp, hypernova.clone()).unwrap();
|
||||||
|
|
||||||
|
// decider proof verification
|
||||||
|
let verified = D::verify(
|
||||||
|
decider_vp,
|
||||||
|
hypernova.i,
|
||||||
|
hypernova.z_0,
|
||||||
|
hypernova.z_i,
|
||||||
|
&(),
|
||||||
|
&(),
|
||||||
|
&proof,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert!(verified);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_decider_serialization() {
|
||||||
|
const MU: usize = 1;
|
||||||
|
const NU: usize = 1;
|
||||||
|
// use HyperNova as FoldingScheme
|
||||||
|
type HN = HyperNova<
|
||||||
|
Projective,
|
||||||
|
GVar,
|
||||||
|
Projective2,
|
||||||
|
GVar2,
|
||||||
|
CubicFCircuit<Fr>,
|
||||||
|
KZG<'static, Bn254>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
MU,
|
||||||
|
NU,
|
||||||
|
false,
|
||||||
|
>;
|
||||||
|
type D = Decider<
|
||||||
|
Projective,
|
||||||
|
GVar,
|
||||||
|
Projective2,
|
||||||
|
GVar2,
|
||||||
|
CubicFCircuit<Fr>,
|
||||||
|
KZG<'static, Bn254>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
Groth16<Bn254>, // here we define the Snark to use in the decider
|
||||||
|
HN, // here we define the FoldingScheme to use
|
||||||
|
MU,
|
||||||
|
NU,
|
||||||
|
>;
|
||||||
|
|
||||||
let mut rng = ark_std::test_rng();
|
let mut rng = ark_std::test_rng();
|
||||||
let poseidon_config = poseidon_canonical_config::<Fr>();
|
let poseidon_config = poseidon_canonical_config::<Fr>();
|
||||||
|
|
||||||
let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
|
let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
|
||||||
let z_0 = vec![Fr::from(3_u32)];
|
let z_0 = vec![Fr::from(3_u32)];
|
||||||
|
|
||||||
let prep_param = PreprocessorParam::new(poseidon_config, F_circuit);
|
let prep_param = PreprocessorParam::new(poseidon_config.clone(), F_circuit);
|
||||||
let hypernova_params = HN::preprocess(&mut rng, &prep_param).unwrap();
|
let hypernova_params = HN::preprocess(&mut rng, &prep_param).unwrap();
|
||||||
|
|
||||||
let start = Instant::now();
|
let hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap();
|
||||||
let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap();
|
|
||||||
println!("Nova initialized, {:?}", start.elapsed());
|
|
||||||
let start = Instant::now();
|
|
||||||
hypernova
|
|
||||||
.prove_step(&mut rng, vec![], Some((vec![], vec![])))
|
|
||||||
.unwrap();
|
|
||||||
println!("prove_step, {:?}", start.elapsed());
|
|
||||||
hypernova
|
|
||||||
.prove_step(&mut rng, vec![], Some((vec![], vec![])))
|
|
||||||
.unwrap(); // do a 2nd step
|
|
||||||
|
|
||||||
let mut rng = rand::rngs::OsRng;
|
let mut rng = rand::rngs::OsRng;
|
||||||
|
|
||||||
// prepare the Decider prover & verifier params
|
// prepare the Decider prover & verifier params
|
||||||
let (decider_pp, decider_vp) =
|
let (decider_pp, decider_vp) =
|
||||||
D::preprocess(&mut rng, hypernova_params, hypernova.clone()).unwrap();
|
D::preprocess(&mut rng, hypernova_params.clone(), hypernova.clone()).unwrap();
|
||||||
|
|
||||||
|
let mut hypernova_pp_serialized = vec![];
|
||||||
|
hypernova_params
|
||||||
|
.0
|
||||||
|
.clone()
|
||||||
|
.serialize_compressed(&mut hypernova_pp_serialized)
|
||||||
|
.unwrap();
|
||||||
|
let mut hypernova_vp_serialized = vec![];
|
||||||
|
hypernova_params
|
||||||
|
.1
|
||||||
|
.clone()
|
||||||
|
.serialize_compressed(&mut hypernova_vp_serialized)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let hypernova_pp_deserialized = ProverParams::<
|
||||||
|
Projective,
|
||||||
|
Projective2,
|
||||||
|
KZG<'static, Bn254>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
false,
|
||||||
|
>::deserialize_prover_params(
|
||||||
|
hypernova_pp_serialized.as_slice(),
|
||||||
|
Compress::Yes,
|
||||||
|
Validate::No,
|
||||||
|
&hypernova_params.0.ccs,
|
||||||
|
&poseidon_config,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let hypernova_vp_deserialized = HyperNovaVerifierParams::<
|
||||||
|
Projective,
|
||||||
|
Projective2,
|
||||||
|
KZG<'static, Bn254>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
false,
|
||||||
|
>::deserialize_verifier_params(
|
||||||
|
hypernova_vp_serialized.as_slice(),
|
||||||
|
Compress::Yes,
|
||||||
|
Validate::No,
|
||||||
|
&hypernova_params.0.ccs.unwrap(),
|
||||||
|
&poseidon_config,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let hypernova_params = (hypernova_pp_deserialized, hypernova_vp_deserialized);
|
||||||
|
let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap();
|
||||||
|
|
||||||
|
hypernova
|
||||||
|
.prove_step(&mut rng, vec![], Some((vec![], vec![])))
|
||||||
|
.unwrap();
|
||||||
|
hypernova
|
||||||
|
.prove_step(&mut rng, vec![], Some((vec![], vec![])))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// decider proof generation
|
// decider proof generation
|
||||||
let start = Instant::now();
|
|
||||||
let proof = D::prove(rng, decider_pp, hypernova.clone()).unwrap();
|
let proof = D::prove(rng, decider_pp, hypernova.clone()).unwrap();
|
||||||
println!("Decider prove, {:?}", start.elapsed());
|
|
||||||
|
|
||||||
// decider proof verification
|
|
||||||
let start = Instant::now();
|
|
||||||
let verified = D::verify(
|
let verified = D::verify(
|
||||||
decider_vp,
|
decider_vp.clone(),
|
||||||
hypernova.i,
|
hypernova.i.clone(),
|
||||||
hypernova.z_0,
|
hypernova.z_0.clone(),
|
||||||
hypernova.z_i,
|
hypernova.z_i.clone(),
|
||||||
&(),
|
&(),
|
||||||
&(),
|
&(),
|
||||||
&proof,
|
&proof,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(verified);
|
assert!(verified);
|
||||||
println!("Decider verify, {:?}", start.elapsed());
|
|
||||||
|
// The rest of this test will serialize the data and deserialize it back, and use it to
|
||||||
|
// verify the proof:
|
||||||
|
|
||||||
|
// serialize the verifier_params, proof and public inputs
|
||||||
|
let mut decider_vp_serialized = vec![];
|
||||||
|
decider_vp
|
||||||
|
.serialize_compressed(&mut decider_vp_serialized)
|
||||||
|
.unwrap();
|
||||||
|
let mut proof_serialized = vec![];
|
||||||
|
proof.serialize_compressed(&mut proof_serialized).unwrap();
|
||||||
|
// serialize the public inputs in a single packet
|
||||||
|
let mut public_inputs_serialized = vec![];
|
||||||
|
hypernova
|
||||||
|
.i
|
||||||
|
.serialize_compressed(&mut public_inputs_serialized)
|
||||||
|
.unwrap();
|
||||||
|
hypernova
|
||||||
|
.z_0
|
||||||
|
.serialize_compressed(&mut public_inputs_serialized)
|
||||||
|
.unwrap();
|
||||||
|
hypernova
|
||||||
|
.z_i
|
||||||
|
.serialize_compressed(&mut public_inputs_serialized)
|
||||||
|
.unwrap();
|
||||||
|
hypernova
|
||||||
|
.U_i
|
||||||
|
.serialize_compressed(&mut public_inputs_serialized)
|
||||||
|
.unwrap();
|
||||||
|
hypernova
|
||||||
|
.u_i
|
||||||
|
.serialize_compressed(&mut public_inputs_serialized)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// deserialize back the verifier_params, proof and public inputs
|
||||||
|
let decider_vp_deserialized =
|
||||||
|
VerifierParam::<
|
||||||
|
Projective,
|
||||||
|
<KZG<'static, Bn254> as CommitmentScheme<Projective>>::VerifierParams,
|
||||||
|
<Groth16<Bn254> as SNARK<Fr>>::VerifyingKey,
|
||||||
|
>::deserialize_compressed(&mut decider_vp_serialized.as_slice())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let proof_deserialized =
|
||||||
|
Proof::<Projective, KZG<'static, Bn254>, Groth16<Bn254>>::deserialize_compressed(
|
||||||
|
&mut proof_serialized.as_slice(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut reader = public_inputs_serialized.as_slice();
|
||||||
|
let i_deserialized = Fr::deserialize_compressed(&mut reader).unwrap();
|
||||||
|
let z_0_deserialized = Vec::<Fr>::deserialize_compressed(&mut reader).unwrap();
|
||||||
|
let z_i_deserialized = Vec::<Fr>::deserialize_compressed(&mut reader).unwrap();
|
||||||
|
let _U_i = LCCCS::<Projective>::deserialize_compressed(&mut reader).unwrap();
|
||||||
|
let _u_i = CCCS::<Projective>::deserialize_compressed(&mut reader).unwrap();
|
||||||
|
|
||||||
|
let verified = D::verify(
|
||||||
|
decider_vp_deserialized,
|
||||||
|
i_deserialized.clone(),
|
||||||
|
z_0_deserialized.clone(),
|
||||||
|
z_i_deserialized.clone(),
|
||||||
|
&(),
|
||||||
|
&(),
|
||||||
|
&proof_deserialized,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert!(verified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ use ark_ec::{CurveGroup, Group};
|
|||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_poly::DenseMultilinearExtension;
|
use ark_poly::DenseMultilinearExtension;
|
||||||
use ark_poly::MultilinearExtension;
|
use ark_poly::MultilinearExtension;
|
||||||
|
use ark_serialize::CanonicalDeserialize;
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
use ark_std::rand::Rng;
|
use ark_std::rand::Rng;
|
||||||
use ark_std::Zero;
|
use ark_std::Zero;
|
||||||
|
|
||||||
@@ -15,7 +17,7 @@ use crate::utils::vec::mat_vec_mul;
|
|||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
/// Linearized Committed CCS instance
|
/// Linearized Committed CCS instance
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize)]
|
||||||
pub struct LCCCS<C: CurveGroup> {
|
pub struct LCCCS<C: CurveGroup> {
|
||||||
// Commitment to witness
|
// Commitment to witness
|
||||||
pub C: C,
|
pub C: C,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use ark_crypto_primitives::sponge::{
|
|||||||
use ark_ec::{CurveGroup, Group};
|
use ark_ec::{CurveGroup, Group};
|
||||||
use ark_ff::{BigInteger, PrimeField};
|
use ark_ff::{BigInteger, PrimeField};
|
||||||
use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar, ToConstraintFieldGadget};
|
use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar, ToConstraintFieldGadget};
|
||||||
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||||
use ark_std::{fmt::Debug, marker::PhantomData, rand::RngCore, One, Zero};
|
use ark_std::{fmt::Debug, marker::PhantomData, rand::RngCore, One, Zero};
|
||||||
|
|
||||||
pub mod cccs;
|
pub mod cccs;
|
||||||
@@ -14,6 +15,7 @@ pub mod decider_eth;
|
|||||||
pub mod decider_eth_circuit;
|
pub mod decider_eth_circuit;
|
||||||
pub mod lcccs;
|
pub mod lcccs;
|
||||||
pub mod nimfs;
|
pub mod nimfs;
|
||||||
|
pub mod serialize;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
use cccs::CCCS;
|
use cccs::CCCS;
|
||||||
@@ -62,7 +64,7 @@ pub type HyperNovaCycleFoldCircuit<C, GC, const MU: usize, const NU: usize> =
|
|||||||
CycleFoldCircuit<HyperNovaCycleFoldConfig<C, MU, NU>, GC>;
|
CycleFoldCircuit<HyperNovaCycleFoldConfig<C, MU, NU>, GC>;
|
||||||
|
|
||||||
/// Witness for the LCCCS & CCCS, containing the w vector, and the r_w used as randomness in the Pedersen commitment.
|
/// Witness for the LCCCS & CCCS, containing the w vector, and the r_w used as randomness in the Pedersen commitment.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize)]
|
||||||
pub struct Witness<F: PrimeField> {
|
pub struct Witness<F: PrimeField> {
|
||||||
pub w: Vec<F>,
|
pub w: Vec<F>,
|
||||||
pub r_w: F,
|
pub r_w: F,
|
||||||
@@ -939,13 +941,25 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test_ivc allowing to choose the CommitmentSchemes
|
// test_ivc allowing to choose the CommitmentSchemes
|
||||||
fn test_ivc_opt<
|
pub fn test_ivc_opt<
|
||||||
CS1: CommitmentScheme<Projective, H>,
|
CS1: CommitmentScheme<Projective, H>,
|
||||||
CS2: CommitmentScheme<Projective2, H>,
|
CS2: CommitmentScheme<Projective2, H>,
|
||||||
const H: bool,
|
const H: bool,
|
||||||
>(
|
>(
|
||||||
poseidon_config: PoseidonConfig<Fr>,
|
poseidon_config: PoseidonConfig<Fr>,
|
||||||
F_circuit: CubicFCircuit<Fr>,
|
F_circuit: CubicFCircuit<Fr>,
|
||||||
|
) -> (
|
||||||
|
HyperNova<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>, CS1, CS2, 2, 3, H>,
|
||||||
|
(
|
||||||
|
ProverParams<Projective, Projective2, CS1, CS2, H>,
|
||||||
|
VerifierParams<Projective, Projective2, CS1, CS2, H>,
|
||||||
|
),
|
||||||
|
(LCCCS<Projective>, Witness<Fr>),
|
||||||
|
(CCCS<Projective>, Witness<Fr>),
|
||||||
|
(
|
||||||
|
CycleFoldCommittedInstance<Projective2>,
|
||||||
|
CycleFoldWitness<Projective2>,
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
let mut rng = ark_std::test_rng();
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
@@ -1001,14 +1015,22 @@ mod tests {
|
|||||||
|
|
||||||
let (running_instance, incoming_instance, cyclefold_instance) = hypernova.instances();
|
let (running_instance, incoming_instance, cyclefold_instance) = hypernova.instances();
|
||||||
HN::verify(
|
HN::verify(
|
||||||
hypernova_params.1, // verifier_params
|
hypernova_params.1.clone(), // verifier_params
|
||||||
z_0,
|
z_0,
|
||||||
hypernova.z_i,
|
hypernova.z_i.clone(),
|
||||||
hypernova.i,
|
hypernova.i.clone(),
|
||||||
|
running_instance.clone(),
|
||||||
|
incoming_instance.clone(),
|
||||||
|
cyclefold_instance.clone(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
(
|
||||||
|
hypernova,
|
||||||
|
hypernova_params,
|
||||||
running_instance,
|
running_instance,
|
||||||
incoming_instance,
|
incoming_instance,
|
||||||
cyclefold_instance,
|
cyclefold_instance,
|
||||||
)
|
)
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
420
folding-schemes/src/folding/hypernova/serialize.rs
Normal file
420
folding-schemes/src/folding/hypernova/serialize.rs
Normal file
@@ -0,0 +1,420 @@
|
|||||||
|
use crate::arith::ccs::CCS;
|
||||||
|
use crate::arith::r1cs::R1CS;
|
||||||
|
use crate::folding::hypernova::ProverParams;
|
||||||
|
use crate::folding::hypernova::VerifierParams;
|
||||||
|
use ark_crypto_primitives::sponge::poseidon::PoseidonConfig;
|
||||||
|
use ark_crypto_primitives::sponge::Absorb;
|
||||||
|
use ark_ec::{CurveGroup, Group};
|
||||||
|
use ark_ff::PrimeField;
|
||||||
|
use ark_r1cs_std::groups::{CurveVar, GroupOpsBounds};
|
||||||
|
use ark_r1cs_std::ToConstraintFieldGadget;
|
||||||
|
use ark_serialize::CanonicalDeserialize;
|
||||||
|
use ark_serialize::{CanonicalSerialize, Compress, SerializationError, Validate};
|
||||||
|
use ark_std::marker::PhantomData;
|
||||||
|
|
||||||
|
use crate::folding::hypernova::cccs::CCCS;
|
||||||
|
use crate::folding::hypernova::lcccs::LCCCS;
|
||||||
|
use crate::folding::hypernova::Witness;
|
||||||
|
use crate::folding::nova::{
|
||||||
|
CommittedInstance as CycleFoldCommittedInstance, Witness as CycleFoldWitness,
|
||||||
|
};
|
||||||
|
use crate::FoldingScheme;
|
||||||
|
use crate::{
|
||||||
|
commitment::CommitmentScheme,
|
||||||
|
folding::{circuits::CF2, nova::PreprocessorParam},
|
||||||
|
frontend::FCircuit,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::HyperNova;
|
||||||
|
|
||||||
|
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const MU: usize, const NU: usize, const H: bool>
|
||||||
|
CanonicalSerialize for HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2, MU, NU, H>
|
||||||
|
where
|
||||||
|
C1: CurveGroup,
|
||||||
|
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
|
||||||
|
C2: CurveGroup,
|
||||||
|
GC2: CurveVar<C2, CF2<C2>>,
|
||||||
|
FC: FCircuit<C1::ScalarField>,
|
||||||
|
CS1: CommitmentScheme<C1, H>,
|
||||||
|
CS2: CommitmentScheme<C2, H>,
|
||||||
|
{
|
||||||
|
fn serialize_compressed<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
writer: W,
|
||||||
|
) -> Result<(), ark_serialize::SerializationError> {
|
||||||
|
self.serialize_with_mode(writer, ark_serialize::Compress::Yes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compressed_size(&self) -> usize {
|
||||||
|
self.serialized_size(ark_serialize::Compress::Yes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_uncompressed<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
writer: W,
|
||||||
|
) -> Result<(), ark_serialize::SerializationError> {
|
||||||
|
self.serialize_with_mode(writer, ark_serialize::Compress::No)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uncompressed_size(&self) -> usize {
|
||||||
|
self.serialized_size(ark_serialize::Compress::No)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_with_mode<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
mut writer: W,
|
||||||
|
compress: ark_serialize::Compress,
|
||||||
|
) -> Result<(), ark_serialize::SerializationError> {
|
||||||
|
self.pp_hash.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.i.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.z_0.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.z_i.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.W_i.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.U_i.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.w_i.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.u_i.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.cf_W_i.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.cf_U_i.serialize_with_mode(&mut writer, compress)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialized_size(&self, compress: ark_serialize::Compress) -> usize {
|
||||||
|
self.pp_hash.serialized_size(compress)
|
||||||
|
+ self.i.serialized_size(compress)
|
||||||
|
+ self.z_0.serialized_size(compress)
|
||||||
|
+ self.z_i.serialized_size(compress)
|
||||||
|
+ self.W_i.serialized_size(compress)
|
||||||
|
+ self.U_i.serialized_size(compress)
|
||||||
|
+ self.w_i.serialized_size(compress)
|
||||||
|
+ self.u_i.serialized_size(compress)
|
||||||
|
+ self.cf_W_i.serialized_size(compress)
|
||||||
|
+ self.cf_U_i.serialized_size(compress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const MU: usize, const NU: usize, const H: bool>
|
||||||
|
HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2, MU, NU, H>
|
||||||
|
where
|
||||||
|
C1: CurveGroup,
|
||||||
|
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
|
||||||
|
C2: CurveGroup,
|
||||||
|
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
|
||||||
|
FC: FCircuit<C1::ScalarField, Params = ()>,
|
||||||
|
CS1: CommitmentScheme<C1, H>,
|
||||||
|
CS2: CommitmentScheme<C2, H>,
|
||||||
|
<C1 as CurveGroup>::BaseField: PrimeField,
|
||||||
|
<C2 as CurveGroup>::BaseField: PrimeField,
|
||||||
|
<C1 as Group>::ScalarField: Absorb,
|
||||||
|
<C2 as Group>::ScalarField: Absorb,
|
||||||
|
C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
|
||||||
|
for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>,
|
||||||
|
for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>,
|
||||||
|
{
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn deserialize_hypernova<R: std::io::prelude::Read>(
|
||||||
|
mut reader: R,
|
||||||
|
compress: Compress,
|
||||||
|
validate: Validate,
|
||||||
|
poseidon_config: PoseidonConfig<C1::ScalarField>,
|
||||||
|
cs_pp: CS1::ProverParams,
|
||||||
|
cs_vp: CS1::VerifierParams,
|
||||||
|
cf_cs_pp: CS2::ProverParams,
|
||||||
|
cf_cs_vp: CS2::VerifierParams,
|
||||||
|
) -> Result<Self, SerializationError> {
|
||||||
|
let f_circuit = FC::new(()).unwrap();
|
||||||
|
let prep_param = PreprocessorParam {
|
||||||
|
poseidon_config: poseidon_config.clone(),
|
||||||
|
F: f_circuit.clone(),
|
||||||
|
cs_pp: Some(cs_pp.clone()),
|
||||||
|
cs_vp: Some(cs_vp.clone()),
|
||||||
|
cf_cs_pp: Some(cf_cs_pp.clone()),
|
||||||
|
cf_cs_vp: Some(cf_cs_vp.clone()),
|
||||||
|
};
|
||||||
|
// `test_rng` won't be used in `preprocess`, since parameters have already been initialized
|
||||||
|
let (prover_params, verifier_params) = Self::preprocess(ark_std::test_rng(), &prep_param)
|
||||||
|
.or(Err(SerializationError::InvalidData))?;
|
||||||
|
let pp_hash = C1::ScalarField::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let i = C1::ScalarField::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let z_0 = Vec::<C1::ScalarField>::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let z_i = Vec::<C1::ScalarField>::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let W_i =
|
||||||
|
Witness::<C1::ScalarField>::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let U_i = LCCCS::<C1>::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let w_i =
|
||||||
|
Witness::<C1::ScalarField>::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let u_i = CCCS::<C1>::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let cf_W_i =
|
||||||
|
CycleFoldWitness::<C2>::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let cf_U_i = CycleFoldCommittedInstance::<C2>::deserialize_with_mode(
|
||||||
|
&mut reader,
|
||||||
|
compress,
|
||||||
|
validate,
|
||||||
|
)?;
|
||||||
|
let ccs = prover_params.ccs.ok_or(SerializationError::InvalidData)?;
|
||||||
|
|
||||||
|
Ok(HyperNova {
|
||||||
|
_gc1: PhantomData,
|
||||||
|
_c2: PhantomData,
|
||||||
|
_gc2: PhantomData,
|
||||||
|
ccs,
|
||||||
|
cf_r1cs: verifier_params.cf_r1cs,
|
||||||
|
poseidon_config,
|
||||||
|
cs_pp,
|
||||||
|
cf_cs_pp,
|
||||||
|
F: f_circuit,
|
||||||
|
pp_hash,
|
||||||
|
i,
|
||||||
|
z_0,
|
||||||
|
z_i,
|
||||||
|
W_i,
|
||||||
|
U_i,
|
||||||
|
w_i,
|
||||||
|
u_i,
|
||||||
|
cf_W_i,
|
||||||
|
cf_U_i,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
C1: CurveGroup,
|
||||||
|
C2: CurveGroup,
|
||||||
|
CS1: CommitmentScheme<C1, H>,
|
||||||
|
CS2: CommitmentScheme<C2, H>,
|
||||||
|
const H: bool,
|
||||||
|
> CanonicalSerialize for ProverParams<C1, C2, CS1, CS2, H>
|
||||||
|
{
|
||||||
|
fn serialize_compressed<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
writer: W,
|
||||||
|
) -> Result<(), SerializationError> {
|
||||||
|
self.serialize_with_mode(writer, Compress::Yes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compressed_size(&self) -> usize {
|
||||||
|
self.serialized_size(Compress::Yes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_uncompressed<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
writer: W,
|
||||||
|
) -> Result<(), SerializationError> {
|
||||||
|
self.serialize_with_mode(writer, Compress::No)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uncompressed_size(&self) -> usize {
|
||||||
|
self.serialized_size(Compress::No)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_with_mode<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
mut writer: W,
|
||||||
|
compress: Compress,
|
||||||
|
) -> Result<(), SerializationError> {
|
||||||
|
self.cs_pp.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.cf_cs_pp.serialize_with_mode(&mut writer, compress)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialized_size(&self, compress: Compress) -> usize {
|
||||||
|
self.cs_pp.serialized_size(compress) + self.cf_cs_pp.serialized_size(compress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
C1: CurveGroup,
|
||||||
|
C2: CurveGroup,
|
||||||
|
CS1: CommitmentScheme<C1, H>,
|
||||||
|
CS2: CommitmentScheme<C2, H>,
|
||||||
|
const H: bool,
|
||||||
|
> ProverParams<C1, C2, CS1, CS2, H>
|
||||||
|
{
|
||||||
|
pub fn deserialize_prover_params<R: std::io::prelude::Read>(
|
||||||
|
mut reader: R,
|
||||||
|
compress: Compress,
|
||||||
|
validate: Validate,
|
||||||
|
ccs: &Option<CCS<C1::ScalarField>>,
|
||||||
|
poseidon_config: &PoseidonConfig<C1::ScalarField>,
|
||||||
|
) -> Result<Self, SerializationError> {
|
||||||
|
let cs_pp = CS1::ProverParams::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let cf_cs_pp = CS2::ProverParams::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
|
||||||
|
Ok(ProverParams {
|
||||||
|
cs_pp,
|
||||||
|
cf_cs_pp,
|
||||||
|
ccs: ccs.clone(),
|
||||||
|
poseidon_config: poseidon_config.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
C1: CurveGroup,
|
||||||
|
C2: CurveGroup,
|
||||||
|
CS1: CommitmentScheme<C1, H>,
|
||||||
|
CS2: CommitmentScheme<C2, H>,
|
||||||
|
const H: bool,
|
||||||
|
> CanonicalSerialize for VerifierParams<C1, C2, CS1, CS2, H>
|
||||||
|
{
|
||||||
|
fn serialize_compressed<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
writer: W,
|
||||||
|
) -> Result<(), SerializationError> {
|
||||||
|
self.serialize_with_mode(writer, Compress::Yes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compressed_size(&self) -> usize {
|
||||||
|
self.serialized_size(Compress::Yes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_uncompressed<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
writer: W,
|
||||||
|
) -> Result<(), SerializationError> {
|
||||||
|
self.serialize_with_mode(writer, Compress::No)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uncompressed_size(&self) -> usize {
|
||||||
|
self.serialized_size(Compress::No)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_with_mode<W: std::io::prelude::Write>(
|
||||||
|
&self,
|
||||||
|
mut writer: W,
|
||||||
|
compress: Compress,
|
||||||
|
) -> Result<(), SerializationError> {
|
||||||
|
self.cf_r1cs.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.cs_vp.serialize_with_mode(&mut writer, compress)?;
|
||||||
|
self.cf_cs_vp.serialize_with_mode(&mut writer, compress)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialized_size(&self, compress: Compress) -> usize {
|
||||||
|
self.cf_r1cs.serialized_size(compress)
|
||||||
|
+ self.cs_vp.serialized_size(compress)
|
||||||
|
+ self.cf_cs_vp.serialized_size(compress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
C1: CurveGroup,
|
||||||
|
C2: CurveGroup,
|
||||||
|
CS1: CommitmentScheme<C1, H>,
|
||||||
|
CS2: CommitmentScheme<C2, H>,
|
||||||
|
const H: bool,
|
||||||
|
> VerifierParams<C1, C2, CS1, CS2, H>
|
||||||
|
{
|
||||||
|
pub fn deserialize_verifier_params<R: std::io::Read>(
|
||||||
|
mut reader: R,
|
||||||
|
compress: Compress,
|
||||||
|
validate: Validate,
|
||||||
|
ccs: &CCS<C1::ScalarField>,
|
||||||
|
poseidon_config: &PoseidonConfig<C1::ScalarField>,
|
||||||
|
) -> Result<Self, SerializationError> {
|
||||||
|
let cf_r1cs = R1CS::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let cs_vp = CS1::VerifierParams::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
let cf_cs_vp = CS2::VerifierParams::deserialize_with_mode(&mut reader, compress, validate)?;
|
||||||
|
Ok(VerifierParams {
|
||||||
|
ccs: ccs.clone(),
|
||||||
|
poseidon_config: poseidon_config.clone(),
|
||||||
|
cf_r1cs,
|
||||||
|
cs_vp,
|
||||||
|
cf_cs_vp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod tests {
|
||||||
|
use crate::FoldingScheme;
|
||||||
|
use crate::MultiFolding;
|
||||||
|
use ark_serialize::{Compress, Validate, Write};
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
commitment::{kzg::KZG, pedersen::Pedersen},
|
||||||
|
folding::hypernova::{tests::test_ivc_opt, HyperNova},
|
||||||
|
frontend::{utils::CubicFCircuit, FCircuit},
|
||||||
|
transcript::poseidon::poseidon_canonical_config,
|
||||||
|
};
|
||||||
|
use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as Projective};
|
||||||
|
use ark_grumpkin::{constraints::GVar as GVar2, Projective as Projective2};
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_hypernova() {
|
||||||
|
let poseidon_config = poseidon_canonical_config::<Fr>();
|
||||||
|
let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
|
||||||
|
let (mut hn, (_, verifier_params), _, _, _) = test_ivc_opt::<
|
||||||
|
KZG<Bn254>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
false,
|
||||||
|
>(poseidon_config.clone(), F_circuit);
|
||||||
|
|
||||||
|
let mut writer = vec![];
|
||||||
|
assert!(hn.serialize_compressed(&mut writer).is_ok());
|
||||||
|
let mut writer = vec![];
|
||||||
|
assert!(hn.serialize_uncompressed(&mut writer).is_ok());
|
||||||
|
|
||||||
|
let mut file = fs::OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.write(true)
|
||||||
|
.open("./hypernova.serde")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
file.write_all(&writer).unwrap();
|
||||||
|
|
||||||
|
let bytes = fs::read("./hypernova.serde").unwrap();
|
||||||
|
|
||||||
|
let mut hn_deserialized = HyperNova::<
|
||||||
|
Projective,
|
||||||
|
GVar,
|
||||||
|
Projective2,
|
||||||
|
GVar2,
|
||||||
|
CubicFCircuit<Fr>,
|
||||||
|
KZG<Bn254>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
false,
|
||||||
|
>::deserialize_hypernova(
|
||||||
|
bytes.as_slice(),
|
||||||
|
Compress::No,
|
||||||
|
Validate::No,
|
||||||
|
poseidon_config,
|
||||||
|
hn.cs_pp.clone(),
|
||||||
|
verifier_params.cs_vp,
|
||||||
|
hn.cf_cs_pp.clone(),
|
||||||
|
verifier_params.cf_cs_vp,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(hn.i, hn_deserialized.i);
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
for _ in 0..3 {
|
||||||
|
// prepare some new instances to fold in the multifolding step
|
||||||
|
let mut lcccs = vec![];
|
||||||
|
for j in 0..1 {
|
||||||
|
let instance_state = vec![Fr::from(j as u32 + 85_u32)];
|
||||||
|
let (U, W) = hn
|
||||||
|
.new_running_instance(&mut rng, instance_state, vec![])
|
||||||
|
.unwrap();
|
||||||
|
lcccs.push((U, W));
|
||||||
|
}
|
||||||
|
let mut cccs = vec![];
|
||||||
|
for j in 0..2 {
|
||||||
|
let instance_state = vec![Fr::from(j as u32 + 15_u32)];
|
||||||
|
let (u, w) = hn
|
||||||
|
.new_incoming_instance(&mut rng, instance_state, vec![])
|
||||||
|
.unwrap();
|
||||||
|
cccs.push((u, w));
|
||||||
|
}
|
||||||
|
|
||||||
|
hn.prove_step(&mut rng, vec![], Some((lcccs.clone(), cccs.clone())))
|
||||||
|
.unwrap();
|
||||||
|
hn_deserialized
|
||||||
|
.prove_step(&mut rng, vec![], Some((lcccs, cccs)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(hn.z_i, hn_deserialized.z_i);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user