From c6d42a83563ad4978c15d6eeefe1cb1efb863afc Mon Sep 17 00:00:00 2001 From: arnaucube Date: Mon, 31 Jul 2023 21:10:37 +0200 Subject: [PATCH] rm unused pedersen.rs methods, some more polishing --- Cargo.toml | 1 - README.md | 10 +++-- src/lib.rs | 2 - src/pedersen.rs | 106 +-------------------------------------------- src/protogalaxy.rs | 81 +++++++++++++++++----------------- src/utils.rs | 20 +++++---- 6 files changed, 59 insertions(+), 161 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 13189cf..c68fe1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ ark-ec = { version = "0.4.0", default-features = false } ark-poly = "0.4.0" ark-serialize = { version = "0.4.0", default-features = false, features = [ "derive" ] } rand = { version = "0.8", features = [ "std", "std_rng" ] } -merlin = { version = "3.0.0" } ark-crypto-primitives = { version = "^0.4.0", default-features = false, features = [ "r1cs", "snark", "sponge", "crh" ] } [dev-dependencies] diff --git a/README.md b/README.md index 1666021..2486e78 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Proof of concept implementation of ProtoGalaxy (https://eprint.iacr.org/2023/1106.pdf) using [arkworks](https://github.com/arkworks-rs). -> Do not use in production. +> Experimental code, do not use in production. Thanks to [Liam Eagen](https://twitter.com/LiamEagen) and [Ariel Gabizon](https://twitter.com/rel_zeta_tech) for their kind explanations. @@ -56,8 +56,10 @@ let betas = powers_of_beta(beta, t); let (F_coeffs, K_coeffs, folded_instance, folded_witness) = Folding::::prover( &mut transcript_p, &r1cs, + // running instance instance.clone(), witness, + // incomming instances instances.clone(), witnesses, ); @@ -66,8 +68,8 @@ let (F_coeffs, K_coeffs, folded_instance, folded_witness) = Folding::::verifier( &mut transcript_v, &r1cs, - instance, - instances, + instance, // running instance + instances, // incomming instances F_coeffs, K_coeffs, ); @@ -75,6 +77,6 @@ let folded_instance_v = Folding::::verifier( // check that the folded instance satisfies the relation assert!(check_instance(&r2cs, folded_instance, folded_witness)); -// now, the folded instance & witness can be folded again with n other instances. +// now, the folded instance & witness can be folded again with k other instances. ``` (see the actual code for more details) diff --git a/src/lib.rs b/src/lib.rs index 6695526..de26919 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,5 @@ #![allow(non_snake_case)] #![allow(non_upper_case_globals)] -// #![allow(unused)] // TMP -// #![allow(dead_code)] // TMP pub mod pedersen; pub mod protogalaxy; diff --git a/src/pedersen.rs b/src/pedersen.rs index 48d58bd..96bd125 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -1,9 +1,6 @@ /// pedersen.rs file adapted from https://github.com/arnaucube/nova-study use ark_ec::{CurveGroup, Group}; -use ark_std::{ - rand::{Rng, RngCore}, - UniformRand, -}; +use ark_std::{rand::Rng, UniformRand}; use std::marker::PhantomData; use crate::utils::{vec_add, vec_scalar_mul}; @@ -11,11 +8,6 @@ use crate::utils::{vec_add, vec_scalar_mul}; use crate::transcript::Transcript; use ark_crypto_primitives::sponge::Absorb; -pub struct ProofElem { - R: C, - t1: C::ScalarField, - t2: C::ScalarField, -} pub struct Proof { R: C, u_: Vec, @@ -23,7 +15,6 @@ pub struct Proof { } pub struct Params { - g: C, h: C, pub generators: Vec, } @@ -46,22 +37,12 @@ where let g: C = C::generator(); let generators: Vec = vec![C::Affine::rand(rng); max]; let params: Params = Params:: { - g, h: g.mul(h_scalar), generators, }; params } - pub fn commit_elem( - rng: &mut R, - params: &Params, - v: &C::ScalarField, - ) -> CommitmentElem { - let r = C::ScalarField::rand(rng); - let cm: C = params.g.mul(v) + params.h.mul(r); - CommitmentElem:: { cm, r } - } pub fn commit( params: &Params, v: &Vec, @@ -71,27 +52,6 @@ where Commitment::(cm) } - pub fn prove_elem( - params: &Params, - transcript: &mut Transcript, - cm: C, - v: C::ScalarField, - r: C::ScalarField, - ) -> ProofElem { - let r1 = transcript.get_challenge(); - let r2 = transcript.get_challenge(); - - let R: C = params.g.mul(r1) + params.h.mul(r2); - - transcript.add_point(&cm); - transcript.add_point(&R); - let e = transcript.get_challenge(); - - let t1 = r1 + v * e; - let t2 = r2 + r * e; - - ProofElem:: { R, t1, t2 } - } pub fn prove( params: &Params, transcript: &mut Transcript, @@ -133,81 +93,17 @@ where } true } - - pub fn verify_elem( - params: &Params, - transcript: &mut Transcript, - cm: C, - proof: ProofElem, - ) -> bool { - // s1, s2 just to match Prover's transcript - transcript.get_challenge(); // r_1 - transcript.get_challenge(); // r_2 - - transcript.add_point(&cm); - transcript.add_point(&proof.R); - let e = transcript.get_challenge(); - let lhs = proof.R + cm.mul(e); - let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2); - if lhs != rhs { - return false; - } - true - } } #[derive(Clone, Debug)] pub struct Commitment(pub C); -pub struct CommitmentElem { - pub cm: C, - pub r: C::ScalarField, -} -impl CommitmentElem -where - ::ScalarField: Absorb, - ::BaseField: Absorb, -{ - pub fn prove( - &self, - params: &Params, - transcript: &mut Transcript, - v: C::ScalarField, - ) -> ProofElem { - Pedersen::::prove_elem(params, transcript, self.cm, v, self.r) - } -} - #[cfg(test)] mod tests { use super::*; use crate::transcript::poseidon_test_config; use ark_bls12_381::{Fr, G1Projective}; - #[test] - fn test_pedersen_single_element() { - let mut rng = ark_std::test_rng(); - - // setup params - let params = Pedersen::::new_params( - &mut rng, 0, /* 0, as here we don't use commit_vec */ - ); - let poseidon_config = poseidon_test_config::(); - - // init Prover's transcript - let mut transcript_p = Transcript::::new(&poseidon_config); - // init Verifier's transcript - let mut transcript_v = Transcript::::new(&poseidon_config); - - let v = Fr::rand(&mut rng); - - 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_elem(¶ms, &mut transcript_p, cm.cm, v, cm.r); - let v = Pedersen::verify_elem(¶ms, &mut transcript_v, cm.cm, proof); - assert!(v); - } #[test] fn test_pedersen_vector() { let mut rng = ark_std::test_rng(); diff --git a/src/protogalaxy.rs b/src/protogalaxy.rs index f746ac7..612aefd 100644 --- a/src/protogalaxy.rs +++ b/src/protogalaxy.rs @@ -37,21 +37,21 @@ where ::ScalarField: Absorb, ::BaseField: Absorb, { - // WIP naming of functions - pub fn prover( + #![allow(clippy::type_complexity)] + pub fn prove( transcript: &mut Transcript, r1cs: &R1CS, // running instance - instance: CommittedInstance, - w: Witness, + instance: &CommittedInstance, + w: &Witness, // incomming instances - vec_instances: Vec>, - vec_w: Vec>, + vec_instances: &[CommittedInstance], + vec_w: &[Witness], ) -> ( - Vec, - Vec, CommittedInstance, Witness, + Vec, + Vec, ) { let t = instance.betas.len(); let n = r1cs.A[0].len(); @@ -66,9 +66,9 @@ where // F(X) let mut F_X: SparsePolynomial = SparsePolynomial::zero(); - for i in 0..n { + for (i, f_w_i) in f_w.iter().enumerate() { let lhs = pow_i_over_x::(i, &instance.betas, &deltas); - let curr = &lhs * f_w[i]; + let curr = &lhs * *f_w_i; F_X = F_X.add(curr); } @@ -102,7 +102,7 @@ where betas: betas_star.clone(), e: F_alpha, }, - &w, + w, )); let mut ws: Vec> = Vec::new(); @@ -146,12 +146,11 @@ where let f_ev = eval_f(r1cs, &inner); let mut Gsum = C::ScalarField::zero(); - for i in 0..n { + for (i, f_ev_i) in f_ev.iter().enumerate() { let pow_i_betas = pow_i(i, &betas_star); - let curr = pow_i_betas * f_ev[i]; + let curr = pow_i_betas * f_ev_i; Gsum += curr; } - // G_evals[hi] = Gsum / Z_X.evaluate(&h); // WIP G_evals[hi] = Gsum; } let G_X: DensePolynomial = @@ -162,7 +161,7 @@ where let G_L0e = &G_X - &L0_e; // TODO move division by Z_X to the prev loop let (K_X, remainder) = G_L0e.divide_by_vanishing_poly(H).unwrap(); - assert!(remainder.is_zero()); + assert!(remainder.is_zero()); // sanity check transcript.add_vec(&K_X.coeffs); @@ -188,8 +187,6 @@ where } ( - F_X_dense.coeffs, - K_X.coeffs, CommittedInstance { betas: betas_star, phi: Commitment(phi_star), @@ -197,18 +194,20 @@ where }, Witness { w: w_star, - r_w: w.r_w, // wip, fold also r_w (blinding used for the w commitment) + r_w: r_w_star, }, + F_X_dense.coeffs, + K_X.coeffs, ) } - pub fn verifier( + pub fn verify( transcript: &mut Transcript, r1cs: &R1CS, // running instance - instance: CommittedInstance, + instance: &CommittedInstance, // incomming instances - vec_instances: Vec>, + vec_instances: &[CommittedInstance], // polys from P F_coeffs: Vec, K_coeffs: Vec, @@ -337,13 +336,13 @@ fn check_instance( instance: &CommittedInstance, w: &Witness, ) -> bool { - let n = 2_u64.pow(instance.betas.len() as u32) as usize; + assert_eq!(instance.betas.len(), log2(w.w.len()) as usize); let f_w = eval_f(r1cs, &w.w); // f(w) let mut r = C::ScalarField::zero(); - for i in 0..n { - r += pow_i(i, &instance.betas) * f_w[i]; + for (i, f_w_i) in f_w.iter().enumerate() { + r += pow_i(i, &instance.betas) * f_w_i; } if instance.e == r { return true; @@ -550,21 +549,21 @@ mod tests { let mut transcript_p = Transcript::::new(&poseidon_config); let mut transcript_v = Transcript::::new(&poseidon_config); - let (F_coeffs, K_coeffs, folded_instance, folded_witness) = Folding::::prover( + let (folded_instance, folded_witness, F_coeffs, K_coeffs) = Folding::::prove( &mut transcript_p, &r1cs, - instance.clone(), - witness, - instances.clone(), - witnesses, + &instance, + &witness, + &instances, + &witnesses, ); // veriier - let folded_instance_v = Folding::::verifier( + let folded_instance_v = Folding::::verify( &mut transcript_v, &r1cs, - instance, - instances, + &instance, + &instances, F_coeffs, K_coeffs, ); @@ -597,22 +596,22 @@ mod tests { // generate the instances to be fold let (_, _, witnesses, instances) = prepare_inputs(k); - let (F_coeffs, K_coeffs, folded_instance, folded_witness) = - Folding::::prover( + let (folded_instance, folded_witness, F_coeffs, K_coeffs) = + Folding::::prove( &mut transcript_p, &r1cs, - running_instance.clone(), - running_witness.clone(), - instances.clone(), - witnesses, + &running_instance, + &running_witness, + &instances, + &witnesses, ); // veriier - let folded_instance_v = Folding::::verifier( + let folded_instance_v = Folding::::verify( &mut transcript_v, &r1cs, - running_instance.clone(), - instances, + &running_instance, + &instances, F_coeffs, K_coeffs, ); diff --git a/src/utils.rs b/src/utils.rs index 1c13634..e9d49bb 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,6 +2,7 @@ use ark_ff::fields::PrimeField; use ark_std::cfg_iter; pub fn vec_add(a: &[F], b: &[F]) -> Vec { + assert_eq!(a.len(), b.len()); let mut r: Vec = vec![F::zero(); a.len()]; for i in 0..a.len() { r[i] = a[i] + b[i]; @@ -10,6 +11,7 @@ pub fn vec_add(a: &[F], b: &[F]) -> Vec { } pub fn vec_sub(a: &[F], b: &[F]) -> Vec { + assert_eq!(a.len(), b.len()); let mut r: Vec = vec![F::zero(); a.len()]; for i in 0..a.len() { r[i] = a[i] - b[i]; @@ -33,23 +35,25 @@ pub fn is_zero_vec(vec: &[F]) -> bool { true } -#[allow(clippy::needless_range_loop)] pub fn mat_vec_mul(M: &Vec>, z: &[F]) -> Vec { - // TODO assert len + assert!(!M.is_empty()); + assert_eq!(M[0].len(), z.len()); + let mut r: Vec = vec![F::zero(); M.len()]; - for i in 0..M.len() { - for j in 0..M[i].len() { - r[i] += M[i][j] * z[j]; + for (i, M_i) in M.iter().enumerate() { + for (j, M_ij) in M_i.iter().enumerate() { + r[i] += *M_ij * z[j]; } } r } pub fn hadamard(a: &[F], b: &[F]) -> Vec { + assert_eq!(a.len(), b.len()); cfg_iter!(a).zip(b).map(|(a, b)| *a * b).collect() } -// returns (b, b^2, b^4, ..., b^{2^{t-1}}) TODO find better name +// returns (b, b^2, b^4, ..., b^{2^{t-1}}) pub fn powers_of_beta(b: F, t: usize) -> Vec { let mut r = vec![F::zero(); t]; r[0] = b; @@ -61,8 +65,8 @@ pub fn powers_of_beta(b: F, t: usize) -> Vec { pub fn all_powers(a: F, n: usize) -> Vec { let mut r = vec![F::zero(); n]; // TODO more efficiently - for i in 0..n { - r[i] = a.pow([i as u64]); + for (i, r_i) in r.iter_mut().enumerate() { + *r_i = a.pow([i as u64]); } r }