From 64c0c29e561478e947807002d7afae16cf57b075 Mon Sep 17 00:00:00 2001 From: Velnbur Date: Sun, 31 Mar 2024 18:04:42 +0300 Subject: [PATCH 1/3] Include README as crate doc This change makes two main profits: * The entry point in the doc site of the crate always will be its README which will exclude the need of repeting the same things inside the `lib.rs` and README itself. * After inclusion of the README as a doc, all the code inside it will be evaludated as Rust _doc test_ which will keep the code examples up-to-date. --- README.md | 12 ++++++++++-- src/lib.rs | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4e1917e..a75e696 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,15 @@ and `Deserialize` was implemented. Use [tests](./src/tests.rs) to run the provided example: ```rust -pub fn main() { +use k256::elliptic_curve::{Group, rand_core::OsRng}; +use k256::ProjectivePoint; + +use bp_pp::range_proof; +use bp_pp::range_proof::u64_proof::G_VEC_FULL_SZ; +use bp_pp::range_proof::u64_proof::H_VEC_FULL_SZ; +use bp_pp::range_proof::reciprocal::{SerializableProof, self}; + +fn main() { let mut rand = OsRng::default(); let x = 123456u64; // private value to create proof for. @@ -63,4 +71,4 @@ pub fn main() { let mut vt = merlin::Transcript::new(b"u64 range proof"); assert!(public.verify(&commitment, proof, &mut vt)); } -``` \ No newline at end of file +``` diff --git a/src/lib.rs b/src/lib.rs index 2309354..9861a32 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,9 @@ +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] + pub mod wnla; pub mod circuit; pub(crate) mod transcript; pub mod range_proof; mod util; -mod tests; \ No newline at end of file +mod tests; From 2a07d6c3d9ce40827e09219b6175abda545fa110 Mon Sep 17 00:00:00 2001 From: olegfomenko Date: Mon, 1 Apr 2024 15:07:16 +0300 Subject: [PATCH 2/3] refactored: fixed warnings from cargo clippy --- src/circuit.rs | 102 +++++++++++++++++----------------- src/range_proof/reciprocal.rs | 26 ++++----- src/range_proof/u64_proof.rs | 8 +-- src/tests.rs | 2 +- src/util.rs | 30 +++++----- src/wnla.rs | 16 +++--- 6 files changed, 92 insertions(+), 92 deletions(-) diff --git a/src/circuit.rs b/src/circuit.rs index aa3792b..249c206 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -1,5 +1,5 @@ #![allow(non_snake_case)] -///! Definition and implementation of the Bulletproofs++ arithmetic circuit protocol. +//! Definition and implementation of the Bulletproofs++ arithmetic circuit protocol. use std::ops::{Add, Mul, Sub}; use k256::{AffinePoint, ProjectivePoint, Scalar}; @@ -51,8 +51,8 @@ impl From<&SerializableProof> for Proof { c_r: ProjectivePoint::from(&value.c_r), c_o: ProjectivePoint::from(&value.c_o), c_s: ProjectivePoint::from(&value.c_s), - r: value.r.iter().map(|r_val| ProjectivePoint::from(r_val)).collect::>(), - x: value.x.iter().map(|x_val| ProjectivePoint::from(x_val)).collect::>(), + r: value.r.iter().map(ProjectivePoint::from).collect::>(), + x: value.x.iter().map(ProjectivePoint::from).collect::>(), l: value.l.clone(), n: value.n.clone(), }; @@ -142,15 +142,15 @@ impl

ArithmeticCircuit

P: Fn(PartitionType, usize) -> Option { /// Creates commitment to the arithmetic circuit witness. - pub fn commit(&self, v: &Vec, s: &Scalar) -> ProjectivePoint { + pub fn commit(&self, v: &[Scalar], s: &Scalar) -> ProjectivePoint { self. g.mul(&v[0]). add(&self.h_vec[0].mul(s)). - add(&vector_mul(&self.h_vec[9..].to_vec(), &v[1..].to_vec())) + add(&vector_mul(&self.h_vec[9..], &v[1..])) } /// Verifies arithmetic circuit proof with respect to the `v` commitments vector. - pub fn verify(&self, v: &Vec, t: &mut Transcript, proof: Proof) -> bool { + pub fn verify(&self, v: &[ProjectivePoint], t: &mut Transcript, proof: Proof) -> bool { transcript::app_point(b"commitment_cl", &proof.c_l, t); transcript::app_point(b"commitment_cr", &proof.c_r, t); transcript::app_point(b"commitment_co", &proof.c_o, t); @@ -222,7 +222,7 @@ impl

ArithmeticCircuit

cl_tau = vector_mul_on_scalar(&cl_tau, &Scalar::from(2u32)); cl_tau = vector_sub(&cl_tau, &c_l0); - let mut c = Vec::from([&cr_tau[..], &cl_tau[..]].concat()); + let mut c = [&cr_tau[..], &cl_tau[..]].concat(); let commitment = pt. add(&proof.c_s.mul(&tau_inv)). @@ -236,25 +236,25 @@ impl

ArithmeticCircuit

} let wnla = WeightNormLinearArgument { - g: ProjectivePoint::from(self.g), - g_vec: Vec::from([&self.g_vec[..], &self.g_vec_[..]].concat()), - h_vec: Vec::from([&self.h_vec[..], &self.h_vec_[..]].concat()), + g: self.g, + g_vec: [&self.g_vec[..], &self.g_vec_[..]].concat(), + h_vec: [&self.h_vec[..], &self.h_vec_[..]].concat(), c, rho, mu, }; - return wnla.verify(&commitment, t, wnla::Proof { + wnla.verify(&commitment, t, wnla::Proof { r: proof.r, x: proof.x, l: proof.l, n: proof.n, - }); + }) } /// Creates arithmetic circuit proof for the corresponding witness. Also, `v` commitments vector /// should correspond input witness in `witness` argument. - pub fn prove(&self, v: &Vec, witness: Witness, t: &mut Transcript, rng: &mut R) -> Proof + pub fn prove(&self, v: &[ProjectivePoint], witness: Witness, t: &mut Transcript, rng: &mut R) -> Proof where R: RngCore + CryptoRng { @@ -299,7 +299,7 @@ impl

ArithmeticCircuit

let no = (0..self.dim_nm).map(|j| if let Some(i) = (self.partition)(PartitionType::NO, j) { - Scalar::from(witness.w_o[i]) + witness.w_o[i] } else { Scalar::ZERO } @@ -307,7 +307,7 @@ impl

ArithmeticCircuit

let lo = (0..self.dim_nv).map(|j| if let Some(i) = (self.partition)(PartitionType::LO, j) { - Scalar::from(witness.w_o[i]) + witness.w_o[i] } else { Scalar::ZERO } @@ -315,7 +315,7 @@ impl

ArithmeticCircuit

let ll = (0..self.dim_nv).map(|j| if let Some(i) = (self.partition)(PartitionType::LL, j) { - Scalar::from(witness.w_o[i]) + witness.w_o[i] } else { Scalar::ZERO } @@ -323,22 +323,22 @@ impl

ArithmeticCircuit

let lr = (0..self.dim_nv).map(|j| if let Some(i) = (self.partition)(PartitionType::LR, j) { - Scalar::from(witness.w_o[i]) + witness.w_o[i] } else { Scalar::ZERO } ).collect::>(); let co = - vector_mul(&self.h_vec, &Vec::from([&ro[..], &lo[..]].concat())). + vector_mul(&self.h_vec, &[&ro[..], &lo[..]].concat()). add(vector_mul(&self.g_vec, &no)); let cl = - vector_mul(&self.h_vec, &Vec::from([&rl[..], &ll[..]].concat())). + vector_mul(&self.h_vec, &[&rl[..], &ll[..]].concat()). add(vector_mul(&self.g_vec, &nl)); let cr = - vector_mul(&self.h_vec, &Vec::from([&rr[..], &lr[..]].concat())). + vector_mul(&self.h_vec, &[&rr[..], &lr[..]].concat()). add(vector_mul(&self.g_vec, &nr)); transcript::app_point(b"commitment_cl", &cl, t); @@ -365,8 +365,8 @@ impl

ArithmeticCircuit

c_lO ) = self.collect_c(&lambda_vec, &mu_vec, &mu); - let ls = (0..self.dim_nv).map(|_| Scalar::generate_biased(rng)).collect(); - let ns = (0..self.dim_nm).map(|_| Scalar::generate_biased(rng)).collect(); + let ls = (0..self.dim_nv).map(|_| Scalar::generate_biased(rng)).collect::>(); + let ns = (0..self.dim_nm).map(|_| Scalar::generate_biased(rng)).collect::>(); let mut v_0 = Scalar::ZERO; (0..self.k). @@ -385,7 +385,7 @@ impl

ArithmeticCircuit

let mut v_1 = vec![Scalar::ZERO; self.dim_nv - 1]; (0..self.k). for_each(|i| - v_1 = vector_add(&v_1, &vector_mul_on_scalar(&witness.v[i][1..].to_vec(), &self.linear_comb_coef(i, &lambda, &mu))) + v_1 = vector_add(&v_1, &vector_mul_on_scalar(&witness.v[i][1..], &self.linear_comb_coef(i, &lambda, &mu))) ); v_1 = vector_mul_on_scalar(&v_1, &Scalar::from(2u32)); @@ -461,7 +461,7 @@ impl

ArithmeticCircuit

f_[7].mul(&beta_inv).add(&ro[7].mul(&delta)).sub(&rl[6]).add(&rr[5]), ]; - let cs = vector_mul(&self.h_vec, &Vec::from([&rs[..], &ls[..]].concat())). + let cs = vector_mul(&self.h_vec, &[&rs[..], &ls[..]].concat()). add(vector_mul(&self.g_vec, &ns)); transcript::app_point(b"commitment_cs", &cs, t); @@ -471,11 +471,11 @@ impl

ArithmeticCircuit

let tau2 = tau.mul(&tau); let tau3 = tau2.mul(&tau); - let mut l = vector_mul_on_scalar(&Vec::from([&rs[..], &ls[..]].concat()), &tau_inv); - l = vector_sub(&l, &vector_mul_on_scalar(&Vec::from([&ro[..], &lo[..]].concat()), &delta)); - l = vector_add(&l, &vector_mul_on_scalar(&Vec::from([&rl[..], &ll[..]].concat()), &tau)); - l = vector_sub(&l, &vector_mul_on_scalar(&Vec::from([&rr[..], &lr[..]].concat()), &tau2)); - l = vector_add(&l, &vector_mul_on_scalar(&Vec::from([&rv[..], &v_1[..]].concat()), &tau3)); + let mut l = vector_mul_on_scalar(&[&rs[..], &ls[..]].concat(), &tau_inv); + l = vector_sub(&l, &vector_mul_on_scalar(&[&ro[..], &lo[..]].concat(), &delta)); + l = vector_add(&l, &vector_mul_on_scalar(&[&rl[..], &ll[..]].concat(), &tau)); + l = vector_sub(&l, &vector_mul_on_scalar(&[&rr[..], &lr[..]].concat(), &tau2)); + l = vector_add(&l, &vector_mul_on_scalar(&[&rv[..], &v_1[..]].concat(), &tau3)); let mut pn_tau = vector_mul_on_scalar(&c_nO, &tau3.mul(&delta_inv)); pn_tau = vector_sub(&pn_tau, &vector_mul_on_scalar(&c_nL, &tau2)); @@ -510,7 +510,7 @@ impl

ArithmeticCircuit

cl_tau = vector_mul_on_scalar(&cl_tau, &Scalar::from(2u32)); cl_tau = vector_sub(&cl_tau, &c_l0); - let mut c = Vec::from([&cr_tau[..], &cl_tau[..]].concat()); + let mut c = [&cr_tau[..], &cl_tau[..]].concat(); let v = ps_tau.add(&tau3.mul(&v_0)); @@ -528,9 +528,9 @@ impl

ArithmeticCircuit

} let wnla = WeightNormLinearArgument { - g: ProjectivePoint::from(self.g), - g_vec: Vec::from([&self.g_vec[..], &self.g_vec_[..]].concat()), - h_vec: Vec::from([&self.h_vec[..], &self.h_vec_[..]].concat()), + g: self.g, + g_vec: [&self.g_vec[..], &self.g_vec_[..]].concat(), + h_vec: [&self.h_vec[..], &self.h_vec_[..]].concat(), c, rho, mu, @@ -538,7 +538,7 @@ impl

ArithmeticCircuit

let proof_wnla = wnla.prove(&commitment, t, l, n); - return Proof { + Proof { c_l: cl, c_r: cr, c_o: co, @@ -547,18 +547,18 @@ impl

ArithmeticCircuit

x: proof_wnla.x, l: proof_wnla.l, n: proof_wnla.n, - }; + } } fn linear_comb_coef(&self, i: usize, lambda: &Scalar, mu: &Scalar) -> Scalar { let mut coef = Scalar::ZERO; if self.f_l { - coef = coef.add(pow(&lambda, self.dim_nv * i)) + coef = coef.add(pow(lambda, self.dim_nv * i)) } if self.f_m { - coef = coef.add(pow(&mu, self.dim_nv * i + 1)) + coef = coef.add(pow(mu, self.dim_nv * i + 1)) } coef @@ -567,30 +567,30 @@ impl

ArithmeticCircuit

fn collect_cl0(&self, lambda: &Scalar, mu: &Scalar) -> Vec { let mut c_l0 = vec![Scalar::ZERO; self.dim_nv - 1]; if self.f_l { - c_l0 = e(&lambda, self.dim_nv)[1..].to_vec(); + c_l0 = e(lambda, self.dim_nv)[1..].to_vec(); } if self.f_m { - c_l0 = vector_sub(&c_l0, &vector_mul_on_scalar(&e(&mu, self.dim_nv)[1..].to_vec(), &mu)); + c_l0 = vector_sub(&c_l0, &vector_mul_on_scalar(&e(mu, self.dim_nv)[1..], mu)); } c_l0 } - fn collect_c(&self, lambda_vec: &Vec, mu_vec: &Vec, mu: &Scalar) -> (Vec, Vec, Vec, Vec, Vec, Vec) { + fn collect_c(&self, lambda_vec: &[Scalar], mu_vec: &[Scalar], mu: &Scalar) -> (Vec, Vec, Vec, Vec, Vec, Vec) { let (M_lnL, M_mnL, M_lnR, M_mnR) = self.collect_m_rl(); let (M_lnO, M_mnO, M_llL, M_mlL, M_llR, M_mlR, M_llO, M_mlO) = self.collect_m_o(); - let mu_diag_inv = diag_inv(&mu, self.dim_nm); + let mu_diag_inv = diag_inv(mu, self.dim_nm); - let c_nL = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_lnL), &vector_mul_on_matrix(&mu_vec, &M_mnL)), &mu_diag_inv); - let c_nR = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_lnR), &vector_mul_on_matrix(&mu_vec, &M_mnR)), &mu_diag_inv); - let c_nO = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_lnO), &vector_mul_on_matrix(&mu_vec, &M_mnO)), &mu_diag_inv); + let c_nL = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(lambda_vec, &M_lnL), &vector_mul_on_matrix(mu_vec, &M_mnL)), &mu_diag_inv); + let c_nR = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(lambda_vec, &M_lnR), &vector_mul_on_matrix(mu_vec, &M_mnR)), &mu_diag_inv); + let c_nO = vector_mul_on_matrix(&vector_sub(&vector_mul_on_matrix(lambda_vec, &M_lnO), &vector_mul_on_matrix(mu_vec, &M_mnO)), &mu_diag_inv); - let c_lL = vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_llL), &vector_mul_on_matrix(&mu_vec, &M_mlL)); - let c_lR = vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_llR), &vector_mul_on_matrix(&mu_vec, &M_mlR)); - let c_lO = vector_sub(&vector_mul_on_matrix(&lambda_vec, &M_llO), &vector_mul_on_matrix(&mu_vec, &M_mlO)); + let c_lL = vector_sub(&vector_mul_on_matrix(lambda_vec, &M_llL), &vector_mul_on_matrix(mu_vec, &M_mlL)); + let c_lR = vector_sub(&vector_mul_on_matrix(lambda_vec, &M_llR), &vector_mul_on_matrix(mu_vec, &M_mlR)); + let c_lO = vector_sub(&vector_mul_on_matrix(lambda_vec, &M_llO), &vector_mul_on_matrix(mu_vec, &M_mlO)); - return (c_nL, c_nR, c_nO, c_lL, c_lR, c_lO); + (c_nL, c_nR, c_nO, c_lL, c_lR, c_lO) } fn collect_lambda(&self, lambda: &Scalar, mu: &Scalar) -> Vec { @@ -605,7 +605,7 @@ impl

ArithmeticCircuit

); } - return lambda_vec; + lambda_vec } fn collect_m_rl(&self) -> (Vec>, Vec>, Vec>, Vec>) { @@ -613,7 +613,7 @@ impl

ArithmeticCircuit

let M_mnL = (0..self.dim_nm).map(|i| Vec::from(&self.W_m[i][..self.dim_nm])).collect::>>(); let M_lnR = (0..self.dim_nl).map(|i| Vec::from(&self.W_l[i][self.dim_nm..self.dim_nm * 2])).collect::>>(); let M_mnR = (0..self.dim_nm).map(|i| Vec::from(&self.W_m[i][self.dim_nm..self.dim_nm * 2])).collect::>>(); - return (M_lnL, M_mnL, M_lnR, M_mnR); + (M_lnL, M_mnL, M_lnR, M_mnR) } fn collect_m_o(&self) -> (Vec>, Vec>, Vec>, Vec>, Vec>, Vec>, Vec>, Vec>) { @@ -624,7 +624,7 @@ impl

ArithmeticCircuit

(0..isz).map(|i| (0..jsz).map(|j| if let Some(j_) = (self.partition)(typ, j) { - Scalar::from(W_x[i][j_]) + W_x[i][j_] } else { Scalar::ZERO } diff --git a/src/range_proof/reciprocal.rs b/src/range_proof/reciprocal.rs index ad20ff3..08614f3 100644 --- a/src/range_proof/reciprocal.rs +++ b/src/range_proof/reciprocal.rs @@ -1,6 +1,6 @@ #![allow(non_snake_case)] -///! Definition and implementation of the reciprocal range-proof protocol based on arithmetic circuits protocol. +//! Definition and implementation of the reciprocal range-proof protocol based on arithmetic circuits protocol. use std::ops::{Add, Mul}; use k256::{AffinePoint, ProjectivePoint, Scalar}; @@ -41,19 +41,19 @@ pub struct SerializableProof { impl From<&SerializableProof> for Proof { fn from(value: &SerializableProof) -> Self { - return Proof { + Proof { circuit_proof: circuit::Proof::from(&value.circuit_proof), r: ProjectivePoint::from(value.r), - }; + } } } impl From<&Proof> for SerializableProof { fn from(value: &Proof) -> Self { - return SerializableProof { + SerializableProof { circuit_proof: circuit::SerializableProof::from(&value.circuit_proof), r: value.r.to_affine(), - }; + } } } @@ -89,8 +89,8 @@ impl ReciprocalRangeProofProtocol { } /// Creates commitment for the reciprocals and blinding: `commitment = s*h_vec[0] + ` - pub fn commit_poles(&self, r: &Vec, s: &Scalar) -> ProjectivePoint { - self.h_vec[0].mul(s).add(&vector_mul(&self.h_vec[9..].to_vec(), &r)) + pub fn commit_poles(&self, r: &[Scalar], s: &Scalar) -> ProjectivePoint { + self.h_vec[0].mul(s).add(&vector_mul(&self.h_vec[9..], r)) } /// Verifies zk-proof that committed value lies in [0..dim_np^dim_nd) range. @@ -102,7 +102,7 @@ impl ReciprocalRangeProofProtocol { let circuit_commitment = commitment.add(&proof.r); - return circuit.verify(&vec![circuit_commitment], t, proof.circuit_proof); + circuit.verify(&[circuit_commitment], t, proof.circuit_proof) } /// Creates zk-proof that committed value lies in [0..dim_np^dim_nd) range. @@ -138,14 +138,14 @@ impl ReciprocalRangeProofProtocol { }; let circuit_commitment = circuit.commit(&circuit_witness.v[0], &circuit_witness.s_v[0]); - return Proof { - circuit_proof: circuit.prove::(&vec![circuit_commitment], circuit_witness, t, rng), + Proof { + circuit_proof: circuit.prove::(&[circuit_commitment], circuit_witness, t, rng), r: r_com, - }; + } } /// Creates circuit parameters based on provided challenge. For the same challenge will generate same parameters. - fn make_circuit<'a>(&'a self, e: Scalar) -> ArithmeticCircuit Option + 'a> + fn make_circuit(&self, e: Scalar) -> ArithmeticCircuit Option + '_> { let dim_nm = self.dim_nd; let dim_no = self.dim_np; @@ -196,7 +196,7 @@ impl ReciprocalRangeProofProtocol { dim_nl, dim_nv, dim_nw, - g: self.g.clone(), + g: self.g, g_vec: self.g_vec.clone(), h_vec: self.h_vec.clone(), W_m, diff --git a/src/range_proof/u64_proof.rs b/src/range_proof/u64_proof.rs index cd5cbc3..22bd01b 100644 --- a/src/range_proof/u64_proof.rs +++ b/src/range_proof/u64_proof.rs @@ -1,5 +1,5 @@ #![allow(non_snake_case)] -///! Definition and implementation of the u64 range-proof protocol based on reciprocal protocol. +//! Definition and implementation of the u64 range-proof protocol based on reciprocal protocol. use std::ops::{Add, Mul}; use k256::{ProjectivePoint, Scalar}; @@ -73,7 +73,7 @@ impl U64RangeProofProtocol { let witness = Witness { x: Scalar::from(x), - s: s.clone(), + s: *s, m: poles, digits, }; @@ -84,7 +84,7 @@ impl U64RangeProofProtocol { pub fn u64_to_hex(mut x: u64) -> Vec { (0..16).map(|_| { let val = Scalar::from(x % 16); - x = x / 16; + x /= 16; val }).collect::>() } @@ -95,7 +95,7 @@ impl U64RangeProofProtocol { (0..16).for_each(|_| { let digit = (x % 16) as usize; result[digit] = result[digit].add(Scalar::ONE); - x = x / 16; + x /= 16; }); result diff --git a/src/tests.rs b/src/tests.rs index 56dceeb..6c01c74 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -126,7 +126,7 @@ mod tests { w_o, }; - let v = (0..k).map(|i| circuit.commit(&witness.v[i], &witness.s_v[i])).collect(); + let v = (0..k).map(|i| circuit.commit(&witness.v[i], &witness.s_v[i])).collect::>(); let mut pt = merlin::Transcript::new(b"circuit test"); let proof = circuit.prove::(&v, witness, &mut pt, &mut rand); diff --git a/src/util.rs b/src/util.rs index b3fc806..0c47d19 100644 --- a/src/util.rs +++ b/src/util.rs @@ -3,7 +3,7 @@ use std::ops::{Add, Mul, Sub}; use k256::elliptic_curve::Field; use k256::Scalar; -pub fn reduce(v: &Vec) -> (Vec, Vec) where T: Copy { +pub fn reduce(v: &[T]) -> (Vec, Vec) where T: Copy { let res0 = v.iter(). enumerate(). filter(|(i, _)| *i as i32 % 2 == 0). @@ -20,11 +20,11 @@ pub fn reduce(v: &Vec) -> (Vec, Vec) where T: Copy { (res0, res1) } -pub fn vector_extend(v: &Vec, n: usize) -> Vec where T: Copy + Default { +pub fn vector_extend(v: &[T], n: usize) -> Vec where T: Copy + Default { (0..n).map(|i| if i < v.len() { v[i] } else { T::default() }).collect::>() } -pub fn weight_vector_mul(a: &Vec, b: &Vec, weight: &Scalar) -> T +pub fn weight_vector_mul(a: &[T], b: &[Scalar], weight: &Scalar) -> T where T: Copy + Default + Mul + Add { @@ -39,10 +39,10 @@ pub fn weight_vector_mul(a: &Vec, b: &Vec, weight: &Scalar) -> T result = result.add(a_val.mul(b_val.mul(&exp))); }); - return result; + result } -pub fn vector_mul(a: &Vec, b: &Vec) -> T +pub fn vector_mul(a: &[T], b: &[Scalar]) -> T where T: Copy + Default + Mul + Add { @@ -55,17 +55,17 @@ pub fn vector_mul(a: &Vec, b: &Vec) -> T result = result.add(a_val.mul(*b_val)); }); - return result; + result } -pub fn vector_mul_on_scalar<'a, T>(a: &Vec, s: &'a Scalar) -> Vec +pub fn vector_mul_on_scalar<'a, T>(a: &[T], s: &'a Scalar) -> Vec where T: Copy + Mul<&'a Scalar, Output=T> { a.iter().map(|x| x.mul(s)).collect::>() } -pub fn vector_add(a: &Vec, b: &Vec) -> Vec +pub fn vector_add(a: &[T], b: &[T]) -> Vec where T: Copy + Default + Add { @@ -74,7 +74,7 @@ pub fn vector_add(a: &Vec, b: &Vec) -> Vec a_ext.iter().zip(b_ext).map(|(a_val, b_val)| a_val.add(*b_val)).collect::>() } -pub fn vector_sub<'a, T>(a: &'a Vec, b: &'a Vec) -> Vec +pub fn vector_sub<'a, T>(a: &'a [T], b: &'a [T]) -> Vec where T: Copy + Default + Sub { @@ -94,11 +94,11 @@ pub fn e(v: &Scalar, n: usize) -> Vec { } pub fn pow(s: &Scalar, n: usize) -> Scalar { - return s.pow(&[n as u64]); + s.pow([n as u64]) } #[allow(dead_code)] -pub fn vector_hadamard_mul(a: &Vec, b: &Vec) -> Vec +pub fn vector_hadamard_mul(a: &[T], b: &[Scalar]) -> Vec where T: Copy + Default + Mul { @@ -107,11 +107,11 @@ pub fn vector_hadamard_mul(a: &Vec, b: &Vec) -> Vec a_ext.iter().zip(b_ext).map(|(a_val, b_val)| a_val.mul(*b_val)).collect::>() } -pub fn vector_tensor_mul<'a, T>(a: &'a Vec, b: &'a Vec) -> Vec +pub fn vector_tensor_mul<'a, T>(a: &'a [T], b: &'a [Scalar]) -> Vec where T: Copy + Mul<&'a Scalar, Output=T> { - b.iter().map(|x| vector_mul_on_scalar(&a, x)).collect::>>().concat() + b.iter().map(|x| vector_mul_on_scalar(a, x)).collect::>>().concat() } pub fn diag_inv(x: &Scalar, n: usize) -> Vec> { @@ -130,7 +130,7 @@ pub fn diag_inv(x: &Scalar, n: usize) -> Vec> { ).collect::>>() } -pub fn vector_mul_on_matrix(a: &Vec, m: &Vec>) -> Vec +pub fn vector_mul_on_matrix(a: &[T], m: &[Vec]) -> Vec where T: Copy + Default + Mul + Add { @@ -141,7 +141,7 @@ pub fn vector_mul_on_matrix(a: &Vec, m: &Vec>) -> Vec } #[allow(dead_code)] -pub fn matrix_mul_on_vector(a: &Vec, m: &Vec>) -> Vec +pub fn matrix_mul_on_vector(a: &[T], m: &[Vec]) -> Vec where T: Copy + Default + Mul + Add { diff --git a/src/wnla.rs b/src/wnla.rs index be5b555..e048698 100644 --- a/src/wnla.rs +++ b/src/wnla.rs @@ -1,4 +1,4 @@ -///! Definition and implementation of the Bulletproofs++ weight norm linear argument protocol. +//! Definition and implementation of the Bulletproofs++ weight norm linear argument protocol. use std::ops::{Add, Mul}; use k256::{AffinePoint, ProjectivePoint, Scalar}; use merlin::Transcript; @@ -40,8 +40,8 @@ pub struct SerializableProof { impl From<&SerializableProof> for Proof { fn from(value: &SerializableProof) -> Self { return Proof { - r: value.r.iter().map(|r_val| ProjectivePoint::from(r_val)).collect::>(), - x: value.x.iter().map(|x_val| ProjectivePoint::from(x_val)).collect::>(), + r: value.r.iter().map(ProjectivePoint::from).collect::>(), + x: value.x.iter().map(ProjectivePoint::from).collect::>(), l: value.l.clone(), n: value.n.clone(), }; @@ -62,7 +62,7 @@ impl From<&Proof> for SerializableProof { impl WeightNormLinearArgument { /// Creates weight norm linear argument commitment to vectors `l`, `n`: /// `C = v*g + + `, where `v = |n|_{mu}^2 + ` - pub fn commit(&self, l: &Vec, n: &Vec) -> ProjectivePoint { + pub fn commit(&self, l: &[Scalar], n: &[Scalar]) -> ProjectivePoint { let v = vector_mul(&self.c, l).add(weight_vector_mul(n, n, &self.mu)); self. g.mul(v). @@ -76,7 +76,7 @@ impl WeightNormLinearArgument { return false; } - if proof.x.len() == 0 { + if proof.x.is_empty() { return commitment.eq(&self.commit(&proof.l, &proof.n)); } @@ -85,8 +85,8 @@ impl WeightNormLinearArgument { let (h0, h1) = reduce(&self.h_vec); transcript::app_point(b"wnla_com", commitment, t); - transcript::app_point(b"wnla_x", &proof.x.last().unwrap(), t); - transcript::app_point(b"wnla_r", &proof.r.last().unwrap(), t); + transcript::app_point(b"wnla_x", proof.x.last().unwrap(), t); + transcript::app_point(b"wnla_r", proof.r.last().unwrap(), t); t.append_u64(b"l.sz", self.h_vec.len() as u64); t.append_u64(b"n.sz", self.g_vec.len() as u64); @@ -116,7 +116,7 @@ impl WeightNormLinearArgument { n: proof.n, }; - return wnla.verify(&com_, t, proof_); + wnla.verify(&com_, t, proof_) } /// Creates weight norm linear argument proof. `commitment` argument should be a weight norm From 70382f6475ec50f42ff8f4a811a23c1484c955b8 Mon Sep 17 00:00:00 2001 From: olegfomenko Date: Mon, 1 Apr 2024 15:10:50 +0300 Subject: [PATCH 3/3] refactored tests --- src/lib.rs | 1 + src/tests.rs | 342 +++++++++++++++++++++++++-------------------------- 2 files changed, 171 insertions(+), 172 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2309354..c82afc9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,4 +4,5 @@ pub(crate) mod transcript; pub mod range_proof; mod util; +#[cfg(test)] mod tests; \ No newline at end of file diff --git a/src/tests.rs b/src/tests.rs index 6c01c74..e2956a8 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,174 +1,172 @@ -#[cfg(test)] -mod tests { - #![allow(non_snake_case)] +#![allow(non_snake_case)] - use k256::elliptic_curve::Group; - use k256::elliptic_curve::rand_core::OsRng; - use k256::{ProjectivePoint, Scalar}; - use crate::circuit::{ArithmeticCircuit, PartitionType, Witness}; - use crate::{circuit, range_proof, wnla}; - use crate::range_proof::reciprocal; - use crate::range_proof::u64_proof::*; - use crate::util::{minus}; - - #[test] - fn u64_proof_works() { - let mut rand = OsRng::default(); - - let x = 123456u64; - let s = k256::Scalar::generate_biased(&mut rand); - - println!("Value {}, blinding: {}", x, serde_json::to_string_pretty(&s).unwrap()); - - // Base points - let g = k256::ProjectivePoint::random(&mut rand); - let g_vec = (0..G_VEC_FULL_SZ).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::>(); - let h_vec = (0..H_VEC_FULL_SZ).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::>(); - - let public = range_proof::u64_proof::U64RangeProofProtocol { - g, - g_vec, - h_vec, - }; - - let commitment = public.commit_value(x, &s); - - let mut pt = merlin::Transcript::new(b"u64 range proof"); - let proof = public.prove(x, &s, &mut pt, &mut rand); - - println!("Commitment: {}", serde_json::to_string_pretty(&commitment.to_affine()).unwrap()); - println!("Proof: {}", serde_json::to_string_pretty(&reciprocal::SerializableProof::from(&proof)).unwrap()); - - let mut vt = merlin::Transcript::new(b"u64 range proof"); - assert!(public.verify(&commitment, proof, &mut vt)); - } - - #[test] - fn ac_works() { - // Test the knowledge of x, y for public z, r, such: - // x + y = r - // x * y = z - - let x = Scalar::from(3u32); - let y = Scalar::from(5u32); - - let r = Scalar::from(8u32); - let z = Scalar::from(15u32); - - - let w_l = vec![Scalar::from(x)]; - let w_r = vec![Scalar::from(y)]; - let w_o = vec![Scalar::from(z), Scalar::from(r)]; - - let dim_nm = 1; - let dim_no = 2; - let dim_nv = 2; - let k = 1; - - let dim_nl = dim_nv * k; // 2 - let dim_nw = dim_nm + dim_nm + dim_no; // 4 - - - let W_m = vec![vec![Scalar::ZERO, Scalar::ZERO, Scalar::ONE, Scalar::ZERO]]; // Nm*Nw - let a_m = vec![Scalar::ZERO]; // Nm - - let W_l = vec![ - vec![Scalar::ZERO, Scalar::ONE, Scalar::ZERO, Scalar::ZERO], - vec![Scalar::ZERO, Scalar::ZERO.sub(&Scalar::ONE), Scalar::ONE, Scalar::ZERO], - ]; // Nl*Nw - - let a_l = vec![minus(&r), minus(&z)]; // Nl - - //let w_v = vec![Scalar::from(x), Scalar::from(y)]; - //let w = vec![Scalar::from(x), Scalar::from(y), Scalar::from(z), Scalar::from(r)]; // w = wl||wr||wo - //println!("Circuit check: {:?} = {:?}", vector_mul(&W_m[0], &w), vector_hadamard_mul(&w_l, &w_r)); - //println!("Circuit check: {:?} = 0", vector_add(&vector_add(&vec![vector_mul(&W_l[0], &w), vector_mul(&W_l[1], &w)], &w_v), &a_l)); - - let mut rand = OsRng::default(); - - let g = k256::ProjectivePoint::random(&mut rand); - let g_vec = (0..1).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::>(); - let h_vec = (0..16).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::>(); - - let partition = |typ: PartitionType, index: usize| -> Option{ - match typ { - PartitionType::LL => Some(index), - _ => None - } - }; - - let circuit = ArithmeticCircuit { - dim_nm, - dim_no, - k, - dim_nl, - dim_nv, - dim_nw, - g, - g_vec: g_vec[..dim_nm].to_vec(), - h_vec: h_vec[..9 + dim_nv].to_vec(), - W_m, - W_l, - a_m, - a_l, - f_l: true, - f_m: false, - g_vec_: g_vec[dim_nm..].to_vec(), - h_vec_: h_vec[9 + dim_nv..].to_vec(), - partition, - }; - - let witness = Witness { - v: vec![vec![x, y]], - s_v: vec![k256::Scalar::generate_biased(&mut rand)], - w_l, - w_r, - w_o, - }; - - let v = (0..k).map(|i| circuit.commit(&witness.v[i], &witness.s_v[i])).collect::>(); - - let mut pt = merlin::Transcript::new(b"circuit test"); - let proof = circuit.prove::(&v, witness, &mut pt, &mut rand); - - println!("{}", serde_json::to_string_pretty(&circuit::SerializableProof::from(&proof)).unwrap()); - - let mut vt = merlin::Transcript::new(b"circuit test"); - assert!(circuit.verify(&v, &mut vt, proof)); - } - - #[test] - fn wnla_works() { - const N: i32 = 4; - - let mut rand = OsRng::default(); - - let g = k256::ProjectivePoint::random(&mut rand); - let g_vec = (0..N).map(|_| k256::ProjectivePoint::random(&mut rand)).collect(); - let h_vec = (0..N).map(|_| k256::ProjectivePoint::random(&mut rand)).collect(); - let c = (0..N).map(|_| k256::Scalar::generate_biased(&mut rand)).collect(); - let rho = k256::Scalar::generate_biased(&mut rand); - - let wnla = wnla::WeightNormLinearArgument { - g, - g_vec, - h_vec, - c, - rho, - mu: rho.mul(&rho), - }; - - let l = vec![Scalar::from(1 as u32), Scalar::from(2 as u32), Scalar::from(3 as u32), Scalar::from(4 as u32)]; - let n = vec![Scalar::from(8 as u32), Scalar::from(7 as u32), Scalar::from(6 as u32), Scalar::from(5 as u32)]; - - let commit = wnla.commit(&l, &n); - let mut pt = merlin::Transcript::new(b"wnla test"); - - let proof = wnla.prove(&commit, &mut pt, l, n); - - println!("{}", serde_json::to_string_pretty(&wnla::SerializableProof::from(&proof)).unwrap()); - - let mut vt = merlin::Transcript::new(b"wnla test"); - assert!(wnla.verify(&commit, &mut vt, proof)) - } +use k256::elliptic_curve::Group; +use k256::elliptic_curve::rand_core::OsRng; +use k256::{ProjectivePoint, Scalar}; +use crate::circuit::{ArithmeticCircuit, PartitionType, Witness}; +use crate::{circuit, range_proof, wnla}; +use crate::range_proof::reciprocal; +use crate::range_proof::u64_proof::*; +use crate::util::{minus}; + +#[test] +fn u64_proof_works() { + let mut rand = OsRng::default(); + + let x = 123456u64; + let s = k256::Scalar::generate_biased(&mut rand); + + println!("Value {}, blinding: {}", x, serde_json::to_string_pretty(&s).unwrap()); + + // Base points + let g = k256::ProjectivePoint::random(&mut rand); + let g_vec = (0..G_VEC_FULL_SZ).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::>(); + let h_vec = (0..H_VEC_FULL_SZ).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::>(); + + let public = range_proof::u64_proof::U64RangeProofProtocol { + g, + g_vec, + h_vec, + }; + + let commitment = public.commit_value(x, &s); + + let mut pt = merlin::Transcript::new(b"u64 range proof"); + let proof = public.prove(x, &s, &mut pt, &mut rand); + + println!("Commitment: {}", serde_json::to_string_pretty(&commitment.to_affine()).unwrap()); + println!("Proof: {}", serde_json::to_string_pretty(&reciprocal::SerializableProof::from(&proof)).unwrap()); + + let mut vt = merlin::Transcript::new(b"u64 range proof"); + assert!(public.verify(&commitment, proof, &mut vt)); +} + +#[test] +fn ac_works() { + // Test the knowledge of x, y for public z, r, such: + // x + y = r + // x * y = z + + let x = Scalar::from(3u32); + let y = Scalar::from(5u32); + + let r = Scalar::from(8u32); + let z = Scalar::from(15u32); + + + let w_l = vec![Scalar::from(x)]; + let w_r = vec![Scalar::from(y)]; + let w_o = vec![Scalar::from(z), Scalar::from(r)]; + + let dim_nm = 1; + let dim_no = 2; + let dim_nv = 2; + let k = 1; + + let dim_nl = dim_nv * k; // 2 + let dim_nw = dim_nm + dim_nm + dim_no; // 4 + + + let W_m = vec![vec![Scalar::ZERO, Scalar::ZERO, Scalar::ONE, Scalar::ZERO]]; // Nm*Nw + let a_m = vec![Scalar::ZERO]; // Nm + + let W_l = vec![ + vec![Scalar::ZERO, Scalar::ONE, Scalar::ZERO, Scalar::ZERO], + vec![Scalar::ZERO, Scalar::ZERO.sub(&Scalar::ONE), Scalar::ONE, Scalar::ZERO], + ]; // Nl*Nw + + let a_l = vec![minus(&r), minus(&z)]; // Nl + + //let w_v = vec![Scalar::from(x), Scalar::from(y)]; + //let w = vec![Scalar::from(x), Scalar::from(y), Scalar::from(z), Scalar::from(r)]; // w = wl||wr||wo + //println!("Circuit check: {:?} = {:?}", vector_mul(&W_m[0], &w), vector_hadamard_mul(&w_l, &w_r)); + //println!("Circuit check: {:?} = 0", vector_add(&vector_add(&vec![vector_mul(&W_l[0], &w), vector_mul(&W_l[1], &w)], &w_v), &a_l)); + + let mut rand = OsRng::default(); + + let g = k256::ProjectivePoint::random(&mut rand); + let g_vec = (0..1).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::>(); + let h_vec = (0..16).map(|_| k256::ProjectivePoint::random(&mut rand)).collect::>(); + + let partition = |typ: PartitionType, index: usize| -> Option{ + match typ { + PartitionType::LL => Some(index), + _ => None + } + }; + + let circuit = ArithmeticCircuit { + dim_nm, + dim_no, + k, + dim_nl, + dim_nv, + dim_nw, + g, + g_vec: g_vec[..dim_nm].to_vec(), + h_vec: h_vec[..9 + dim_nv].to_vec(), + W_m, + W_l, + a_m, + a_l, + f_l: true, + f_m: false, + g_vec_: g_vec[dim_nm..].to_vec(), + h_vec_: h_vec[9 + dim_nv..].to_vec(), + partition, + }; + + let witness = Witness { + v: vec![vec![x, y]], + s_v: vec![k256::Scalar::generate_biased(&mut rand)], + w_l, + w_r, + w_o, + }; + + let v = (0..k).map(|i| circuit.commit(&witness.v[i], &witness.s_v[i])).collect::>(); + + let mut pt = merlin::Transcript::new(b"circuit test"); + let proof = circuit.prove::(&v, witness, &mut pt, &mut rand); + + println!("{}", serde_json::to_string_pretty(&circuit::SerializableProof::from(&proof)).unwrap()); + + let mut vt = merlin::Transcript::new(b"circuit test"); + assert!(circuit.verify(&v, &mut vt, proof)); } + +#[test] +fn wnla_works() { + const N: i32 = 4; + + let mut rand = OsRng::default(); + + let g = k256::ProjectivePoint::random(&mut rand); + let g_vec = (0..N).map(|_| k256::ProjectivePoint::random(&mut rand)).collect(); + let h_vec = (0..N).map(|_| k256::ProjectivePoint::random(&mut rand)).collect(); + let c = (0..N).map(|_| k256::Scalar::generate_biased(&mut rand)).collect(); + let rho = k256::Scalar::generate_biased(&mut rand); + + let wnla = wnla::WeightNormLinearArgument { + g, + g_vec, + h_vec, + c, + rho, + mu: rho.mul(&rho), + }; + + let l = vec![Scalar::from(1 as u32), Scalar::from(2 as u32), Scalar::from(3 as u32), Scalar::from(4 as u32)]; + let n = vec![Scalar::from(8 as u32), Scalar::from(7 as u32), Scalar::from(6 as u32), Scalar::from(5 as u32)]; + + let commit = wnla.commit(&l, &n); + let mut pt = merlin::Transcript::new(b"wnla test"); + + let proof = wnla.prove(&commit, &mut pt, l, n); + + println!("{}", serde_json::to_string_pretty(&wnla::SerializableProof::from(&proof)).unwrap()); + + let mut vt = merlin::Transcript::new(b"wnla test"); + assert!(wnla.verify(&commit, &mut vt, proof)) +} +