Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into introducing_mova
Browse files Browse the repository at this point in the history
  • Loading branch information
NiDimi committed Oct 16, 2024
2 parents 9e60b9d + cb1b8e3 commit 9f9361b
Show file tree
Hide file tree
Showing 43 changed files with 4,005 additions and 2,277 deletions.
1 change: 1 addition & 0 deletions .github/workflows/typos.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[default.extend-words]
groth = "groth"
mimc = "mimc"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ solidity-verifiers/generated
examples/*.sol
examples/*.calldata
examples/*.inputs
*.serialized
*/*.serialized
11 changes: 10 additions & 1 deletion examples/circom_full_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ fn main() {
let mut nova = N::init(&nova_params, f_circuit.clone(), z_0).unwrap();

// prepare the Decider prover & verifier params
let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone()).unwrap();
let (decider_pp, decider_vp) =
D::preprocess(&mut rng, nova_params.clone(), nova.clone()).unwrap();

// run n steps of the folding iteration
for (i, external_inputs_at_step) in external_inputs.iter().enumerate() {
Expand All @@ -99,6 +100,14 @@ fn main() {
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}

// verify the last IVC proof
let ivc_proof = nova.ivc_proof();
N::verify(
nova_params.1, // Nova's verifier params
ivc_proof,
)
.unwrap();

let start = Instant::now();
let proof = D::prove(rng, decider_pp, nova.clone()).unwrap();
println!("generated Decider proof: {:?}", start.elapsed());
Expand Down
12 changes: 3 additions & 9 deletions examples/external_inputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,11 @@ fn main() {
folding_scheme.state()
);

let (running_instance, incoming_instance, cyclefold_instance) = folding_scheme.instances();

println!("Run the Nova's IVC verifier");
let ivc_proof = folding_scheme.ivc_proof();
N::verify(
nova_params.1,
initial_state.clone(),
folding_scheme.state(), // latest state
Fr::from(num_steps as u32),
running_instance,
incoming_instance,
cyclefold_instance,
nova_params.1, // Nova's verifier params
ivc_proof,
)
.unwrap();
}
12 changes: 3 additions & 9 deletions examples/multi_inputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,11 @@ fn main() {
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}

let (running_instance, incoming_instance, cyclefold_instance) = folding_scheme.instances();

println!("Run the Nova's IVC verifier");
let ivc_proof = folding_scheme.ivc_proof();
N::verify(
nova_params.1,
initial_state.clone(),
folding_scheme.state(), // latest state
Fr::from(num_steps as u32),
running_instance,
incoming_instance,
cyclefold_instance,
nova_params.1, // Nova's verifier params
ivc_proof,
)
.unwrap();
}
10 changes: 9 additions & 1 deletion examples/noir_full_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,22 @@ fn main() {
let mut nova = N::init(&nova_params, f_circuit.clone(), z_0).unwrap();

// prepare the Decider prover & verifier params
let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone()).unwrap();
let (decider_pp, decider_vp) =
D::preprocess(&mut rng, nova_params.clone(), nova.clone()).unwrap();

// run n steps of the folding iteration
for i in 0..5 {
let start = Instant::now();
nova.prove_step(rng, vec![], None).unwrap();
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}
// verify the last IVC proof
let ivc_proof = nova.ivc_proof();
N::verify(
nova_params.1, // Nova's verifier params
ivc_proof,
)
.unwrap();

let start = Instant::now();
let proof = D::prove(rng, decider_pp, nova.clone()).unwrap();
Expand Down
11 changes: 10 additions & 1 deletion examples/noname_full_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ fn main() {
let mut nova = N::init(&nova_params, f_circuit.clone(), z_0).unwrap();

// prepare the Decider prover & verifier params
let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone()).unwrap();
let (decider_pp, decider_vp) =
D::preprocess(&mut rng, nova_params.clone(), nova.clone()).unwrap();

// run n steps of the folding iteration
for (i, external_inputs_at_step) in external_inputs.iter().enumerate() {
Expand All @@ -99,6 +100,14 @@ fn main() {
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}

// verify the last IVC proof
let ivc_proof = nova.ivc_proof();
N::verify(
nova_params.1, // Nova's verifier params
ivc_proof,
)
.unwrap();

let start = Instant::now();
let proof = D::prove(rng, decider_pp, nova.clone()).unwrap();
println!("generated Decider proof: {:?}", start.elapsed());
Expand Down
12 changes: 3 additions & 9 deletions examples/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,11 @@ fn main() {
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}

let (running_instance, incoming_instance, cyclefold_instance) = folding_scheme.instances();

println!("Run the Nova's IVC verifier");
let ivc_proof = folding_scheme.ivc_proof();
N::verify(
nova_params.1,
initial_state,
folding_scheme.state(), // latest state
Fr::from(num_steps as u32),
running_instance,
incoming_instance,
cyclefold_instance,
nova_params.1, // Nova's verifier params
ivc_proof,
)
.unwrap();
}
4 changes: 4 additions & 0 deletions folding-schemes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ ark-pallas = {version="0.4.0", features=["r1cs"]}
ark-vesta = {version="0.4.0", features=["r1cs"]}
ark-bn254 = {version="0.4.0", features=["r1cs"]}
ark-grumpkin = {version="0.4.0", features=["r1cs"]}
# Note: do not use the MNTx_298 curves in practice due security reasons, here
# we only use them in the tests.
ark-mnt4-298 = {version="0.4.0", features=["r1cs"]}
ark-mnt6-298 = {version="0.4.0", features=["r1cs"]}
rand = "0.8.5"
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
tracing-subscriber = { version = "0.2" }
Expand Down
65 changes: 39 additions & 26 deletions folding-schemes/src/arith/ccs.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use ark_ff::PrimeField;
use ark_std::log2;

