From ba567dffde3a9335fc7f336c79422c64c3d6b471 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Wed, 19 Apr 2023 22:25:29 +0200 Subject: [PATCH] update vec commitment, add check of comm E, W in NIFS test --- src/nifs.rs | 95 +++++++++++++++++++------------------------------ src/pedersen.rs | 45 +++++++++++------------ src/utils.rs | 6 ++-- 3 files changed, 61 insertions(+), 85 deletions(-) diff --git a/src/nifs.rs b/src/nifs.rs index 893958a..8bc1315 100644 --- a/src/nifs.rs +++ b/src/nifs.rs @@ -3,7 +3,7 @@ use ark_std::ops::Add; use ark_std::One; use std::marker::PhantomData; -use crate::pedersen::{Commitment, CommitmentVec, Params as PedersenParams, Pedersen}; +use crate::pedersen::{Commitment, Params as PedersenParams, Pedersen}; use crate::r1cs::*; use crate::transcript::Transcript; use crate::utils::*; @@ -14,37 +14,28 @@ use ark_std::{ // Phi: φ in the paper (later 𝖴), a folded instance pub struct Phi { - // cmE: CommitmentVec, // TODO not Commitment but directly C (without rE) - cmE: C, + cmE: Commitment, u: C::ScalarField, - // cmW: CommitmentVec, // TODO not Commitment but directly C (without rW) - cmW: C, + cmW: Commitment, x: Vec, } // FWit: Folded Witness pub struct FWit { E: Vec, - rE: C::ScalarField, W: Vec, - rW: C::ScalarField, } impl FWit { - pub fn commit( - &self, - rng: &mut R, - params: &PedersenParams, - x: Vec, - ) -> Phi { - // TODO instead of rand r, use self.rE and self.rW for the commit_vec - let cmE = Pedersen::commit_vec(rng, ¶ms, &self.E); - let cmW = Pedersen::commit_vec(rng, ¶ms, &self.W); + pub fn commit(self, params: &PedersenParams, x: &Vec) -> Phi { + // TODO instead of r_vec, use self.rE and self.rW for the commit + let cmE = Pedersen::commit(¶ms.r_vec, &self.E); + let cmW = Pedersen::commit(¶ms.r_vec, &self.W); Phi { - cmE: cmE.cm, + cmE, u: C::ScalarField::one(), - cmW: cmW.cm, - x, + cmW, + x: x.clone(), } } } @@ -91,19 +82,15 @@ impl NIFS { let E: Vec = vec_add( // this syntax will be simplified with future operators impl (or at least a method // for r-lin) - vec_add(fw1.E.clone(), vector_elem_product(&T, &r)), + &vec_add(&fw1.E, &vector_elem_product(&T, &r)), // rlin(fw1.E.clone(), T, r), - vector_elem_product(&fw2.E, &r2), + &vector_elem_product(&fw2.E, &r2), ); - let rE = fw1.rE + r2 * fw2.rE; // TODO rT - let W = vec_add(fw1.W.clone(), vector_elem_product(&fw2.W, &r)); + let W = vec_add(&fw1.W, &vector_elem_product(&fw2.W, &r)); // let W = rlin(fw1.W.clone(), fw2.W.clone(), r); - let rW = fw1.rW + r * fw2.rW; FWit:: { E: E.into(), - rE, W: W.into(), - rW, } } @@ -111,28 +98,20 @@ impl NIFS { r: C::ScalarField, phi1: Phi, phi2: Phi, - cmT: CommitmentVec, + cmT: Commitment, ) -> Phi { let r2 = r * r; - let cmE = phi1.cmE + cmT.cm.mul(r) + phi2.cmE.mul(r2); + let cmE = phi1.cmE.0 + cmT.0.mul(r) + phi2.cmE.0.mul(r2); let u = phi1.u + r * phi2.u; - let cmW = phi1.cmW + phi2.cmW.mul(r); - let x = vec_add(phi1.x, vector_elem_product(&phi2.x, &r)); + let cmW = phi1.cmW.0 + phi2.cmW.0.mul(r); + let x = vec_add(&phi1.x, &vector_elem_product(&phi2.x, &r)); // let x = rlin(phi1.x, phi2.x, r); Phi:: { - // cmE: Commitment:: { - // cm: cmE.into(), - // r: phi1.cmE.r, - // }, - cmE: cmE.into(), + cmE: Commitment(cmE.into()), u, - // cmW: Commitment:: { - // cm: cmW.into(), - // r: phi1.cmW.r, - // }, - cmW: cmW.into(), + cmW: Commitment(cmW.into()), x, } } @@ -194,44 +173,44 @@ mod tests { .relax(); let T = NIFS::::comp_T(relaxed_r1cs_1, relaxed_r1cs_2, &z1, &z2); - let params = Pedersen::::new_params(&mut rng); - let cmT = Pedersen::commit_vec(&mut rng, ¶ms, &T); + let pedersen_params = Pedersen::::new_params(&mut rng, 100); // 100 is wip, will get it from actual vec + let cmT = Pedersen::commit(&pedersen_params.r_vec, &T); let r = Fr::rand(&mut rng); // this would come from the transcript // WIP TMP let fw1 = FWit:: { E: vec![Fr::zero(); T.len()], - rE: Fr::zero(), W: z1, - rW: Fr::zero(), }; let fw2 = FWit:: { E: vec![Fr::zero(); T.len()], - rE: Fr::zero(), W: z2, - rW: Fr::zero(), }; // fold witness - let folded_witness = NIFS::::fold_witness(r, &fw1, &fw2, T); + let fw3 = NIFS::::fold_witness(r, &fw1, &fw2, T); - let pedersen_params = Pedersen::::new_params(&mut rng); - let phi1 = fw1.commit(&mut rng, &pedersen_params, x1); // wip - let phi2 = fw2.commit(&mut rng, &pedersen_params, x2); + // let pedersen_params = Pedersen::::new_params(&mut rng, 100); // 100 is wip, will get it from actual vec + let phi1 = fw1.commit(&pedersen_params, &x1); // wip + let phi2 = fw2.commit(&pedersen_params, &x2); // fold instance - let folded_instance = NIFS::::fold_instance(r, phi1, phi2, cmT); + let phi3 = NIFS::::fold_instance(r, phi1, phi2, cmT); // naive check that the folded witness satisfies the relaxed r1cs - let Az = matrix_vector_product(&A, &folded_witness.W); - let Bz = matrix_vector_product(&B, &folded_witness.W); - let Cz = matrix_vector_product(&C, &folded_witness.W); + let Az = matrix_vector_product(&A, &fw3.W); + let Bz = matrix_vector_product(&B, &fw3.W); + let Cz = matrix_vector_product(&C, &fw3.W); assert_eq!( hadamard_product(Az, Bz), - vec_add( - vector_elem_product(&Cz, &folded_instance.u), - folded_witness.E - ) + vec_add(&vector_elem_product(&Cz, &phi3.u), &fw3.E) ); + + // check that folded commitments from folded instance (phi) are equal to folding the + // witnesses and committing into it + let x3 = vec_add(&x1, &vector_elem_product(&x2, &r)); + let phi3_expected = fw3.commit(&pedersen_params, &x3); + assert_eq!(phi3_expected.cmE.0, phi3.cmE.0); + assert_eq!(phi3_expected.cmW.0, phi3.cmW.0); } } diff --git a/src/pedersen.rs b/src/pedersen.rs index 202934e..a44915f 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -17,6 +17,7 @@ pub struct Proof { pub struct Params { g: C, h: C, + pub r_vec: Vec, } pub struct Pedersen { @@ -24,12 +25,14 @@ pub struct Pedersen { } impl Pedersen { - pub fn new_params(rng: &mut R) -> Params { + pub fn new_params(rng: &mut R, max: usize) -> Params { let h_scalar = C::ScalarField::rand(rng); let g: C = C::generator(); + let r_vec: Vec = vec![C::rand(rng); max]; let params: Params = Params:: { g, h: g.mul(h_scalar).into(), + r_vec, // will need 2 r: rE, rW }; params } @@ -38,22 +41,17 @@ impl Pedersen { rng: &mut R, params: &Params, v: &C::ScalarField, - ) -> Commitment { + ) -> CommitmentElem { let r = C::ScalarField::rand(rng); let cm: C = (params.g.mul(v) + params.h.mul(r)).into(); - Commitment:: { cm, r } + CommitmentElem:: { cm, r } } - pub fn commit_vec( - rng: &mut R, - params: &Params, - v: &Vec, - ) -> CommitmentVec { - let r: Vec = vec![C::rand(rng); v.len()]; // wip - let cm = naive_msm(v, &r); - CommitmentVec:: { cm, r } + pub fn commit(rs: &Vec, v: &Vec) -> Commitment { + let cm = naive_msm(v, &rs); + Commitment::(cm) } - pub fn prove( + pub fn prove_elem( params: &Params, transcript: &mut Transcript, cm: C, @@ -75,7 +73,7 @@ impl Pedersen { Proof:: { R, t1, t2 } } - pub fn verify( + pub fn verify_elem( params: &Params, transcript: &mut Transcript, cm: C, @@ -97,23 +95,20 @@ impl Pedersen { } } -pub struct CommitmentVec { - // WIP - pub cm: C, - pub r: Vec, -} -pub struct Commitment { +pub struct Commitment(pub C); + +pub struct CommitmentElem { pub cm: C, pub r: C::ScalarField, } -impl Commitment { +impl CommitmentElem { pub fn prove( &self, params: &Params, transcript: &mut Transcript, v: C::ScalarField, ) -> Proof { - Pedersen::::prove(params, transcript, self.cm, v, self.r) + Pedersen::::prove_elem(params, transcript, self.cm, v, self.r) } } @@ -129,7 +124,9 @@ mod tests { let mut rng = ark_std::test_rng(); // setup params - let params = Pedersen::::new_params(&mut rng); + let params = Pedersen::::new_params( + &mut rng, 0, /* 0, as here we don't use commit_vec */ + ); // init Prover's transcript let mut transcript_p: Transcript = Transcript::::new(); @@ -141,8 +138,8 @@ mod tests { let cm = Pedersen::commit_elem(&mut rng, ¶ms, &v); let proof = cm.prove(¶ms, &mut transcript_p, v); // also can use: - // let proof = Pedersen::prove(¶ms, &mut transcript_p, cm.cm, v, cm.r); - let v = Pedersen::verify(¶ms, &mut transcript_v, cm.cm, proof); + // let proof = Pedersen::prove_elem(¶ms, &mut transcript_p, cm.cm, v, cm.r); + let v = Pedersen::verify_elem(¶ms, &mut transcript_v, cm.cm, proof); assert!(v); } } diff --git a/src/utils.rs b/src/utils.rs index 4618150..0af04d8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -37,7 +37,7 @@ pub fn hadamard_product(a: Vec, b: Vec) -> Vec { // } pub fn naive_msm(s: &Vec, p: &Vec) -> C { - // check lengths + // TODO check lengths, or at least check s.len()>= p.len() let mut r = p[0].mul(s[0]); for i in 1..s.len() { @@ -46,7 +46,7 @@ pub fn naive_msm(s: &Vec, p: &Vec) -> C { r.into() } -pub fn vec_add(a: Vec, b: Vec) -> Vec { +pub fn vec_add(a: &Vec, b: &Vec) -> Vec { let mut r: Vec = vec![F::zero(); a.len()]; for i in 0..a.len() { r[i] = a[i] + b[i]; @@ -155,7 +155,7 @@ mod tests { fn test_vec_add() { let a: Vec = to_F_vec::(vec![1, 2, 3, 4, 5, 6]); let b: Vec = to_F_vec(vec![7, 8, 9, 10, 11, 12]); - assert_eq!(vec_add(a.clone(), b.clone()), (Ve(a) + Ve(b)).0); + assert_eq!(vec_add(&a, &b), (Ve(a) + Ve(b)).0); } #[test]