From 4b62120c6db7c933c0d250f4205c2e0ef459af9e Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sat, 5 Dec 2020 21:31:12 +0700 Subject: [PATCH 1/8] Upgrade inner_product --- Cargo.toml | 3 +- src/lib.rs | 40 ++++ src/proofs/inner_product.rs | 380 ++++++++++++++++++++---------------- src/proofs/mod.rs | 9 +- src/proofs/test_utils.rs | 8 + 5 files changed, 270 insertions(+), 170 deletions(-) create mode 100644 src/proofs/test_utils.rs diff --git a/Cargo.toml b/Cargo.toml index d070d85..6df3a4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,8 +18,9 @@ serde_derive = "1.0" [dev-dependencies] criterion = "0.2" +paste = "1.0.3" [[bench]] name = "range_proof" path = "benches/range_proof.rs" -harness = false \ No newline at end of file +harness = false diff --git a/src/lib.rs b/src/lib.rs index 1009f2a..6c1aa76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,3 +29,43 @@ pub enum Errors { WeightedInnerProdError, RangeProofError, } + +#[cfg(test)] +#[macro_export] +macro_rules! test_for_all_curves { + (#[should_panic] $fn: ident) => { + crate::test_for_all_curves!([#[should_panic]] $fn); + }; + ($fn: ident) => { + crate::test_for_all_curves!([] $fn); + }; + ([$($attrs:tt)*] $fn: ident) => { + paste::paste!{ + #[test] + $($attrs)* + fn [<$fn _secp256k1>]() { + $fn::() + } + #[test] + $($attrs)* + fn [<$fn _ristretto>]() { + $fn::() + } + #[test] + $($attrs)* + fn [<$fn _ed25519>]() { + $fn::() + } + #[test] + $($attrs)* + fn [<$fn _bls12_381>]() { + $fn::() + } + #[test] + $($attrs)* + fn [<$fn _p256>]() { + $fn::() + } + } + }; +} diff --git a/src/proofs/inner_product.rs b/src/proofs/inner_product.rs index 4f18303..ad1f9f7 100644 --- a/src/proofs/inner_product.rs +++ b/src/proofs/inner_product.rs @@ -21,31 +21,31 @@ use curv::cryptographic_primitives::hashing::hash_sha256::HSha256; use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; use curv::BigInt; -type GE = curv::elliptic::curves::secp256_k1::GE; -type FE = curv::elliptic::curves::secp256_k1::FE; - use Errors::{self, InnerProductError}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct InnerProductArg { - pub(super) L: Vec, - pub(super) R: Vec, +pub struct InnerProductArg { + pub(super) L: Vec

, + pub(super) R: Vec

, pub(super) a_tag: BigInt, pub(super) b_tag: BigInt, } -impl InnerProductArg { +impl

InnerProductArg

+where P: ECPoint + Clone, + P::Scalar: Clone, +{ pub fn prove( - G: &[GE], - H: &[GE], - ux: &GE, - P: &GE, + G: &[P], + H: &[P], + ux: &P, + P: &P, a: &[BigInt], b: &[BigInt], - mut L_vec: Vec, - mut R_vec: Vec, - ) -> InnerProductArg { + mut L_vec: Vec

, + mut R_vec: Vec

, + ) -> InnerProductArg

{ let n = G.len(); // All of the input vectors must have the same length. @@ -64,19 +64,19 @@ impl InnerProductArg { let (G_L, G_R) = G.split_at(n); let (H_L, H_R) = H.split_at(n); - let c_L = inner_product(&a_L, &b_R); - let c_R = inner_product(&a_R, &b_L); + let c_L = inner_product(&a_L, &b_R, &P::Scalar::q()); + let c_R = inner_product(&a_R, &b_L, &P::Scalar::q()); // Note that no element in vectors a_L and b_R can be 0 // since 0 is an invalid secret key! // // L = + + c_L * ux - let c_L_fe: FE = ECScalar::from(&c_L); - let ux_CL: GE = ux * &c_L_fe; + let c_L_fe: P::Scalar = ECScalar::from(&c_L); + let ux_CL: P = ux.clone() * c_L_fe.clone(); let aL_GR = G_R.iter().zip(a_L.clone()).fold(ux_CL, |acc, x| { if x.1 != &BigInt::zero() { - let aLi: FE = ECScalar::from(&x.1); - let aLi_GRi: GE = x.0 * &aLi; + let aLi: P::Scalar = ECScalar::from(&x.1); + let aLi_GRi: P = x.0.clone() * aLi; acc.add_point(&aLi_GRi.get_element()) } else { acc @@ -84,8 +84,8 @@ impl InnerProductArg { }); let L = H_L.iter().zip(b_R.clone()).fold(aL_GR, |acc, x| { if x.1 != &BigInt::zero() { - let bRi: FE = ECScalar::from(&x.1); - let bRi_HLi: GE = x.0 * &bRi; + let bRi: P::Scalar = ECScalar::from(&x.1); + let bRi_HLi: P = x.0.clone() * bRi; acc.add_point(&bRi_HLi.get_element()) } else { acc @@ -96,12 +96,12 @@ impl InnerProductArg { // since 0 is an invalid secret key! // // R = + + c_R * ux - let c_R_fe: FE = ECScalar::from(&c_R); - let ux_CR: GE = ux * &c_R_fe; + let c_R_fe: P::Scalar = ECScalar::from(&c_R); + let ux_CR: P = ux.clone() * c_R_fe; let aR_GL = G_L.iter().zip(a_R.clone()).fold(ux_CR, |acc, x| { if x.1 != &BigInt::zero() { - let aRi: FE = ECScalar::from(&x.1); - let aRi_GLi: GE = x.0 * &aRi; + let aRi: P::Scalar = ECScalar::from(&x.1); + let aRi_GLi: P = x.0.clone() * aRi; acc.add_point(&aRi_GLi.get_element()) } else { acc @@ -109,8 +109,8 @@ impl InnerProductArg { }); let R = H_R.iter().zip(b_L.clone()).fold(aR_GL, |acc, x| { if x.1 != &BigInt::zero() { - let bLi: FE = ECScalar::from(&x.1); - let bLi_HRi: GE = x.0 * &bLi; + let bLi: P::Scalar = ECScalar::from(&x.1); + let bLi_HRi: P = x.0.clone() * bLi; acc.add_point(&bLi_HRi.get_element()) } else { acc @@ -119,7 +119,7 @@ impl InnerProductArg { let x = HSha256::create_hash_from_ge(&[&L, &R, &ux]); let x_bn = x.to_big_int(); - let order = FE::q(); + let order = ::q(); let x_inv_fe = x.invert(); let a_new = (0..n) @@ -142,20 +142,20 @@ impl InnerProductArg { let G_new = (0..n) .map(|i| { - let GLx_inv = &G_L[i] * &x_inv_fe; - let GRx = &G_R[i] * &x; + let GLx_inv = G_L[i].clone() * x_inv_fe.clone(); + let GRx = G_R[i].clone() * x.clone(); GRx + GLx_inv }) - .collect::>(); + .collect::>(); // G = &mut G_new[..]; let H_new = (0..n) .map(|i| { - let HLx = &H_L[i] * &x; - let HRx_inv = &H_R[i] * &x_inv_fe; + let HLx = H_L[i].clone() * x.clone(); + let HRx_inv = H_R[i].clone() * x_inv_fe.clone(); HLx + HRx_inv }) - .collect::>(); + .collect::>(); // H = &mut H_new[..]; L_vec.push(L); @@ -171,7 +171,7 @@ impl InnerProductArg { } } - pub fn verify(&self, g_vec: &[GE], hi_tag: &[GE], ux: &GE, P: &GE) -> Result<(), Errors> { + pub fn verify(&self, g_vec: &[P], hi_tag: &[P], ux: &P, P: &P) -> Result<(), Errors> { let G = &g_vec[..]; let H = &hi_tag[..]; let n = G.len(); @@ -188,34 +188,34 @@ impl InnerProductArg { let x = HSha256::create_hash_from_ge(&[&self.L[0], &self.R[0], &ux]); let x_bn = x.to_big_int(); - let order = FE::q(); + let order = ::q(); let x_inv_fe = x.invert(); let x_sq_bn = BigInt::mod_mul(&x_bn, &x_bn, &order); let x_inv_sq_bn = BigInt::mod_mul(&x_inv_fe.to_big_int(), &x_inv_fe.to_big_int(), &order); - let x_sq_fe: FE = ECScalar::from(&x_sq_bn); - let x_inv_sq_fe: FE = ECScalar::from(&x_inv_sq_bn); + let x_sq_fe: P::Scalar = ECScalar::from(&x_sq_bn); + let x_inv_sq_fe: P::Scalar = ECScalar::from(&x_inv_sq_bn); let G_new = (0..n) .map(|i| { - let GLx_inv = &G_L[i] * &x_inv_fe; - let GRx = &G_R[i] * &x; + let GLx_inv = G_L[i].clone() * x_inv_fe.clone(); + let GRx = G_R[i].clone() * x.clone(); GRx + GLx_inv }) - .collect::>(); + .collect::>(); // G = &mut G_new[..]; let H_new = (0..n) .map(|i| { - let HLx = &H_L[i] * &x; - let HRx_inv = &H_R[i] * &x_inv_fe; + let HLx = H_L[i].clone() * x.clone(); + let HRx_inv = H_R[i].clone() * x_inv_fe.clone(); HLx + HRx_inv }) - .collect::>(); + .collect::>(); // H = &mut H_new[..]; - let Lx_sq = &self.L[0] * &x_sq_fe; - let Rx_sq_inv = &self.R[0] * &x_inv_sq_fe; - let P_tag = Lx_sq + Rx_sq_inv + P; + let Lx_sq = self.L[0].clone() * x_sq_fe.clone(); + let Rx_sq_inv = self.R[0].clone() * x_inv_sq_fe.clone(); + let P_tag = Lx_sq + Rx_sq_inv + P.clone(); let ip = InnerProductArg { L: (&self.L[1..]).to_vec(), R: (&self.R[1..]).to_vec(), @@ -225,12 +225,12 @@ impl InnerProductArg { return ip.verify(&G_new, &H_new, ux, &P_tag); } - let a_fe: FE = ECScalar::from(&self.a_tag); - let b_fe: FE = ECScalar::from(&self.b_tag); + let a_fe: P::Scalar = ECScalar::from(&self.a_tag); + let b_fe: P::Scalar = ECScalar::from(&self.b_tag); let c = a_fe.mul(&b_fe.get_element()); - let Ga = &G[0] * &a_fe; - let Hb = &H[0] * &b_fe; - let ux_c = ux * &c; + let Ga = G[0].clone() * a_fe.clone(); + let Hb = H[0].clone() * b_fe.clone(); + let ux_c = ux.clone() * c.clone(); let P_calc = Ga + Hb + ux_c; if P.clone() == P_calc { Ok(()) @@ -246,11 +246,11 @@ impl InnerProductArg { /// Uses a single multiexponentiation (multiscalar multiplication in additive notation) /// check to verify an inner product proof. /// - pub fn fast_verify(&self, g_vec: &[GE], hi_tag: &[GE], ux: &GE, P: &GE) -> Result<(), Errors> { + pub fn fast_verify(&self, g_vec: &[P], hi_tag: &[P], ux: &P, P: &P) -> Result<(), Errors> { let G = &g_vec[..]; let H = &hi_tag[..]; let n = G.len(); - let order = FE::q(); + let order = ::q(); // All of the input vectors must have the same length. assert_eq!(G.len(), n); @@ -269,7 +269,7 @@ impl InnerProductArg { let mut minus_x_inv_sq_vec: Vec = Vec::with_capacity(lg_n); let mut allinv = BigInt::one(); for (Li, Ri) in self.L.iter().zip(self.R.iter()) { - let x = HSha256::create_hash_from_ge::(&[Li, Ri, ux]); + let x = HSha256::create_hash_from_ge::

(&[Li, Ri, ux]); let x_bn = x.to_big_int(); let x_inv_fe = x.invert(); let x_inv_bn = x_inv_fe.to_big_int(); @@ -313,20 +313,20 @@ impl InnerProductArg { scalars.extend_from_slice(&minus_x_sq_vec); scalars.extend_from_slice(&minus_x_inv_sq_vec); - let mut points: Vec = Vec::with_capacity(2 * n + 2 * lg_n + 1); + let mut points: Vec

= Vec::with_capacity(2 * n + 2 * lg_n + 1); points.extend_from_slice(g_vec); points.extend_from_slice(hi_tag); points.extend_from_slice(&self.L); points.extend_from_slice(&self.R); let c = BigInt::mod_mul(&self.a_tag, &self.b_tag, &order); - let ux_c = ux * &ECScalar::from(&c); + let ux_c = ux.clone() * ECScalar::from(&c); let tot_len = points.len(); let expect_P = (0..tot_len) - .map(|i| points[i] * &ECScalar::from(&scalars[i])) - .fold(ux_c, |acc, x| acc + x as GE); + .map(|i| points[i].clone() * ECScalar::from(&scalars[i])) + .fold(ux_c, |acc, x| acc + x as P); if *P == expect_P { Ok(()) @@ -336,17 +336,16 @@ impl InnerProductArg { } } -fn inner_product(a: &[BigInt], b: &[BigInt]) -> BigInt { +fn inner_product(a: &[BigInt], b: &[BigInt], order: &BigInt) -> BigInt { assert_eq!( a.len(), b.len(), "inner_product(a,b): lengths of vectors do not match" ); let out = BigInt::zero(); - let order = FE::q(); let out = a.iter().zip(b).fold(out, |acc, x| { - let aibi = BigInt::mod_mul(x.0, x.1, &order); - BigInt::mod_add(&acc, &aibi, &order) + let aibi = BigInt::mod_mul(x.0, x.1, order); + BigInt::mod_add(&acc, &aibi, order) }); return out; } @@ -358,12 +357,14 @@ mod tests { use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; use curv::BigInt; - use curv::elliptic::curves::secp256_k1::GE; - use curv::elliptic::curves::secp256_k1::FE; use proofs::inner_product::InnerProductArg; - use proofs::range_proof::generate_random_point; + use proofs::test_utils::generate_random_point; + use crate::test_for_all_curves; - fn test_helper(n: usize) { + fn test_helper

(n: usize) + where P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -373,7 +374,7 @@ mod tests { let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..n) @@ -382,57 +383,57 @@ mod tests { let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let Gx = generate_random_point(&Converter::to_vec(&hash)); + let Gx: P = generate_random_point(&Converter::to_vec(&hash)); let a: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); let b: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); - let c = super::inner_product(&a, &b); + let c = super::inner_product(&a, &b, &P::Scalar::q()); - let y: FE = ECScalar::new_random(); - let order = FE::q(); + let y: P::Scalar = ECScalar::new_random(); + let order = ::q(); let yi = (0..n) .map(|i| BigInt::mod_pow(&y.to_big_int(), &BigInt::from(i as u32), &order)) .collect::>(); let yi_inv = (0..n) .map(|i| { - let yi_fe: FE = ECScalar::from(&yi[i]); + let yi_fe: P::Scalar = ECScalar::from(&yi[i]); yi_fe.invert() }) - .collect::>(); + .collect::>(); - let hi_tag = (0..n).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..n).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); // R = + + c * ux - let c_fe: FE = ECScalar::from(&c); - let ux_c: GE = &Gx * &c_fe; + let c_fe: P::Scalar = ECScalar::from(&c); + let ux_c: P = Gx.clone() * c_fe.clone(); let a_G = (0..n) .map(|i| { - let ai: FE = ECScalar::from(&a[i]); - &g_vec[i] * &ai + let ai: P::Scalar = ECScalar::from(&a[i]); + g_vec[i].clone() * ai.clone() }) - .fold(ux_c, |acc, x: GE| acc + x as GE); + .fold(ux_c, |acc, x: P| acc + x as P); let P = (0..n) .map(|i| { - let bi: FE = ECScalar::from(&b[i]); - &hi_tag[i] * &bi + let bi: P::Scalar = ECScalar::from(&b[i]); + hi_tag[i].clone() * bi.clone() }) - .fold(a_G, |acc, x: GE| acc + x as GE); + .fold(a_G, |acc, x: P| acc + x as P); let L_vec = Vec::with_capacity(n); let R_vec = Vec::with_capacity(n); @@ -441,7 +442,10 @@ mod tests { assert!(verifier.is_ok()) } - fn test_helper_fast_verify(n: usize) { + fn test_helper_fast_verify

(n: usize) + where P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -451,7 +455,7 @@ mod tests { let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..n) @@ -460,57 +464,57 @@ mod tests { let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let Gx = generate_random_point(&Converter::to_vec(&hash)); + let Gx: P = generate_random_point(&Converter::to_vec(&hash)); let a: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); let b: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); - let c = super::inner_product(&a, &b); + let c = super::inner_product(&a, &b, &P::Scalar::q()); - let y: FE = ECScalar::new_random(); - let order = FE::q(); + let y: P::Scalar = ECScalar::new_random(); + let order = ::q(); let yi = (0..n) .map(|i| BigInt::mod_pow(&y.to_big_int(), &BigInt::from(i as u32), &order)) .collect::>(); let yi_inv = (0..n) .map(|i| { - let yi_fe: FE = ECScalar::from(&yi[i]); + let yi_fe: P::Scalar = ECScalar::from(&yi[i]); yi_fe.invert() }) - .collect::>(); + .collect::>(); - let hi_tag = (0..n).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..n).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); // R = + + c * ux - let c_fe: FE = ECScalar::from(&c); - let ux_c: GE = &Gx * &c_fe; + let c_fe: P::Scalar = ECScalar::from(&c); + let ux_c: P = Gx.clone() * c_fe.clone(); let a_G = (0..n) .map(|i| { - let ai: FE = ECScalar::from(&a[i]); - &g_vec[i] * &ai + let ai: P::Scalar = ECScalar::from(&a[i]); + g_vec[i].clone() * ai.clone() }) - .fold(ux_c, |acc, x: GE| acc + x as GE); + .fold(ux_c, |acc, x: P| acc + x as P); let P = (0..n) .map(|i| { - let bi: FE = ECScalar::from(&b[i]); - &hi_tag[i] * &bi + let bi: P::Scalar = ECScalar::from(&b[i]); + hi_tag[i].clone() * bi.clone() }) - .fold(a_G, |acc, x: GE| acc + x as GE); + .fold(a_G, |acc, x: P| acc + x as P); let L_vec = Vec::with_capacity(n); let R_vec = Vec::with_capacity(n); @@ -519,7 +523,10 @@ mod tests { assert!(verifier.is_ok()) } - fn test_helper_non_power_2(m: usize, n: usize, a: &[BigInt], b: &[BigInt]) { + fn test_helper_non_power_2

(m: usize, n: usize, a: &[BigInt], b: &[BigInt]) + where P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -529,7 +536,7 @@ mod tests { let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..n) @@ -538,46 +545,46 @@ mod tests { let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let Gx = generate_random_point(&Converter::to_vec(&hash)); + let Gx: P = generate_random_point(&Converter::to_vec(&hash)); - let c = super::inner_product(&a, &b); + let c = super::inner_product(&a, &b, &P::Scalar::q()); - let y: FE = ECScalar::new_random(); - let order = FE::q(); + let y: P::Scalar = ECScalar::new_random(); + let order = ::q(); let yi = (0..n) .map(|i| BigInt::mod_pow(&y.to_big_int(), &BigInt::from(i as u32), &order)) .collect::>(); let yi_inv = (0..n) .map(|i| { - let yi_fe: FE = ECScalar::from(&yi[i]); + let yi_fe: P::Scalar = ECScalar::from(&yi[i]); yi_fe.invert() }) - .collect::>(); + .collect::>(); - let hi_tag = (0..n).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..n).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); // R = + + c * ux - let c_fe: FE = ECScalar::from(&c); + let c_fe: P::Scalar = ECScalar::from(&c); - let ux_c: GE = &Gx * &c_fe; + let ux_c: P = Gx.clone() * c_fe.clone(); let a_G = (0..m) .map(|i| { - let ai: FE = ECScalar::from(&a[i]); - &g_vec[i] * &ai + let ai: P::Scalar = ECScalar::from(&a[i]); + g_vec[i].clone() * ai.clone() }) - .fold(ux_c, |acc, x: GE| acc + x as GE); + .fold(ux_c, |acc, x: P| acc + x as P); let P = (0..m) .map(|i| { - let bi: FE = ECScalar::from(&b[i]); - &hi_tag[i] * &bi + let bi: P::Scalar = ECScalar::from(&b[i]); + hi_tag[i].clone() * bi.clone() }) - .fold(a_G, |acc, x: GE| acc + x as GE); + .fold(a_G, |acc, x: P| acc + x as P); let L_vec = Vec::with_capacity(n); let R_vec = Vec::with_capacity(n); @@ -586,78 +593,119 @@ mod tests { assert!(verifier.is_ok()) } - #[test] - fn make_ipp_32() { - test_helper(32); + test_for_all_curves!(make_ipp_32); + fn make_ipp_32

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(32); } - #[test] - fn make_ipp_16() { - test_helper(16); + test_for_all_curves!(make_ipp_16); + fn make_ipp_16

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(16); } - #[test] - fn make_ipp_8() { - test_helper(8); + + test_for_all_curves!(make_ipp_8); + fn make_ipp_8

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(8); } - #[test] - fn make_ipp_4() { - test_helper(4); + test_for_all_curves!(make_ipp_4); + fn make_ipp_4

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(4); } - #[test] - fn make_ipp_2() { - test_helper(2); + test_for_all_curves!(make_ipp_2); + fn make_ipp_2

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(2); } - #[test] - fn make_ipp_1() { - test_helper(1); + test_for_all_curves!(make_ipp_1); + fn make_ipp_1

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(1); } - #[test] - fn make_ipp_32_fast_verify() { - test_helper_fast_verify(32); + test_for_all_curves!(make_ipp_32_fast_verify); + fn make_ipp_32_fast_verify

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(32); } - #[test] - fn make_ipp_16_fast_verify() { - test_helper_fast_verify(16); + test_for_all_curves!(make_ipp_16_fast_verify); + fn make_ipp_16_fast_verify

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(16); } - #[test] - fn make_ipp_8_fast_verify() { - test_helper_fast_verify(8); + + test_for_all_curves!(make_ipp_8_fast_verify); + fn make_ipp_8_fast_verify

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(8); } - #[test] - fn make_ipp_4_fast_verify() { - test_helper_fast_verify(4); + test_for_all_curves!(make_ipp_4_fast_verify); + fn make_ipp_4_fast_verify

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(4); } - #[test] - fn make_ipp_2_fast_verify() { - test_helper_fast_verify(2); + test_for_all_curves!(make_ipp_2_fast_verify); + fn make_ipp_2_fast_verify

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(2); } - #[test] - fn make_ipp_1_fast_verify() { - test_helper_fast_verify(1); + test_for_all_curves!(make_ipp_1_fast_verify); + fn make_ipp_1_fast_verify

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(1); } - #[test] - fn make_ipp_non_power_2() { + test_for_all_curves!(make_ipp_non_power_2); + fn make_ipp_non_power_2

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { // Create random scalar vectors a, b with size non-power of 2 let n: usize = 9; let mut a: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); let mut b: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); @@ -673,6 +721,6 @@ mod tests { // let mut padded_b = b.clone(); b.extend_from_slice(&zero_append_vec); - test_helper_non_power_2(n, _n, &a, &b); + test_helper_non_power_2::

(n, _n, &a, &b); } } diff --git a/src/proofs/mod.rs b/src/proofs/mod.rs index 56a0b9b..1291758 100644 --- a/src/proofs/mod.rs +++ b/src/proofs/mod.rs @@ -15,7 +15,10 @@ version 3 of the License, or (at your option) any later version. // based on the paper: https://eprint.iacr.org/2017/1066.pdf +#[cfg(test)] +mod test_utils; + pub mod inner_product; -pub mod range_proof; -pub mod range_proof_wip; -pub mod weighted_inner_product; +// pub mod range_proof; +// pub mod range_proof_wip; +// pub mod weighted_inner_product; diff --git a/src/proofs/test_utils.rs b/src/proofs/test_utils.rs new file mode 100644 index 0000000..70e82b8 --- /dev/null +++ b/src/proofs/test_utils.rs @@ -0,0 +1,8 @@ +use curv::elliptic::curves::traits::*; +use curv::arithmetic::big_gmp::*; + +pub fn generate_random_point(random_source: &[u8]) -> P { + let bn = BigInt::from(random_source); + let scalar = ::from(&bn); + P::generator() * scalar +} From b91f1bb2b7267706926055365adef3a4d7026cb2 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sun, 6 Dec 2020 13:55:42 +0700 Subject: [PATCH 2/8] Update range_proof --- src/proofs/mod.rs | 2 +- src/proofs/range_proof.rs | 479 +++++++++++++++++++------------------- 2 files changed, 245 insertions(+), 236 deletions(-) diff --git a/src/proofs/mod.rs b/src/proofs/mod.rs index 1291758..3f99a51 100644 --- a/src/proofs/mod.rs +++ b/src/proofs/mod.rs @@ -19,6 +19,6 @@ version 3 of the License, or (at your option) any later version. mod test_utils; pub mod inner_product; -// pub mod range_proof; +pub mod range_proof; // pub mod range_proof_wip; // pub mod weighted_inner_product; diff --git a/src/proofs/range_proof.rs b/src/proofs/range_proof.rs index 5ecdd9a..8d3fd6d 100644 --- a/src/proofs/range_proof.rs +++ b/src/proofs/range_proof.rs @@ -21,8 +21,6 @@ use curv::cryptographic_primitives::hashing::hash_sha256::HSha256; use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; use curv::BigInt; -type GE = curv::elliptic::curves::secp256_k1::GE; -type FE = curv::elliptic::curves::secp256_k1::FE; use itertools::iterate; use proofs::inner_product::InnerProductArg; @@ -30,45 +28,47 @@ use std::ops::{Shl, Shr}; use Errors::{self, RangeProofError}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct RangeProof { - A: GE, - S: GE, - T1: GE, - T2: GE, - tau_x: FE, - miu: FE, - tx: FE, - inner_product_proof: InnerProductArg, +pub struct RangeProof { + A: P, + S: P, + T1: P, + T2: P, + tau_x: P::Scalar, + miu: P::Scalar, + tx: P::Scalar, + inner_product_proof: InnerProductArg