use crate::utils::vec::{hadamard, mat_vec_mul, vec_add, vec_scalar_mul, SparseMatrix};
use crate::utils::vec::{
hadamard, is_zero_vec, mat_vec_mul, vec_add, vec_scalar_mul, SparseMatrix,
};
use crate::Error;

use super::ArithSerializer;
use super::{r1cs::R1CS, Arith};

/// CCS represents the Customizable Constraint Systems structure defined in
Expand Down Expand Up @@ -35,8 +38,9 @@ pub struct CCS<F: PrimeField> {
pub c: Vec<F>,
}

impl<F: PrimeField> Arith<F> for CCS<F> {
fn eval_relation(&self, z: &[F]) -> Result<Vec<F>, Error> {
impl<F: PrimeField> CCS<F> {
/// Evaluates the CCS relation at a given vector of assignments `z`
pub fn eval_at_z(&self, z: &[F]) -> Result<Vec<F>, Error> {
let mut result = vec![F::zero(); self.m];

for i in 0..self.q {
Expand All @@ -59,6 +63,25 @@ impl<F: PrimeField> Arith<F> for CCS<F> {
Ok(result)
}

/// returns a tuple containing (w, x) (witness and public inputs respectively)
pub fn split_z(&self, z: &[F]) -> (Vec<F>, Vec<F>) {
(z[self.l + 1..].to_vec(), z[1..self.l + 1].to_vec())
}
}

impl<F: PrimeField, W: AsRef<[F]>, U: AsRef<[F]>> Arith<W, U> for CCS<F> {
type Evaluation = Vec<F>;

fn eval_relation(&self, w: &W, u: &U) -> Result<Self::Evaluation, Error> {
self.eval_at_z(&[&[F::one()], u.as_ref(), w.as_ref()].concat())
}

fn check_evaluation(_w: &W, _u: &U, e: Self::Evaluation) -> Result<(), Error> {
is_zero_vec(&e).then_some(()).ok_or(Error::NotSatisfied)
}
}

impl<F: PrimeField> ArithSerializer for CCS<F> {
fn params_to_le_bytes(&self) -> Vec<u8> {
[
self.l.to_le_bytes(),
Expand All @@ -72,14 +95,14 @@ impl<F: PrimeField> Arith<F> for CCS<F> {
}
}

impl<F: PrimeField> CCS<F> {
pub fn from_r1cs(r1cs: R1CS<F>) -> Self {
let m = r1cs.A.n_rows;
let n = r1cs.A.n_cols;
impl<F: PrimeField> From<R1CS<F>> for CCS<F> {
fn from(r1cs: R1CS<F>) -> Self {
let m = r1cs.num_constraints();
let n = r1cs.num_variables();
CCS {
m,
n,
l: r1cs.l,
l: r1cs.num_public_inputs(),
s: log2(m) as usize,
s_prime: log2(n) as usize,
t: 3,
Expand All @@ -91,29 +114,19 @@ impl<F: PrimeField> CCS<F> {
M: vec![r1cs.A, r1cs.B, r1cs.C],
}
}

pub fn to_r1cs(self) -> R1CS<F> {
R1CS::<F> {
l: self.l,
A: self.M[0].clone(),
B: self.M[1].clone(),
C: self.M[2].clone(),
}
}
}

#[cfg(test)]
pub mod tests {
use super::*;
use crate::{
arith::r1cs::tests::{get_test_r1cs, get_test_z as r1cs_get_test_z},
arith::r1cs::tests::{get_test_r1cs, get_test_z as r1cs_get_test_z, get_test_z_split},
utils::vec::is_zero_vec,
};
use ark_pallas::Fr;

pub fn get_test_ccs<F: PrimeField>() -> CCS<F> {
let r1cs = get_test_r1cs::<F>();
CCS::<F>::from_r1cs(r1cs)
get_test_r1cs::<F>().into()
}
pub fn get_test_z<F: PrimeField>(input: usize) -> Vec<F> {
r1cs_get_test_z(input)
Expand All @@ -122,22 +135,22 @@ pub mod tests {
#[test]
fn test_eval_ccs_relation() {
let ccs = get_test_ccs::<Fr>();
let mut z = get_test_z(3);
let (_, x, mut w) = get_test_z_split(3);

let f_w = ccs.eval_relation(&z).unwrap();
let f_w = ccs.eval_relation(&w, &x).unwrap();
assert!(is_zero_vec(&f_w));

z[1] = Fr::from(111);
let f_w = ccs.eval_relation(&z).unwrap();
w[1] = Fr::from(111);
let f_w = ccs.eval_relation(&w, &x).unwrap();
assert!(!is_zero_vec(&f_w));
}

/// Test that a basic CCS relation can be satisfied
#[test]
fn test_check_ccs_relation() {
let ccs = get_test_ccs::<Fr>();
let z = get_test_z(3);
let (_, x, w) = get_test_z_split(3);

ccs.check_relation(&z).unwrap();
ccs.check_relation(&w, &x).unwrap();
}
}
Loading

0 comments on commit 9f9361b

Please sign in to comment.