Skip to content

Commit

Permalink
feat: implemented all checks, need to spec cyclefold
Browse files Browse the repository at this point in the history
  • Loading branch information
dmpierre committed Jul 16, 2024
1 parent 2dd78a3 commit 966bb20
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
13 changes: 11 additions & 2 deletions folding-schemes/src/folding/nova/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -938,8 +938,17 @@ pub mod tests {
>(poseidon_config.clone(), F_circuit);

let proof = RandomizedIVCProof::new(&nova, &mut rng).unwrap();
let verify =
RandomizedIVCProof::verify::<Pedersen<Projective, true>>(nova.r1cs, &proof).unwrap();
let pp_hash = nova.pp_hash;
let verify = RandomizedIVCProof::verify::<Pedersen<Projective, true>>(
nova.r1cs,
nova.pp_hash,
nova.poseidon_config,
nova.i,
nova.z_0,
nova.z_i,
&proof,
)
.unwrap();
}

/// This test tests the Nova+CycleFold IVC, and by consequence it is also testing the
Expand Down
44 changes: 36 additions & 8 deletions folding-schemes/src/folding/nova/zk.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// specifies nova's zero-knowledge layer, as described in https://eprint.iacr.org/2023/573.pdf

use ark_std::UniformRand;
use rayon::vec;
use ark_crypto_primitives::sponge::CryptographicSponge;
use ark_ff::PrimeField;
use ark_std::{One, UniformRand, Zero};

use crate::{
arith::r1cs::{RelaxedR1CS, R1CS},
RngCore,
};
use ark_crypto_primitives::sponge::Absorb;
use ark_crypto_primitives::sponge::{
poseidon::{PoseidonConfig, PoseidonSponge},
Absorb,
};
use ark_ec::{CurveGroup, Group};
use ark_r1cs_std::{groups::CurveVar, ToConstraintFieldGadget};

Expand All @@ -31,7 +35,8 @@ pub struct RandomizedIVCProof<C1: CurveGroup> {

impl<C1: CurveGroup> RandomizedIVCProof<C1>
where
C1::ScalarField: Absorb,
<C1 as Group>::ScalarField: Absorb,
<C1 as CurveGroup>::BaseField: PrimeField,
{
pub fn new<
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
Expand All @@ -43,10 +48,7 @@ where
>(
nova: &Nova<C1, GC1, C2, GC2, FC, CS1, CS2, true>,
mut rng: impl RngCore,
) -> Result<RandomizedIVCProof<C1>, Error>
where
<C1 as Group>::ScalarField: Absorb,
{
) -> Result<RandomizedIVCProof<C1>, Error> {
// 1. Compute $U_f$ and $\pi$, proof consisting of ($\bar{T}, r$)
let (T, cmT) = NIFS::<C1, CS1, true>::compute_cmT(
&nova.cs_pp,
Expand Down Expand Up @@ -132,23 +134,49 @@ where
}
pub fn verify<CS1: CommitmentScheme<C1, true>>(
r1cs: R1CS<C1::ScalarField>,
pp_hash: C1::ScalarField,
poseidon_config: PoseidonConfig<C1::ScalarField>,
i: C1::ScalarField,
z_0: Vec<C1::ScalarField>,
z_i: Vec<C1::ScalarField>,
proof: &RandomizedIVCProof<C1>,
) -> Result<(), Error>
where
<C1 as Group>::ScalarField: Absorb,
{
if i == C1::ScalarField::zero() {
if z_0 == z_i {
()
} else {
return Err(Error::zkIVCVerificationFail);
}
}

let sponge = PoseidonSponge::<C1::ScalarField>::new(&poseidon_config);

let expected_u_i_x = proof.U_i.hash(&sponge, pp_hash, i, z_0, z_i);
if expected_u_i_x != proof.u_i.x[0] {
return Err(Error::zkIVCVerificationFail);
}

if !proof.u_i.cmE.is_zero() || proof.u_i.u != C1::ScalarField::one() {
return Err(Error::zkIVCVerificationFail);
}

let U_f = NIFS::<C1, CS1, true>::fold_committed_instance(
proof.pi.r,
&proof.u_i,
&proof.U_i,
&proof.pi.cmT,
);

let U_i_prime = NIFS::<C1, CS1, true>::fold_committed_instance(
proof.pi_prime.r,
&U_f,
&proof.U_r,
&proof.pi_prime.cmT,
);

let mut z = vec![U_i_prime.u];
z.extend(&U_i_prime.x);
z.extend(&proof.W_i_prime.W);
Expand Down
2 changes: 2 additions & 0 deletions folding-schemes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ pub enum Error {
SNARKVerificationFail,
#[error("IVC verification failed")]
IVCVerificationFail,
#[error("zkIVC verification failed")]
zkIVCVerificationFail,
#[error("R1CS instance is expected to not be relaxed")]
R1CSUnrelaxedFail,
#[error("Could not find the inner ConstraintSystem")]
Expand Down

0 comments on commit 966bb20

Please sign in to comment.