, } -impl RangeProof { +impl

RangeProof

+where P: ECPoint + Clone, + P::Scalar: Clone, +{ pub fn prove( - g_vec: &[GE], - h_vec: &[GE], - G: &GE, - H: &GE, - mut secret: Vec, - blinding: &[FE], + g_vec: &[P], + h_vec: &[P], + G: &P, + H: &P, + secret: Vec, + blinding: &[P::Scalar], bit_length: usize, - ) -> RangeProof { + ) -> RangeProof

{ let num_of_proofs = secret.len(); //num of proofs times bit length let nm = num_of_proofs * bit_length; - let alpha: FE = ECScalar::new_random(); - let rho: FE = ECScalar::new_random(); + let alpha: P::Scalar = ECScalar::new_random(); + let rho: P::Scalar = ECScalar::new_random(); let g_vec = g_vec.to_vec(); let h_vec = h_vec.to_vec(); - let mut A = H * α - let mut S = H * ρ + let mut A = H.clone() * alpha.clone(); + let mut S = H.clone() * rho.clone(); let two = BigInt::from(2); let one = BigInt::from(1); - let order = FE::q(); + let order = ::q(); //concat all secrets: - secret.reverse(); - let secret_agg = secret.iter().fold(BigInt::zero(), |acc, x| { + let secret_agg = secret.iter().rev().fold(BigInt::zero(), |acc, x| { acc.shl(bit_length) + x.to_big_int() }); @@ -106,37 +106,37 @@ impl RangeProof { } }); - let SR = (0..nm).map(|_| ECScalar::new_random()).collect::>(); - let SL = (0..nm).map(|_| ECScalar::new_random()).collect::>(); + let SR = (0..nm).map(|_| ECScalar::new_random()).collect::>(); + let SL = (0..nm).map(|_| ECScalar::new_random()).collect::>(); S = SL.iter().zip(&SR).fold(S, |acc, x| { - let g_vec_i_SLi = &g_vec[index] * x.0; - let h_vec_i_SRi = &h_vec[index] * x.1; + let g_vec_i_SLi = g_vec[index].clone() * x.0.clone(); + let h_vec_i_SRi = h_vec[index].clone() * x.1.clone(); index = index + 1; let SRhi_plus_SLgi = h_vec_i_SRi + g_vec_i_SLi; acc + SRhi_plus_SLgi }); let y = HSha256::create_hash_from_ge(&[&A, &S]); - let base_point: GE = ECPoint::generator(); - let yG: GE = base_point * &y; + let base_point: P = ECPoint::generator(); + let yG: P = base_point * y.clone(); let z = HSha256::create_hash_from_ge(&[&yG]); let z_bn = z.to_big_int(); - let one_fe: FE = ECScalar::from(&one); - let yi = iterate(one_fe.clone(), |i| i.clone() * &y) + let one_fe: P::Scalar = ECScalar::from(&one); + let yi = iterate(one_fe.clone(), |i| i.clone() * y.clone()) .take(nm) - .collect::>(); + .collect::>(); let t2 = (0..nm) - .map(|i| SR[i].clone() * &yi[i] * &SL[i]) - .fold(FE::zero(), |acc, x| acc + x); + .map(|i| SR[i].clone() * yi[i].clone() * SL[i].clone()) + .fold(::zero(), |acc, x| acc + x); let t2 = t2.to_big_int(); - let two_fe: FE = ECScalar::from(&two); - let vec_2n = iterate(one_fe.clone(), |i| i.clone() * &two_fe) + let two_fe: P::Scalar = ECScalar::from(&two); + let vec_2n = iterate(one_fe.clone(), |i| i.clone() * two_fe.clone()) .take(bit_length) - .collect::>(); + .collect::>(); let t1 = (0..nm) .map(|i| { @@ -157,12 +157,12 @@ impl RangeProof { }) .fold(BigInt::zero(), |acc, x| BigInt::mod_add(&acc, &x, &order)); - let tau1: FE = ECScalar::new_random(); - let tau2: FE = ECScalar::new_random(); - let t1_fe = ECScalar::from(&t1); - let t2_fe = ECScalar::from(&t2); - let T1 = G * &t1_fe + H * &tau1; - let T2 = G * &t2_fe + H * &tau2; + let tau1: P::Scalar = ECScalar::new_random(); + let tau2: P::Scalar = ECScalar::new_random(); + let t1_fe: P::Scalar = ECScalar::from(&t1); + let t2_fe: P::Scalar = ECScalar::from(&t2); + let T1 = G.clone() * t1_fe.clone() + H.clone() * tau1.clone(); + let T2 = G.clone() * t2_fe.clone() + H.clone() * tau2.clone(); let fs_challenge = HSha256::create_hash_from_ge(&[&T1, &T2, G, H]); let fs_challenge_square = fs_challenge.mul(&fs_challenge.get_element()); @@ -172,7 +172,7 @@ impl RangeProof { .map(|i| { let j = BigInt::mod_add(&two, &BigInt::from(i as u32), &order); let z_j = BigInt::mod_pow(&z_bn, &j, &order); - let z_j_fe: FE = ECScalar::from(&z_j); + let z_j_fe: P::Scalar = ECScalar::from(&z_j); z_j_fe.mul(&blinding[i].get_element()) }) .fold(taux_2, |acc, x| acc.add(&x.get_element())); @@ -205,31 +205,31 @@ impl RangeProof { let Lp_iRp_i = BigInt::mod_mul(x.0, x.1, &order); BigInt::mod_add(&acc, &Lp_iRp_i, &order) }); - let tx_fe: FE = ECScalar::from(&tx); + let tx_fe: P::Scalar = ECScalar::from(&tx); let challenge_x = HSha256::create_hash(&[&tau_x.to_big_int(), &miu.to_big_int(), &tx]); - let challenge_x: FE = ECScalar::from(&challenge_x); - let Gx = G * &challenge_x; + let challenge_x: P::Scalar = ECScalar::from(&challenge_x); + let Gx = G.clone() * challenge_x.clone(); // P' = u^{xc} - let P = &Gx * &tx_fe; + let P = Gx.clone() * tx_fe.clone(); let yi_inv = (0..nm) .map(|i| { - // let yi_fe: FE = ECScalar::from(&yi[i]); + // let yi_fe: P::Scalar = ECScalar::from(&yi[i]); // yi_fe.invert() yi[i].invert() }) - .collect::>(); + .collect::>(); - let hi_tag = (0..nm).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..nm).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); // P' = P' g^l let P = g_vec.iter().zip(&Lp).fold(P, |acc, x| { - let g_vec_i_lp_i = x.0 * &ECScalar::from(x.1); + let g_vec_i_lp_i = x.0.clone() * ECScalar::from(x.1); acc + g_vec_i_lp_i }); // P' = P' h'^r let P = hi_tag.iter().zip(&Rp).fold(P, |acc, x| { - let h_vec_i_rp_i = x.0 * &ECScalar::from(x.1); + let h_vec_i_rp_i = x.0.clone() * ECScalar::from(x.1); acc + h_vec_i_rp_i }); // line 9 @@ -254,42 +254,42 @@ impl RangeProof { pub fn verify( &self, - g_vec: &[GE], - h_vec: &[GE], - G: &GE, - H: &GE, - ped_com: &[GE], + g_vec: &[P], + h_vec: &[P], + G: &P, + H: &P, + ped_com: &[P], bit_length: usize, ) -> Result<(), Errors> { let num_of_proofs = ped_com.len(); let nm = num_of_proofs * bit_length; let y = HSha256::create_hash_from_ge(&[&self.A, &self.S]); - let base_point: GE = ECPoint::generator(); - let yG: GE = base_point * &y; + let base_point: P = ECPoint::generator(); + let yG: P = base_point * y.clone(); let z = HSha256::create_hash_from_ge(&[&yG]); let z_bn = z.to_big_int(); - let order = FE::q(); + let order = ::q(); let z_minus = BigInt::mod_sub(&order, &z.to_big_int(), &order); - let z_minus_fe: FE = ECScalar::from(&z_minus); + let z_minus_fe: P::Scalar = ECScalar::from(&z_minus); let z_squared = BigInt::mod_pow(&z.to_big_int(), &BigInt::from(2), &order); // delta(x,y): let one_bn = BigInt::one(); - let one_fe: FE = ECScalar::from(&one_bn); - let yi = iterate(one_fe.clone(), |i| i.clone() * &y) + let one_fe: P::Scalar = ECScalar::from(&one_bn); + let yi = iterate(one_fe.clone(), |i| i.clone() * y.clone()) .take(nm) - .collect::>(); + .collect::>(); - let scalar_mul_yn = yi.iter().fold(FE::zero(), |acc, x| acc + x); + let scalar_mul_yn = yi.iter().fold(::zero(), |acc, x| acc + x.clone()); let scalar_mul_yn = scalar_mul_yn.to_big_int(); let two = BigInt::from(2); - let two_fe: FE = ECScalar::from(&two); - let vec_2n = iterate(one_fe.clone(), |i| i.clone() * &two_fe) + let two_fe: P::Scalar = ECScalar::from(&two); + let vec_2n = iterate(one_fe.clone(), |i| i.clone() * two_fe.clone()) .take(bit_length) - .collect::>(); + .collect::>(); - let scalar_mul_2n = vec_2n.iter().fold(FE::zero(), |acc, x| acc + x); + let scalar_mul_2n = vec_2n.iter().fold(::zero(), |acc, x| acc + x.clone()); let scalar_mul_2n = scalar_mul_2n.to_big_int(); let z_cubed_scalar_mul_2n = (0..num_of_proofs) @@ -304,31 +304,31 @@ impl RangeProof { let z_minus_zsq_scalar_mul_yn = BigInt::mod_mul(&z_minus_zsq, &scalar_mul_yn, &order); let delta = BigInt::mod_sub(&z_minus_zsq_scalar_mul_yn, &z_cubed_scalar_mul_2n, &order); - let yi_inv = (0..nm).map(|i| yi[i].invert()).collect::>(); + let yi_inv = (0..nm).map(|i| yi[i].invert()).collect::>(); - let hi_tag = (0..nm).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..nm).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); let fs_challenge = HSha256::create_hash_from_ge(&[&self.T1, &self.T2, G, H]); let fs_challenge_square = fs_challenge.mul(&fs_challenge.get_element()); // eq 65: - let Gtx = G * &self.tx; - let Htaux = H * &self.tau_x; + let Gtx = G.clone() * self.tx.clone(); + let Htaux = H.clone() * self.tau_x.clone(); let left_side = Gtx + Htaux; - let delta_fe: FE = ECScalar::from(&delta); - let Gdelta = G * &delta_fe; - let Tx = &self.T1 * &fs_challenge; - let Tx_sq = &self.T2 * &fs_challenge_square; + let delta_fe: P::Scalar = ECScalar::from(&delta); + let Gdelta = G.clone() * delta_fe; + let Tx = self.T1.clone() * fs_challenge.clone(); + let Tx_sq = self.T2.clone() * fs_challenge_square.clone(); let mut vec_ped_zm = (0..num_of_proofs) .map(|i| { let z_2_m = BigInt::mod_pow(&z_bn, &BigInt::from((2 + i) as u32), &order); - let z_2_m_fe: FE = ECScalar::from(&z_2_m); - &ped_com[i] * &z_2_m_fe + let z_2_m_fe: P::Scalar = ECScalar::from(&z_2_m); + ped_com[i].clone() * z_2_m_fe.clone() }) - .collect::>(); + .collect::>(); let vec_ped_zm_1 = vec_ped_zm.remove(0); - let ped_com_sum = vec_ped_zm.iter().fold(vec_ped_zm_1, |acc, x| acc + x); + let ped_com_sum = vec_ped_zm.iter().fold(vec_ped_zm_1, |acc, x| acc + x.clone()); let right_side = ped_com_sum + Gdelta + Tx + Tx_sq; let challenge_x = HSha256::create_hash(&[ @@ -336,15 +336,15 @@ impl RangeProof { &self.miu.to_big_int(), &self.tx.to_big_int(), ]); - let challenge_x: FE = ECScalar::from(&challenge_x); - let Gx = G * &challenge_x; + let challenge_x: P::Scalar = ECScalar::from(&challenge_x); + let Gx = G.clone() * challenge_x.clone(); // P' = u^{xc} - let P = &Gx * &self.tx; - let minus_miu = BigInt::mod_sub(&FE::q(), &self.miu.to_big_int(), &FE::q()); - let minus_miu_fe: FE = ECScalar::from(&minus_miu); - let Hmiu = H * &minus_miu_fe; - let Sx = &self.S * &fs_challenge; + let P = Gx.clone() * self.tx.clone(); + let minus_miu = BigInt::mod_sub(&::q(), &self.miu.to_big_int(), &::q()); + let minus_miu_fe: P::Scalar = ECScalar::from(&minus_miu); + let Hmiu = H.clone() * minus_miu_fe.clone(); + let Sx = self.S.clone() * fs_challenge.clone(); let P = Hmiu + P + self.A.clone() + Sx; let P1 = (0..nm) @@ -356,13 +356,13 @@ impl RangeProof { let z_j_2_n = BigInt::mod_mul(&z_j, &vec_2n[k].to_big_int(), &order); // let z_sq_2n = BigInt::mod_mul(&z_squared, &vec_2n[i], &order); let zyn_zsq2n = BigInt::mod_add(&z_yn, &z_j_2_n, &order); - let zyn_zsq2n_fe: FE = ECScalar::from(&zyn_zsq2n); - &hi_tag[i] * &zyn_zsq2n_fe + let zyn_zsq2n_fe: P::Scalar = ECScalar::from(&zyn_zsq2n); + hi_tag[i].clone() * zyn_zsq2n_fe.clone() }) .fold(P, |acc, x| acc + x); let P = (0..nm) - .map(|i| &g_vec[i] * &z_minus_fe) + .map(|i| g_vec[i].clone() * z_minus_fe.clone()) .fold(P1, |acc, x| acc + x); let verify = self.inner_product_proof.verify(g_vec, &hi_tag, &Gx, &P); if verify.is_ok() && left_side == right_side { @@ -374,42 +374,42 @@ impl RangeProof { pub fn fast_verify( &self, - g_vec: &[GE], - h_vec: &[GE], - G: &GE, - H: &GE, - ped_com: &[GE], + g_vec: &[P], + h_vec: &[P], + G: &P, + H: &P, + ped_com: &[P], bit_length: usize, ) -> Result<(), Errors> { let num_of_proofs = ped_com.len(); let nm = num_of_proofs * bit_length; let y = HSha256::create_hash_from_ge(&[&self.A, &self.S]); - let base_point: GE = ECPoint::generator(); - let yG: GE = base_point * &y; + let base_point: P = ECPoint::generator(); + let yG: P = base_point * y.clone(); let z = HSha256::create_hash_from_ge(&[&yG]); let z_bn = z.to_big_int(); - let order = FE::q(); + let order = ::q(); let z_minus = BigInt::mod_sub(&order, &z.to_big_int(), &order); - let z_minus_fe: FE = ECScalar::from(&z_minus); + let z_minus_fe: P::Scalar = ECScalar::from(&z_minus); let z_squared = BigInt::mod_pow(&z.to_big_int(), &BigInt::from(2), &order); // delta(x,y): let one_bn = BigInt::one(); - let one_fe: FE = ECScalar::from(&one_bn); - let yi = iterate(one_fe.clone(), |i| i.clone() * &y) + let one_fe: P::Scalar = ECScalar::from(&one_bn); + let yi = iterate(one_fe.clone(), |i| i.clone() * y.clone()) .take(nm) - .collect::>(); + .collect::>(); - let scalar_mul_yn = yi.iter().fold(FE::zero(), |acc, x| acc + x); + let scalar_mul_yn = yi.iter().fold(::zero(), |acc, x| acc + x.clone()); let scalar_mul_yn = scalar_mul_yn.to_big_int(); let two = BigInt::from(2); - let two_fe: FE = ECScalar::from(&two); - let vec_2n = iterate(one_fe.clone(), |i| i.clone() * &two_fe) + let two_fe: P::Scalar = ECScalar::from(&two); + let vec_2n = iterate(one_fe.clone(), |i| i.clone() * two_fe.clone()) .take(bit_length) - .collect::>(); + .collect::>(); - let scalar_mul_2n = vec_2n.iter().fold(FE::zero(), |acc, x| acc + x); + let scalar_mul_2n = vec_2n.iter().fold(::zero(), |acc, x| acc + x.clone()); let scalar_mul_2n = scalar_mul_2n.to_big_int(); let z_cubed_scalar_mul_2n = (0..num_of_proofs) @@ -424,31 +424,31 @@ impl RangeProof { let z_minus_zsq_scalar_mul_yn = BigInt::mod_mul(&z_minus_zsq, &scalar_mul_yn, &order); let delta = BigInt::mod_sub(&z_minus_zsq_scalar_mul_yn, &z_cubed_scalar_mul_2n, &order); - let yi_inv = (0..nm).map(|i| yi[i].invert()).collect::>(); + let yi_inv = (0..nm).map(|i| yi[i].invert()).collect::>(); - let hi_tag = (0..nm).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..nm).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); let fs_challenge = HSha256::create_hash_from_ge(&[&self.T1, &self.T2, G, H]); let fs_challenge_square = fs_challenge.mul(&fs_challenge.get_element()); // eq 65: - let Gtx = G * &self.tx; - let Htaux = H * &self.tau_x; + let Gtx = G.clone() * self.tx.clone(); + let Htaux = H.clone() * self.tau_x.clone(); let left_side = Gtx + Htaux; - let delta_fe: FE = ECScalar::from(&delta); - let Gdelta = G * &delta_fe; - let Tx = &self.T1 * &fs_challenge; - let Tx_sq = &self.T2 * &fs_challenge_square; + let delta_fe: P::Scalar = ECScalar::from(&delta); + let Gdelta = G.clone() * delta_fe.clone(); + let Tx = self.T1.clone() * fs_challenge.clone(); + let Tx_sq = self.T2.clone() * fs_challenge_square.clone(); let mut vec_ped_zm = (0..num_of_proofs) .map(|i| { let z_2_m = BigInt::mod_pow(&z_bn, &BigInt::from((2 + i) as u32), &order); - let z_2_m_fe: FE = ECScalar::from(&z_2_m); - &ped_com[i] * &z_2_m_fe + let z_2_m_fe: P::Scalar = ECScalar::from(&z_2_m); + ped_com[i].clone() * z_2_m_fe.clone() }) - .collect::>(); + .collect::>(); let vec_ped_zm_1 = vec_ped_zm.remove(0); - let ped_com_sum = vec_ped_zm.iter().fold(vec_ped_zm_1, |acc, x| acc + x); + let ped_com_sum = vec_ped_zm.iter().fold(vec_ped_zm_1, |acc, x| acc + x.clone()); let right_side = ped_com_sum + Gdelta + Tx + Tx_sq; let challenge_x = HSha256::create_hash(&[ @@ -456,15 +456,15 @@ impl RangeProof { &self.miu.to_big_int(), &self.tx.to_big_int(), ]); - let challenge_x: FE = ECScalar::from(&challenge_x); - let Gx = G * &challenge_x; + let challenge_x: P::Scalar = ECScalar::from(&challenge_x); + let Gx = G.clone() * challenge_x.clone(); // P' = u^{xc} - let P = &Gx * &self.tx; - let minus_miu = BigInt::mod_sub(&FE::q(), &self.miu.to_big_int(), &FE::q()); - let minus_miu_fe: FE = ECScalar::from(&minus_miu); - let Hmiu = H * &minus_miu_fe; - let Sx = &self.S * &fs_challenge; + let P = Gx.clone() * self.tx.clone(); + let minus_miu = BigInt::mod_sub(&::q(), &self.miu.to_big_int(), &::q()); + let minus_miu_fe: P::Scalar = ECScalar::from(&minus_miu); + let Hmiu = H.clone() * minus_miu_fe.clone(); + let Sx = self.S.clone() * fs_challenge.clone(); let P = Hmiu + P + self.A.clone() + Sx; let P1 = (0..nm) @@ -476,13 +476,13 @@ impl RangeProof { let z_j_2_n = BigInt::mod_mul(&z_j, &vec_2n[k].to_big_int(), &order); // let z_sq_2n = BigInt::mod_mul(&z_squared, &vec_2n[i], &order); let zyn_zsq2n = BigInt::mod_add(&z_yn, &z_j_2_n, &order); - let zyn_zsq2n_fe: FE = ECScalar::from(&zyn_zsq2n); - &hi_tag[i] * &zyn_zsq2n_fe + let zyn_zsq2n_fe: P::Scalar = ECScalar::from(&zyn_zsq2n); + hi_tag[i].clone() * zyn_zsq2n_fe.clone() }) .fold(P, |acc, x| acc + x); let P = (0..nm) - .map(|i| &g_vec[i] * &z_minus_fe) + .map(|i| g_vec[i].clone() * z_minus_fe.clone()) .fold(P1, |acc, x| acc + x); let verify = self .inner_product_proof @@ -496,18 +496,18 @@ impl RangeProof { pub fn aggregated_verify( &self, - g_vec: &[GE], - h_vec: &[GE], - G: &GE, - H: &GE, - ped_com: &[GE], + g_vec: &[P], + h_vec: &[P], + G: &P, + H: &P, + ped_com: &[P], bit_length: usize, ) -> Result<(), Errors> { let n = bit_length; let m = ped_com.len(); let nm = m * n; let lg_nm = self.inner_product_proof.L.len(); - let order = FE::q(); + let order = ::q(); let two = BigInt::from(2); let one = BigInt::from(1); let zero = BigInt::zero(); @@ -525,8 +525,8 @@ impl RangeProof { let y = HSha256::create_hash_from_ge(&[&self.A, &self.S]); let y_bn = y.to_big_int(); let y_inv_bn = BigInt::mod_inv(&y_bn, &order); - let base_point: GE = ECPoint::generator(); - let yG: GE = base_point * &y; + let base_point: P = ECPoint::generator(); + let yG: P = base_point * y.clone(); let z = HSha256::create_hash_from_ge(&[&yG]); let z_bn = z.to_big_int(); let z_squared = BigInt::mod_pow(&z_bn, &BigInt::from(2), &order); @@ -541,8 +541,8 @@ impl RangeProof { ]); // ux = g^{x_u} - let x_u_fe: FE = ECScalar::from(&x_u); - let ux = G * &x_u_fe; + let x_u_fe: P::Scalar = ECScalar::from(&x_u); + let ux = G.clone() * x_u_fe.clone(); // generate a random scalar to combine 2 verification equations let challenge_ver = @@ -609,7 +609,7 @@ impl RangeProof { .iter() .zip(self.inner_product_proof.R.iter()) { - let x = HSha256::create_hash_from_ge::(&[&Li, &Ri, &ux]); + let x = HSha256::create_hash_from_ge::

(&[&Li, &Ri, &ux]); let x_bn = x.to_big_int(); let x_inv_fe = x.invert(); let x_inv_bn = x_inv_fe.to_big_int(); @@ -711,24 +711,24 @@ impl RangeProof { scalars.push(scalar_T2); // compute concatenated base vector - let mut points: Vec = Vec::with_capacity(2 * nm + 2 * lg_nm + m + 6); + let mut points: Vec

= Vec::with_capacity(2 * nm + 2 * lg_nm + m + 6); points.extend_from_slice(g_vec); points.extend_from_slice(h_vec); - points.push(*G); + points.push(G.clone()); // points.push(*H); // points.push(self.A); - points.push(self.S); + points.push(self.S.clone()); points.extend_from_slice(&self.inner_product_proof.L); points.extend_from_slice(&self.inner_product_proof.R); points.extend_from_slice(&ped_com); - points.push(self.T1); - points.push(self.T2); + points.push(self.T1.clone()); + points.push(self.T2.clone()); - let H_times_scalar_H = H * &ECScalar::from(&scalar_H); + let H_times_scalar_H = H.clone() * ECScalar::from(&scalar_H); let tot_len = points.len(); let lhs = (0..tot_len) - .map(|i| points[i] * &ECScalar::from(&scalars[i])) - .fold(H_times_scalar_H, |acc, x| acc + x as GE); + .map(|i| points[i].clone() * ECScalar::from(&scalars[i])) + .fold(H_times_scalar_H, |acc, x| acc + x as P); // single multi-exponentiation check if lhs == self.A { @@ -739,19 +739,6 @@ impl RangeProof { } } -pub fn generate_random_point(bytes: &[u8]) -> GE { - let result: Result = ECPoint::from_bytes(&bytes); - if result.is_ok() { - return result.unwrap(); - } else { - let two = BigInt::from(2); - let bn = BigInt::from(bytes); - let bn_times_two = BigInt::mod_mul(&bn, &two, &FE::q()); - let bytes = BigInt::to_vec(&bn_times_two); - return generate_random_point(&bytes); - } -} - #[cfg(test)] mod tests { use curv::arithmetic::traits::{Converter, Samplable}; @@ -759,18 +746,20 @@ mod tests { use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; use curv::BigInt; - type GE = curv::elliptic::curves::secp256_k1::GE; -type FE = curv::elliptic::curves::secp256_k1::FE; - use proofs::range_proof::generate_random_point; - use proofs::range_proof::RangeProof; + use super::RangeProof; + use proofs::test_utils::generate_random_point; + use crate::test_for_all_curves; - pub fn test_helper(seed: &BigInt, n: usize, m: usize) { + fn test_helper

(seed: &BigInt, n: usize, m: usize) + where P: ECPoint + Clone, + P::Scalar: Clone, + { let nm = n * m; - let G: GE = ECPoint::generator(); + let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H = generate_random_point(&Converter::to_vec(&hash)); + let H: P = generate_random_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { @@ -778,7 +767,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..nm) @@ -787,33 +776,36 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let range = BigInt::from(2).pow(n as u32); let v_vec = (0..m) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); let range_proof = RangeProof::prove(&g_vec, &h_vec, &G, &H, v_vec, &r_vec, n); let result = RangeProof::verify(&range_proof, &g_vec, &h_vec, &G, &H, &ped_com_vec, n); assert!(result.is_ok()); } - pub fn test_helper_aggregated(seed: &BigInt, n: usize, m: usize) { + fn test_helper_aggregated

(seed: &BigInt, n: usize, m: usize) + where P: ECPoint + Clone, + P::Scalar: Clone, + { let nm = n * m; - let G: GE = ECPoint::generator(); + let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H = generate_random_point(&Converter::to_vec(&hash)); + let H: P = generate_random_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { @@ -821,7 +813,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..nm) @@ -830,21 +822,21 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let range = BigInt::from(2).pow(n as u32); let v_vec = (0..m) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); let range_proof = RangeProof::prove(&g_vec, &h_vec, &G, &H, v_vec, &r_vec, n); let result = @@ -852,8 +844,11 @@ type FE = curv::elliptic::curves::secp256_k1::FE; assert!(result.is_ok()); } - #[test] - pub fn test_batch_4_range_proof_32() { + test_for_all_curves!(test_batch_4_range_proof_32); + fn test_batch_4_range_proof_32

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { let n = 32; // num of proofs let m = 4; @@ -861,10 +856,10 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - let G: GE = ECPoint::generator(); + let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H = generate_random_point(&Converter::to_vec(&hash)); + let H: P = generate_random_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { @@ -872,7 +867,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..nm) @@ -881,30 +876,32 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let range = BigInt::from(2).pow(n as u32); let v_vec = (0..m) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); let range_proof = RangeProof::prove(&g_vec, &h_vec, &G, &H, v_vec, &r_vec, n); let result = RangeProof::verify(&range_proof, &g_vec, &h_vec, &G, &H, &ped_com_vec, n); assert!(result.is_ok()); } - #[test] - #[should_panic] - pub fn test_batch_4_range_proof_32_out_of_range() { + test_for_all_curves!(#[should_panic] test_batch_4_range_proof_32_out_of_range); + fn test_batch_4_range_proof_32_out_of_range

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { let n = 32; // num of proofs let m = 4; @@ -912,10 +909,10 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - let G: GE = ECPoint::generator(); + let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H = generate_random_point(&Converter::to_vec(&hash)); + let H: P = generate_random_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { @@ -923,7 +920,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..nm) @@ -932,32 +929,35 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let range = BigInt::from(2).pow(n as u32); let mut v_vec = (0..m - 1) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); let bad_v = BigInt::from(2).pow(33); v_vec.push(ECScalar::from(&bad_v)); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); let range_proof = RangeProof::prove(&g_vec, &h_vec, &G, &H, v_vec, &r_vec, n); let result = RangeProof::verify(&range_proof, &g_vec, &h_vec, &G, &H, &ped_com_vec, n); assert!(result.is_ok()); } - #[test] - pub fn test_batch_2_range_proof_16() { + test_for_all_curves!(test_batch_2_range_proof_16); + fn test_batch_2_range_proof_16

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { let n = 16; // num of proofs let m = 2; @@ -965,10 +965,10 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - let G: GE = ECPoint::generator(); + let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H = generate_random_point(&Converter::to_vec(&hash)); + let H: P = generate_random_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { @@ -976,7 +976,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..nm) @@ -985,29 +985,32 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let range = BigInt::from(2).pow(n as u32); let v_vec = (0..m) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); let range_proof = RangeProof::prove(&g_vec, &h_vec, &G, &H, v_vec, &r_vec, n); let result = RangeProof::verify(&range_proof, &g_vec, &h_vec, &G, &H, &ped_com_vec, n); assert!(result.is_ok()); } - #[test] - pub fn test_batch_1_range_proof_8() { + test_for_all_curves!(test_batch_1_range_proof_8); + fn test_batch_1_range_proof_8

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { // bit range let n = 8; // batch size @@ -1018,10 +1021,10 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let kzen_label = BigInt::from(KZen); // G,H - points for pederson commitment: com = vG + rH - let G: GE = ECPoint::generator(); + let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H = generate_random_point(&Converter::to_vec(&hash)); + let H: P = generate_random_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { @@ -1029,7 +1032,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..nm) @@ -1038,38 +1041,44 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let range = BigInt::from(2).pow(n as u32); let v_vec = (0..m) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); let range_proof = RangeProof::prove(&g_vec, &h_vec, &G, &H, v_vec, &r_vec, n); let result = RangeProof::verify(&range_proof, &g_vec, &h_vec, &G, &H, &ped_com_vec, n); assert!(result.is_ok()); } - #[test] - pub fn test_batch_4_range_proof_64() { + test_for_all_curves!(test_batch_4_range_proof_64); + fn test_batch_4_range_proof_64

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - test_helper(&kzen_label, 64, 4); + test_helper::

(&kzen_label, 64, 4); } - #[test] - pub fn test_agg_batch_4_range_proof_64() { + test_for_all_curves!(test_agg_batch_4_range_proof_64); + fn test_agg_batch_4_range_proof_64

() + where P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - test_helper_aggregated(&kzen_label, 64, 4); + test_helper_aggregated::

(&kzen_label, 64, 4); } } From bc782d0251bed0125e6405f59a2dd36b51d8f23e Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sun, 6 Dec 2020 16:51:28 +0700 Subject: [PATCH 3/8] Apply rustfmt --- src/proofs/inner_product.rs | 99 ++++++++++++++++----------- src/proofs/range_proof.rs | 132 +++++++++++++++++++++++++----------- 2 files changed, 154 insertions(+), 77 deletions(-) diff --git a/src/proofs/inner_product.rs b/src/proofs/inner_product.rs index ad1f9f7..264a4df 100644 --- a/src/proofs/inner_product.rs +++ b/src/proofs/inner_product.rs @@ -33,8 +33,9 @@ pub struct InnerProductArg { } impl

InnerProductArg

-where P: ECPoint + Clone, - P::Scalar: Clone, +where + P: ECPoint + Clone, + P::Scalar: Clone, { pub fn prove( G: &[P], @@ -352,6 +353,7 @@ fn inner_product(a: &[BigInt], b: &[BigInt], order: &BigInt) -> BigInt { #[cfg(test)] mod tests { + use crate::test_for_all_curves; use curv::arithmetic::traits::{Converter, Modulo}; use curv::cryptographic_primitives::hashing::hash_sha512::HSha512; use curv::cryptographic_primitives::hashing::traits::*; @@ -359,11 +361,11 @@ mod tests { use curv::BigInt; use proofs::inner_product::InnerProductArg; use proofs::test_utils::generate_random_point; - use crate::test_for_all_curves; fn test_helper

(n: usize) - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -417,7 +419,9 @@ mod tests { }) .collect::>(); - let hi_tag = (0..n).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); + let hi_tag = (0..n) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); // R = + + c * ux let c_fe: P::Scalar = ECScalar::from(&c); @@ -443,8 +447,9 @@ mod tests { } fn test_helper_fast_verify

(n: usize) - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -498,7 +503,9 @@ mod tests { }) .collect::>(); - let hi_tag = (0..n).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); + let hi_tag = (0..n) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); // R = + + c * ux let c_fe: P::Scalar = ECScalar::from(&c); @@ -524,8 +531,9 @@ mod tests { } fn test_helper_non_power_2

(m: usize, n: usize, a: &[BigInt], b: &[BigInt]) - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -566,7 +574,9 @@ mod tests { }) .collect::>(); - let hi_tag = (0..n).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); + let hi_tag = (0..n) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); // R = + + c * ux let c_fe: P::Scalar = ECScalar::from(&c); @@ -595,104 +605,117 @@ mod tests { test_for_all_curves!(make_ipp_32); fn make_ipp_32

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper::

