mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-01-10 16:01:35 +01:00
Add Decider impl for Nova onchain (#66)
* Add Decider impl for Nova onchain Add Decider impl for Nova onchain. Update also the Decider trait. Nova onchain decider: (compressed SNARK / final proof), in order to later verify the Nova+CycleFold proofs onchain (in Ethereum’s EVM). * PR review updates and few other changes
This commit is contained in:
@@ -12,6 +12,7 @@ ark-crypto-primitives = { version = "^0.4.0", default-features = false, features
|
|||||||
ark-poly-commit = "^0.4.0"
|
ark-poly-commit = "^0.4.0"
|
||||||
ark-relations = { version = "^0.4.0", default-features = false }
|
ark-relations = { version = "^0.4.0", default-features = false }
|
||||||
ark-r1cs-std = { default-features = false } # use latest version from the patch
|
ark-r1cs-std = { default-features = false } # use latest version from the patch
|
||||||
|
ark-snark = { version = "^0.4.0"}
|
||||||
ark-serialize = "^0.4.0"
|
ark-serialize = "^0.4.0"
|
||||||
ark-circom = { git = "https://github.com/gakonst/ark-circom.git" }
|
ark-circom = { git = "https://github.com/gakonst/ark-circom.git" }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
@@ -26,6 +27,10 @@ espresso_subroutines = {git="https://github.com/EspressoSystems/hyperplonk", pac
|
|||||||
ark-pallas = {version="0.4.0", features=["r1cs"]}
|
ark-pallas = {version="0.4.0", features=["r1cs"]}
|
||||||
ark-vesta = {version="0.4.0", features=["r1cs"]}
|
ark-vesta = {version="0.4.0", features=["r1cs"]}
|
||||||
ark-bn254 = "0.4.0"
|
ark-bn254 = "0.4.0"
|
||||||
|
ark-mnt4-298 = {version="0.4.0", features=["r1cs"]}
|
||||||
|
ark-mnt6-298 = {version="0.4.0", features=["r1cs"]}
|
||||||
|
ark-groth16 = { version = "^0.4.0" }
|
||||||
|
rand = "0.8.5"
|
||||||
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
|
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
|
||||||
tracing-subscriber = { version = "0.2" }
|
tracing-subscriber = { version = "0.2" }
|
||||||
|
|
||||||
@@ -35,7 +40,10 @@ default = ["parallel"]
|
|||||||
parallel = [
|
parallel = [
|
||||||
"ark-std/parallel",
|
"ark-std/parallel",
|
||||||
"ark-ff/parallel",
|
"ark-ff/parallel",
|
||||||
|
"ark-ec/parallel",
|
||||||
"ark-poly/parallel",
|
"ark-poly/parallel",
|
||||||
|
"ark-crypto-primitives/parallel",
|
||||||
|
"ark-r1cs-std/parallel",
|
||||||
]
|
]
|
||||||
|
|
||||||
# The following patch is to use a version of ark-r1cs-std compatible with
|
# The following patch is to use a version of ark-r1cs-std compatible with
|
||||||
|
|||||||
@@ -54,12 +54,26 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// point_to_nonnative_limbs is used to compute (outside the circuit) the limbs representation of a
|
/// Wrapper on top of [`point_to_nonnative_limbs_custom_opt`] which always uses
|
||||||
/// point that matches the one used in-circuit.
|
/// [`OptimizationType::Weight`].
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn point_to_nonnative_limbs<C: CurveGroup>(
|
pub fn point_to_nonnative_limbs<C: CurveGroup>(
|
||||||
p: C,
|
p: C,
|
||||||
) -> Result<(Vec<C::ScalarField>, Vec<C::ScalarField>), SynthesisError>
|
) -> Result<(Vec<C::ScalarField>, Vec<C::ScalarField>), SynthesisError>
|
||||||
|
where
|
||||||
|
<C as ark_ec::CurveGroup>::BaseField: ark_ff::PrimeField,
|
||||||
|
{
|
||||||
|
point_to_nonnative_limbs_custom_opt(p, OptimizationType::Weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to compute (outside the circuit) the limbs representation of a point that matches the one
|
||||||
|
/// used in-circuit, and in particular this method allows to specify which [`OptimizationType`] to
|
||||||
|
/// use.
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
pub fn point_to_nonnative_limbs_custom_opt<C: CurveGroup>(
|
||||||
|
p: C,
|
||||||
|
optimization_type: OptimizationType,
|
||||||
|
) -> Result<(Vec<C::ScalarField>, Vec<C::ScalarField>), SynthesisError>
|
||||||
where
|
where
|
||||||
<C as ark_ec::CurveGroup>::BaseField: ark_ff::PrimeField,
|
<C as ark_ec::CurveGroup>::BaseField: ark_ff::PrimeField,
|
||||||
{
|
{
|
||||||
@@ -68,12 +82,12 @@ where
|
|||||||
let x =
|
let x =
|
||||||
AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
|
AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
|
||||||
&C::BaseField::zero(),
|
&C::BaseField::zero(),
|
||||||
OptimizationType::Weight,
|
optimization_type,
|
||||||
)?;
|
)?;
|
||||||
let y =
|
let y =
|
||||||
AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
|
AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
|
||||||
&C::BaseField::one(),
|
&C::BaseField::one(),
|
||||||
OptimizationType::Weight,
|
optimization_type,
|
||||||
)?;
|
)?;
|
||||||
return Ok((x, y));
|
return Ok((x, y));
|
||||||
}
|
}
|
||||||
@@ -81,11 +95,11 @@ where
|
|||||||
let (x, y) = affine.xy().unwrap();
|
let (x, y) = affine.xy().unwrap();
|
||||||
let x = AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
|
let x = AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
|
||||||
x,
|
x,
|
||||||
OptimizationType::Weight,
|
optimization_type,
|
||||||
)?;
|
)?;
|
||||||
let y = AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
|
let y = AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
|
||||||
y,
|
y,
|
||||||
OptimizationType::Weight,
|
optimization_type,
|
||||||
)?;
|
)?;
|
||||||
Ok((x, y))
|
Ok((x, y))
|
||||||
}
|
}
|
||||||
@@ -94,16 +108,24 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use ark_pallas::{Fr, Projective};
|
use ark_pallas::{Fr, Projective};
|
||||||
use ark_r1cs_std::alloc::AllocVar;
|
use ark_r1cs_std::{alloc::AllocVar, R1CSVar};
|
||||||
use ark_relations::r1cs::ConstraintSystem;
|
use ark_relations::r1cs::ConstraintSystem;
|
||||||
use ark_std::Zero;
|
use ark_std::{UniformRand, Zero};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_alloc_nonnativeaffinevar_zero() {
|
fn test_alloc_nonnativeaffinevar() {
|
||||||
let cs = ConstraintSystem::<Fr>::new_ref();
|
let cs = ConstraintSystem::<Fr>::new_ref();
|
||||||
|
|
||||||
// dealing with the 'zero' point should not panic when doing the unwrap
|
// dealing with the 'zero' point should not panic when doing the unwrap
|
||||||
let p = Projective::zero();
|
let p = Projective::zero();
|
||||||
NonNativeAffineVar::<Fr>::new_witness(cs.clone(), || Ok(p)).unwrap();
|
NonNativeAffineVar::<Fr>::new_witness(cs.clone(), || Ok(p)).unwrap();
|
||||||
|
|
||||||
|
// check that point_to_nonnative_limbs returns the expected values
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
let p = Projective::rand(&mut rng);
|
||||||
|
let pVar = NonNativeAffineVar::<Fr>::new_witness(cs.clone(), || Ok(p)).unwrap();
|
||||||
|
let (x, y) = point_to_nonnative_limbs(p).unwrap();
|
||||||
|
assert_eq!(pVar.x.value().unwrap(), x);
|
||||||
|
assert_eq!(pVar.y.value().unwrap(), y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
205
src/folding/nova/decider_eth.rs
Normal file
205
src/folding/nova/decider_eth.rs
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
/// This file implements the onchain (Ethereum's EVM) decider.
|
||||||
|
use ark_crypto_primitives::sponge::Absorb;
|
||||||
|
use ark_ec::{CurveGroup, Group};
|
||||||
|
use ark_ff::PrimeField;
|
||||||
|
use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar};
|
||||||
|
use ark_snark::SNARK;
|
||||||
|
use ark_std::rand::CryptoRng;
|
||||||
|
use ark_std::rand::RngCore;
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
pub use super::decider_eth_circuit::DeciderEthCircuit;
|
||||||
|
use crate::commitment::{pedersen::Params as PedersenParams, CommitmentProver};
|
||||||
|
use crate::folding::circuits::nonnative::point_to_nonnative_limbs_custom_opt;
|
||||||
|
use crate::folding::nova::{circuits::CF2, CommittedInstance, Nova};
|
||||||
|
use crate::frontend::FCircuit;
|
||||||
|
use crate::Error;
|
||||||
|
use crate::{Decider as DeciderTrait, FoldingScheme};
|
||||||
|
use ark_r1cs_std::fields::nonnative::params::OptimizationType;
|
||||||
|
|
||||||
|
/// Onchain Decider, for ethereum use cases
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Decider<C1, GC1, C2, GC2, FC, CP1, CP2, S, FS> {
|
||||||
|
_c1: PhantomData<C1>,
|
||||||
|
_gc1: PhantomData<GC1>,
|
||||||
|
_c2: PhantomData<C2>,
|
||||||
|
_gc2: PhantomData<GC2>,
|
||||||
|
_fc: PhantomData<FC>,
|
||||||
|
_cp1: PhantomData<CP1>,
|
||||||
|
_cp2: PhantomData<CP2>,
|
||||||
|
_s: PhantomData<S>,
|
||||||
|
_fs: PhantomData<FS>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C1, GC1, C2, GC2, FC, CP1, CP2, S, FS> DeciderTrait<C1, C2, FC, FS>
|
||||||
|
for Decider<C1, GC1, C2, GC2, FC, CP1, CP2, S, FS>
|
||||||
|
where
|
||||||
|
C1: CurveGroup,
|
||||||
|
C2: CurveGroup,
|
||||||
|
GC1: CurveVar<C1, CF2<C1>>,
|
||||||
|
GC2: CurveVar<C2, CF2<C2>>,
|
||||||
|
FC: FCircuit<C1::ScalarField>,
|
||||||
|
CP1: CommitmentProver<C1>,
|
||||||
|
// enforce that the CP2 is Pedersen commitment, since we're at Ethereum's EVM decider
|
||||||
|
CP2: CommitmentProver<C2, Params = PedersenParams<C2>>,
|
||||||
|
S: SNARK<C1::ScalarField>,
|
||||||
|
FS: FoldingScheme<C1, C2, FC>,
|
||||||
|
<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<'b> &'b GC2: GroupOpsBounds<'b, C2, GC2>,
|
||||||
|
// constrain FS into Nova, since this is a Decider specificly for Nova
|
||||||
|
Nova<C1, GC1, C2, GC2, FC, CP1, CP2>: From<FS>,
|
||||||
|
{
|
||||||
|
type ProverParam = S::ProvingKey;
|
||||||
|
type Proof = S::Proof;
|
||||||
|
type VerifierParam = S::VerifyingKey;
|
||||||
|
type PublicInput = Vec<C1::ScalarField>;
|
||||||
|
type CommittedInstanceWithWitness = ();
|
||||||
|
type CommittedInstance = CommittedInstance<C1>;
|
||||||
|
|
||||||
|
fn prove(
|
||||||
|
pp: &Self::ProverParam,
|
||||||
|
mut rng: impl RngCore + CryptoRng,
|
||||||
|
folding_scheme: FS,
|
||||||
|
) -> Result<Self::Proof, Error> {
|
||||||
|
let circuit =
|
||||||
|
DeciderEthCircuit::<C1, GC1, C2, GC2, CP1, CP2>::from_nova::<FC>(folding_scheme.into());
|
||||||
|
|
||||||
|
let proof = S::prove(pp, circuit.clone(), &mut rng).unwrap();
|
||||||
|
|
||||||
|
Ok(proof)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify(
|
||||||
|
vp: &Self::VerifierParam,
|
||||||
|
i: C1::ScalarField,
|
||||||
|
z_0: Vec<C1::ScalarField>,
|
||||||
|
z_i: Vec<C1::ScalarField>,
|
||||||
|
running_instance: &Self::CommittedInstance,
|
||||||
|
proof: Self::Proof,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
let (cmE_x, cmE_y) = point_to_nonnative_limbs_custom_opt::<C1>(
|
||||||
|
running_instance.cmE,
|
||||||
|
OptimizationType::Constraints,
|
||||||
|
)?;
|
||||||
|
let (cmW_x, cmW_y) = point_to_nonnative_limbs_custom_opt::<C1>(
|
||||||
|
running_instance.cmW,
|
||||||
|
OptimizationType::Constraints,
|
||||||
|
)?;
|
||||||
|
let public_input: Vec<C1::ScalarField> = vec![
|
||||||
|
vec![i],
|
||||||
|
z_0,
|
||||||
|
z_i,
|
||||||
|
vec![running_instance.u],
|
||||||
|
running_instance.x.clone(),
|
||||||
|
cmE_x,
|
||||||
|
cmE_y,
|
||||||
|
cmW_x,
|
||||||
|
cmW_y,
|
||||||
|
]
|
||||||
|
.concat();
|
||||||
|
S::verify(vp, &public_input, &proof).map_err(|e| Error::Other(e.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod tests {
|
||||||
|
use super::*;
|
||||||
|
use ark_groth16::Groth16;
|
||||||
|
use ark_mnt4_298::{constraints::G1Var as GVar, Fr, G1Projective as Projective, MNT4_298};
|
||||||
|
use ark_mnt6_298::{constraints::G1Var as GVar2, G1Projective as Projective2};
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use crate::commitment::pedersen::Pedersen;
|
||||||
|
use crate::folding::nova::{get_pedersen_params_len, ProverParams};
|
||||||
|
use crate::frontend::tests::CubicFCircuit;
|
||||||
|
use crate::transcript::poseidon::poseidon_test_config;
|
||||||
|
|
||||||
|
// Note: since we're testing a big circuit, this test takes a bit more of computation and time,
|
||||||
|
// do not run in the normal CI.
|
||||||
|
// To run the test use `--ignored` flag, eg. `cargo test -- --ignored`
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn test_decider() {
|
||||||
|
type NOVA = Nova<
|
||||||
|
Projective,
|
||||||
|
GVar,
|
||||||
|
Projective2,
|
||||||
|
GVar2,
|
||||||
|
CubicFCircuit<Fr>,
|
||||||
|
Pedersen<Projective>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
>;
|
||||||
|
type DECIDER = Decider<
|
||||||
|
Projective,
|
||||||
|
GVar,
|
||||||
|
Projective2,
|
||||||
|
GVar2,
|
||||||
|
CubicFCircuit<Fr>,
|
||||||
|
Pedersen<Projective>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
Groth16<MNT4_298>, // here we define the Snark to use in the decider
|
||||||
|
NOVA, // here we define the FoldingScheme to use
|
||||||
|
>;
|
||||||
|
|
||||||
|
let mut rng = ark_std::test_rng();
|
||||||
|
let poseidon_config = poseidon_test_config::<Fr>();
|
||||||
|
|
||||||
|
let F_circuit = CubicFCircuit::<Fr>::new(());
|
||||||
|
let z_0 = vec![Fr::from(3_u32)];
|
||||||
|
|
||||||
|
let (cm_len, cf_cm_len) =
|
||||||
|
get_pedersen_params_len::<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>>(
|
||||||
|
&poseidon_config,
|
||||||
|
F_circuit,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, cm_len);
|
||||||
|
let cf_pedersen_params = Pedersen::<Projective2>::new_params(&mut rng, cf_cm_len);
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
let prover_params =
|
||||||
|
ProverParams::<Projective, Projective2, Pedersen<Projective>, Pedersen<Projective2>> {
|
||||||
|
poseidon_config: poseidon_config.clone(),
|
||||||
|
cm_params: pedersen_params,
|
||||||
|
cf_cm_params: cf_pedersen_params,
|
||||||
|
};
|
||||||
|
println!("generating pedersen params, {:?}", start.elapsed());
|
||||||
|
|
||||||
|
// use Nova as FoldingScheme
|
||||||
|
let start = Instant::now();
|
||||||
|
let mut nova = NOVA::init(&prover_params, F_circuit, z_0.clone()).unwrap();
|
||||||
|
println!("Nova initialized, {:?}", start.elapsed());
|
||||||
|
let start = Instant::now();
|
||||||
|
nova.prove_step().unwrap();
|
||||||
|
println!("prove_step, {:?}", start.elapsed());
|
||||||
|
|
||||||
|
// generate Groth16 setup
|
||||||
|
let circuit = DeciderEthCircuit::<
|
||||||
|
Projective,
|
||||||
|
GVar,
|
||||||
|
Projective2,
|
||||||
|
GVar2,
|
||||||
|
Pedersen<Projective>,
|
||||||
|
Pedersen<Projective2>,
|
||||||
|
>::from_nova::<CubicFCircuit<Fr>>(nova.clone());
|
||||||
|
let mut rng = rand::rngs::OsRng;
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
let (pk, vk) =
|
||||||
|
Groth16::<MNT4_298>::circuit_specific_setup(circuit.clone(), &mut rng).unwrap();
|
||||||
|
println!("Groth16 setup, {:?}", start.elapsed());
|
||||||
|
|
||||||
|
// decider proof generation
|
||||||
|
let start = Instant::now();
|
||||||
|
let proof = DECIDER::prove(&pk, rng, nova.clone()).unwrap();
|
||||||
|
println!("Decider Groth16 prove, {:?}", start.elapsed());
|
||||||
|
|
||||||
|
// decider proof verification
|
||||||
|
let verified = DECIDER::verify(&vk, nova.i, nova.z_0, nova.z_i, &nova.U_i, proof).unwrap();
|
||||||
|
assert!(verified);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -178,6 +178,7 @@ where
|
|||||||
|
|
||||||
/// Circuit that implements the in-circuit checks needed for the onchain (Ethereum's EVM)
|
/// Circuit that implements the in-circuit checks needed for the onchain (Ethereum's EVM)
|
||||||
/// verification.
|
/// verification.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct DeciderEthCircuit<C1, GC1, C2, GC2, CP1, CP2>
|
pub struct DeciderEthCircuit<C1, GC1, C2, GC2, CP1, CP2>
|
||||||
where
|
where
|
||||||
C1: CurveGroup,
|
C1: CurveGroup,
|
||||||
@@ -281,13 +282,12 @@ where
|
|||||||
Ok(self.r1cs.clone())
|
Ok(self.r1cs.clone())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let i = FpVar::<CF1<C1>>::new_witness(cs.clone(), || {
|
let i =
|
||||||
Ok(self.i.unwrap_or_else(CF1::<C1>::zero))
|
FpVar::<CF1<C1>>::new_input(cs.clone(), || Ok(self.i.unwrap_or_else(CF1::<C1>::zero)))?;
|
||||||
})?;
|
let z_0 = Vec::<FpVar<CF1<C1>>>::new_input(cs.clone(), || {
|
||||||
let z_0 = Vec::<FpVar<CF1<C1>>>::new_witness(cs.clone(), || {
|
|
||||||
Ok(self.z_0.unwrap_or(vec![CF1::<C1>::zero()]))
|
Ok(self.z_0.unwrap_or(vec![CF1::<C1>::zero()]))
|
||||||
})?;
|
})?;
|
||||||
let z_i = Vec::<FpVar<CF1<C1>>>::new_witness(cs.clone(), || {
|
let z_i = Vec::<FpVar<CF1<C1>>>::new_input(cs.clone(), || {
|
||||||
Ok(self.z_i.unwrap_or(vec![CF1::<C1>::zero()]))
|
Ok(self.z_i.unwrap_or(vec![CF1::<C1>::zero()]))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ where
|
|||||||
let w_i = WitnessVar::<C1>::new_witness(cs.clone(), || {
|
let w_i = WitnessVar::<C1>::new_witness(cs.clone(), || {
|
||||||
Ok(self.w_i.unwrap_or(w_dummy_native.clone()))
|
Ok(self.w_i.unwrap_or(w_dummy_native.clone()))
|
||||||
})?;
|
})?;
|
||||||
let U_i = CommittedInstanceVar::<C1>::new_witness(cs.clone(), || {
|
let U_i = CommittedInstanceVar::<C1>::new_input(cs.clone(), || {
|
||||||
Ok(self.U_i.unwrap_or(u_dummy_native.clone()))
|
Ok(self.U_i.unwrap_or(u_dummy_native.clone()))
|
||||||
})?;
|
})?;
|
||||||
let W_i = WitnessVar::<C1>::new_witness(cs.clone(), || {
|
let W_i = WitnessVar::<C1>::new_witness(cs.clone(), || {
|
||||||
@@ -367,7 +367,7 @@ where
|
|||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
{
|
{
|
||||||
// imports here instead of at the top of the file, so we avoid having multiple
|
// imports here instead of at the top of the file, so we avoid having multiple
|
||||||
// `#[cfg(not(test))]
|
// `#[cfg(not(test))]`
|
||||||
use crate::commitment::pedersen::PedersenGadget;
|
use crate::commitment::pedersen::PedersenGadget;
|
||||||
use crate::folding::nova::cyclefold::{CycleFoldCommittedInstanceVar, CF_IO_LEN};
|
use crate::folding::nova::cyclefold::{CycleFoldCommittedInstanceVar, CF_IO_LEN};
|
||||||
use ark_r1cs_std::ToBitsGadget;
|
use ark_r1cs_std::ToBitsGadget;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/// Implements the scheme described in [Nova](https://eprint.iacr.org/2021/370.pdf)
|
/// Implements the scheme described in [Nova](https://eprint.iacr.org/2021/370.pdf) and
|
||||||
|
/// [CycleFold](https://eprint.iacr.org/2023/1192.pdf).
|
||||||
use ark_crypto_primitives::{
|
use ark_crypto_primitives::{
|
||||||
crh::{poseidon::CRH, CRHScheme},
|
crh::{poseidon::CRH, CRHScheme},
|
||||||
sponge::{poseidon::PoseidonConfig, Absorb},
|
sponge::{poseidon::PoseidonConfig, Absorb},
|
||||||
@@ -22,6 +23,7 @@ use crate::FoldingScheme;
|
|||||||
|
|
||||||
pub mod circuits;
|
pub mod circuits;
|
||||||
pub mod cyclefold;
|
pub mod cyclefold;
|
||||||
|
pub mod decider_eth;
|
||||||
pub mod decider_eth_circuit;
|
pub mod decider_eth_circuit;
|
||||||
pub mod nifs;
|
pub mod nifs;
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
@@ -216,10 +218,8 @@ where
|
|||||||
type PreprocessorParam = (Self::ProverParam, FC);
|
type PreprocessorParam = (Self::ProverParam, FC);
|
||||||
type ProverParam = ProverParams<C1, C2, CP1, CP2>;
|
type ProverParam = ProverParams<C1, C2, CP1, CP2>;
|
||||||
type VerifierParam = VerifierParams<C1, C2>;
|
type VerifierParam = VerifierParams<C1, C2>;
|
||||||
type Witness = Witness<C1>;
|
|
||||||
type CommittedInstanceWithWitness = (CommittedInstance<C1>, Witness<C1>);
|
type CommittedInstanceWithWitness = (CommittedInstance<C1>, Witness<C1>);
|
||||||
type CFCommittedInstanceWithWitness = (CommittedInstance<C2>, Witness<C2>);
|
type CFCommittedInstanceWithWitness = (CommittedInstance<C2>, Witness<C2>);
|
||||||
type CommittedInstance = CommittedInstance<C1>;
|
|
||||||
|
|
||||||
fn preprocess(
|
fn preprocess(
|
||||||
prep_param: &Self::PreprocessorParam,
|
prep_param: &Self::PreprocessorParam,
|
||||||
|
|||||||
40
src/lib.rs
40
src/lib.rs
@@ -5,18 +5,18 @@
|
|||||||
|
|
||||||
use ark_ec::CurveGroup;
|
use ark_ec::CurveGroup;
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
|
use ark_std::rand::CryptoRng;
|
||||||
use ark_std::{fmt::Debug, rand::RngCore};
|
use ark_std::{fmt::Debug, rand::RngCore};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::frontend::FCircuit;
|
use crate::frontend::FCircuit;
|
||||||
|
|
||||||
pub mod transcript;
|
|
||||||
use transcript::Transcript;
|
|
||||||
pub mod ccs;
|
pub mod ccs;
|
||||||
pub mod commitment;
|
pub mod commitment;
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub mod folding;
|
pub mod folding;
|
||||||
pub mod frontend;
|
pub mod frontend;
|
||||||
|
pub mod transcript;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
@@ -82,10 +82,8 @@ where
|
|||||||
type PreprocessorParam: Debug;
|
type PreprocessorParam: Debug;
|
||||||
type ProverParam: Debug;
|
type ProverParam: Debug;
|
||||||
type VerifierParam: Debug;
|
type VerifierParam: Debug;
|
||||||
type Witness: Debug;
|
|
||||||
type CommittedInstanceWithWitness: Debug;
|
type CommittedInstanceWithWitness: Debug;
|
||||||
type CFCommittedInstanceWithWitness: Debug; // CycleFold CommittedInstance & Witness
|
type CFCommittedInstanceWithWitness: Debug; // CycleFold CommittedInstance & Witness
|
||||||
type CommittedInstance: Clone + Debug;
|
|
||||||
|
|
||||||
fn preprocess(
|
fn preprocess(
|
||||||
prep_param: &Self::PreprocessorParam,
|
prep_param: &Self::PreprocessorParam,
|
||||||
@@ -123,26 +121,36 @@ where
|
|||||||
) -> Result<(), Error>;
|
) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Decider<C: CurveGroup>: Clone + Debug {
|
pub trait Decider<
|
||||||
type PreprocessorParam: Debug;
|
C1: CurveGroup,
|
||||||
type ProverParam: Debug;
|
C2: CurveGroup,
|
||||||
type VerifierParam: Debug;
|
FC: FCircuit<C1::ScalarField>,
|
||||||
type FreshInstance: Debug;
|
FS: FoldingScheme<C1, C2, FC>,
|
||||||
|
> where
|
||||||
|
C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
|
||||||
|
C2::BaseField: PrimeField,
|
||||||
|
{
|
||||||
|
type ProverParam: Clone;
|
||||||
|
type Proof: Clone;
|
||||||
|
type VerifierParam;
|
||||||
type PublicInput: Debug;
|
type PublicInput: Debug;
|
||||||
type CommittedInstanceWithWitness: Debug;
|
type CommittedInstanceWithWitness: Debug;
|
||||||
type CommittedInstance: Clone + Debug;
|
type CommittedInstance: Clone + Debug;
|
||||||
|
|
||||||
fn prove(
|
fn prove(
|
||||||
pp: &Self::ProverParam,
|
pp: &Self::ProverParam,
|
||||||
running_instance: &Self::CommittedInstanceWithWitness,
|
rng: impl RngCore + CryptoRng,
|
||||||
transcript: &mut impl Transcript<C>,
|
folding_scheme: FS,
|
||||||
rng: impl RngCore,
|
) -> Result<Self::Proof, Error>;
|
||||||
) -> Result<(), Error>;
|
|
||||||
|
|
||||||
fn verify(
|
fn verify(
|
||||||
vp: &Self::VerifierParam,
|
vp: &Self::VerifierParam,
|
||||||
|
i: C1::ScalarField,
|
||||||
|
z_0: Vec<C1::ScalarField>,
|
||||||
|
z_i: Vec<C1::ScalarField>,
|
||||||
running_instance: &Self::CommittedInstance,
|
running_instance: &Self::CommittedInstance,
|
||||||
transcript: &mut impl Transcript<C>,
|
proof: Self::Proof,
|
||||||
rng: impl RngCore,
|
// returns `Result<bool, Error>` to differentiate between an error occurred while performing
|
||||||
) -> Result<(), Error>;
|
// the verification steps, and the verification logic of the scheme not passing.
|
||||||
|
) -> Result<bool, Error>;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user