Skip to content

Commit

Permalink
Add DeciderEnabledNIFS::fold_group_elements_native to wrap code for…
Browse files Browse the repository at this point in the history
… folding commitments
  • Loading branch information
winderica committed Oct 14, 2024
1 parent a8f3449 commit 7add907
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 39 deletions.
23 changes: 18 additions & 5 deletions folding-schemes/src/folding/circuits/decider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ impl EvalGadget {
}
}

/// This is a temporary workaround for step 8 (running NIFS.V in circuit) in a
/// folding scheme-agnostic way, as different folding schemes have different
/// interfaces of folding verification now.
/// This is a temporary workaround for step 6 (running NIFS.V for group elements
/// in circuit) in an NIFS-agnostic way, because different folding schemes have
/// different interfaces of folding verification now.
///
/// In the future, we may introduce a better solution that use a trait for all
/// In the future, we may introduce a better solution that uses a trait for all
/// folding schemes that specifies their native and in-circuit behaviors.
pub trait DeciderEnabledNIFS<
C: CurveGroup,
Expand All @@ -107,8 +107,12 @@ pub trait DeciderEnabledNIFS<
type RandomnessDummyCfg;
type Randomness: Dummy<Self::RandomnessDummyCfg>;

/// Fold the field elements in `U` and `u` inside the circuit.
///
/// `U_vec` is `U` expressed as a vector of `FpVar`s, which can be reused
/// before or after calling this function to save constraints.
#[allow(clippy::too_many_arguments)]
fn fold_gadget(
fn fold_field_elements_gadget(
arith: &A,
transcript: &mut PoseidonSpongeVar<CF1<C>>,
pp_hash: FpVar<CF1<C>>,
Expand All @@ -118,6 +122,15 @@ pub trait DeciderEnabledNIFS<
proof: Self::Proof,
randomness: Self::Randomness,
) -> Result<RU::Var, SynthesisError>;

/// Fold the group elements (i.e., commitments) in `U` and `u` outside the
/// circuit.
fn fold_group_elements_native(
U_commitments: &[C],
u_commitments: &[C],
proof: Option<Self::Proof>,
randomness: Self::Randomness,
) -> Result<Vec<C>, Error>;
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion folding-schemes/src/folding/circuits/decider/off_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ where
u_i.get_public_inputs().enforce_equal(&[u_i_x, cf_u_i_x])?;

// 6.1. partially enforce `NIFS.V(U_i, u_i) = U_{i+1}`.
D::fold_gadget(
D::fold_field_elements_gadget(
&self.arith,
&mut transcript,
pp_hash,
Expand Down
2 changes: 1 addition & 1 deletion folding-schemes/src/folding/circuits/decider/on_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ where
}

// 6.1. partially enforce `NIFS.V(U_i, u_i) = U_{i+1}`.
D::fold_gadget(
D::fold_field_elements_gadget(
&self.arith,
&mut transcript,
pp_hash,
Expand Down
11 changes: 8 additions & 3 deletions folding-schemes/src/folding/hypernova/decider_eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ use ark_std::{One, Zero};
use core::marker::PhantomData;

pub use super::decider_eth_circuit::DeciderEthCircuit;
use super::decider_eth_circuit::DeciderHyperNovaGadget;
use super::HyperNova;
use crate::commitment::{
kzg::Proof as KZGProof, pedersen::Params as PedersenParams, CommitmentScheme,
};
use crate::folding::circuits::decider::DeciderEnabledNIFS;
use crate::folding::circuits::CF2;
use crate::folding::nova::decider_eth::VerifierParam;
use crate::folding::traits::{Inputize, WitnessOps};
Expand Down Expand Up @@ -187,9 +189,12 @@ where
} = vp;

// 6.2. Fold the commitments
let U_C = running_commitments[0];
let u_C = incoming_commitments[0];
let C = U_C + u_C.mul(proof.rho);
let C = DeciderHyperNovaGadget::fold_group_elements_native(
running_commitments,
incoming_commitments,
None,
proof.rho,
)?[0];

// Note: the NIMFS proof is checked inside the DeciderEthCircuit, which ensures that the
// 'proof.U_i1' is correctly computed
Expand Down
14 changes: 13 additions & 1 deletion folding-schemes/src/folding/hypernova/decider_eth_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ where
type Randomness = CF1<C>;
type RandomnessDummyCfg = ();

fn fold_gadget(
fn fold_field_elements_gadget(
arith: &CCS<CF1<C>>,
transcript: &mut PoseidonSpongeVar<CF1<C>>,
pp_hash: FpVar<CF1<C>>,
Expand All @@ -220,6 +220,18 @@ where
Boolean::le_bits_to_fp_var(&rho_bits)?.enforce_equal(&rho)?;
Ok(computed_U_i1)
}

fn fold_group_elements_native(
U_commitments: &[C],
u_commitments: &[C],
_: Option<Self::Proof>,
r: Self::Randomness,
) -> Result<Vec<C>, Error> {
let U_C = U_commitments[0];
let u_C = u_commitments[0];
let C = U_C + u_C.mul(r);
Ok(vec![C])
}
}

#[cfg(test)]
Expand Down
25 changes: 13 additions & 12 deletions folding-schemes/src/folding/nova/decider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ use ark_std::{One, Zero};
use core::marker::PhantomData;

use super::decider_circuits::{DeciderCircuit1, DeciderCircuit2};
use super::decider_eth_circuit::DeciderNovaGadget;
use super::Nova;
use crate::commitment::CommitmentScheme;
use crate::folding::circuits::decider::DeciderEnabledNIFS;
use crate::folding::circuits::{
cyclefold::{CycleFoldCommittedInstance, CycleFoldCommittedInstanceVar},
CF2,
Expand Down Expand Up @@ -255,24 +257,23 @@ where
}

// 6.2. Fold the commitments
let U_cmW = running_commitments[0];
let U_cmE = running_commitments[1];
let u_cmW = incoming_commitments[0];
let u_cmE = incoming_commitments[1];
if !u_cmE.is_zero() {
return Err(Error::NotIncomingCommittedInstance);
}
let cmW = U_cmW + u_cmW.mul(proof.r);
let cmE = U_cmE + proof.cmT.mul(proof.r);
let U_final_commitments = DeciderNovaGadget::fold_group_elements_native(
running_commitments,
incoming_commitments,
Some(proof.cmT),
proof.r,
)?;
let cf_U = proof.cf_U_final.clone();

// snark proof 1
let c1_public_input = [
&[vp.pp_hash, i][..],
&z_0,
&z_i,
&cmW.inputize(),
&cmE.inputize(),
&U_final_commitments
.iter()
.flat_map(|c| c.inputize())
.collect::<Vec<_>>(),
&Inputize::<CF2<C2>, CycleFoldCommittedInstanceVar<C2, GC2>>::inputize(&cf_U),
&proof.cs1_challenges,
&proof.cs1_proofs.iter().map(|p| p.eval).collect::<Vec<_>>(),
Expand Down Expand Up @@ -306,7 +307,7 @@ where
}

// 7.3. check C1 commitments (main instance commitments)
for ((cm, &c), pi) in [cmW, cmE]
for ((cm, &c), pi) in U_final_commitments
.iter()
.zip(&proof.cs1_challenges)
.zip(&proof.cs1_proofs)
Expand Down
25 changes: 13 additions & 12 deletions folding-schemes/src/folding/nova/decider_eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ use ark_std::{One, Zero};
use core::marker::PhantomData;

pub use super::decider_eth_circuit::DeciderEthCircuit;
use super::decider_eth_circuit::DeciderNovaGadget;
use super::{CommittedInstance, Nova};
use crate::commitment::{
kzg::{Proof as KZGProof, KZG},
pedersen::Params as PedersenParams,
CommitmentScheme,
};
use crate::folding::circuits::decider::DeciderEnabledNIFS;
use crate::folding::circuits::CF2;
use crate::folding::traits::{Inputize, WitnessOps};
use crate::frontend::FCircuit;
Expand Down Expand Up @@ -203,22 +205,21 @@ where
} = vp;

// 6.2. Fold the commitments
let U_cmW = running_commitments[0];
let U_cmE = running_commitments[1];
let u_cmW = incoming_commitments[0];
let u_cmE = incoming_commitments[1];
if !u_cmE.is_zero() {
return Err(Error::NotIncomingCommittedInstance);
}
let cmW = U_cmW + u_cmW.mul(proof.r);
let cmE = U_cmE + proof.cmT.mul(proof.r);
let U_final_commitments = DeciderNovaGadget::fold_group_elements_native(
running_commitments,
incoming_commitments,
Some(proof.cmT),
proof.r,
)?;

let public_input = [
&[pp_hash, i][..],
&z_0,
&z_i,
&cmW.inputize(),
&cmE.inputize(),
&U_final_commitments
.iter()
.flat_map(|c| c.inputize())
.collect::<Vec<_>>(),
&proof.kzg_challenges,
&proof.kzg_proofs.iter().map(|p| p.eval).collect::<Vec<_>>(),
&proof.cmT.inputize(),
Expand All @@ -233,7 +234,7 @@ where
}

// 7.3. Verify the KZG proofs
for ((cm, &c), pi) in [cmW, cmE]
for ((cm, &c), pi) in U_final_commitments
.iter()
.zip(&proof.kzg_challenges)
.zip(&proof.kzg_proofs)
Expand Down
21 changes: 20 additions & 1 deletion folding-schemes/src/folding/nova/decider_eth_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ where
type RandomnessDummyCfg = ();
type Randomness = CF1<C>;

fn fold_gadget(
fn fold_field_elements_gadget(
_arith: &R1CS<CF1<C>>,
transcript: &mut PoseidonSpongeVar<CF1<C>>,
pp_hash: FpVar<CF1<C>>,
Expand All @@ -213,6 +213,25 @@ where

NIFSGadget::<C>::fold_committed_instance(r, U, u)
}

fn fold_group_elements_native(
U_commitments: &[C],
u_commitments: &[C],
cmT: Option<Self::Proof>,
r: Self::Randomness,
) -> Result<Vec<C>, Error> {
let cmT = cmT.ok_or(Error::Empty)?;
let U_cmW = U_commitments[0];
let U_cmE = U_commitments[1];
let u_cmW = u_commitments[0];
let u_cmE = u_commitments[1];
if !u_cmE.is_zero() {
return Err(Error::NotIncomingCommittedInstance);
}
let cmW = U_cmW + u_cmW.mul(r);
let cmE = U_cmE + cmT.mul(r);
Ok(vec![cmW, cmE])
}
}

#[cfg(test)]
Expand Down
17 changes: 14 additions & 3 deletions folding-schemes/src/folding/protogalaxy/decider_eth_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl<C: CurveGroup>
type Randomness = Vec<CF1<C>>;
type RandomnessDummyCfg = usize;

fn fold_gadget(
fn fold_field_elements_gadget(
_arith: &R1CS<CF1<C>>,
transcript: &mut PoseidonSpongeVar<CF1<C>>,
_pp_hash: FpVar<CF1<C>>,
Expand All @@ -178,14 +178,25 @@ impl<C: CurveGroup>
let cs = transcript.cs();
let F_coeffs = Vec::new_witness(cs.clone(), || Ok(&proof.F_coeffs[..]))?;
let K_coeffs = Vec::new_witness(cs.clone(), || Ok(&proof.K_coeffs[..]))?;
let challenge = Vec::new_input(cs.clone(), || Ok(randomness))?;
let randomness = Vec::new_input(cs.clone(), || Ok(randomness))?;

let (U_next, L_X_evals) =
FoldingGadget::fold_committed_instance(transcript, &U, &[u], F_coeffs, K_coeffs)?;
L_X_evals.enforce_equal(&challenge)?;
L_X_evals.enforce_equal(&randomness)?;

Ok(U_next)
}

fn fold_group_elements_native(
U_commitments: &[C],
u_commitments: &[C],
_: Option<Self::Proof>,
L_X_evals: Self::Randomness,
) -> Result<Vec<C>, Error> {
let U_phi = U_commitments[0];
let u_phi = u_commitments[0];
Ok(vec![U_phi * L_X_evals[0] + u_phi * L_X_evals[1]])
}
}

#[cfg(test)]
Expand Down

0 comments on commit 7add907

Please sign in to comment.