(32); } test_for_all_curves!(make_ipp_16); fn make_ipp_16

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper::

(16); } test_for_all_curves!(make_ipp_8); fn make_ipp_8

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper::

(8); } test_for_all_curves!(make_ipp_4); fn make_ipp_4

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper::

(4); } test_for_all_curves!(make_ipp_2); fn make_ipp_2

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper::

(2); } test_for_all_curves!(make_ipp_1); fn make_ipp_1

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper::

(1); } test_for_all_curves!(make_ipp_32_fast_verify); fn make_ipp_32_fast_verify

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper_fast_verify::

(32); } test_for_all_curves!(make_ipp_16_fast_verify); fn make_ipp_16_fast_verify

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper_fast_verify::

(16); } test_for_all_curves!(make_ipp_8_fast_verify); fn make_ipp_8_fast_verify

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper_fast_verify::

(8); } test_for_all_curves!(make_ipp_4_fast_verify); fn make_ipp_4_fast_verify

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper_fast_verify::

(4); } test_for_all_curves!(make_ipp_2_fast_verify); fn make_ipp_2_fast_verify

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper_fast_verify::

(2); } test_for_all_curves!(make_ipp_1_fast_verify); fn make_ipp_1_fast_verify

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { test_helper_fast_verify::

(1); } test_for_all_curves!(make_ipp_non_power_2); fn make_ipp_non_power_2

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { // Create random scalar vectors a, b with size non-power of 2 let n: usize = 9; diff --git a/src/proofs/range_proof.rs b/src/proofs/range_proof.rs index 8d3fd6d..2a1d999 100644 --- a/src/proofs/range_proof.rs +++ b/src/proofs/range_proof.rs @@ -40,8 +40,9 @@ pub struct RangeProof { } impl

RangeProof

-where P: ECPoint + Clone, - P::Scalar: Clone, +where + P: ECPoint + Clone, + P::Scalar: Clone, { pub fn prove( g_vec: &[P], @@ -106,8 +107,12 @@ where P: ECPoint + Clone, } }); - let SR = (0..nm).map(|_| ECScalar::new_random()).collect::>(); - let SL = (0..nm).map(|_| ECScalar::new_random()).collect::>(); + let SR = (0..nm) + .map(|_| ECScalar::new_random()) + .collect::>(); + let SL = (0..nm) + .map(|_| ECScalar::new_random()) + .collect::>(); S = SL.iter().zip(&SR).fold(S, |acc, x| { let g_vec_i_SLi = g_vec[index].clone() * x.0.clone(); @@ -220,7 +225,9 @@ where P: ECPoint + Clone, }) .collect::>(); - let hi_tag = (0..nm).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); + let hi_tag = (0..nm) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); // P' = P' g^l let P = g_vec.iter().zip(&Lp).fold(P, |acc, x| { @@ -280,7 +287,9 @@ where P: ECPoint + Clone, .take(nm) .collect::>(); - let scalar_mul_yn = yi.iter().fold(::zero(), |acc, x| acc + x.clone()); + let scalar_mul_yn = yi + .iter() + .fold(::zero(), |acc, x| acc + x.clone()); let scalar_mul_yn = scalar_mul_yn.to_big_int(); let two = BigInt::from(2); @@ -289,7 +298,9 @@ where P: ECPoint + Clone, .take(bit_length) .collect::>(); - let scalar_mul_2n = vec_2n.iter().fold(::zero(), |acc, x| acc + x.clone()); + let scalar_mul_2n = vec_2n + .iter() + .fold(::zero(), |acc, x| acc + x.clone()); let scalar_mul_2n = scalar_mul_2n.to_big_int(); let z_cubed_scalar_mul_2n = (0..num_of_proofs) @@ -306,7 +317,9 @@ where P: ECPoint + Clone, let yi_inv = (0..nm).map(|i| yi[i].invert()).collect::>(); - let hi_tag = (0..nm).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); + let hi_tag = (0..nm) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); let fs_challenge = HSha256::create_hash_from_ge(&[&self.T1, &self.T2, G, H]); let fs_challenge_square = fs_challenge.mul(&fs_challenge.get_element()); @@ -328,7 +341,9 @@ where P: ECPoint + Clone, }) .collect::>(); let vec_ped_zm_1 = vec_ped_zm.remove(0); - let ped_com_sum = vec_ped_zm.iter().fold(vec_ped_zm_1, |acc, x| acc + x.clone()); + let ped_com_sum = vec_ped_zm + .iter() + .fold(vec_ped_zm_1, |acc, x| acc + x.clone()); let right_side = ped_com_sum + Gdelta + Tx + Tx_sq; let challenge_x = HSha256::create_hash(&[ @@ -341,7 +356,11 @@ where P: ECPoint + Clone, // P' = u^{xc} let P = Gx.clone() * self.tx.clone(); - let minus_miu = BigInt::mod_sub(&::q(), &self.miu.to_big_int(), &::q()); + let minus_miu = BigInt::mod_sub( + &::q(), + &self.miu.to_big_int(), + &::q(), + ); let minus_miu_fe: P::Scalar = ECScalar::from(&minus_miu); let Hmiu = H.clone() * minus_miu_fe.clone(); let Sx = self.S.clone() * fs_challenge.clone(); @@ -400,7 +419,9 @@ where P: ECPoint + Clone, .take(nm) .collect::>(); - let scalar_mul_yn = yi.iter().fold(::zero(), |acc, x| acc + x.clone()); + let scalar_mul_yn = yi + .iter() + .fold(::zero(), |acc, x| acc + x.clone()); let scalar_mul_yn = scalar_mul_yn.to_big_int(); let two = BigInt::from(2); @@ -409,7 +430,9 @@ where P: ECPoint + Clone, .take(bit_length) .collect::>(); - let scalar_mul_2n = vec_2n.iter().fold(::zero(), |acc, x| acc + x.clone()); + let scalar_mul_2n = vec_2n + .iter() + .fold(::zero(), |acc, x| acc + x.clone()); let scalar_mul_2n = scalar_mul_2n.to_big_int(); let z_cubed_scalar_mul_2n = (0..num_of_proofs) @@ -426,7 +449,9 @@ where P: ECPoint + Clone, let yi_inv = (0..nm).map(|i| yi[i].invert()).collect::>(); - let hi_tag = (0..nm).map(|i| h_vec[i].clone() * yi_inv[i].clone()).collect::>(); + let hi_tag = (0..nm) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); let fs_challenge = HSha256::create_hash_from_ge(&[&self.T1, &self.T2, G, H]); let fs_challenge_square = fs_challenge.mul(&fs_challenge.get_element()); @@ -448,7 +473,9 @@ where P: ECPoint + Clone, }) .collect::>(); let vec_ped_zm_1 = vec_ped_zm.remove(0); - let ped_com_sum = vec_ped_zm.iter().fold(vec_ped_zm_1, |acc, x| acc + x.clone()); + let ped_com_sum = vec_ped_zm + .iter() + .fold(vec_ped_zm_1, |acc, x| acc + x.clone()); let right_side = ped_com_sum + Gdelta + Tx + Tx_sq; let challenge_x = HSha256::create_hash(&[ @@ -461,7 +488,11 @@ where P: ECPoint + Clone, // P' = u^{xc} let P = Gx.clone() * self.tx.clone(); - let minus_miu = BigInt::mod_sub(&::q(), &self.miu.to_big_int(), &::q()); + let minus_miu = BigInt::mod_sub( + &::q(), + &self.miu.to_big_int(), + &::q(), + ); let minus_miu_fe: P::Scalar = ECScalar::from(&minus_miu); let Hmiu = H.clone() * minus_miu_fe.clone(); let Sx = self.S.clone() * fs_challenge.clone(); @@ -748,12 +779,13 @@ mod tests { use curv::BigInt; use super::RangeProof; - use proofs::test_utils::generate_random_point; use crate::test_for_all_curves; + use proofs::test_utils::generate_random_point; fn test_helper

(seed: &BigInt, n: usize, m: usize) - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let nm = n * m; let G: P = ECPoint::generator(); @@ -783,7 +815,9 @@ mod tests { .map(|_| ECScalar::from(&BigInt::sample_below(&range))) .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { @@ -798,8 +832,9 @@ mod tests { } fn test_helper_aggregated

(seed: &BigInt, n: usize, m: usize) - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let nm = n * m; let G: P = ECPoint::generator(); @@ -829,7 +864,9 @@ mod tests { .map(|_| ECScalar::from(&BigInt::sample_below(&range))) .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { @@ -846,8 +883,9 @@ mod tests { test_for_all_curves!(test_batch_4_range_proof_32); fn test_batch_4_range_proof_32

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let n = 32; // num of proofs @@ -883,7 +921,9 @@ mod tests { .map(|_| ECScalar::from(&BigInt::sample_below(&range))) .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { @@ -897,10 +937,14 @@ mod tests { assert!(result.is_ok()); } - test_for_all_curves!(#[should_panic] test_batch_4_range_proof_32_out_of_range); + test_for_all_curves!( + #[should_panic] + test_batch_4_range_proof_32_out_of_range + ); fn test_batch_4_range_proof_32_out_of_range

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let n = 32; // num of proofs @@ -939,7 +983,9 @@ mod tests { let bad_v = BigInt::from(2).pow(33); v_vec.push(ECScalar::from(&bad_v)); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { @@ -955,8 +1001,9 @@ mod tests { test_for_all_curves!(test_batch_2_range_proof_16); fn test_batch_2_range_proof_16

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let n = 16; // num of proofs @@ -992,7 +1039,9 @@ mod tests { .map(|_| ECScalar::from(&BigInt::sample_below(&range))) .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { @@ -1008,8 +1057,9 @@ mod tests { test_for_all_curves!(test_batch_1_range_proof_8); fn test_batch_1_range_proof_8

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { // bit range let n = 8; @@ -1048,7 +1098,9 @@ mod tests { .map(|_| ECScalar::from(&BigInt::sample_below(&range))) .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { @@ -1064,8 +1116,9 @@ mod tests { test_for_all_curves!(test_batch_4_range_proof_64); fn test_batch_4_range_proof_64

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -1074,8 +1127,9 @@ mod tests { test_for_all_curves!(test_agg_batch_4_range_proof_64); fn test_agg_batch_4_range_proof_64

() - where P: ECPoint + Clone, - P::Scalar: Clone, + where + P: ECPoint + Clone, + P::Scalar: Clone, { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); From 3acddbfd19d5f0acdeda3db2ee0782f3ef77ff2e Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sun, 6 Dec 2020 17:06:20 +0700 Subject: [PATCH 4/8] Update weighted_inner_product --- src/proofs/mod.rs | 2 +- src/proofs/weighted_inner_product.rs | 500 +++++++++++++++------------ 2 files changed, 289 insertions(+), 213 deletions(-) diff --git a/src/proofs/mod.rs b/src/proofs/mod.rs index 3f99a51..fd8a0fc 100644 --- a/src/proofs/mod.rs +++ b/src/proofs/mod.rs @@ -21,4 +21,4 @@ mod test_utils; pub mod inner_product; pub mod range_proof; // pub mod range_proof_wip; -// pub mod weighted_inner_product; +pub mod weighted_inner_product; diff --git a/src/proofs/weighted_inner_product.rs b/src/proofs/weighted_inner_product.rs index b4c0eeb..c878bc0 100644 --- a/src/proofs/weighted_inner_product.rs +++ b/src/proofs/weighted_inner_product.rs @@ -26,40 +26,42 @@ use curv::cryptographic_primitives::hashing::hash_sha256::HSha256; use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; use curv::BigInt; -type GE = curv::elliptic::curves::secp256_k1::GE; -type FE = curv::elliptic::curves::secp256_k1::FE; use itertools::iterate; use Errors::{self, WeightedInnerProdError}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct WeightedInnerProdArg { - pub(super) L: Vec, - pub(super) R: Vec, - pub(super) a_tag: GE, - pub(super) b_tag: GE, +pub struct WeightedInnerProdArg { + pub(super) L: Vec

, + pub(super) R: Vec

, + pub(super) a_tag: P, + pub(super) b_tag: P, pub(super) r_prime: BigInt, pub(super) s_prime: BigInt, pub(super) delta_prime: BigInt, } -impl WeightedInnerProdArg { +impl

WeightedInnerProdArg

+where + P: ECPoint + Clone, + P::Scalar: Clone, +{ pub fn prove( - G: &[GE], - H: &[GE], - g: &GE, - h: &GE, - P: &GE, + G: &[P], + H: &[P], + g: &P, + h: &P, + P: &P, a: &[BigInt], b: &[BigInt], alpha: &BigInt, y: &BigInt, - mut L_vec: Vec, - mut R_vec: Vec, - ) -> WeightedInnerProdArg { + mut L_vec: Vec

, + mut R_vec: Vec

, + ) -> Self { let n = G.len(); - let order = FE::q(); + let order = ::q(); // All of the input vectors must have the same length. assert_eq!(H.len(), n); @@ -95,22 +97,22 @@ impl WeightedInnerProdArg { .map(|i| BigInt::mod_mul(&powers_yinv[n - 1], &a_L[i], &order)) .collect::>(); - let c_L = weighted_inner_product(&a_L, &b_R, y.clone()); - let c_R = weighted_inner_product(&yn_aR, b_L, y.clone()); + let c_L = weighted_inner_product(&a_L, &b_R, y.clone(), &::q()); + let c_R = weighted_inner_product(&yn_aR, b_L, y.clone(), &::q()); // Note that no element in vectors a_L and b_R can be 0 // since 0 is an invalid secret key! // // L = + + (c_L * g) + (d_L * h) - let c_L_fe: FE = ECScalar::from(&c_L); - let g_cL: GE = g * &c_L_fe; - let d_L_fe: FE = ECScalar::new_random(); - let h_dL = h * &d_L_fe; + let c_L_fe: P::Scalar = ECScalar::from(&c_L); + let g_cL: P = g.clone() * c_L_fe.clone(); + let d_L_fe: P::Scalar = ECScalar::new_random(); + let h_dL = h.clone() * d_L_fe.clone(); let g_cL_h_dL = g_cL.add_point(&h_dL.get_element()); let yninv_aL_GR = G_R.iter().zip(yninv_aL.clone()).fold(g_cL_h_dL, |acc, x| { if x.1 != BigInt::zero() { - let aLi: FE = ECScalar::from(&x.1); - let aLi_GRi: GE = x.0 * &aLi; + let aLi: P::Scalar = ECScalar::from(&x.1); + let aLi_GRi: P = x.0.clone() * aLi.clone(); acc.add_point(&aLi_GRi.get_element()) } else { acc @@ -118,8 +120,8 @@ impl WeightedInnerProdArg { }); let L = H_L.iter().zip(b_R.clone()).fold(yninv_aL_GR, |acc, x| { if x.1 != &BigInt::zero() { - let bRi: FE = ECScalar::from(&x.1); - let bRi_HLi: GE = x.0 * &bRi; + let bRi: P::Scalar = ECScalar::from(&x.1); + let bRi_HLi: P = x.0.clone() * bRi.clone(); acc.add_point(&bRi_HLi.get_element()) } else { acc @@ -130,15 +132,15 @@ impl WeightedInnerProdArg { // since 0 is an invalid secret key! // // R = + + (c_R * g) + (d_R * h) - let c_R_fe: FE = ECScalar::from(&c_R); - let g_cR: GE = g * &c_R_fe; - let d_R_fe: FE = ECScalar::new_random(); - let h_dR = h * &d_R_fe; + let c_R_fe: P::Scalar = ECScalar::from(&c_R); + let g_cR: P = g.clone() * c_R_fe.clone(); + let d_R_fe: P::Scalar = ECScalar::new_random(); + let h_dR = h.clone() * d_R_fe.clone(); let g_cR_h_dR = g_cR.add_point(&h_dR.get_element()); let aR_GL = G_L.iter().zip(yn_aR.clone()).fold(g_cR_h_dR, |acc, x| { if x.1 != BigInt::zero() { - let aRi: FE = ECScalar::from(&x.1); - let aRi_GLi: GE = x.0 * &aRi; + let aRi: P::Scalar = ECScalar::from(&x.1); + let aRi_GLi: P = x.0.clone() * aRi.clone(); acc.add_point(&aRi_GLi.get_element()) } else { acc @@ -146,8 +148,8 @@ impl WeightedInnerProdArg { }); let R = H_R.iter().zip(b_L.clone()).fold(aR_GL, |acc, x| { if x.1 != &BigInt::zero() { - let bLi: FE = ECScalar::from(&x.1); - let bLi_HRi: GE = x.0 * &bLi; + let bLi: P::Scalar = ECScalar::from(&x.1); + let bLi_HRi: P = x.0.clone() * bLi.clone(); acc.add_point(&bLi_HRi.get_element()) } else { acc @@ -186,23 +188,23 @@ impl WeightedInnerProdArg { let alpha_hat = BigInt::mod_add(&alpha, &x2_dL_xinv2_dR, &order); let x_yinv = BigInt::mod_mul(&x_bn, &powers_yinv[n - 1], &order); - let x_yinv_fe = ECScalar::from(&x_yinv); + let x_yinv_fe: P::Scalar = ECScalar::from(&x_yinv); let G_hat = (0..n) .map(|i| { - let GLx_inv = &G_L[i] * &x_inv_fe; - let GRx_yinv = &G_R[i] * &x_yinv_fe; + let GLx_inv = G_L[i].clone() * x_inv_fe.clone(); + let GRx_yinv = G_R[i].clone() * x_yinv_fe.clone(); GRx_yinv + GLx_inv }) - .collect::>(); + .collect::>(); // G = &mut G_hat[..]; let H_hat = (0..n) .map(|i| { - let HLx = &H_L[i] * &x; - let HRx_inv = &H_R[i] * &x_inv_fe; + let HLx = H_L[i].clone() * x.clone(); + let HRx_inv = H_R[i].clone() * x_inv_fe.clone(); HLx + HRx_inv }) - .collect::>(); + .collect::>(); // H = &mut H_hat[..]; L_vec.push(L); @@ -211,32 +213,32 @@ impl WeightedInnerProdArg { &G_hat, &H_hat, &g, &h, &P, &a_hat, &b_hat, &alpha_hat, &y, L_vec, R_vec, ); } else { - let r: FE = ECScalar::new_random(); + let r: P::Scalar = ECScalar::new_random(); let r_bn: BigInt = r.to_big_int(); - let s: FE = ECScalar::new_random(); + let s: P::Scalar = ECScalar::new_random(); let s_bn: BigInt = s.to_big_int(); - let delta: FE = ECScalar::new_random(); + let delta: P::Scalar = ECScalar::new_random(); let delta_bn: BigInt = delta.to_big_int(); - let eta: FE = ECScalar::new_random(); + let eta: P::Scalar = ECScalar::new_random(); let eta_bn: BigInt = eta.to_big_int(); // compute A - let Gr = &G[0] * &r; - let Hs = &H[0] * &s; + let Gr = G[0].clone() * r.clone(); + let Hs = H[0].clone() * s.clone(); let a_s = BigInt::mod_mul(&a[0], &s_bn, &order); let a_sy = BigInt::mod_mul(&a_s, &y, &order); let b_r = BigInt::mod_mul(&b[0], &r_bn, &order); let b_ry = BigInt::mod_mul(&b_r, &y, &order); let a_sy_b_ry = BigInt::mod_add(&a_sy, &b_ry, &order); - let g_a_sy_b_ry = g * &ECScalar::from(&a_sy_b_ry); - let h_delta = h * δ + let g_a_sy_b_ry = g.clone() * ECScalar::from(&a_sy_b_ry); + let h_delta = h.clone() * delta.clone(); let A = Gr + Hs + g_a_sy_b_ry + h_delta; // compute B let r_s = BigInt::mod_mul(&r_bn, &s_bn, &order); let r_sy = BigInt::mod_mul(&y, &r_s, &order); - let g_r_sy = g * &ECScalar::from(&r_sy); - let h_eta = h * η + let g_r_sy = g.clone() * ECScalar::from(&r_sy); + let h_eta = h.clone() * eta.clone(); let B = g_r_sy + h_eta; // compute challenge e @@ -270,17 +272,17 @@ impl WeightedInnerProdArg { pub fn verify( &self, - g_vec: &[GE], - hi_tag: &[GE], - g: &GE, - h: &GE, - P: &GE, + g_vec: &[P], + hi_tag: &[P], + g: &P, + h: &P, + P: &P, y: &BigInt, ) -> Result<(), Errors> { let G = &g_vec[..]; let H = &hi_tag[..]; let n = G.len(); - let order = FE::q(); + let order = ::q(); // All of the input vectors must have the same length. assert_eq!(H.len(), n); @@ -299,37 +301,37 @@ impl WeightedInnerProdArg { let x = HSha256::create_hash_from_ge(&[&self.L[0], &self.R[0], &g, &h]); let x_bn = x.to_big_int(); - let order = FE::q(); + let order = ::q(); let x_inv_fe = x.invert(); let x_sq_bn = BigInt::mod_mul(&x_bn, &x_bn, &order); let x_inv_sq_bn = BigInt::mod_mul(&x_inv_fe.to_big_int(), &x_inv_fe.to_big_int(), &order); - let x_sq_fe: FE = ECScalar::from(&x_sq_bn); - let x_inv_sq_fe: FE = ECScalar::from(&x_inv_sq_bn); + let x_sq_fe: P::Scalar = ECScalar::from(&x_sq_bn); + let x_inv_sq_fe: P::Scalar = ECScalar::from(&x_inv_sq_bn); let x_yinv = BigInt::mod_mul(&x_bn, &powers_yinv[n - 1], &order); - let x_yinv_fe = ECScalar::from(&x_yinv); + let x_yinv_fe: P::Scalar = ECScalar::from(&x_yinv); let G_hat = (0..n) .map(|i| { - let GLx_inv = &G_L[i] * &x_inv_fe; - let GRx_yinv = &G_R[i] * &x_yinv_fe; + let GLx_inv = G_L[i].clone() * x_inv_fe.clone(); + let GRx_yinv = G_R[i].clone() * x_yinv_fe.clone(); GRx_yinv + GLx_inv }) - .collect::>(); + .collect::>(); // G = &mut G_hat[..]; let H_hat = (0..n) .map(|i| { - let HLx = &H_L[i] * &x; - let HRx_inv = &H_R[i] * &x_inv_fe; + let HLx = H_L[i].clone() * x.clone(); + let HRx_inv = H_R[i].clone() * x_inv_fe.clone(); HLx + HRx_inv }) - .collect::>(); + .collect::>(); // H = &mut H_hat[..]; - let Lx_sq = &self.L[0] * &x_sq_fe; - let Rx_sq_inv = &self.R[0] * &x_inv_sq_fe; - let P_tag = Lx_sq + Rx_sq_inv + P; + let Lx_sq = self.L[0].clone() * x_sq_fe.clone(); + let Rx_sq_inv = self.R[0].clone() * x_inv_sq_fe.clone(); + let P_tag = Lx_sq + Rx_sq_inv + P.clone(); let ip = WeightedInnerProdArg { L: (&self.L[1..]).to_vec(), @@ -347,23 +349,23 @@ impl WeightedInnerProdArg { let e = HSha256::create_hash_from_ge(&[&self.a_tag, &self.b_tag, &g, &h]); let e_bn = e.to_big_int(); let e_sq_bn = BigInt::mod_mul(&e_bn, &e_bn, &order); - let e_sq_fe: FE = ECScalar::from(&e_sq_bn); + let e_sq_fe: P::Scalar = ECScalar::from(&e_sq_bn); // left hand side of verification // LHS = e^2*P + e*A + B - let P_e2 = P * &e_sq_fe; - let Ae = self.a_tag * &e; - let left = P_e2 + Ae + self.b_tag; + let P_e2 = P.clone() * e_sq_fe.clone(); + let Ae = self.a_tag.clone() * e.clone(); + let left = P_e2 + Ae + self.b_tag.clone(); // RHS = (er')*G + (es')*H + (r's'y)*g + (delta')*h let er_prime = BigInt::mod_mul(&e_bn, &self.r_prime, &order); - let Ger_prime = &G[0] * &ECScalar::from(&er_prime); + let Ger_prime = G[0].clone() * ECScalar::from(&er_prime); let es_prime = BigInt::mod_mul(&e_bn, &self.s_prime, &order); - let Hes_prime = &H[0] * &ECScalar::from(&es_prime); + let Hes_prime = H[0].clone() * ECScalar::from(&es_prime); let rs_prime = BigInt::mod_mul(&self.s_prime, &self.r_prime, &order); let yrs_prime = BigInt::mod_mul(&rs_prime, &y, &order); - let g_yrs_prime = g * &ECScalar::from(&yrs_prime); - let h_delta_prime = h * &ECScalar::from(&self.delta_prime); + let g_yrs_prime = g.clone() * ECScalar::from(&yrs_prime); + let h_delta_prime = h.clone() * ECScalar::from(&self.delta_prime); let right = Ger_prime + Hes_prime + g_yrs_prime + h_delta_prime; if left == right { @@ -382,17 +384,17 @@ impl WeightedInnerProdArg { /// pub fn fast_verify( &self, - g_vec: &[GE], - hi_tag: &[GE], - g: &GE, - h: &GE, - P: &GE, + g_vec: &[P], + hi_tag: &[P], + g: &P, + h: &P, + P: &P, y: &BigInt, ) -> Result<(), Errors> { let G = &g_vec[..]; let H = &hi_tag[..]; let n = G.len(); - let order = FE::q(); + let order = ::q(); // All of the input vectors must have the same length. assert_eq!(H.len(), n); @@ -421,7 +423,7 @@ impl WeightedInnerProdArg { let mut allinv = BigInt::one(); let mut all = BigInt::one(); for (Li, Ri) in self.L.iter().zip(self.R.iter()) { - let x = HSha256::create_hash_from_ge::(&[&Li, &Ri, &g, &h]); + let x = HSha256::create_hash_from_ge::

(&[&Li, &Ri, &g, &h]); let x_bn = x.to_big_int(); let x_inv_fe = x.invert(); let x_inv_bn = x_inv_fe.to_big_int(); @@ -486,22 +488,22 @@ impl WeightedInnerProdArg { scalars.extend_from_slice(&minus_e_sq_x_inv_sq_vec); scalars.push(r_times_s_y); - let mut points: Vec = Vec::with_capacity(2 * n + 2 * lg_n + 1); + let mut points: Vec

= Vec::with_capacity(2 * n + 2 * lg_n + 1); points.extend_from_slice(g_vec); points.extend_from_slice(hi_tag); points.extend_from_slice(&self.L); points.extend_from_slice(&self.R); - points.push(*g); + points.push(g.clone()); - let h_delta_prime = h * &ECScalar::from(&self.delta_prime); + let h_delta_prime = h.clone() * ECScalar::from(&self.delta_prime); let tot_len = points.len(); let lhs = (0..tot_len) - .map(|i| points[i] * &ECScalar::from(&scalars[i])) - .fold(h_delta_prime, |acc, x| acc + x as GE); + .map(|i| points[i].clone() * ECScalar::from(&scalars[i])) + .fold(h_delta_prime, |acc, x| acc + x as P); - let Ae = self.a_tag * &ECScalar::from(&e_bn); - let Pe_sq = P * &ECScalar::from(&e_sq_bn); - let rhs = Pe_sq + Ae + self.b_tag; + let Ae = self.a_tag.clone() * ECScalar::from(&e_bn); + let Pe_sq = P.clone() * ECScalar::from(&e_sq_bn); + let rhs = Pe_sq + Ae + self.b_tag.clone(); if lhs == rhs { Ok(()) @@ -511,13 +513,12 @@ impl WeightedInnerProdArg { } } -fn weighted_inner_product(a: &[BigInt], b: &[BigInt], y: BigInt) -> BigInt { +fn weighted_inner_product(a: &[BigInt], b: &[BigInt], y: BigInt, order: &BigInt) -> BigInt { assert_eq!( a.len(), b.len(), "weighted_inner_product(a,b): lengths of vectors do not match" ); - let order = FE::q(); let y_powers = iterate(y.clone(), |i| i.clone() * y.clone()) .take(a.len()) .collect::>(); @@ -540,15 +541,17 @@ mod tests { use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; use curv::BigInt; - type GE = curv::elliptic::curves::secp256_k1::GE; -type FE = curv::elliptic::curves::secp256_k1::FE; + use super::{weighted_inner_product, WeightedInnerProdArg}; + use crate::test_for_all_curves; use itertools::iterate; - use proofs::range_proof::generate_random_point; - use proofs::weighted_inner_product::weighted_inner_product; - use proofs::weighted_inner_product::WeightedInnerProdArg; + use proofs::test_utils::generate_random_point; - fn test_helper(n: usize) { + fn test_helper

(n: usize) + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -558,7 +561,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..n) @@ -567,68 +570,71 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let label = BigInt::from(2); let hash = HSha512::create_hash(&[&label]); - let g = generate_random_point(&Converter::to_vec(&hash)); + let g: P = generate_random_point(&Converter::to_vec(&hash)); let label = BigInt::from(3); let hash = HSha512::create_hash(&[&label]); - let h = generate_random_point(&Converter::to_vec(&hash)); + let h: P = generate_random_point(&Converter::to_vec(&hash)); let a: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); let b: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); let y_scalar: BigInt = HSha256::create_hash_from_slice("Seed string decided by P,V!".as_bytes()); - let c = super::weighted_inner_product(&a, &b, y_scalar.clone()); + let c = + super::weighted_inner_product(&a, &b, y_scalar.clone(), &::q()); - let alpha_fe: FE = ECScalar::new_random(); + let alpha_fe: P::Scalar = ECScalar::new_random(); let alpha = alpha_fe.to_big_int(); - let y: FE = ECScalar::new_random(); - let order = FE::q(); + let y: P::Scalar = ECScalar::new_random(); + let order = ::q(); let yi = (0..n) .map(|i| BigInt::mod_pow(&y.to_big_int(), &BigInt::from(i as u32), &order)) .collect::>(); let yi_inv = (0..n) .map(|i| { - let yi_fe: FE = ECScalar::from(&yi[i]); + let yi_fe: P::Scalar = ECScalar::from(&yi[i]); yi_fe.invert() }) - .collect::>(); + .collect::>(); - let hi_tag = (0..n).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..n) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); // R = + + c * g + alpha*h - let c_fe: FE = ECScalar::from(&c); - let g_c: GE = &g * &c_fe; - let h_alpha: GE = &h * &alpha_fe; + let c_fe: P::Scalar = ECScalar::from(&c); + let g_c: P = g.clone() * c_fe.clone(); + let h_alpha: P = h.clone() * alpha_fe.clone(); let gc_halpha = g_c + h_alpha; let a_G = (0..n) .map(|i| { - let ai: FE = ECScalar::from(&a[i]); - &g_vec[i] * &ai + let ai: P::Scalar = ECScalar::from(&a[i]); + g_vec[i].clone() * ai.clone() }) - .fold(gc_halpha, |acc, x: GE| acc + x as GE); + .fold(gc_halpha, |acc, x: P| acc + x as P); let P = (0..n) .map(|i| { - let bi: FE = ECScalar::from(&b[i]); - &hi_tag[i] * &bi + let bi: P::Scalar = ECScalar::from(&b[i]); + hi_tag[i].clone() * bi.clone() }) - .fold(a_G, |acc, x: GE| acc + x as GE); + .fold(a_G, |acc, x: P| acc + x as P); let L_vec = Vec::with_capacity(n); let R_vec = Vec::with_capacity(n); @@ -639,7 +645,11 @@ type FE = curv::elliptic::curves::secp256_k1::FE; assert!(verifier.is_ok()) } - fn test_helper_fast_verify(n: usize) { + fn test_helper_fast_verify

(n: usize) + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -649,7 +659,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..n) @@ -658,68 +668,71 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); let label = BigInt::from(2); let hash = HSha512::create_hash(&[&label]); - let g = generate_random_point(&Converter::to_vec(&hash)); + let g: P = generate_random_point(&Converter::to_vec(&hash)); let label = BigInt::from(3); let hash = HSha512::create_hash(&[&label]); - let h = generate_random_point(&Converter::to_vec(&hash)); + let h: P = generate_random_point(&Converter::to_vec(&hash)); let a: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); let b: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); let y_scalar: BigInt = HSha256::create_hash_from_slice("Seed string decided by P,V!".as_bytes()); - let c = super::weighted_inner_product(&a, &b, y_scalar.clone()); + let c = + super::weighted_inner_product(&a, &b, y_scalar.clone(), &::q()); - let alpha_fe: FE = ECScalar::new_random(); + let alpha_fe: P::Scalar = ECScalar::new_random(); let alpha = alpha_fe.to_big_int(); - let y: FE = ECScalar::new_random(); - let order = FE::q(); + let y: P::Scalar = ECScalar::new_random(); + let order = ::q(); let yi = (0..n) .map(|i| BigInt::mod_pow(&y.to_big_int(), &BigInt::from(i as u32), &order)) .collect::>(); let yi_inv = (0..n) .map(|i| { - let yi_fe: FE = ECScalar::from(&yi[i]); + let yi_fe: P::Scalar = ECScalar::from(&yi[i]); yi_fe.invert() }) - .collect::>(); + .collect::>(); - let hi_tag = (0..n).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..n) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); // R = + + c * g + alpha*h - let c_fe: FE = ECScalar::from(&c); - let g_c: GE = &g * &c_fe; - let h_alpha: GE = &h * &alpha_fe; + let c_fe: P::Scalar = ECScalar::from(&c); + let g_c: P = g.clone() * c_fe.clone(); + let h_alpha: P = h.clone() * alpha_fe.clone(); let gc_halpha = g_c + h_alpha; let a_G = (0..n) .map(|i| { - let ai: FE = ECScalar::from(&a[i]); - &g_vec[i] * &ai + let ai: P::Scalar = ECScalar::from(&a[i]); + g_vec[i].clone() * ai.clone() }) - .fold(gc_halpha, |acc, x: GE| acc + x as GE); + .fold(gc_halpha, |acc, x: P| acc + x as P); let P = (0..n) .map(|i| { - let bi: FE = ECScalar::from(&b[i]); - &hi_tag[i] * &bi + let bi: P::Scalar = ECScalar::from(&b[i]); + hi_tag[i].clone() * bi.clone() }) - .fold(a_G, |acc, x: GE| acc + x as GE); + .fold(a_G, |acc, x: P| acc + x as P); let L_vec = Vec::with_capacity(n); let R_vec = Vec::with_capacity(n); @@ -730,7 +743,11 @@ type FE = curv::elliptic::curves::secp256_k1::FE; assert!(verifier.is_ok()) } - fn test_helper_non_power_2(m: usize, n: usize, a: &[BigInt], b: &[BigInt]) { + fn test_helper_non_power_2

(m: usize, n: usize, a: &[BigInt], b: &[BigInt]) + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); @@ -740,7 +757,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_i = HSha512::create_hash(&[&kzen_label_i]); generate_random_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..n) @@ -749,55 +766,58 @@ type FE = curv::elliptic::curves::secp256_k1::FE; let hash_j = HSha512::create_hash(&[&kzen_label_j]); generate_random_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); // generate g, h let label = BigInt::from(2); let hash = HSha512::create_hash(&[&label]); - let g = generate_random_point(&Converter::to_vec(&hash)); + let g: P = generate_random_point(&Converter::to_vec(&hash)); let label = BigInt::from(3); let hash = HSha512::create_hash(&[&label]); - let h = generate_random_point(&Converter::to_vec(&hash)); + let h: P = generate_random_point(&Converter::to_vec(&hash)); let y_scalar: BigInt = HSha256::create_hash_from_slice("Seed string decided by P,V!".as_bytes()); - let c = super::weighted_inner_product(&a, &b, y_scalar.clone()); + let c = + super::weighted_inner_product(&a, &b, y_scalar.clone(), &::q()); - let alpha_fe: FE = ECScalar::new_random(); + let alpha_fe: P::Scalar = ECScalar::new_random(); let alpha = alpha_fe.to_big_int(); - let y: FE = ECScalar::new_random(); - let order = FE::q(); + let y: P::Scalar = ECScalar::new_random(); + let order = ::q(); let yi = (0..n) .map(|i| BigInt::mod_pow(&y.to_big_int(), &BigInt::from(i as u32), &order)) .collect::>(); let yi_inv = (0..n) .map(|i| { - let yi_fe: FE = ECScalar::from(&yi[i]); + let yi_fe: P::Scalar = ECScalar::from(&yi[i]); yi_fe.invert() }) - .collect::>(); + .collect::>(); - let hi_tag = (0..n).map(|i| &h_vec[i] * &yi_inv[i]).collect::>(); + let hi_tag = (0..n) + .map(|i| h_vec[i].clone() * yi_inv[i].clone()) + .collect::>(); // R = + + c * g + alpha*h - let c_fe: FE = ECScalar::from(&c); - let g_c: GE = &g * &c_fe; - let h_alpha: GE = &h * &alpha_fe; + let c_fe: P::Scalar = ECScalar::from(&c); + let g_c: P = g.clone() * c_fe.clone(); + let h_alpha: P = h.clone() * alpha_fe.clone(); let gc_halpha = g_c + h_alpha; let a_G = (0..m) .map(|i| { - let ai: FE = ECScalar::from(&a[i]); - &g_vec[i] * &ai + let ai: P::Scalar = ECScalar::from(&a[i]); + g_vec[i].clone() * ai.clone() }) - .fold(gc_halpha, |acc, x: GE| acc + x as GE); + .fold(gc_halpha, |acc, x: P| acc + x as P); let P = (0..m) .map(|i| { - let bi: FE = ECScalar::from(&b[i]); - &hi_tag[i] * &bi + let bi: P::Scalar = ECScalar::from(&b[i]); + hi_tag[i].clone() * bi.clone() }) - .fold(a_G, |acc, x: GE| acc + x as GE); + .fold(a_G, |acc, x: P| acc + x as P); let L_vec = Vec::with_capacity(n); let R_vec = Vec::with_capacity(n); @@ -808,8 +828,12 @@ type FE = curv::elliptic::curves::secp256_k1::FE; assert!(verifier.is_ok()) } - #[test] - fn test_wip() { + test_for_all_curves!(test_wip); + fn test_wip

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let a: Vec = vec![ BigInt::from(3), BigInt::from(2), @@ -836,7 +860,7 @@ type FE = curv::elliptic::curves::secp256_k1::FE; ]; assert_eq!(y_powers, expect_y_powers, "Scalar powers of y fails!"); - let a_weighted_b = weighted_inner_product(&a, &b, y.clone()); + let a_weighted_b = weighted_inner_product(&a, &b, y.clone(), &::q()); assert_eq!( a_weighted_b, BigInt::from(46), @@ -844,78 +868,130 @@ type FE = curv::elliptic::curves::secp256_k1::FE; ); } - #[test] - fn make_wip_32() { - test_helper(32); + test_for_all_curves!(make_wip_32); + fn make_wip_32

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(32); } - #[test] - fn make_wip_16() { - test_helper(16); + test_for_all_curves!(make_wip_16); + fn make_wip_16

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(16); } - #[test] - fn make_wip_8() { - test_helper(8); + test_for_all_curves!(make_wip_8); + fn make_wip_8

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(8); } - #[test] - fn make_wip_4() { - test_helper(4); + test_for_all_curves!(make_wip_4); + fn make_wip_4

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(4); } - #[test] - fn make_wip_2() { - test_helper(2); + test_for_all_curves!(make_wip_2); + fn make_wip_2

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(2); } - #[test] - fn make_wip_1() { - test_helper(1); + test_for_all_curves!(make_wip_1); + fn make_wip_1

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper::

(1); } - #[test] - fn make_wip_32_fast_verify() { - test_helper_fast_verify(32); + test_for_all_curves!(make_wip_32_fast_verify); + fn make_wip_32_fast_verify

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(32); } - #[test] - fn make_wip_16_fast_verify() { - test_helper_fast_verify(16); + test_for_all_curves!(make_wip_16_fast_verify); + fn make_wip_16_fast_verify

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(16); } - #[test] - fn make_wip_8_fast_verify() { - test_helper_fast_verify(8); + test_for_all_curves!(make_wip_8_fast_verify); + fn make_wip_8_fast_verify

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(8); } - #[test] - fn make_wip_4_fast_verify() { - test_helper_fast_verify(4); + test_for_all_curves!(make_wip_4_fast_verify); + fn make_wip_4_fast_verify

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(4); } - #[test] - fn make_wip_2_fast_verify() { - test_helper_fast_verify(2); + test_for_all_curves!(make_wip_2_fast_verify); + fn make_wip_2_fast_verify

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(2); } - #[test] - fn make_wip_1_fast_verify() { - test_helper_fast_verify(1); + test_for_all_curves!(make_wip_1_fast_verify); + fn make_wip_1_fast_verify

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { + test_helper_fast_verify::

(1); } - #[test] - fn make_wip_non_power_2() { + test_for_all_curves!(make_wip_non_power_2); + fn make_wip_non_power_2

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { // Create random scalar vectors a, b with size non-power of 2 let n: usize = 9; let mut a: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); let mut b: Vec<_> = (0..n) .map(|_| { - let rand: FE = ECScalar::new_random(); + let rand: P::Scalar = ECScalar::new_random(); rand.to_big_int() }) .collect(); @@ -928,6 +1004,6 @@ type FE = curv::elliptic::curves::secp256_k1::FE; a.extend_from_slice(&zero_append_vec); b.extend_from_slice(&zero_append_vec); - test_helper_non_power_2(n, _n, &a, &b); + test_helper_non_power_2::

(n, _n, &a, &b); } } From 4b7101125077913ff95661477dfe508b4ac459dd Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sun, 6 Dec 2020 18:15:03 +0700 Subject: [PATCH 5/8] Rename generate_random_point --- src/proofs/inner_product.rs | 20 +++++++-------- src/proofs/mod.rs | 7 +++-- src/proofs/range_proof.rs | 38 ++++++++++++++-------------- src/proofs/test_utils.rs | 8 ------ src/proofs/utils.rs | 10 ++++++++ src/proofs/weighted_inner_product.rs | 26 +++++++++---------- 6 files changed, 55 insertions(+), 54 deletions(-) delete mode 100644 src/proofs/test_utils.rs create mode 100644 src/proofs/utils.rs diff --git a/src/proofs/inner_product.rs b/src/proofs/inner_product.rs index 264a4df..89d863d 100644 --- a/src/proofs/inner_product.rs +++ b/src/proofs/inner_product.rs @@ -360,7 +360,7 @@ mod tests { use curv::elliptic::curves::traits::*; use curv::BigInt; use proofs::inner_product::InnerProductArg; - use proofs::test_utils::generate_random_point; + use proofs::utils::derive_point; fn test_helper

(n: usize) where @@ -374,7 +374,7 @@ mod tests { .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -383,13 +383,13 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let Gx: P = generate_random_point(&Converter::to_vec(&hash)); + let Gx: P = derive_point(&Converter::to_vec(&hash)); let a: Vec<_> = (0..n) .map(|_| { @@ -458,7 +458,7 @@ mod tests { .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -467,13 +467,13 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let Gx: P = generate_random_point(&Converter::to_vec(&hash)); + let Gx: P = derive_point(&Converter::to_vec(&hash)); let a: Vec<_> = (0..n) .map(|_| { @@ -542,7 +542,7 @@ mod tests { .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -551,13 +551,13 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let Gx: P = generate_random_point(&Converter::to_vec(&hash)); + let Gx: P = derive_point(&Converter::to_vec(&hash)); let c = super::inner_product(&a, &b, &P::Scalar::q()); diff --git a/src/proofs/mod.rs b/src/proofs/mod.rs index fd8a0fc..1be563f 100644 --- a/src/proofs/mod.rs +++ b/src/proofs/mod.rs @@ -15,10 +15,9 @@ version 3 of the License, or (at your option) any later version. // based on the paper: https://eprint.iacr.org/2017/1066.pdf -#[cfg(test)] -mod test_utils; - pub mod inner_product; pub mod range_proof; -// pub mod range_proof_wip; +pub mod range_proof_wip; pub mod weighted_inner_product; + +mod utils; diff --git a/src/proofs/range_proof.rs b/src/proofs/range_proof.rs index 2a1d999..db78c04 100644 --- a/src/proofs/range_proof.rs +++ b/src/proofs/range_proof.rs @@ -780,7 +780,7 @@ mod tests { use super::RangeProof; use crate::test_for_all_curves; - use proofs::test_utils::generate_random_point; + use proofs::utils::derive_point; fn test_helper

(seed: &BigInt, n: usize, m: usize) where @@ -791,13 +791,13 @@ mod tests { let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H: P = generate_random_point(&Converter::to_vec(&hash)); + let H: P = derive_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { let kzen_label_i = BigInt::from(i as u32) + seed; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -806,7 +806,7 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + seed; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); @@ -840,13 +840,13 @@ mod tests { let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H: P = generate_random_point(&Converter::to_vec(&hash)); + let H: P = derive_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { let kzen_label_i = BigInt::from(i as u32) + seed; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -855,7 +855,7 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + seed; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); @@ -897,13 +897,13 @@ mod tests { let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H: P = generate_random_point(&Converter::to_vec(&hash)); + let H: P = derive_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -912,7 +912,7 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); @@ -956,13 +956,13 @@ mod tests { let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H: P = generate_random_point(&Converter::to_vec(&hash)); + let H: P = derive_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -971,7 +971,7 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); @@ -1015,13 +1015,13 @@ mod tests { let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H: P = generate_random_point(&Converter::to_vec(&hash)); + let H: P = derive_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -1030,7 +1030,7 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); @@ -1074,13 +1074,13 @@ mod tests { let G: P = ECPoint::generator(); let label = BigInt::from(1); let hash = HSha512::create_hash(&[&label]); - let H: P = generate_random_point(&Converter::to_vec(&hash)); + let H: P = derive_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -1089,7 +1089,7 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); diff --git a/src/proofs/test_utils.rs b/src/proofs/test_utils.rs deleted file mode 100644 index 70e82b8..0000000 --- a/src/proofs/test_utils.rs +++ /dev/null @@ -1,8 +0,0 @@ -use curv::elliptic::curves::traits::*; -use curv::arithmetic::big_gmp::*; - -pub fn generate_random_point(random_source: &[u8]) -> P { - let bn = BigInt::from(random_source); - let scalar = ::from(&bn); - P::generator() * scalar -} diff --git a/src/proofs/utils.rs b/src/proofs/utils.rs new file mode 100644 index 0000000..1bf0443 --- /dev/null +++ b/src/proofs/utils.rs @@ -0,0 +1,10 @@ +use curv::arithmetic::big_gmp::BigInt; +use curv::elliptic::curves::traits::*; + +// TODO: this function needs to be reviewed. consider applying KDF +// to given bytes before converting them to ec scalar +pub fn derive_point(source: &[u8]) -> P { + let bn = BigInt::from(source); + let scalar = ::from(&bn); + P::generator() * scalar +} diff --git a/src/proofs/weighted_inner_product.rs b/src/proofs/weighted_inner_product.rs index c878bc0..51ac22b 100644 --- a/src/proofs/weighted_inner_product.rs +++ b/src/proofs/weighted_inner_product.rs @@ -545,7 +545,7 @@ mod tests { use super::{weighted_inner_product, WeightedInnerProdArg}; use crate::test_for_all_curves; use itertools::iterate; - use proofs::test_utils::generate_random_point; + use proofs::utils::derive_point; fn test_helper

(n: usize) where @@ -559,7 +559,7 @@ mod tests { .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -568,16 +568,16 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); let label = BigInt::from(2); let hash = HSha512::create_hash(&[&label]); - let g: P = generate_random_point(&Converter::to_vec(&hash)); + let g: P = derive_point(&Converter::to_vec(&hash)); let label = BigInt::from(3); let hash = HSha512::create_hash(&[&label]); - let h: P = generate_random_point(&Converter::to_vec(&hash)); + let h: P = derive_point(&Converter::to_vec(&hash)); let a: Vec<_> = (0..n) .map(|_| { @@ -657,7 +657,7 @@ mod tests { .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -666,16 +666,16 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); let label = BigInt::from(2); let hash = HSha512::create_hash(&[&label]); - let g: P = generate_random_point(&Converter::to_vec(&hash)); + let g: P = derive_point(&Converter::to_vec(&hash)); let label = BigInt::from(3); let hash = HSha512::create_hash(&[&label]); - let h: P = generate_random_point(&Converter::to_vec(&hash)); + let h: P = derive_point(&Converter::to_vec(&hash)); let a: Vec<_> = (0..n) .map(|_| { @@ -755,7 +755,7 @@ mod tests { .map(|i| { let kzen_label_i = BigInt::from(i as u32) + &kzen_label; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) .collect::>(); @@ -764,17 +764,17 @@ mod tests { .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + &kzen_label; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) .collect::>(); // generate g, h let label = BigInt::from(2); let hash = HSha512::create_hash(&[&label]); - let g: P = generate_random_point(&Converter::to_vec(&hash)); + let g: P = derive_point(&Converter::to_vec(&hash)); let label = BigInt::from(3); let hash = HSha512::create_hash(&[&label]); - let h: P = generate_random_point(&Converter::to_vec(&hash)); + let h: P = derive_point(&Converter::to_vec(&hash)); let y_scalar: BigInt = HSha256::create_hash_from_slice("Seed string decided by P,V!".as_bytes()); From ab14585407431767deb2c5615e284debbd1c6203 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sun, 6 Dec 2020 18:15:18 +0700 Subject: [PATCH 6/8] Update range_proof_wip --- src/proofs/range_proof_wip.rs | 255 ++++++++++++++++++++-------------- 1 file changed, 149 insertions(+), 106 deletions(-) diff --git a/src/proofs/range_proof_wip.rs b/src/proofs/range_proof_wip.rs index dfdb97d..2f04426 100644 --- a/src/proofs/range_proof_wip.rs +++ b/src/proofs/range_proof_wip.rs @@ -28,56 +28,50 @@ use curv::cryptographic_primitives::hashing::hash_sha512::HSha512; use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; use curv::BigInt; -type GE = curv::elliptic::curves::secp256_k1::GE; -type FE = curv::elliptic::curves::secp256_k1::FE; use itertools::iterate; -use proofs::range_proof::generate_random_point; +use proofs::utils::derive_point; use proofs::weighted_inner_product::WeightedInnerProdArg; use std::ops::{Shl, Shr}; use Errors::{self, RangeProofError}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct StatementRP { - pub g_vec: Vec, - pub h_vec: Vec, - pub G: GE, - pub H: GE, +pub struct StatementRP { + pub g_vec: Vec

, + pub h_vec: Vec

, + pub G: P, + pub H: P, pub bit_length: usize, } -impl StatementRP { - pub fn generate_bases( - init_seed: &BigInt, - num_of_proofs: usize, - bit_length: usize, - ) -> StatementRP { +impl StatementRP

{ + pub fn generate_bases(init_seed: &BigInt, num_of_proofs: usize, bit_length: usize) -> Self { let n = bit_length; let m = num_of_proofs; let nm = n * m; // G,H - points for pederson commitment: com = vG + rH - let G: GE = ECPoint::generator(); - let label = BigInt::mod_sub(&init_seed, &BigInt::one(), &FE::q()); + let G: P = ECPoint::generator(); + let label = BigInt::mod_sub(&init_seed, &BigInt::one(), &::q()); let hash = HSha512::create_hash(&[&label]); - let H = generate_random_point(&Converter::to_vec(&hash)); + let H = derive_point(&Converter::to_vec(&hash)); let g_vec = (0..nm) .map(|i| { let kzen_label_i = BigInt::from(i as u32) + init_seed; let hash_i = HSha512::create_hash(&[&kzen_label_i]); - generate_random_point(&Converter::to_vec(&hash_i)) + derive_point(&Converter::to_vec(&hash_i)) }) - .collect::>(); + .collect::>(); // can run in parallel to g_vec: let h_vec = (0..nm) .map(|i| { let kzen_label_j = BigInt::from(n as u32) + BigInt::from(i as u32) + init_seed; let hash_j = HSha512::create_hash(&[&kzen_label_j]); - generate_random_point(&Converter::to_vec(&hash_j)) + derive_point(&Converter::to_vec(&hash_j)) }) - .collect::>(); + .collect::>(); return StatementRP { g_vec, @@ -90,13 +84,21 @@ impl StatementRP { } #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct RangeProofWIP { - A: GE, - weighted_inner_product_proof: WeightedInnerProdArg, +pub struct RangeProofWIP { + A: P, + weighted_inner_product_proof: WeightedInnerProdArg

, } -impl RangeProofWIP { - pub fn prove(stmt: StatementRP, mut secret: Vec, blinding: &[FE]) -> RangeProofWIP { +impl

RangeProofWIP

+where + P: ECPoint + Clone, + P::Scalar: Clone, +{ + pub fn prove( + stmt: StatementRP

, + mut secret: Vec, + blinding: &[P::Scalar], + ) -> RangeProofWIP

{ let num_of_proofs = secret.len(); let bit_length = stmt.bit_length; //num of proofs times bit length @@ -110,7 +112,7 @@ impl RangeProofWIP { let N = g_vec.len(); let two = BigInt::from(2); let one = BigInt::from(1); - let order = FE::q(); + let order = ::q(); // All of the input vectors must have the same length. assert_eq!(h_vec.len(), N); @@ -141,8 +143,8 @@ impl RangeProofWIP { .collect::>(); // let mut index: usize = 0; - let alpha: FE = ECScalar::new_random(); - let mut A = H * α + let alpha: P::Scalar = ECScalar::new_random(); + let mut A = H.clone() * alpha.clone(); A = g_vec.iter().zip(secret_bits.clone()).fold(A, |acc, x| { if x.1 { acc.add_point(&x.0.get_element()) @@ -160,8 +162,8 @@ impl RangeProofWIP { let y = HSha256::create_hash_from_ge(&[&A]); let y_bn = y.to_big_int(); - let base_point: GE = ECPoint::generator(); - let yG: GE = base_point * &y; + let base_point: P = ECPoint::generator(); + let yG: P = base_point.clone() * y.clone(); let z = HSha256::create_hash_from_ge(&[&A, &yG]); let z_bn = z.to_big_int(); let z_sq_bn = BigInt::mod_mul(&z_bn, &z_bn, &order); @@ -235,14 +237,14 @@ impl RangeProofWIP { A_hat_scalars.extend_from_slice(&scalars_h_vec); A_hat_scalars.extend_from_slice(&[scalar_G.clone(), scalar_H.clone()]); - let mut A_hat_bases: Vec = Vec::with_capacity(2 * nm + 2); + let mut A_hat_bases: Vec

= Vec::with_capacity(2 * nm + 2); A_hat_bases.extend_from_slice(&g_vec); A_hat_bases.extend_from_slice(&h_vec); - A_hat_bases.extend_from_slice(&[G, H]); + A_hat_bases.extend_from_slice(&[G.clone(), H.clone()]); let A_hat = (0..(2 * nm + 2)) - .map(|i| A_hat_bases[i] * &ECScalar::from(&A_hat_scalars[i])) - .fold(A.clone(), |acc, x| acc + x as GE); + .map(|i| A_hat_bases[i].clone() * ECScalar::from(&A_hat_scalars[i])) + .fold(A.clone(), |acc, x| acc + x as P); // compute aL_hat, aR_hat, alpha_hat let aL_hat = (0..nm) @@ -267,7 +269,7 @@ impl RangeProofWIP { }; } - pub fn verify(&self, stmt: StatementRP, ped_com: &[GE]) -> Result<(), Errors> { + pub fn verify(&self, stmt: StatementRP

, ped_com: &[P]) -> Result<(), Errors> { let bit_length = stmt.bit_length; let num_of_proofs = ped_com.len(); let nm = num_of_proofs * bit_length; @@ -279,12 +281,12 @@ impl RangeProofWIP { let two = BigInt::from(2); let one = BigInt::from(1); - let order = FE::q(); + let order = ::q(); let y = HSha256::create_hash_from_ge(&[&self.A]); let y_bn = y.to_big_int(); - let base_point: GE = ECPoint::generator(); - let yG: GE = base_point * &y; + let base_point: P = ECPoint::generator(); + let yG: P = base_point.clone() * y.clone(); let z = HSha256::create_hash_from_ge(&[&self.A, &yG]); let z_bn = z.to_big_int(); let z_sq_bn = BigInt::mod_mul(&z_bn, &z_bn, &order); @@ -346,9 +348,9 @@ impl RangeProofWIP { let sum_com = (0..num_of_proofs) .map(|i| { let y_pow_z2i = BigInt::mod_mul(&y_pow, &vec_z2m[i].clone(), &order); - ped_com[i] * &ECScalar::from(&y_pow_z2i) + ped_com[i].clone() * ECScalar::from(&y_pow_z2i) }) - .fold(self.A, |acc, x| acc + x as GE); + .fold(self.A.clone(), |acc, x| acc + x as P); // compute A_hat let mut A_hat_scalars: Vec = Vec::with_capacity(2 * nm + 2); @@ -356,14 +358,14 @@ impl RangeProofWIP { A_hat_scalars.extend_from_slice(&scalars_h_vec); A_hat_scalars.extend_from_slice(&[scalar_G.clone()]); - let mut A_hat_bases: Vec = Vec::with_capacity(2 * nm + 2); + let mut A_hat_bases: Vec

= Vec::with_capacity(2 * nm + 2); A_hat_bases.extend_from_slice(&g_vec); A_hat_bases.extend_from_slice(&h_vec); - A_hat_bases.extend_from_slice(&[G]); + A_hat_bases.extend_from_slice(&[G.clone()]); let A_hat = (0..(2 * nm + 1)) - .map(|i| A_hat_bases[i] * &ECScalar::from(&A_hat_scalars[i])) - .fold(sum_com.clone(), |acc, x| acc + x as GE); + .map(|i| A_hat_bases[i].clone() * ECScalar::from(&A_hat_scalars[i])) + .fold(sum_com.clone(), |acc, x| acc + x as P); let verify = self .weighted_inner_product_proof @@ -379,9 +381,9 @@ impl RangeProofWIP { /// Verify a wip-based range proof in a using a single multi-exponentiation equation. /// The final check costs a multi-exponentiation of size (2mn + 2log(mn) + m + 5). /// - pub fn aggregated_verify(&self, stmt: StatementRP, ped_com: &[GE]) -> Result<(), Errors> { + pub fn aggregated_verify(&self, stmt: StatementRP

, ped_com: &[P]) -> Result<(), Errors> { let wip = &self.weighted_inner_product_proof; - let P = self.A; + let P = self.A.clone(); let n = stmt.bit_length; let m = ped_com.len(); @@ -392,7 +394,7 @@ impl RangeProofWIP { let g = &stmt.G; let h = &stmt.H; // let n = stmt.bit_length; - let order = FE::q(); + let order = ::q(); let lg_nm = wip.L.len(); let two = BigInt::from(2); let one = BigInt::from(1); @@ -409,8 +411,8 @@ impl RangeProofWIP { // compute challenges let y = HSha256::create_hash_from_ge(&[&self.A]); let y_bn = y.to_big_int(); - let base_point: GE = ECPoint::generator(); - let yG: GE = base_point * &y; + let base_point: P = ECPoint::generator(); + let yG: P = base_point.clone() * y.clone(); let z = HSha256::create_hash_from_ge(&[&self.A, &yG]); let z_bn = z.to_big_int(); let z_sq_bn = BigInt::mod_mul(&z_bn, &z_bn, &order); @@ -461,7 +463,7 @@ impl RangeProofWIP { let mut allinv = BigInt::one(); let mut all = BigInt::one(); for (Li, Ri) in wip.L.iter().zip(wip.R.iter()) { - let x = HSha256::create_hash_from_ge::(&[&Li, &Ri, &g, &h]); + let x = HSha256::create_hash_from_ge::

(&[&Li, &Ri, &g, &h]); let x_bn = x.to_big_int(); let x_inv_fe = x.invert(); let x_inv_bn = x_inv_fe.to_big_int(); @@ -573,21 +575,21 @@ impl RangeProofWIP { scalars.push(scalar_A); // compute concatenated base vector - let mut points: Vec = Vec::with_capacity(2 * nm + 2 * lg_nm + m + 5); + let mut points: Vec

= Vec::with_capacity(2 * nm + 2 * lg_nm + m + 5); points.extend_from_slice(G); points.extend_from_slice(H); - points.push(*g); + points.push(g.clone()); points.extend_from_slice(&wip.L); points.extend_from_slice(&wip.R); points.push(P); points.extend_from_slice(&ped_com); - points.push(wip.a_tag); + points.push(wip.a_tag.clone()); - let h_delta_prime = h * &ECScalar::from(&wip.delta_prime); + let h_delta_prime = h.clone() * ECScalar::from(&wip.delta_prime); let tot_len = points.len(); let lhs = (0..tot_len) - .map(|i| points[i] * &ECScalar::from(&scalars[i])) - .fold(h_delta_prime, |acc, x| acc + x as GE); + .map(|i| points[i].clone() * ECScalar::from(&scalars[i])) + .fold(h_delta_prime, |acc, x| acc + x as P); if lhs == wip.b_tag { Ok(()) @@ -602,31 +604,36 @@ mod tests { use curv::arithmetic::traits::Samplable; use curv::elliptic::curves::traits::*; use curv::BigInt; - type GE = curv::elliptic::curves::secp256_k1::GE; -type FE = curv::elliptic::curves::secp256_k1::FE; + use crate::test_for_all_curves; use proofs::range_proof_wip::{RangeProofWIP, StatementRP}; - pub fn test_helper(seed: &BigInt, n: usize, m: usize) { + fn test_helper

(seed: &BigInt, n: usize, m: usize) + where + P: ECPoint + Clone, + P::Scalar: Clone, + { // generate stmt - let stmt = StatementRP::generate_bases(&seed, m, n); + let stmt = StatementRP::

::generate_bases(&seed, m, n); // generate witness - let G = stmt.G; - let H = stmt.H; + let G = stmt.G.clone(); + let H = stmt.H.clone(); let range = BigInt::from(2).pow(n as u32); let v_vec = (0..m) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); // simulate range proof let range_proof_wip = RangeProofWIP::prove(stmt.clone(), v_vec, &r_vec); @@ -634,26 +641,32 @@ type FE = curv::elliptic::curves::secp256_k1::FE; assert!(result.is_ok()); } - pub fn test_helper_aggregate(seed: &BigInt, n: usize, m: usize) { + fn test_helper_aggregate

(seed: &BigInt, n: usize, m: usize) + where + P: ECPoint + Clone, + P::Scalar: Clone, + { // generate stmt - let stmt = StatementRP::generate_bases(&seed, m, n); + let stmt = StatementRP::

::generate_bases(&seed, m, n); // generate witness - let G = stmt.G; - let H = stmt.H; + let G = stmt.G.clone(); + let H = stmt.H.clone(); let range = BigInt::from(2).pow(n as u32); let v_vec = (0..m) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); // simulate range proof let range_proof_wip = RangeProofWIP::prove(stmt.clone(), v_vec, &r_vec); @@ -661,99 +674,129 @@ type FE = curv::elliptic::curves::secp256_k1::FE; assert!(result.is_ok()); } - #[test] - pub fn test_batch_4_wip_range_proof_32() { + test_for_all_curves!(test_batch_4_wip_range_proof_32); + fn test_batch_4_wip_range_proof_32

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let n = 32; // num of proofs let m = 4; let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - let stmt = StatementRP::generate_bases(&kzen_label, m, n); + let stmt = StatementRP::

::generate_bases(&kzen_label, m, n); // generate witness - let G = stmt.G; - let H = stmt.H; + let G = stmt.G.clone(); + let H = stmt.H.clone(); let range = BigInt::from(2).pow(n as u32); let v_vec = (0..m) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); let range_proof_wip = RangeProofWIP::prove(stmt.clone(), v_vec, &r_vec); let result = RangeProofWIP::verify(&range_proof_wip, stmt.clone(), &ped_com_vec); assert!(result.is_ok()); } - #[test] - #[should_panic] - pub fn test_batch_4_wip_range_proof_32_out_of_range() { + test_for_all_curves!( + #[should_panic] + test_batch_4_wip_range_proof_32_out_of_range + ); + fn test_batch_4_wip_range_proof_32_out_of_range

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let n = 32; // num of proofs let m = 4; let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - let stmt = StatementRP::generate_bases(&kzen_label, m, n); + let stmt = StatementRP::

::generate_bases(&kzen_label, m, n); // generate witness - let G = stmt.G; - let H = stmt.H; + let G = stmt.G.clone(); + let H = stmt.H.clone(); let range = BigInt::from(2).pow(n as u32); let mut v_vec = (0..m - 1) .map(|_| ECScalar::from(&BigInt::sample_below(&range))) - .collect::>(); + .collect::>(); let bad_v = BigInt::from(2).pow(33); v_vec.push(ECScalar::from(&bad_v)); - let r_vec = (0..m).map(|_| ECScalar::new_random()).collect::>(); + let r_vec = (0..m) + .map(|_| ECScalar::new_random()) + .collect::>(); let ped_com_vec = (0..m) .map(|i| { - let ped_com = &G * &v_vec[i] + &H * &r_vec[i]; + let ped_com = G.clone() * v_vec[i].clone() + H.clone() * r_vec[i].clone(); ped_com }) - .collect::>(); + .collect::>(); let range_proof_wip = RangeProofWIP::prove(stmt.clone(), v_vec, &r_vec); let result = RangeProofWIP::verify(&range_proof_wip, stmt.clone(), &ped_com_vec); assert!(result.is_ok()); } - #[test] - pub fn test_batch_2_wip_range_proof_16() { + test_for_all_curves!(test_batch_2_wip_range_proof_16); + fn test_batch_2_wip_range_proof_16

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - test_helper(&kzen_label, 16, 2); + test_helper::

(&kzen_label, 16, 2); } - #[test] - pub fn test_batch_1_wip_range_proof_8() { + test_for_all_curves!(test_batch_1_wip_range_proof_8); + fn test_batch_1_wip_range_proof_8

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - test_helper(&kzen_label, 8, 1); + test_helper::

(&kzen_label, 8, 1); } - #[test] - pub fn test_batch_4_wip_range_proof_64() { + test_for_all_curves!(test_batch_4_wip_range_proof_64); + fn test_batch_4_wip_range_proof_64

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - test_helper(&kzen_label, 64, 4); + test_helper::

(&kzen_label, 64, 4); } - #[test] - pub fn test_batch_agg_4_wip_range_proof_64() { + test_for_all_curves!(test_batch_agg_4_wip_range_proof_64); + fn test_batch_agg_4_wip_range_proof_64

() + where + P: ECPoint + Clone, + P::Scalar: Clone, + { let KZen: &[u8] = &[75, 90, 101, 110]; let kzen_label = BigInt::from(KZen); - test_helper_aggregate(&kzen_label, 64, 4); + test_helper_aggregate::

(&kzen_label, 64, 4); } } From 1e856b17aefd37e2085144097df69c26832bb2b6 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sun, 6 Dec 2020 19:40:55 +0700 Subject: [PATCH 7/8] Use test_for_all_curves macro from `curv` crate --- Cargo.toml | 3 ++- src/lib.rs | 40 ---------------------------- src/proofs/inner_product.rs | 2 +- src/proofs/range_proof.rs | 2 +- src/proofs/range_proof_wip.rs | 2 +- src/proofs/weighted_inner_product.rs | 2 +- 6 files changed, 6 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6df3a4a..e218640 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ authors = [ crate-type = ["lib"] [dependencies] -curv = { git = "https://github.com/KZen-networks/curv" , tag = "v0.3.4"} +curv = { git = "https://github.com/survived/curv.git" , branch = "expose-testing-macro" } itertools = "0.7.8" serde = "1.0" @@ -19,6 +19,7 @@ serde_derive = "1.0" [dev-dependencies] criterion = "0.2" paste = "1.0.3" +curv = { git = "https://github.com/survived/curv.git" , branch = "expose-testing-macro", features = ["testing-utils"] } [[bench]] name = "range_proof" diff --git a/src/lib.rs b/src/lib.rs index 6c1aa76..1009f2a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,43 +29,3 @@ pub enum Errors { WeightedInnerProdError, RangeProofError, } - -#[cfg(test)] -#[macro_export] -macro_rules! test_for_all_curves { - (#[should_panic] $fn: ident) => { - crate::test_for_all_curves!([#[should_panic]] $fn); - }; - ($fn: ident) => { - crate::test_for_all_curves!([] $fn); - }; - ([$($attrs:tt)*] $fn: ident) => { - paste::paste!{ - #[test] - $($attrs)* - fn [<$fn _secp256k1>]() { - $fn::() - } - #[test] - $($attrs)* - fn [<$fn _ristretto>]() { - $fn::() - } - #[test] - $($attrs)* - fn [<$fn _ed25519>]() { - $fn::() - } - #[test] - $($attrs)* - fn [<$fn _bls12_381>]() { - $fn::() - } - #[test] - $($attrs)* - fn [<$fn _p256>]() { - $fn::() - } - } - }; -} diff --git a/src/proofs/inner_product.rs b/src/proofs/inner_product.rs index 89d863d..6bd7ac9 100644 --- a/src/proofs/inner_product.rs +++ b/src/proofs/inner_product.rs @@ -353,11 +353,11 @@ fn inner_product(a: &[BigInt], b: &[BigInt], order: &BigInt) -> BigInt { #[cfg(test)] mod tests { - use crate::test_for_all_curves; use curv::arithmetic::traits::{Converter, Modulo}; use curv::cryptographic_primitives::hashing::hash_sha512::HSha512; use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; + use curv::test_for_all_curves; use curv::BigInt; use proofs::inner_product::InnerProductArg; use proofs::utils::derive_point; diff --git a/src/proofs/range_proof.rs b/src/proofs/range_proof.rs index db78c04..4e77033 100644 --- a/src/proofs/range_proof.rs +++ b/src/proofs/range_proof.rs @@ -776,10 +776,10 @@ mod tests { use curv::cryptographic_primitives::hashing::hash_sha512::HSha512; use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; + use curv::test_for_all_curves; use curv::BigInt; use super::RangeProof; - use crate::test_for_all_curves; use proofs::utils::derive_point; fn test_helper

(seed: &BigInt, n: usize, m: usize) diff --git a/src/proofs/range_proof_wip.rs b/src/proofs/range_proof_wip.rs index 2f04426..f54196b 100644 --- a/src/proofs/range_proof_wip.rs +++ b/src/proofs/range_proof_wip.rs @@ -603,9 +603,9 @@ where mod tests { use curv::arithmetic::traits::Samplable; use curv::elliptic::curves::traits::*; + use curv::test_for_all_curves; use curv::BigInt; - use crate::test_for_all_curves; use proofs::range_proof_wip::{RangeProofWIP, StatementRP}; fn test_helper

(seed: &BigInt, n: usize, m: usize) diff --git a/src/proofs/weighted_inner_product.rs b/src/proofs/weighted_inner_product.rs index 51ac22b..3594ade 100644 --- a/src/proofs/weighted_inner_product.rs +++ b/src/proofs/weighted_inner_product.rs @@ -540,10 +540,10 @@ mod tests { use curv::cryptographic_primitives::hashing::hash_sha512::HSha512; use curv::cryptographic_primitives::hashing::traits::*; use curv::elliptic::curves::traits::*; + use curv::test_for_all_curves; use curv::BigInt; use super::{weighted_inner_product, WeightedInnerProdArg}; - use crate::test_for_all_curves; use itertools::iterate; use proofs::utils::derive_point; From c7fca9bc076ba1dc388e3aae2046e1b3fd001e13 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sun, 13 Dec 2020 18:51:22 +0700 Subject: [PATCH 8/8] Expose utils module, remove unnecessary dependency --- Cargo.toml | 1 - src/proofs/mod.rs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e218640..6cb04cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,6 @@ serde_derive = "1.0" [dev-dependencies] criterion = "0.2" -paste = "1.0.3" curv = { git = "https://github.com/survived/curv.git" , branch = "expose-testing-macro", features = ["testing-utils"] } [[bench]] diff --git a/src/proofs/mod.rs b/src/proofs/mod.rs index 1be563f..22aba32 100644 --- a/src/proofs/mod.rs +++ b/src/proofs/mod.rs @@ -18,6 +18,5 @@ version 3 of the License, or (at your option) any later version. pub mod inner_product; pub mod range_proof; pub mod range_proof_wip; +pub mod utils; pub mod weighted_inner_product; - -mod utils;