From 6daad350947ba0fd8805cd777b71f0d790408c74 Mon Sep 17 00:00:00 2001 From: Matthew Issac Date: Mon, 22 Aug 2022 21:25:36 -0400 Subject: [PATCH 01/33] wip: migrating GLV to arkworks --- manta-crypto/src/arkworks/ec.rs | 248 +++++++++++++++++++++++++++++++ manta-crypto/src/arkworks/glv.rs | 18 +++ 2 files changed, 266 insertions(+) create mode 100644 manta-crypto/src/arkworks/ec.rs create mode 100644 manta-crypto/src/arkworks/glv.rs diff --git a/manta-crypto/src/arkworks/ec.rs b/manta-crypto/src/arkworks/ec.rs new file mode 100644 index 000000000..e560d85f8 --- /dev/null +++ b/manta-crypto/src/arkworks/ec.rs @@ -0,0 +1,248 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Arkwprks Elliptic Curve Implementation + +use crate::arkworks::ff::PrimeField; +use models::short_weierstrass_jacobian; +use models::twisted_edwards_extended; +use models::SWModelParameters; +use models::TEModelParameters; +use num_bigint::Sign; +use num_bigint::{BigInt, BigUint}; + +#[doc(inline)] +pub use ark_ec::*; + +/// +pub trait AffineCurveExt: AffineCurve { + /// + fn x(&self) -> &Self::BaseField; + + /// + fn y(&self) -> &Self::BaseField; + + /// + fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self; +} + +impl

AffineCurveExt for short_weierstrass_jacobian::GroupAffine

+where + P: SWModelParameters, +{ + #[inline] + fn x(&self) -> &Self::BaseField { + &self.x + } + + #[inline] + fn y(&self) -> &Self::BaseField { + &self.y + } + + #[inline] + fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { + Self::new(x, y, false) + } +} + +impl

AffineCurveExt for twisted_edwards_extended::GroupAffine

+where + P: TEModelParameters, +{ + #[inline] + fn x(&self) -> &Self::BaseField { + &self.x + } + + #[inline] + fn y(&self) -> &Self::BaseField { + &self.y + } + + #[inline] + fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { + Self::new(x, y) + } +} + +/// +pub struct GLVParameters +where + C: AffineCurve, +{ + /// + pub lambda: C::ScalarField, + + /// + pub beta: C::BaseField, + + /// + pub base_v1: (BigInt, BigInt), + + /// + pub base_v2: (BigInt, BigInt), +} + +impl GLVParameters +where + C: AffineCurve, +{ + /// + #[inline] + pub fn generate() -> Self { + todo!() + } + + /// + #[inline] + pub fn scalar_mul(&self, point: &C, scalar: &C::ScalarField) -> C { + let (k1, k2) = glv_decompose_scalar::<&C>(&scalar, self.base_v1, self.base_v2); + + let mut P1 = C::zero(); + let mut P2 = C::zero(); + + let P1 = match k1.sign() { + Sign::Minus => { + let k1_unsigned: BigUint = BigInt::to_biguint(&-k1).unwrap(); + let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); + -point.mul(*&k1_scalar.into_repr()) + }, + _ => { + let k1_unsigned: BigUint = BigInt::to_biguint(&k1).unwrap(); + let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); + point.mul(*&k1_scalar.into_repr()) + } + }; + let P2 = match k2.sign() { + Sign::Minus => { + let k2_unsigned: BigUint = BigInt::to_biguint(&-k2).unwrap(); + let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); + -glv_endomorphism::(point, &self.beta).mul(*&k2_scalar.into_repr()) + }, + _ => { + let k1_unsigned: BigUint = BigInt::to_biguint(&k1).unwrap(); + let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); + point.mul(*&k1_scalar.into_repr()) + } + }; + + // if Sign::Minus == k1.sign() { + // let k1_unsigned: BigUint = BigInt::to_biguint(&-(&decomposition[0])).unwrap(); + // let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); + // P1 = -point.mul(&k1_scalar.into_repr()); + // } else { + // let k1_unsigned: BigUint = BigInt::to_biguint(&decomposition[0]).unwrap(); + // let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); + // P1 = point.mul(&k1_scalar.into_repr()); + // } + + // if Sign::Minus == decomposition[1].sign() { + // let k2_unsigned: BigUint = BigInt::to_biguint(&-(&decomposition[1])).unwrap(); + // let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); + // let p_affine= point.into_affine(); + // let p_affine_x = AffineCurveExt::x(&p_affine); + // //P2 = -endomorphism::(point, beta_raw).mul(&k2_scalar.into_repr()); + // } else { + // let k2_unsigned: BigUint = BigInt::to_biguint(&decomposition[1]).unwrap(); + // let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); + // //P2 = endomorphism::(point, beta_raw).mul(&k2_scalar.into_repr()); + // } + let answer = P1 + P2; + answer + todo!() + } +} + +/// Given a scalar `k` and basis vectors `v` and `u` finds integer scalars `z1` and `z2`, +/// so that `(k, 0)` is close to `z1v + z2u` +#[inline] +pub fn glv_decompose_scalar(k: &F, v: (BigInt, BigInt), u: (BigInt, BigInt)) -> (BigInt, BigInt) +where + F: PrimeField, +{ + // NOTE: We first find rational solutions to `(k,0) = q1v + q2u` + // We can re-write this problem as a matrix `A(q1,q2) = (k,0)` + // so that `(q1,q2) = A^-1(k,0)`. + let k = BigInt::from_biguint(Sign::Plus, k.into()); + let det = (v.0 * u.1) - (v.1 * u.0); + let q1 = (u.1 * k) / det; + let q2 = (-v.1 * k) / det; + let k1 = k - q1 * v.0 - q2 * u.0; + let k2 = 0 - q1 * v.1 - q2 * u.1; + (k1, k2) +} + +/// +#[inline] +fn glv_endomorphism(point: &C, beta: &C::BaseField) -> C +where + C: AffineCurveExt, +{ + C::from_xy_unchecked(*point.x() * beta, *point.y()) +} + +/// +#[inline] +pub fn mul_glv(scalar: &C::ScalarField, point: &C) -> C +//, parameters: &GLVParameters) -> C +where + C: ProjectiveCurve, +{ + let beta_raw: BigUint = "2203960485148121921418603742825762020974279258880205651966".parse().unwrap(); + // NOTE: First generate basis vectors u and v + let v1: BigInt = "9931322734385697763".parse().unwrap(); + let v2: BigInt = "-147946756881789319000765030803803410728".parse().unwrap(); + let mut v: Vec = Vec::new(); + v.push(v1); + v.push(v2); + + // NOTE: Components for second basis vector u: + let u1: BigInt = "147946756881789319010696353538189108491".parse().unwrap(); + let u2: BigInt = "9931322734385697763".parse().unwrap(); + let mut u: Vec = Vec::new(); + u.push(u1); + u.push(u2); + + let decomposition = decompose_scalar::(&scalar, v, u); + + // NOTE: Check sign for k1 + let mut P1 = C::zero(); + let mut P2 = C::zero().into_affine(); + if Sign::Minus == decomposition[0].sign() { + let k1_unsigned: BigUint = BigInt::to_biguint(&-(&decomposition[0])).unwrap(); + let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); + P1 = -point.mul(&k1_scalar.into_repr()); + } else { + let k1_unsigned: BigUint = BigInt::to_biguint(&decomposition[0]).unwrap(); + let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); + P1 = point.mul(&k1_scalar.into_repr()); + } + //Check sign for k2 + if Sign::Minus == decomposition[1].sign() { + let k2_unsigned: BigUint = BigInt::to_biguint(&-(&decomposition[1])).unwrap(); + let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); + let p_affine= point.into_affine(); + let p_affine_x = AffineCurveExt::x(&p_affine); + //P2 = -endomorphism::(point, beta_raw).mul(&k2_scalar.into_repr()); + } else { + let k2_unsigned: BigUint = BigInt::to_biguint(&decomposition[1]).unwrap(); + let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); + //P2 = endomorphism::(point, beta_raw).mul(&k2_scalar.into_repr()); + } + let answer = P1 + P2; + answer +} diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv.rs new file mode 100644 index 000000000..7057ec7b5 --- /dev/null +++ b/manta-crypto/src/arkworks/glv.rs @@ -0,0 +1,18 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Arkworks GLV Implementation + From 2c2d170055ed9a1ebc502259328ea1352315137f Mon Sep 17 00:00:00 2001 From: missac213 <106991808+missac213@users.noreply.github.com> Date: Tue, 23 Aug 2022 20:47:06 -0400 Subject: [PATCH 02/33] Delete glv.rs Signed-off-by: missac213 <106991808+missac213@users.noreply.github.com> --- manta-crypto/src/arkworks/glv.rs | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 manta-crypto/src/arkworks/glv.rs diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv.rs deleted file mode 100644 index 7057ec7b5..000000000 --- a/manta-crypto/src/arkworks/glv.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2019-2022 Manta Network. -// This file is part of manta-rs. -// -// manta-rs is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// manta-rs is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with manta-rs. If not, see . - -//! Arkworks GLV Implementation - From 87929e5035d45b7bd4cc2064815e0e5f0a822102 Mon Sep 17 00:00:00 2001 From: missac213 <106991808+missac213@users.noreply.github.com> Date: Tue, 23 Aug 2022 20:48:27 -0400 Subject: [PATCH 03/33] wip: benchmarking glv --- manta-crypto/src/arkworks/ec.rs | 170 ++++++++++++-------------------- 1 file changed, 61 insertions(+), 109 deletions(-) diff --git a/manta-crypto/src/arkworks/ec.rs b/manta-crypto/src/arkworks/ec.rs index e560d85f8..d07efd87b 100644 --- a/manta-crypto/src/arkworks/ec.rs +++ b/manta-crypto/src/arkworks/ec.rs @@ -16,13 +16,16 @@ //! Arkwprks Elliptic Curve Implementation +use crate::alloc::string::ToString; use crate::arkworks::ff::PrimeField; use models::short_weierstrass_jacobian; use models::twisted_edwards_extended; use models::SWModelParameters; use models::TEModelParameters; +use num_bigint::BigInt; use num_bigint::Sign; -use num_bigint::{BigInt, BigUint}; + + #[doc(inline)] pub use ark_ec::*; @@ -109,61 +112,28 @@ where /// #[inline] - pub fn scalar_mul(&self, point: &C, scalar: &C::ScalarField) -> C { - let (k1, k2) = glv_decompose_scalar::<&C>(&scalar, self.base_v1, self.base_v2); - - let mut P1 = C::zero(); - let mut P2 = C::zero(); - - let P1 = match k1.sign() { - Sign::Minus => { - let k1_unsigned: BigUint = BigInt::to_biguint(&-k1).unwrap(); - let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); - -point.mul(*&k1_scalar.into_repr()) - }, - _ => { - let k1_unsigned: BigUint = BigInt::to_biguint(&k1).unwrap(); - let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); - point.mul(*&k1_scalar.into_repr()) - } - }; - let P2 = match k2.sign() { - Sign::Minus => { - let k2_unsigned: BigUint = BigInt::to_biguint(&-k2).unwrap(); - let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); - -glv_endomorphism::(point, &self.beta).mul(*&k2_scalar.into_repr()) - }, - _ => { - let k1_unsigned: BigUint = BigInt::to_biguint(&k1).unwrap(); - let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); - point.mul(*&k1_scalar.into_repr()) - } - }; - - // if Sign::Minus == k1.sign() { - // let k1_unsigned: BigUint = BigInt::to_biguint(&-(&decomposition[0])).unwrap(); - // let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); - // P1 = -point.mul(&k1_scalar.into_repr()); - // } else { - // let k1_unsigned: BigUint = BigInt::to_biguint(&decomposition[0]).unwrap(); - // let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); - // P1 = point.mul(&k1_scalar.into_repr()); - // } - - // if Sign::Minus == decomposition[1].sign() { - // let k2_unsigned: BigUint = BigInt::to_biguint(&-(&decomposition[1])).unwrap(); - // let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); - // let p_affine= point.into_affine(); - // let p_affine_x = AffineCurveExt::x(&p_affine); - // //P2 = -endomorphism::(point, beta_raw).mul(&k2_scalar.into_repr()); - // } else { - // let k2_unsigned: BigUint = BigInt::to_biguint(&decomposition[1]).unwrap(); - // let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); - // //P2 = endomorphism::(point, beta_raw).mul(&k2_scalar.into_repr()); - // } - let answer = P1 + P2; - answer - todo!() + pub fn scalar_mul(&self, point: &C, scalar: &C::ScalarField) -> C + where + C: AffineCurveExt, + { + let (k1, k2) = glv_decompose_scalar(scalar, self.base_v1.clone(), self.base_v2.clone()); + + let (k1_sign, k1) = k1.into_parts(); + let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1.to_bytes_le()); + + let p1 = match k1_sign { + Sign::Minus => -point.mul(k1_scalar.into_repr()), + _ => point.mul(k1_scalar.into_repr()), + }; + + let (k2_sign, k2) = k2.into_parts(); + let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2.to_bytes_le()); + + let p2 = match k2_sign { + Sign::Minus => -glv_endomorphism(point, &self.beta).mul(k2_scalar.into_repr()), + _ => glv_endomorphism(point, &self.beta).mul(k2_scalar.into_repr()), + }; + (p1 + p2).into_affine() } } @@ -177,11 +147,11 @@ where // NOTE: We first find rational solutions to `(k,0) = q1v + q2u` // We can re-write this problem as a matrix `A(q1,q2) = (k,0)` // so that `(q1,q2) = A^-1(k,0)`. - let k = BigInt::from_biguint(Sign::Plus, k.into()); - let det = (v.0 * u.1) - (v.1 * u.0); - let q1 = (u.1 * k) / det; - let q2 = (-v.1 * k) / det; - let k1 = k - q1 * v.0 - q2 * u.0; + let k: BigInt = k.into_repr().to_string().parse().unwrap(); + let det = (v.0.clone() * u.1.clone()) - (v.1.clone() * u.0.clone()); + let q1 = (u.1.clone() * k.clone()) / det.clone(); + let q2 = (-v.1.clone() * k.clone()) / det; + let k1 = k - q1.clone() * v.0 - q2.clone() * u.0; let k2 = 0 - q1 * v.1 - q2 * u.1; (k1, k2) } @@ -195,54 +165,36 @@ where C::from_xy_unchecked(*point.x() * beta, *point.y()) } -/// -#[inline] -pub fn mul_glv(scalar: &C::ScalarField, point: &C) -> C -//, parameters: &GLVParameters) -> C -where - C: ProjectiveCurve, -{ - let beta_raw: BigUint = "2203960485148121921418603742825762020974279258880205651966".parse().unwrap(); - // NOTE: First generate basis vectors u and v - let v1: BigInt = "9931322734385697763".parse().unwrap(); - let v2: BigInt = "-147946756881789319000765030803803410728".parse().unwrap(); - let mut v: Vec = Vec::new(); - v.push(v1); - v.push(v2); - - // NOTE: Components for second basis vector u: - let u1: BigInt = "147946756881789319010696353538189108491".parse().unwrap(); - let u2: BigInt = "9931322734385697763".parse().unwrap(); - let mut u: Vec = Vec::new(); - u.push(u1); - u.push(u2); - - let decomposition = decompose_scalar::(&scalar, v, u); - - // NOTE: Check sign for k1 - let mut P1 = C::zero(); - let mut P2 = C::zero().into_affine(); - if Sign::Minus == decomposition[0].sign() { - let k1_unsigned: BigUint = BigInt::to_biguint(&-(&decomposition[0])).unwrap(); - let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); - P1 = -point.mul(&k1_scalar.into_repr()); - } else { - let k1_unsigned: BigUint = BigInt::to_biguint(&decomposition[0]).unwrap(); - let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1_unsigned.to_bytes_le()); - P1 = point.mul(&k1_scalar.into_repr()); +/// Testing Suite +#[cfg(test)] +mod test { + use core::str::FromStr; + use super::*; + use crate::arkworks::ff::UniformRand; + use crate::arkworks::ff::{Field, PrimeField}; + use crate::rand::OsRng; + + pub fn glv_is_correct() + where + C: AffineCurveExt, + { + let mut rng = OsRng; + let scalar = C::ScalarField::rand(&mut rng); + let point = C::rand(&mut rng); + assert_eq!( + point.mul(&scalar.into_repr()), + GLVParameters::{ + lambda: C::ScalarField::from_le_bytes_mod_order(&"228988810152649578064853576960394133503".parse().unwrap().to_bytes_le()), + beta: C::BaseField::from_random_bytes(&"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436".parse().unwrap().to_bytes_le()).unwrap(), + base_v1: (BigInt::from_str("1").unwrap(), BigInt::from_str("228988810152649578064853576960394133504").unwrap()), + base_v2: ("228988810152649578064853576960394133503".parse().unwrap(),"-1".parse().unwrap()) + }.scalar_mul(&point, &scalar), + "GLV should produce the same results as Arkworks scalar multiplication." + ); } - //Check sign for k2 - if Sign::Minus == decomposition[1].sign() { - let k2_unsigned: BigUint = BigInt::to_biguint(&-(&decomposition[1])).unwrap(); - let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); - let p_affine= point.into_affine(); - let p_affine_x = AffineCurveExt::x(&p_affine); - //P2 = -endomorphism::(point, beta_raw).mul(&k2_scalar.into_repr()); - } else { - let k2_unsigned: BigUint = BigInt::to_biguint(&decomposition[1]).unwrap(); - let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2_unsigned.to_bytes_le()); - //P2 = endomorphism::(point, beta_raw).mul(&k2_scalar.into_repr()); + + #[test] + fn glv_matches_arkworks_scalar_mul() { + glv_is_correct::(); } - let answer = P1 + P2; - answer } From 3af01f5218745f0a27f57263c88a6afb697f407b Mon Sep 17 00:00:00 2001 From: missac213 <106991808+missac213@users.noreply.github.com> Date: Fri, 26 Aug 2022 16:59:32 -0400 Subject: [PATCH 04/33] feat: add glv to arkworks --- manta-crypto/Cargo.toml | 2 + manta-crypto/src/arkworks/{ec.rs => glv.rs} | 57 +++++++++++---------- manta-crypto/src/arkworks/mod.rs | 1 + 3 files changed, 33 insertions(+), 27 deletions(-) rename manta-crypto/src/arkworks/{ec.rs => glv.rs} (82%) diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index 9d3a4c41a..cdb3cc758 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -54,10 +54,12 @@ ark-relations = { version = "0.3.0", optional = true, default-features = false } ark-serialize = { version = "0.3.0", optional = true, default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } manta-util = { path = "../manta-util", default-features = false, features = ["alloc"] } +num-bigint = {version = "0.4.3", optional = true, default-features = false} rand = { version = "0.8.4", optional = true, default-features = false, features = ["alloc"] } rand_core = { version = "0.6.3", default-features = false } workspace-hack = { version = "0.1.0", path = "../workspace-hack" } [dev-dependencies] +ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["scalar_field"] } ark-bn254 = { version = "0.3.0", default-features = false, features = ["scalar_field"] } manta-crypto = { path = ".", default-features = false, features = ["getrandom"] } diff --git a/manta-crypto/src/arkworks/ec.rs b/manta-crypto/src/arkworks/glv.rs similarity index 82% rename from manta-crypto/src/arkworks/ec.rs rename to manta-crypto/src/arkworks/glv.rs index d07efd87b..d2a511b02 100644 --- a/manta-crypto/src/arkworks/ec.rs +++ b/manta-crypto/src/arkworks/glv.rs @@ -18,15 +18,14 @@ use crate::alloc::string::ToString; use crate::arkworks::ff::PrimeField; +use ark_ff::BigInteger; use models::short_weierstrass_jacobian; use models::twisted_edwards_extended; use models::SWModelParameters; use models::TEModelParameters; -use num_bigint::BigInt; +use num_bigint::{BigInt,BigUint}; use num_bigint::Sign; - - #[doc(inline)] pub use ark_ec::*; @@ -62,25 +61,26 @@ where } } -impl

AffineCurveExt for twisted_edwards_extended::GroupAffine

-where - P: TEModelParameters, -{ - #[inline] - fn x(&self) -> &Self::BaseField { - &self.x - } +// impl

AffineCurveExt for twisted_edwards_extended::GroupAffine

+// where +// P: TEModelParameters, +// { +// #[inline] +// fn x(&self) -> &Self::BaseField { +// &self.x +// } - #[inline] - fn y(&self) -> &Self::BaseField { - &self.y - } +// #[inline] +// fn y(&self) -> &Self::BaseField { +// &self.y +// } +// } + +// #[inline] +// fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { +// Self::new(x, y) +// } - #[inline] - fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { - Self::new(x, y) - } -} /// pub struct GLVParameters @@ -147,7 +147,7 @@ where // NOTE: We first find rational solutions to `(k,0) = q1v + q2u` // We can re-write this problem as a matrix `A(q1,q2) = (k,0)` // so that `(q1,q2) = A^-1(k,0)`. - let k: BigInt = k.into_repr().to_string().parse().unwrap(); + let k: BigInt = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); let det = (v.0.clone() * u.1.clone()) - (v.1.clone() * u.0.clone()); let q1 = (u.1.clone() * k.clone()) / det.clone(); let q2 = (-v.1.clone() * k.clone()) / det; @@ -169,6 +169,9 @@ where #[cfg(test)] mod test { use core::str::FromStr; + use ark_ff::biginteger; + use rand::distributions::Standard; + use rand::prelude::Distribution; use super::*; use crate::arkworks::ff::UniformRand; use crate::arkworks::ff::{Field, PrimeField}; @@ -176,19 +179,19 @@ mod test { pub fn glv_is_correct() where - C: AffineCurveExt, + C: AffineCurveExt { let mut rng = OsRng; let scalar = C::ScalarField::rand(&mut rng); - let point = C::rand(&mut rng); + let point = C::Projective::rand(&mut rng); assert_eq!( - point.mul(&scalar.into_repr()), + point.mul(scalar.into_repr()).into_affine(), GLVParameters::{ - lambda: C::ScalarField::from_le_bytes_mod_order(&"228988810152649578064853576960394133503".parse().unwrap().to_bytes_le()), - beta: C::BaseField::from_random_bytes(&"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436".parse().unwrap().to_bytes_le()).unwrap(), + lambda: C::ScalarField::from_le_bytes_mod_order(&"228988810152649578064853576960394133503".parse::().unwrap().to_bytes_le()), + beta: C::BaseField::from_random_bytes(&"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436".parse::().unwrap().to_bytes_le()).unwrap(), base_v1: (BigInt::from_str("1").unwrap(), BigInt::from_str("228988810152649578064853576960394133504").unwrap()), base_v2: ("228988810152649578064853576960394133503".parse().unwrap(),"-1".parse().unwrap()) - }.scalar_mul(&point, &scalar), + }.scalar_mul(&point.into_affine(), &scalar), "GLV should produce the same results as Arkworks scalar multiplication." ); } diff --git a/manta-crypto/src/arkworks/mod.rs b/manta-crypto/src/arkworks/mod.rs index 454070ac3..95ec4fd69 100644 --- a/manta-crypto/src/arkworks/mod.rs +++ b/manta-crypto/src/arkworks/mod.rs @@ -26,3 +26,4 @@ pub mod constraint; pub mod ff; pub mod pairing; pub mod rand; +pub mod glv; \ No newline at end of file From c80103fc15c69213c168e47e686c9e8d7362f339 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Fri, 26 Aug 2022 18:20:30 -0400 Subject: [PATCH 05/33] chore: fix dependency --- manta-crypto/Cargo.toml | 6 +- manta-crypto/src/arkworks/glv.rs | 109 ++++++++++++------------------- 2 files changed, 45 insertions(+), 70 deletions(-) diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index cdb3cc758..f6536dc3e 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -54,12 +54,12 @@ ark-relations = { version = "0.3.0", optional = true, default-features = false } ark-serialize = { version = "0.3.0", optional = true, default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } manta-util = { path = "../manta-util", default-features = false, features = ["alloc"] } -num-bigint = {version = "0.4.3", optional = true, default-features = false} +num-bigint = { version = "0.4.3", default-features = false } rand = { version = "0.8.4", optional = true, default-features = false, features = ["alloc"] } rand_core = { version = "0.6.3", default-features = false } workspace-hack = { version = "0.1.0", path = "../workspace-hack" } [dev-dependencies] -ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["scalar_field"] } -ark-bn254 = { version = "0.3.0", default-features = false, features = ["scalar_field"] } +ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["curve"] } +ark-bn254 = { version = "0.3.0", default-features = false, features = ["curve"] } manta-crypto = { path = ".", default-features = false, features = ["getrandom"] } diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv.rs index d2a511b02..d6fe22f81 100644 --- a/manta-crypto/src/arkworks/glv.rs +++ b/manta-crypto/src/arkworks/glv.rs @@ -16,28 +16,25 @@ //! Arkwprks Elliptic Curve Implementation -use crate::alloc::string::ToString; -use crate::arkworks::ff::PrimeField; +use crate::arkworks::{ + ec::{ + models::{short_weierstrass_jacobian, SWModelParameters}, + AffineCurve, ProjectiveCurve, + }, + ff::PrimeField, +}; use ark_ff::BigInteger; -use models::short_weierstrass_jacobian; -use models::twisted_edwards_extended; -use models::SWModelParameters; -use models::TEModelParameters; -use num_bigint::{BigInt,BigUint}; -use num_bigint::Sign; +use num_bigint::{BigInt, Sign}; -#[doc(inline)] -pub use ark_ec::*; - -/// +/// Affine Curve Extension pub trait AffineCurveExt: AffineCurve { - /// + /// Gets `x` coordinate. fn x(&self) -> &Self::BaseField; - /// + /// Gets `y` coordinate. fn y(&self) -> &Self::BaseField; - /// + /// Builds [`Self`] from `x` and `y`. fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self; } @@ -61,28 +58,30 @@ where } } -// impl

AffineCurveExt for twisted_edwards_extended::GroupAffine

-// where -// P: TEModelParameters, -// { -// #[inline] -// fn x(&self) -> &Self::BaseField { -// &self.x -// } - -// #[inline] -// fn y(&self) -> &Self::BaseField { -// &self.y -// } -// } - -// #[inline] -// fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { -// Self::new(x, y) -// } +/// Basis Vectors +pub struct Basis(pub ((BigInt, BigInt), (BigInt, BigInt))); +/// Given a scalar `k` and basis vectors `v` and `u` finds integer scalars `k1` and `k2`, +/// so that `(k, 0)` is close to `k1v + k2u` +/// TODO: Check the bit length of BitInt v.s. BaseField or ScalarField. See if there is any overflow issue. +#[inline] +pub fn decompose_scalar(k: &F, v: (BigInt, BigInt), u: (BigInt, BigInt)) -> (BigInt, BigInt) +where + F: PrimeField, +{ + // NOTE: We first find rational solutions to `(k,0) = q1v + q2u` + // We can re-write this problem as a matrix `A(q1,q2) = (k,0)` + // so that `(q1,q2) = A^-1(k,0)`. + let k: BigInt = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); + let det = (v.0.clone() * u.1.clone()) - (v.1.clone() * u.0.clone()); + let q1 = (u.1.clone() * k.clone()) / det.clone(); + let q2 = (-v.1.clone() * k.clone()) / det; + let k1 = k - q1.clone() * v.0 - q2.clone() * u.0; + let k2 = 0 - q1 * v.1 - q2 * u.1; + (k1, k2) +} -/// +/// GLV Parameters pub struct GLVParameters where C: AffineCurve, @@ -116,19 +115,15 @@ where where C: AffineCurveExt, { - let (k1, k2) = glv_decompose_scalar(scalar, self.base_v1.clone(), self.base_v2.clone()); - + let (k1, k2) = decompose_scalar(scalar, self.base_v1.clone(), self.base_v2.clone()); let (k1_sign, k1) = k1.into_parts(); let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1.to_bytes_le()); - let p1 = match k1_sign { Sign::Minus => -point.mul(k1_scalar.into_repr()), _ => point.mul(k1_scalar.into_repr()), }; - let (k2_sign, k2) = k2.into_parts(); let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2.to_bytes_le()); - let p2 = match k2_sign { Sign::Minus => -glv_endomorphism(point, &self.beta).mul(k2_scalar.into_repr()), _ => glv_endomorphism(point, &self.beta).mul(k2_scalar.into_repr()), @@ -137,25 +132,6 @@ where } } -/// Given a scalar `k` and basis vectors `v` and `u` finds integer scalars `z1` and `z2`, -/// so that `(k, 0)` is close to `z1v + z2u` -#[inline] -pub fn glv_decompose_scalar(k: &F, v: (BigInt, BigInt), u: (BigInt, BigInt)) -> (BigInt, BigInt) -where - F: PrimeField, -{ - // NOTE: We first find rational solutions to `(k,0) = q1v + q2u` - // We can re-write this problem as a matrix `A(q1,q2) = (k,0)` - // so that `(q1,q2) = A^-1(k,0)`. - let k: BigInt = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); - let det = (v.0.clone() * u.1.clone()) - (v.1.clone() * u.0.clone()); - let q1 = (u.1.clone() * k.clone()) / det.clone(); - let q2 = (-v.1.clone() * k.clone()) / det; - let k1 = k - q1.clone() * v.0 - q2.clone() * u.0; - let k2 = 0 - q1 * v.1 - q2 * u.1; - (k1, k2) -} - /// #[inline] fn glv_endomorphism(point: &C, beta: &C::BaseField) -> C @@ -168,18 +144,17 @@ where /// Testing Suite #[cfg(test)] mod test { - use core::str::FromStr; - use ark_ff::biginteger; - use rand::distributions::Standard; - use rand::prelude::Distribution; use super::*; - use crate::arkworks::ff::UniformRand; - use crate::arkworks::ff::{Field, PrimeField}; - use crate::rand::OsRng; + use crate::{ + arkworks::ff::{Field, PrimeField, UniformRand}, + rand::OsRng, + }; + use core::str::FromStr; + use num_bigint::BigUint; pub fn glv_is_correct() where - C: AffineCurveExt + C: AffineCurveExt, { let mut rng = OsRng; let scalar = C::ScalarField::rand(&mut rng); From 05bab1b27662564393059c5917baa1dc49ccbc7b Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Wed, 7 Sep 2022 17:02:57 -0400 Subject: [PATCH 06/33] sage scripts precompute beta and the short basis for bls and bn Signed-off-by: Francisco Hernandez Iglesias --- .../src/arkworks/{glv.rs => glv/mod.rs} | 2 +- .../glv/precomputed_bls_values/.gitignore | 1 + .../bls_beta_basis.sage | 68 +++++++++++++++++++ .../glv/precomputed_bls_values/bls_values | 1 + .../glv/precomputed_bn_values/.gitignore | 1 + .../precomputed_bn_values/bn_beta_basis.sage | 68 +++++++++++++++++++ .../glv/precomputed_bn_values/bn_values | 1 + manta-crypto/src/arkworks/mod.rs | 2 +- 8 files changed, 142 insertions(+), 2 deletions(-) rename manta-crypto/src/arkworks/{glv.rs => glv/mod.rs} (99%) create mode 100644 manta-crypto/src/arkworks/glv/precomputed_bls_values/.gitignore create mode 100644 manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_beta_basis.sage create mode 100644 manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_values create mode 100644 manta-crypto/src/arkworks/glv/precomputed_bn_values/.gitignore create mode 100644 manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_beta_basis.sage create mode 100644 manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_values diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv/mod.rs similarity index 99% rename from manta-crypto/src/arkworks/glv.rs rename to manta-crypto/src/arkworks/glv/mod.rs index d6fe22f81..1a600d18b 100644 --- a/manta-crypto/src/arkworks/glv.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with manta-rs. If not, see . -//! Arkwprks Elliptic Curve Implementation +//! Arkworks Elliptic Curve Implementation use crate::arkworks::{ ec::{ diff --git a/manta-crypto/src/arkworks/glv/precomputed_bls_values/.gitignore b/manta-crypto/src/arkworks/glv/precomputed_bls_values/.gitignore new file mode 100644 index 000000000..e4327a684 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_bls_values/.gitignore @@ -0,0 +1 @@ +bls_beta_basis.sage.py diff --git a/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_beta_basis.sage b/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_beta_basis.sage new file mode 100644 index 000000000..749e8b2fb --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_beta_basis.sage @@ -0,0 +1,68 @@ +# BLS12-381 parameters taken from https://neuromancer.sk/std/bls/BLS12-381. + +p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab +K = GF(p) +a = K(0x00) +b = K(0x04) +E = EllipticCurve(K, (a, b)) +G = E(0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB, 0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1) +order_subgroup = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 +cofactor = 0x396C8C005555E1568C00AAAB0000AAAB +E.set_order(order_subgroup * cofactor) +EK = GF(order_subgroup) + +def generate_cubic_root(field): + # Given a finite field, its primitive cubic roots of unity. + R. = field[] + f = x^2+x+1 + return [f.roots()[0][0], f.roots()[1][0]] + +def endomorphism(E, P, factor): + # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. + return E(factor*P[0], P[1], P[2]) + +def valid_pair(beta_values, lambda_values, E, P, b=1): + # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to + # the largest `lambda`. If `b=0`, it returns the other valid pair. + if b: + lambda_value = max(lambda_values) + else: + lambda_value = min(lambda_values) + for beta_value in beta_values: + if endomorphism(E, P, beta_value) == lambda_value*P: + return [beta_value, lambda_value] + +def shorter(v, u): + # Returns the shorter of the two vectors in the L2 norm. + if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): + return v + else: + return u; + +def generate_short_basis(n, l): + # Generates a basis of short vectors in Z^2 for the kernel of the map + # (i, j) -> i+l*j (mod n) + next_r, r = l, n + next_t, t = 1, 0 + + while r >= sqrt(n): + v2 = [r, -t] + q = r // next_r + r, next_r = next_r, r - q*next_r + t, next_t = next_t, t - q*next_t + v1 = [r, -t] + v2 = shorter(v2, [next_r, -next_t]) + return (v1, v2) + +def print_for_rust(): + # Prints `beta` and `basis` as a rust array + beta_values = generate_cubic_root(K) + lambda_values = generate_cubic_root(EK) + pair = valid_pair(beta_values, lambda_values, E, G) + basis = generate_short_basis(order_subgroup, int(pair[1])) + print([str(pair[0]), str(basis[0][0]), str(basis[0][1]), str(basis[1][0]), str(basis[1][1])]) +def main(): + print_for_rust() + +if __name__ == '__main__': + main() diff --git a/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_values b/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_values new file mode 100644 index 000000000..18b912540 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_values @@ -0,0 +1 @@ +['793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350', '1', '-228988810152649578064853576960394133503', '228988810152649578064853576960394133504', '1'] \ No newline at end of file diff --git a/manta-crypto/src/arkworks/glv/precomputed_bn_values/.gitignore b/manta-crypto/src/arkworks/glv/precomputed_bn_values/.gitignore new file mode 100644 index 000000000..4824962c0 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_bn_values/.gitignore @@ -0,0 +1 @@ +bn_beta_basis.sage.py diff --git a/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_beta_basis.sage b/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_beta_basis.sage new file mode 100644 index 000000000..c0875e9f1 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_beta_basis.sage @@ -0,0 +1,68 @@ +# BN254 parameters taken from https://neuromancer.sk/std/bn/bn254. + +p = 0x2523648240000001BA344D80000000086121000000000013A700000000000013 +K = GF(p) +a = K(0x0000000000000000000000000000000000000000000000000000000000000000) +b = K(0x0000000000000000000000000000000000000000000000000000000000000002) +E = EllipticCurve(K, (a, b)) +G = E(0x2523648240000001BA344D80000000086121000000000013A700000000000012, 0x0000000000000000000000000000000000000000000000000000000000000001) +order_subgroup = 0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D +cofactor = 0x01 +E.set_order(0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D * 0x01) +EK = GF(order_subgroup) + +def generate_cubic_root(field): + # Given a finite field, its primitive cubic roots of unity. + R. = field[] + f = x^2+x+1 + return [f.roots()[0][0], f.roots()[1][0]] + +def endomorphism(E, P, factor): + # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. + return E(factor*P[0], P[1], P[2]) + +def valid_pair(beta_values, lambda_values, E, P, b=1): + # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to + # the largest `lambda`. If `b=0`, it returns the other valid pair. + if b: + lambda_value = max(lambda_values) + else: + lambda_value = min(lambda_values) + for beta_value in beta_values: + if endomorphism(E, P, beta_value) == lambda_value*P: + return [beta_value, lambda_value] + +def shorter(v, u): + # Returns the shorter of the two vectors in the L2 norm. + if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): + return v + else: + return u; + +def generate_short_basis(n, l): + # Generates a basis of short vectors in Z^2 for the kernel of the map + # (i, j) -> i+l*j (mod n) + next_r, r = l, n + next_t, t = 1, 0 + + while r >= sqrt(n): + v2 = [r, -t] + q = r // next_r + r, next_r = next_r, r - q*next_r + t, next_t = next_t, t - q*next_t + v1 = [r, -t] + v2 = shorter(v2, [next_r, -next_t]) + return (v1, v2) + +def print_for_rust(): + # Prints `beta` and `basis` as a rust array + beta_values = generate_cubic_root(K) + lambda_values = generate_cubic_root(EK) + pair = valid_pair(beta_values, lambda_values, E, G) + basis = generate_short_basis(order_subgroup, int(pair[1])) + print([str(pair[0]), str(basis[0][0]), str(basis[0][1]), str(basis[1][0]), str(basis[1][1])]) +def main(): + print_for_rust() + +if __name__ == '__main__': + main() diff --git a/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_values b/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_values new file mode 100644 index 000000000..d7bf370a2 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_values @@ -0,0 +1 @@ +['16798108731015832283133667796947756444075910019074449559301910896669540483083', '129607518034317099886745702645398241283', '-9295429630892703745', '9295429630892703745', '129607518034317099896041132276290945028'] \ No newline at end of file diff --git a/manta-crypto/src/arkworks/mod.rs b/manta-crypto/src/arkworks/mod.rs index 846b19095..a9c71c06d 100644 --- a/manta-crypto/src/arkworks/mod.rs +++ b/manta-crypto/src/arkworks/mod.rs @@ -27,4 +27,4 @@ pub mod ff; pub mod glv; pub mod pairing; pub mod rand; -pub mod ratio; \ No newline at end of file +pub mod ratio; From b69430ba94f9ae3181070f01e6a8502ced09ab57 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Wed, 7 Sep 2022 21:06:03 -0400 Subject: [PATCH 07/33] local changes before pull --- manta-crypto/src/arkworks/glv/mod.rs | 99 ++++++-------- .../glv/precomputed_bls_values/.gitignore | 1 - .../bls_beta_basis.sage | 68 ---------- .../glv/precomputed_bls_values/bls_values | 1 - .../glv/precomputed_bn_values/.gitignore | 1 - .../precomputed_bn_values/bn_beta_basis.sage | 68 ---------- .../glv/precomputed_bn_values/bn_values | 1 - manta-pay/Cargo.toml | 3 + manta-pay/src/crypto/ecc/arkworks.rs | 128 ++++++++++++++---- 9 files changed, 147 insertions(+), 223 deletions(-) delete mode 100644 manta-crypto/src/arkworks/glv/precomputed_bls_values/.gitignore delete mode 100644 manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_beta_basis.sage delete mode 100644 manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_values delete mode 100644 manta-crypto/src/arkworks/glv/precomputed_bn_values/.gitignore delete mode 100644 manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_beta_basis.sage delete mode 100644 manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_values diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index 1a600d18b..a3f9b1ba5 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -58,25 +58,21 @@ where } } -/// Basis Vectors -pub struct Basis(pub ((BigInt, BigInt), (BigInt, BigInt))); - /// Given a scalar `k` and basis vectors `v` and `u` finds integer scalars `k1` and `k2`, /// so that `(k, 0)` is close to `k1v + k2u` /// TODO: Check the bit length of BitInt v.s. BaseField or ScalarField. See if there is any overflow issue. #[inline] -pub fn decompose_scalar(k: &F, v: (BigInt, BigInt), u: (BigInt, BigInt)) -> (BigInt, BigInt) +pub fn decompose_scalar(k: &F, v: (&BigInt, &BigInt), u: (&BigInt, &BigInt)) -> (BigInt, BigInt) where F: PrimeField, { // NOTE: We first find rational solutions to `(k,0) = q1v + q2u` // We can re-write this problem as a matrix `A(q1,q2) = (k,0)` // so that `(q1,q2) = A^-1(k,0)`. - let k: BigInt = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); - let det = (v.0.clone() * u.1.clone()) - (v.1.clone() * u.0.clone()); - let q1 = (u.1.clone() * k.clone()) / det.clone(); - let q2 = (-v.1.clone() * k.clone()) / det; - let k1 = k - q1.clone() * v.0 - q2.clone() * u.0; + let k = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); + let q1 = (u.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); + let q2 = (-v.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); + let k1 = k - &q1 * v.0 - &q2 * u.0; let k2 = 0 - q1 * v.1 - q2 * u.1; (k1, k2) } @@ -86,16 +82,13 @@ pub struct GLVParameters where C: AffineCurve, { - /// - pub lambda: C::ScalarField, - - /// + /// Endomorphism-defining Element pub beta: C::BaseField, - /// + /// Basis Element pub base_v1: (BigInt, BigInt), - /// + /// Basis Element pub base_v2: (BigInt, BigInt), } @@ -103,19 +96,47 @@ impl GLVParameters where C: AffineCurve, { - /// + /// Creates a new instance of [`GLVParameters`] without checking that `base_v1` and `base_v2` form a + /// basis of the kernel of the function defined by the root of the characteristic polynomial + /// of the endomorphism associated with `beta`. #[inline] - pub fn generate() -> Self { - todo!() + pub fn new_unchecked( + beta: C::BaseField, + base_v1: (BigInt, BigInt), + base_v2: (BigInt, BigInt), + ) -> Self { + Self { + beta, + base_v1, + base_v2, + } + } + + /// Returns a reference to `beta`. + pub fn beta(&self) -> &C::BaseField { + &self.beta + } + + /// Returns `beta`, dropping `self`. + pub fn into_beta(self) -> C::BaseField { + self.beta + } + + /// Returns a reference to the basis elements. + pub fn basis(&self) -> ((&BigInt, &BigInt), (&BigInt, &BigInt)) { + ( + (&self.base_v1.0, &self.base_v1.1), + (&self.base_v2.0, &self.base_v2.1), + ) } - /// + /// Multiplies `point` by `scalar` using the GLV method. #[inline] pub fn scalar_mul(&self, point: &C, scalar: &C::ScalarField) -> C where C: AffineCurveExt, { - let (k1, k2) = decompose_scalar(scalar, self.base_v1.clone(), self.base_v2.clone()); + let (k1, k2) = decompose_scalar(scalar, self.basis().0, self.basis().1); let (k1_sign, k1) = k1.into_parts(); let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1.to_bytes_le()); let p1 = match k1_sign { @@ -132,7 +153,7 @@ where } } -/// +/// Multiplies the `x` coordinate of `point` by `beta`. #[inline] fn glv_endomorphism(point: &C, beta: &C::BaseField) -> C where @@ -140,39 +161,3 @@ where { C::from_xy_unchecked(*point.x() * beta, *point.y()) } - -/// Testing Suite -#[cfg(test)] -mod test { - use super::*; - use crate::{ - arkworks::ff::{Field, PrimeField, UniformRand}, - rand::OsRng, - }; - use core::str::FromStr; - use num_bigint::BigUint; - - pub fn glv_is_correct() - where - C: AffineCurveExt, - { - let mut rng = OsRng; - let scalar = C::ScalarField::rand(&mut rng); - let point = C::Projective::rand(&mut rng); - assert_eq!( - point.mul(scalar.into_repr()).into_affine(), - GLVParameters::{ - lambda: C::ScalarField::from_le_bytes_mod_order(&"228988810152649578064853576960394133503".parse::().unwrap().to_bytes_le()), - beta: C::BaseField::from_random_bytes(&"4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436".parse::().unwrap().to_bytes_le()).unwrap(), - base_v1: (BigInt::from_str("1").unwrap(), BigInt::from_str("228988810152649578064853576960394133504").unwrap()), - base_v2: ("228988810152649578064853576960394133503".parse().unwrap(),"-1".parse().unwrap()) - }.scalar_mul(&point.into_affine(), &scalar), - "GLV should produce the same results as Arkworks scalar multiplication." - ); - } - - #[test] - fn glv_matches_arkworks_scalar_mul() { - glv_is_correct::(); - } -} diff --git a/manta-crypto/src/arkworks/glv/precomputed_bls_values/.gitignore b/manta-crypto/src/arkworks/glv/precomputed_bls_values/.gitignore deleted file mode 100644 index e4327a684..000000000 --- a/manta-crypto/src/arkworks/glv/precomputed_bls_values/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bls_beta_basis.sage.py diff --git a/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_beta_basis.sage b/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_beta_basis.sage deleted file mode 100644 index 749e8b2fb..000000000 --- a/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_beta_basis.sage +++ /dev/null @@ -1,68 +0,0 @@ -# BLS12-381 parameters taken from https://neuromancer.sk/std/bls/BLS12-381. - -p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab -K = GF(p) -a = K(0x00) -b = K(0x04) -E = EllipticCurve(K, (a, b)) -G = E(0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB, 0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1) -order_subgroup = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 -cofactor = 0x396C8C005555E1568C00AAAB0000AAAB -E.set_order(order_subgroup * cofactor) -EK = GF(order_subgroup) - -def generate_cubic_root(field): - # Given a finite field, its primitive cubic roots of unity. - R. = field[] - f = x^2+x+1 - return [f.roots()[0][0], f.roots()[1][0]] - -def endomorphism(E, P, factor): - # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. - return E(factor*P[0], P[1], P[2]) - -def valid_pair(beta_values, lambda_values, E, P, b=1): - # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to - # the largest `lambda`. If `b=0`, it returns the other valid pair. - if b: - lambda_value = max(lambda_values) - else: - lambda_value = min(lambda_values) - for beta_value in beta_values: - if endomorphism(E, P, beta_value) == lambda_value*P: - return [beta_value, lambda_value] - -def shorter(v, u): - # Returns the shorter of the two vectors in the L2 norm. - if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): - return v - else: - return u; - -def generate_short_basis(n, l): - # Generates a basis of short vectors in Z^2 for the kernel of the map - # (i, j) -> i+l*j (mod n) - next_r, r = l, n - next_t, t = 1, 0 - - while r >= sqrt(n): - v2 = [r, -t] - q = r // next_r - r, next_r = next_r, r - q*next_r - t, next_t = next_t, t - q*next_t - v1 = [r, -t] - v2 = shorter(v2, [next_r, -next_t]) - return (v1, v2) - -def print_for_rust(): - # Prints `beta` and `basis` as a rust array - beta_values = generate_cubic_root(K) - lambda_values = generate_cubic_root(EK) - pair = valid_pair(beta_values, lambda_values, E, G) - basis = generate_short_basis(order_subgroup, int(pair[1])) - print([str(pair[0]), str(basis[0][0]), str(basis[0][1]), str(basis[1][0]), str(basis[1][1])]) -def main(): - print_for_rust() - -if __name__ == '__main__': - main() diff --git a/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_values b/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_values deleted file mode 100644 index 18b912540..000000000 --- a/manta-crypto/src/arkworks/glv/precomputed_bls_values/bls_values +++ /dev/null @@ -1 +0,0 @@ -['793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350', '1', '-228988810152649578064853576960394133503', '228988810152649578064853576960394133504', '1'] \ No newline at end of file diff --git a/manta-crypto/src/arkworks/glv/precomputed_bn_values/.gitignore b/manta-crypto/src/arkworks/glv/precomputed_bn_values/.gitignore deleted file mode 100644 index 4824962c0..000000000 --- a/manta-crypto/src/arkworks/glv/precomputed_bn_values/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bn_beta_basis.sage.py diff --git a/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_beta_basis.sage b/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_beta_basis.sage deleted file mode 100644 index c0875e9f1..000000000 --- a/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_beta_basis.sage +++ /dev/null @@ -1,68 +0,0 @@ -# BN254 parameters taken from https://neuromancer.sk/std/bn/bn254. - -p = 0x2523648240000001BA344D80000000086121000000000013A700000000000013 -K = GF(p) -a = K(0x0000000000000000000000000000000000000000000000000000000000000000) -b = K(0x0000000000000000000000000000000000000000000000000000000000000002) -E = EllipticCurve(K, (a, b)) -G = E(0x2523648240000001BA344D80000000086121000000000013A700000000000012, 0x0000000000000000000000000000000000000000000000000000000000000001) -order_subgroup = 0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D -cofactor = 0x01 -E.set_order(0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D * 0x01) -EK = GF(order_subgroup) - -def generate_cubic_root(field): - # Given a finite field, its primitive cubic roots of unity. - R. = field[] - f = x^2+x+1 - return [f.roots()[0][0], f.roots()[1][0]] - -def endomorphism(E, P, factor): - # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. - return E(factor*P[0], P[1], P[2]) - -def valid_pair(beta_values, lambda_values, E, P, b=1): - # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to - # the largest `lambda`. If `b=0`, it returns the other valid pair. - if b: - lambda_value = max(lambda_values) - else: - lambda_value = min(lambda_values) - for beta_value in beta_values: - if endomorphism(E, P, beta_value) == lambda_value*P: - return [beta_value, lambda_value] - -def shorter(v, u): - # Returns the shorter of the two vectors in the L2 norm. - if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): - return v - else: - return u; - -def generate_short_basis(n, l): - # Generates a basis of short vectors in Z^2 for the kernel of the map - # (i, j) -> i+l*j (mod n) - next_r, r = l, n - next_t, t = 1, 0 - - while r >= sqrt(n): - v2 = [r, -t] - q = r // next_r - r, next_r = next_r, r - q*next_r - t, next_t = next_t, t - q*next_t - v1 = [r, -t] - v2 = shorter(v2, [next_r, -next_t]) - return (v1, v2) - -def print_for_rust(): - # Prints `beta` and `basis` as a rust array - beta_values = generate_cubic_root(K) - lambda_values = generate_cubic_root(EK) - pair = valid_pair(beta_values, lambda_values, E, G) - basis = generate_short_basis(order_subgroup, int(pair[1])) - print([str(pair[0]), str(basis[0][0]), str(basis[0][1]), str(basis[1][0]), str(basis[1][1])]) -def main(): - print_for_rust() - -if __name__ == '__main__': - main() diff --git a/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_values b/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_values deleted file mode 100644 index d7bf370a2..000000000 --- a/manta-crypto/src/arkworks/glv/precomputed_bn_values/bn_values +++ /dev/null @@ -1 +0,0 @@ -['16798108731015832283133667796947756444075910019074449559301910896669540483083', '129607518034317099886745702645398241283', '-9295429630892703745', '9295429630892703745', '129607518034317099896041132276290945028'] \ No newline at end of file diff --git a/manta-pay/Cargo.toml b/manta-pay/Cargo.toml index 96fdcdcf4..414171212 100644 --- a/manta-pay/Cargo.toml +++ b/manta-pay/Cargo.toml @@ -101,6 +101,7 @@ websocket = [ [dependencies] aes-gcm = { version = "0.9.4", default-features = false, features = ["aes", "alloc"] } ark-bls12-381 = { version = "0.3.0", optional = true, default-features = false, features = ["curve"] } +ark-bn254 = { version = "0.3.0", optional = true, default-features = false, features = ["curve", "scalar_field"] } ark-ed-on-bls12-381 = { version = "0.3.0", optional = true, default-features = false, features = ["r1cs"] } ark-groth16 = { version = "0.3.0", optional = true, default-features = false } ark-snark = { version = "0.3.0", optional = true, default-features = false } @@ -115,6 +116,7 @@ indexmap = { version = "1.8.2", optional = true, default-features = false } manta-accounting = { path = "../manta-accounting", default-features = false } manta-crypto = { path = "../manta-crypto", default-features = false } manta-parameters = { path = "../manta-parameters", optional = true, default-features = false } +num-bigint = { version = "0.4.3", default-features = false } manta-util = { path = "../manta-util", default-features = false } parking_lot = { version = "0.12.1", optional = true, default-features = false } rand_chacha = { version = "0.3.1", default-features = false } @@ -129,5 +131,6 @@ tokio-tungstenite = { version = "0.17.2", optional = true, default-features = fa ws_stream_wasm = { version = "0.7.3", optional = true, default-features = false } [dev-dependencies] +ark-bn254 = { version = "0.3.0", default-features = false, features = ["curve", "scalar_field"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["getrandom"] } manta-pay = { path = ".", default-features = false, features = ["download", "groth16", "scale", "scale-std", "std", "test"] } diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 972e65cee..8d240a4f1 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -566,39 +566,115 @@ where } } +// /// Testing Suite +// #[cfg(test)] +// mod test { +// use super::*; +// use crate::config::Bls12_381_Edwards; +// use manta_crypto::{ +// algebra::{PrecomputedBaseTable, ScalarMul}, +// arkworks::{algebra::scalar_bits, r1cs_std::groups::curves::twisted_edwards::AffineVar}, +// constraint::measure::Measure, +// eclair::bool::AssertEq, +// rand::OsRng, +// }; + +// /// Checks if the fixed base multiplcation is correct. +// #[test] +// fn fixed_base_mul_is_correct() { +// let mut cs = Compiler::::for_proofs(); +// let scalar = Scalar::::gen(&mut OsRng); +// let base = Group::::sample((), &mut OsRng); +// const SCALAR_BITS: usize = scalar_bits::(); +// let precomputed_table = PrecomputedBaseTable::<_, SCALAR_BITS>::from_base(base, &mut ()); +// let base_var = +// base.as_known::>>(&mut cs); +// let scalar_var = +// scalar.as_known::>>(&mut cs); +// let ctr1 = cs.constraint_count(); +// let expected = base_var.scalar_mul(&scalar_var, &mut cs); +// let ctr2 = cs.constraint_count(); +// let actual = GroupVar::fixed_base_scalar_mul(precomputed_table, &scalar_var, &mut cs); +// let ctr3 = cs.constraint_count(); +// cs.assert_eq(&expected, &actual); +// assert!(cs.is_satisfied()); +// println!("variable base mul constraint: {:?}", ctr2 - ctr1); +// println!("fixed base mul constraint: {:?}", ctr3 - ctr2); +// } +// } + /// Testing Suite #[cfg(test)] mod test { - use super::*; - use crate::config::Bls12_381_Edwards; + use core::str::FromStr; use manta_crypto::{ - algebra::{PrecomputedBaseTable, ScalarMul}, - arkworks::{algebra::scalar_bits, r1cs_std::groups::curves::twisted_edwards::AffineVar}, - constraint::measure::Measure, - eclair::bool::AssertEq, + arkworks::{ + ec::{AffineCurve, ProjectiveCurve}, + ff::{Field, UniformRand}, + glv::GLVParameters, + }, rand::OsRng, }; + use num_bigint::{BigInt, BigUint}; + pub type BN = ark_bn254::G1Affine; + pub type BLS = ark_bls12_381::G1Affine; - /// Checks if the fixed base multiplcation is correct. #[test] - fn fixed_base_mul_is_correct() { - let mut cs = Compiler::::for_proofs(); - let scalar = Scalar::::gen(&mut OsRng); - let base = Group::::sample((), &mut OsRng); - const SCALAR_BITS: usize = scalar_bits::(); - let precomputed_table = PrecomputedBaseTable::<_, SCALAR_BITS>::from_base(base, &mut ()); - let base_var = - base.as_known::>>(&mut cs); - let scalar_var = - scalar.as_known::>>(&mut cs); - let ctr1 = cs.constraint_count(); - let expected = base_var.scalar_mul(&scalar_var, &mut cs); - let ctr2 = cs.constraint_count(); - let actual = GroupVar::fixed_base_scalar_mul(precomputed_table, &scalar_var, &mut cs); - let ctr3 = cs.constraint_count(); - cs.assert_eq(&expected, &actual); - assert!(cs.is_satisfied()); - println!("variable base mul constraint: {:?}", ctr2 - ctr1); - println!("fixed base mul constraint: {:?}", ctr3 - ctr2); + pub fn glv_bls_is_correct() { + let mut rng = OsRng; + let scalar = ::ScalarField::rand(&mut rng); + let point = ::Projective::rand(&mut rng).into_affine(); + let bls_values = include!("precomputed_bls_values/bls_values"); + let beta = ::BaseField::from_random_bytes( + &bls_values.0.parse::().unwrap().to_bytes_le(), + ) + .unwrap(); + let base_v1 = ( + BigInt::from_str(bls_values.1).unwrap(), + BigInt::from_str(bls_values.2).unwrap(), + ); + let base_v2 = ( + BigInt::from_str(bls_values.3).unwrap(), + BigInt::from_str(bls_values.4).unwrap(), + ); + let glv = GLVParameters::new_unchecked(beta, base_v1, base_v2); + println!( + "lhs = {}\n rhs = {}", + glv.scalar_mul(&point, &scalar), + point.mul(scalar).into_affine() + ); + assert_eq!( + glv.scalar_mul(&point, &scalar), + point.mul(scalar).into_affine() + ); + } + #[test] + pub fn glv_bn_is_correct() { + let mut rng = OsRng; + let scalar = ::ScalarField::rand(&mut rng); + let point = ::Projective::rand(&mut rng).into_affine(); + let bn_values = include!("precomputed_bn_values/bn_values"); + let beta = ::BaseField::from_random_bytes( + &bn_values.0.parse::().unwrap().to_bytes_le(), + ) + .unwrap(); + let base_v1 = ( + BigInt::from_str(bn_values.1).unwrap(), + BigInt::from_str(bn_values.2).unwrap(), + ); + let base_v2 = ( + BigInt::from_str(bn_values.3).unwrap(), + BigInt::from_str(bn_values.4).unwrap(), + ); + let glv = GLVParameters::new_unchecked(beta, base_v1, base_v2); + println!( + "lhs = {}\n rhs = {}", + glv.scalar_mul(&point, &scalar), + point.mul(scalar).into_affine() + ); + assert_eq!( + glv.scalar_mul(&point, &scalar), + point.mul(scalar).into_affine() + ); } } From 50e546293800292ae000e1a71c2f70eea2264f7d Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Wed, 7 Sep 2022 21:15:21 -0400 Subject: [PATCH 08/33] fmt Signed-off-by: Francisco Hernandez Iglesias --- manta-pay/src/crypto/ecc/arkworks.rs | 12 ++-- .../ecc/precomputed_bls_values/.gitignore | 1 + .../bls_beta_basis.sage | 68 +++++++++++++++++++ .../ecc/precomputed_bls_values/bls_values | 1 + .../ecc/precomputed_bn_values/.gitignore | 1 + .../precomputed_bn_values/bn_beta_basis.sage | 68 +++++++++++++++++++ .../ecc/precomputed_bn_values/bn_values | 1 + 7 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 manta-pay/src/crypto/ecc/precomputed_bls_values/.gitignore create mode 100644 manta-pay/src/crypto/ecc/precomputed_bls_values/bls_beta_basis.sage create mode 100644 manta-pay/src/crypto/ecc/precomputed_bls_values/bls_values create mode 100644 manta-pay/src/crypto/ecc/precomputed_bn_values/.gitignore create mode 100644 manta-pay/src/crypto/ecc/precomputed_bn_values/bn_beta_basis.sage create mode 100644 manta-pay/src/crypto/ecc/precomputed_bn_values/bn_values diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index aeafc80f3..09798ccc1 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -671,10 +671,14 @@ mod test { use crate::config::Bls12_381_Edwards; use core::str::FromStr; use manta_crypto::{ - algebra::{PrecomputedBaseTable, test::window_correctness, ScalarMul}, - arkworks::{algebra::scalar_bits,ec::{AffineCurve, ProjectiveCurve}, - ff::{Field, UniformRand}, - glv::GLVParameters, r1cs_std::groups::curves::twisted_edwards::AffineVar}, + algebra::{test::window_correctness, PrecomputedBaseTable, ScalarMul}, + arkworks::{ + algebra::scalar_bits, + ec::{AffineCurve, ProjectiveCurve}, + ff::{Field, UniformRand}, + glv::GLVParameters, + r1cs_std::groups::curves::twisted_edwards::AffineVar, + }, constraint::measure::Measure, eclair::bool::AssertEq, rand::OsRng, diff --git a/manta-pay/src/crypto/ecc/precomputed_bls_values/.gitignore b/manta-pay/src/crypto/ecc/precomputed_bls_values/.gitignore new file mode 100644 index 000000000..e4327a684 --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_bls_values/.gitignore @@ -0,0 +1 @@ +bls_beta_basis.sage.py diff --git a/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_beta_basis.sage new file mode 100644 index 000000000..749e8b2fb --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_beta_basis.sage @@ -0,0 +1,68 @@ +# BLS12-381 parameters taken from https://neuromancer.sk/std/bls/BLS12-381. + +p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab +K = GF(p) +a = K(0x00) +b = K(0x04) +E = EllipticCurve(K, (a, b)) +G = E(0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB, 0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1) +order_subgroup = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 +cofactor = 0x396C8C005555E1568C00AAAB0000AAAB +E.set_order(order_subgroup * cofactor) +EK = GF(order_subgroup) + +def generate_cubic_root(field): + # Given a finite field, its primitive cubic roots of unity. + R. = field[] + f = x^2+x+1 + return [f.roots()[0][0], f.roots()[1][0]] + +def endomorphism(E, P, factor): + # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. + return E(factor*P[0], P[1], P[2]) + +def valid_pair(beta_values, lambda_values, E, P, b=1): + # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to + # the largest `lambda`. If `b=0`, it returns the other valid pair. + if b: + lambda_value = max(lambda_values) + else: + lambda_value = min(lambda_values) + for beta_value in beta_values: + if endomorphism(E, P, beta_value) == lambda_value*P: + return [beta_value, lambda_value] + +def shorter(v, u): + # Returns the shorter of the two vectors in the L2 norm. + if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): + return v + else: + return u; + +def generate_short_basis(n, l): + # Generates a basis of short vectors in Z^2 for the kernel of the map + # (i, j) -> i+l*j (mod n) + next_r, r = l, n + next_t, t = 1, 0 + + while r >= sqrt(n): + v2 = [r, -t] + q = r // next_r + r, next_r = next_r, r - q*next_r + t, next_t = next_t, t - q*next_t + v1 = [r, -t] + v2 = shorter(v2, [next_r, -next_t]) + return (v1, v2) + +def print_for_rust(): + # Prints `beta` and `basis` as a rust array + beta_values = generate_cubic_root(K) + lambda_values = generate_cubic_root(EK) + pair = valid_pair(beta_values, lambda_values, E, G) + basis = generate_short_basis(order_subgroup, int(pair[1])) + print([str(pair[0]), str(basis[0][0]), str(basis[0][1]), str(basis[1][0]), str(basis[1][1])]) +def main(): + print_for_rust() + +if __name__ == '__main__': + main() diff --git a/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_values b/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_values new file mode 100644 index 000000000..b9eba600e --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_values @@ -0,0 +1 @@ +("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350", "1", "-228988810152649578064853576960394133503", "228988810152649578064853576960394133504", "1") \ No newline at end of file diff --git a/manta-pay/src/crypto/ecc/precomputed_bn_values/.gitignore b/manta-pay/src/crypto/ecc/precomputed_bn_values/.gitignore new file mode 100644 index 000000000..4824962c0 --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_bn_values/.gitignore @@ -0,0 +1 @@ +bn_beta_basis.sage.py diff --git a/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_beta_basis.sage new file mode 100644 index 000000000..c0875e9f1 --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_beta_basis.sage @@ -0,0 +1,68 @@ +# BN254 parameters taken from https://neuromancer.sk/std/bn/bn254. + +p = 0x2523648240000001BA344D80000000086121000000000013A700000000000013 +K = GF(p) +a = K(0x0000000000000000000000000000000000000000000000000000000000000000) +b = K(0x0000000000000000000000000000000000000000000000000000000000000002) +E = EllipticCurve(K, (a, b)) +G = E(0x2523648240000001BA344D80000000086121000000000013A700000000000012, 0x0000000000000000000000000000000000000000000000000000000000000001) +order_subgroup = 0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D +cofactor = 0x01 +E.set_order(0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D * 0x01) +EK = GF(order_subgroup) + +def generate_cubic_root(field): + # Given a finite field, its primitive cubic roots of unity. + R. = field[] + f = x^2+x+1 + return [f.roots()[0][0], f.roots()[1][0]] + +def endomorphism(E, P, factor): + # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. + return E(factor*P[0], P[1], P[2]) + +def valid_pair(beta_values, lambda_values, E, P, b=1): + # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to + # the largest `lambda`. If `b=0`, it returns the other valid pair. + if b: + lambda_value = max(lambda_values) + else: + lambda_value = min(lambda_values) + for beta_value in beta_values: + if endomorphism(E, P, beta_value) == lambda_value*P: + return [beta_value, lambda_value] + +def shorter(v, u): + # Returns the shorter of the two vectors in the L2 norm. + if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): + return v + else: + return u; + +def generate_short_basis(n, l): + # Generates a basis of short vectors in Z^2 for the kernel of the map + # (i, j) -> i+l*j (mod n) + next_r, r = l, n + next_t, t = 1, 0 + + while r >= sqrt(n): + v2 = [r, -t] + q = r // next_r + r, next_r = next_r, r - q*next_r + t, next_t = next_t, t - q*next_t + v1 = [r, -t] + v2 = shorter(v2, [next_r, -next_t]) + return (v1, v2) + +def print_for_rust(): + # Prints `beta` and `basis` as a rust array + beta_values = generate_cubic_root(K) + lambda_values = generate_cubic_root(EK) + pair = valid_pair(beta_values, lambda_values, E, G) + basis = generate_short_basis(order_subgroup, int(pair[1])) + print([str(pair[0]), str(basis[0][0]), str(basis[0][1]), str(basis[1][0]), str(basis[1][1])]) +def main(): + print_for_rust() + +if __name__ == '__main__': + main() diff --git a/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_values b/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_values new file mode 100644 index 000000000..46949aaa9 --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_values @@ -0,0 +1 @@ +("16798108731015832283133667796947756444075910019074449559301910896669540483083", "129607518034317099886745702645398241283", "-9295429630892703745", "9295429630892703745", "129607518034317099896041132276290945028") \ No newline at end of file From 9863c79098d7cb4e74deb2338545ffe780b95c11 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 8 Sep 2022 14:31:27 -0400 Subject: [PATCH 09/33] Tests for BLS and BN --- manta-pay/src/crypto/ecc/arkworks.rs | 89 ++++++++++--------- .../ecc/precomputed_bls_values/.gitignore | 1 - .../bls_beta_basis.sage | 68 -------------- .../ecc/precomputed_bls_values/bls_values | 1 - .../ecc/precomputed_bn_values/.gitignore | 1 - .../precomputed_bn_values/bn_beta_basis.sage | 68 -------------- .../ecc/precomputed_bn_values/bn_values | 1 - 7 files changed, 45 insertions(+), 184 deletions(-) delete mode 100644 manta-pay/src/crypto/ecc/precomputed_bls_values/.gitignore delete mode 100644 manta-pay/src/crypto/ecc/precomputed_bls_values/bls_beta_basis.sage delete mode 100644 manta-pay/src/crypto/ecc/precomputed_bls_values/bls_values delete mode 100644 manta-pay/src/crypto/ecc/precomputed_bn_values/.gitignore delete mode 100644 manta-pay/src/crypto/ecc/precomputed_bn_values/bn_beta_basis.sage delete mode 100644 manta-pay/src/crypto/ecc/precomputed_bn_values/bn_values diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 09798ccc1..bfcb61ff8 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -674,9 +674,9 @@ mod test { algebra::{test::window_correctness, PrecomputedBaseTable, ScalarMul}, arkworks::{ algebra::scalar_bits, - ec::{AffineCurve, ProjectiveCurve}, + ec::ProjectiveCurve, ff::{Field, UniformRand}, - glv::GLVParameters, + glv::{AffineCurveExt, GLVParameters}, r1cs_std::groups::curves::twisted_edwards::AffineVar, }, constraint::measure::Measure, @@ -684,6 +684,10 @@ mod test { rand::OsRng, }; use num_bigint::{BigInt, BigUint}; + use std::{ + fs::File, + io::{BufRead, BufReader}, + }; /// Checks if the fixed base multiplcation is correct. #[test] @@ -711,62 +715,59 @@ mod test { pub type BN = ark_bn254::G1Affine; pub type BLS = ark_bls12_381::G1Affine; - #[test] - pub fn glv_bls_is_correct() { - let mut rng = OsRng; - let scalar = ::ScalarField::rand(&mut rng); - let point = ::Projective::rand(&mut rng).into_affine(); - let bls_values = include!("precomputed_bls_values/bls_values"); - let beta = ::BaseField::from_random_bytes( - &bls_values.0.parse::().unwrap().to_bytes_le(), + /// Checks that the GLV implementation on the curve `C` with the parameters given in `file` + /// is correct. + #[inline] + fn glv_is_correct(file_path: &str, rng: &mut R) + where + C: AffineCurveExt, + R: RngCore + ?Sized, + { + let file = File::open(file_path).expect("Could not open file."); + let reader = BufReader::new(file); + let mut glv_strings: Vec = Vec::with_capacity(5); + for parameter in reader.lines() { + glv_strings.push(parameter.unwrap()); + } + let glv_parameters: Vec<&str> = glv_strings.iter().map(|s| &s[..]).collect(); + let scalar = C::ScalarField::rand(rng); + let point = C::Projective::rand(rng).into_affine(); + let beta = C::BaseField::from_random_bytes( + &glv_parameters[0].parse::().unwrap().to_bytes_le(), ) .unwrap(); let base_v1 = ( - BigInt::from_str(bls_values.1).unwrap(), - BigInt::from_str(bls_values.2).unwrap(), + BigInt::from_str(glv_parameters[1]).unwrap(), + BigInt::from_str(glv_parameters[2]).unwrap(), ); let base_v2 = ( - BigInt::from_str(bls_values.3).unwrap(), - BigInt::from_str(bls_values.4).unwrap(), - ); - let glv = GLVParameters::new_unchecked(beta, base_v1, base_v2); - println!( - "lhs = {}\n rhs = {}", - glv.scalar_mul(&point, &scalar), - point.mul(scalar).into_affine() + BigInt::from_str(glv_parameters[3]).unwrap(), + BigInt::from_str(glv_parameters[4]).unwrap(), ); + let glv = GLVParameters::::new_unchecked(beta, base_v1, base_v2); assert_eq!( glv.scalar_mul(&point, &scalar), point.mul(scalar).into_affine() ); } + + /// Checks the implementation of GLV for BLS is correct. #[test] - pub fn glv_bn_is_correct() { + pub fn glv_bls_is_correct() { let mut rng = OsRng; - let scalar = ::ScalarField::rand(&mut rng); - let point = ::Projective::rand(&mut rng).into_affine(); - let bn_values = include!("precomputed_bn_values/bn_values"); - let beta = ::BaseField::from_random_bytes( - &bn_values.0.parse::().unwrap().to_bytes_le(), + glv_is_correct::( + "../manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values", + &mut rng, ) - .unwrap(); - let base_v1 = ( - BigInt::from_str(bn_values.1).unwrap(), - BigInt::from_str(bn_values.2).unwrap(), - ); - let base_v2 = ( - BigInt::from_str(bn_values.3).unwrap(), - BigInt::from_str(bn_values.4).unwrap(), - ); - let glv = GLVParameters::new_unchecked(beta, base_v1, base_v2); - println!( - "lhs = {}\n rhs = {}", - glv.scalar_mul(&point, &scalar), - point.mul(scalar).into_affine() - ); - assert_eq!( - glv.scalar_mul(&point, &scalar), - point.mul(scalar).into_affine() + } + + /// Checks the implementation of GLV for BN is correct. + #[test] + pub fn glv_bn_is_correct() { + let mut rng = OsRng; + glv_is_correct::( + "../manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values", + &mut rng, ); } diff --git a/manta-pay/src/crypto/ecc/precomputed_bls_values/.gitignore b/manta-pay/src/crypto/ecc/precomputed_bls_values/.gitignore deleted file mode 100644 index e4327a684..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_bls_values/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bls_beta_basis.sage.py diff --git a/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_beta_basis.sage deleted file mode 100644 index 749e8b2fb..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_beta_basis.sage +++ /dev/null @@ -1,68 +0,0 @@ -# BLS12-381 parameters taken from https://neuromancer.sk/std/bls/BLS12-381. - -p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab -K = GF(p) -a = K(0x00) -b = K(0x04) -E = EllipticCurve(K, (a, b)) -G = E(0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB, 0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1) -order_subgroup = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 -cofactor = 0x396C8C005555E1568C00AAAB0000AAAB -E.set_order(order_subgroup * cofactor) -EK = GF(order_subgroup) - -def generate_cubic_root(field): - # Given a finite field, its primitive cubic roots of unity. - R. = field[] - f = x^2+x+1 - return [f.roots()[0][0], f.roots()[1][0]] - -def endomorphism(E, P, factor): - # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. - return E(factor*P[0], P[1], P[2]) - -def valid_pair(beta_values, lambda_values, E, P, b=1): - # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to - # the largest `lambda`. If `b=0`, it returns the other valid pair. - if b: - lambda_value = max(lambda_values) - else: - lambda_value = min(lambda_values) - for beta_value in beta_values: - if endomorphism(E, P, beta_value) == lambda_value*P: - return [beta_value, lambda_value] - -def shorter(v, u): - # Returns the shorter of the two vectors in the L2 norm. - if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): - return v - else: - return u; - -def generate_short_basis(n, l): - # Generates a basis of short vectors in Z^2 for the kernel of the map - # (i, j) -> i+l*j (mod n) - next_r, r = l, n - next_t, t = 1, 0 - - while r >= sqrt(n): - v2 = [r, -t] - q = r // next_r - r, next_r = next_r, r - q*next_r - t, next_t = next_t, t - q*next_t - v1 = [r, -t] - v2 = shorter(v2, [next_r, -next_t]) - return (v1, v2) - -def print_for_rust(): - # Prints `beta` and `basis` as a rust array - beta_values = generate_cubic_root(K) - lambda_values = generate_cubic_root(EK) - pair = valid_pair(beta_values, lambda_values, E, G) - basis = generate_short_basis(order_subgroup, int(pair[1])) - print([str(pair[0]), str(basis[0][0]), str(basis[0][1]), str(basis[1][0]), str(basis[1][1])]) -def main(): - print_for_rust() - -if __name__ == '__main__': - main() diff --git a/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_values b/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_values deleted file mode 100644 index b9eba600e..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_bls_values/bls_values +++ /dev/null @@ -1 +0,0 @@ -("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350", "1", "-228988810152649578064853576960394133503", "228988810152649578064853576960394133504", "1") \ No newline at end of file diff --git a/manta-pay/src/crypto/ecc/precomputed_bn_values/.gitignore b/manta-pay/src/crypto/ecc/precomputed_bn_values/.gitignore deleted file mode 100644 index 4824962c0..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_bn_values/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bn_beta_basis.sage.py diff --git a/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_beta_basis.sage deleted file mode 100644 index c0875e9f1..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_beta_basis.sage +++ /dev/null @@ -1,68 +0,0 @@ -# BN254 parameters taken from https://neuromancer.sk/std/bn/bn254. - -p = 0x2523648240000001BA344D80000000086121000000000013A700000000000013 -K = GF(p) -a = K(0x0000000000000000000000000000000000000000000000000000000000000000) -b = K(0x0000000000000000000000000000000000000000000000000000000000000002) -E = EllipticCurve(K, (a, b)) -G = E(0x2523648240000001BA344D80000000086121000000000013A700000000000012, 0x0000000000000000000000000000000000000000000000000000000000000001) -order_subgroup = 0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D -cofactor = 0x01 -E.set_order(0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D * 0x01) -EK = GF(order_subgroup) - -def generate_cubic_root(field): - # Given a finite field, its primitive cubic roots of unity. - R. = field[] - f = x^2+x+1 - return [f.roots()[0][0], f.roots()[1][0]] - -def endomorphism(E, P, factor): - # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. - return E(factor*P[0], P[1], P[2]) - -def valid_pair(beta_values, lambda_values, E, P, b=1): - # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to - # the largest `lambda`. If `b=0`, it returns the other valid pair. - if b: - lambda_value = max(lambda_values) - else: - lambda_value = min(lambda_values) - for beta_value in beta_values: - if endomorphism(E, P, beta_value) == lambda_value*P: - return [beta_value, lambda_value] - -def shorter(v, u): - # Returns the shorter of the two vectors in the L2 norm. - if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): - return v - else: - return u; - -def generate_short_basis(n, l): - # Generates a basis of short vectors in Z^2 for the kernel of the map - # (i, j) -> i+l*j (mod n) - next_r, r = l, n - next_t, t = 1, 0 - - while r >= sqrt(n): - v2 = [r, -t] - q = r // next_r - r, next_r = next_r, r - q*next_r - t, next_t = next_t, t - q*next_t - v1 = [r, -t] - v2 = shorter(v2, [next_r, -next_t]) - return (v1, v2) - -def print_for_rust(): - # Prints `beta` and `basis` as a rust array - beta_values = generate_cubic_root(K) - lambda_values = generate_cubic_root(EK) - pair = valid_pair(beta_values, lambda_values, E, G) - basis = generate_short_basis(order_subgroup, int(pair[1])) - print([str(pair[0]), str(basis[0][0]), str(basis[0][1]), str(basis[1][0]), str(basis[1][1])]) -def main(): - print_for_rust() - -if __name__ == '__main__': - main() diff --git a/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_values b/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_values deleted file mode 100644 index 46949aaa9..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_bn_values/bn_values +++ /dev/null @@ -1 +0,0 @@ -("16798108731015832283133667796947756444075910019074449559301910896669540483083", "129607518034317099886745702645398241283", "-9295429630892703745", "9295429630892703745", "129607518034317099896041132276290945028") \ No newline at end of file From 1b462a74cb4e5c59360e915e4dc5fe9308c24df5 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 8 Sep 2022 14:32:30 -0400 Subject: [PATCH 10/33] merge with latest commit Signed-off-by: Francisco Hernandez Iglesias --- .DS_Store | Bin 0 -> 8196 bytes fake_text_file.txt | 1 + manta-pay/.DS_Store | Bin 0 -> 6148 bytes manta-pay/src/.DS_Store | Bin 0 -> 6148 bytes manta-pay/src/crypto/.DS_Store | Bin 0 -> 6148 bytes manta-pay/src/crypto/ecc/.DS_Store | Bin 0 -> 6148 bytes .../ecc/precomputed_glv_values/.gitignore | 2 + .../bls_beta_basis.sage | 70 ++++++++++++++++++ .../ecc/precomputed_glv_values/bls_values | 5 ++ .../precomputed_glv_values/bn_beta_basis.sage | 70 ++++++++++++++++++ .../ecc/precomputed_glv_values/bn_values | 5 ++ 11 files changed, 153 insertions(+) create mode 100644 .DS_Store create mode 100644 fake_text_file.txt create mode 100644 manta-pay/.DS_Store create mode 100644 manta-pay/src/.DS_Store create mode 100644 manta-pay/src/crypto/.DS_Store create mode 100644 manta-pay/src/crypto/ecc/.DS_Store create mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/.gitignore create mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/bls_beta_basis.sage create mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values create mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage create mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..598f7c04b6788952ee3763588b3d1f38fd323f16 GIT binary patch literal 8196 zcmeI1-)_?|6vmIYZcX=xRT@aUL5jrf7-gVI6E|Jg0+j|s>wpVDC230+EsLurSv5_Q zdJXTuD{#w`@Ge}zXFIE6ue+PjB<#vQj&pv;&R09BQzBxuwELK7jffm%VatmsrX+D* z8Za$5*^ro>Zh-6R9J_CDE8zA)9nt|csYY*6Ysx6o z=x+wSOwZxHhaTJD8uW_Z;AltGjedU{(c(Mjl*_b)>uk0MG?K1A-|!zq<50ZN0H`sMi*jrXYsrb9=v6<4SC z&V+t>dP$=@(Bq5-7z;Nzp%oHE;Mq9365V`j>Uje;4#d?eg7S z9wlB7^@b7%x;?mjd>=$zKC1CF>c*07sS{4gDYeUM=jWT-TkG!A%I3wod%nF{LH)_r z#YM@v_u$d9gZ6QF67jFl4T)tBHd!fuSH~nx^1_79|BAn5$aME{!Q+RW|Tl)UmP}Q`a-DKqKZ6SKV(g7xWP^%p%R# zKK~~Z!B(sSH>$v_ing{0+qnMy|Bd!(gINWv0=G*6R;ah?HH_)7I r{Km>k1cls=!^-VA?Bowa)Lpm=rkdHYvS>lFF9M_twy+BPQw9D4;4MF7 literal 0 HcmV?d00001 diff --git a/fake_text_file.txt b/fake_text_file.txt new file mode 100644 index 000000000..43f93f822 --- /dev/null +++ b/fake_text_file.txt @@ -0,0 +1 @@ +UGHHHH \ No newline at end of file diff --git a/manta-pay/.DS_Store b/manta-pay/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..701869f04ee64eb04a829b5ecb6f6e8d57a03bfb GIT binary patch literal 6148 zcmeHKO>fgc5S>jzV^bmJK&4)gEOD(u2&huU#Z8k#CE!paH~gzJI5=K2LI;pr0R(V|e$sG1Q3K^pZ}I zH=@@R(P)GHV}tF}8JNd3q*uT$o{w}rLp|EaXi|w8oo}$d-^@zp<&~T3&*Uo4%Bt7< zr5erFy`8q#_IACG(Pur6s<@h!gLwL$TW_?^lT|%V-e!~exbyHt7gd}Ulc`C_(g`RZ z-epCq=L0<}($eHcw!`y1f85z$Ec!=>2f_1Re|Zorj`}^+pB*ljzPI=I$&0h`m;AEO z-!OBS!h2%ufx{K>%G{d2M$;nK#RVcO_KGDa3Wx%t!0jmDzAoPG?F=WQhytR(9a4b5 z4*{GpbXZ$7pAHn}2mov$Yz%e&UF4j=Vd${7h#r`-sX&{m+z~_Bbi@P43mw)LZ8|A; z_)zZ3%AHV@xjM!V44qVHQA$xj6j)cFX`3D1|3`m6|F0)WOB4_V?vw(mHH?M>EXnPy yTZ`kpHh_PEvoWu>c%6cZ*^0sCt#}`94Do;~z|diB5fPaD2pAcp5C#6J0)GI|LwMN$ literal 0 HcmV?d00001 diff --git a/manta-pay/src/.DS_Store b/manta-pay/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c58d1a4107d782e00ecb4443757bad9cd1780e01 GIT binary patch literal 6148 zcmeHKO>fgM7=GP`F5Q^a14z3dMdCV*QqZJ{ODN;Ol^{3(D#=<#w9KyZL4~SHIm3V8 zFL33T@LxE=^V*)&WQEHlgeJd|{rKa3UdK-yJ0>DAuBP{i21Mi|F?!p`HW>GFx?~;O zauX;xhB`?ym7vDqoH+%Y0{^=L{Oxurp_JsatnvLmM$f@7ZF&-YIw3`p-oy8l4k)Lh z#rW1@^uWmJ6V0h4)$|p2{^px3in-lMz9;i6Ez05Whv;;@8@(-m%ir7!#CCfOKvs@F>=?pG!UZrxX7GqV(X`#81>G1o0e=^ux zE=Na)`@zHEXtf_Kk48h39~`b$egF2|dyk$^&a!icHe#k2p~92J7$xPE(cwc&@yOIKS z?fN@cisHyl0jI!qRDkz~0EscQSR2$^2QqyH0D5TFhO++o2L{{#3@z3M(E<~O3N%z< zuNcDK9fYByKeYa}K|?2@M@AewvamN4VXqz{(C#EcgD!UpI0c#tbWL@@=l|0`-~XE= zS91zD1+J9>!aI(R$C#2mTQ5zH&)NX#9TFS+)dn>MnLUnmfsf)nByH#mxBv_-)&|i6 Qb3X!F2A4Sn{;2}L0VA@?tpET3 literal 0 HcmV?d00001 diff --git a/manta-pay/src/crypto/.DS_Store b/manta-pay/src/crypto/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0ec4bba4bb3520808e60ed6b8acd230518303050 GIT binary patch literal 6148 zcmeHKO>Yx15FIC>by6Ya08%eVD{-w#2&huUWeM$pD~sR&DC}leu0r1#2o}e~ z0qiG7%Vk&IfB5LxtMOTJuJl*4DiS!yjNEm21>az}HGhdpRcQ4IEgang6AE0EbU{-v zm@}8Fyod*gyUyMYogwRj4v|%@#qvn2vFGS9-5UFIEmmR%8oy(PS)`luXz`q{_l>HT zTg!m^ugkq#%Ya|FXTURX69arc1W?A%VPnx89VpBb0N6pZ5!n2>z&U}#&|zZ{9*D51 zK$|Mu6GPZ^vla)=`9%1E5}zEOD*c5KyIxiyO*;YhBSpsf=A)VAb(Pu~Q$SNIt{I zaOF$*9eA_5K{SN}LaJ0WBh9|q-I-bMTYJ|_L~1-wpAij+$b&L=dMJJ)+|PPTI<93C zs7ww`GrFRR_JAVyfdO8-KE-C;8v1qpsyBtcObVUAgI|v$=-ziDu!y#30{_&k^}6qu zHQ&cH#RwT)B4Pr2PBm&NMU+s1_a&lhJVSx@jMj3gC;yTwX{xE4!`Eb5!wA}RjukK!Gu5w!bk00W1uMYKTVN5Ie^g)nfZ4Ez8cwS`0g literal 0 HcmV?d00001 diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/.gitignore b/manta-pay/src/crypto/ecc/precomputed_glv_values/.gitignore new file mode 100644 index 000000000..c0d193c6e --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_glv_values/.gitignore @@ -0,0 +1,2 @@ +bls_beta_basis.sage.py +bn_beta_basis.sage.py diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_beta_basis.sage new file mode 100644 index 000000000..27ff70458 --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_beta_basis.sage @@ -0,0 +1,70 @@ +# BLS12-381 parameters taken from https://neuromancer.sk/std/bls/BLS12-381. + +p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab +K = GF(p) +a = K(0x00) +b = K(0x04) +E = EllipticCurve(K, (a, b)) +G = E(0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB, 0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1) +order_subgroup = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 +cofactor = 0x396C8C005555E1568C00AAAB0000AAAB +E.set_order(order_subgroup * cofactor) +EK = GF(order_subgroup) + +def generate_cubic_root(field): + # Given a finite field, its primitive cubic roots of unity. + R. = field[] + f = x^2+x+1 + return [f.roots()[0][0], f.roots()[1][0]] + +def endomorphism(E, P, factor): + # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. + return E(factor*P[0], P[1], P[2]) + +def valid_pair(beta_values, lambda_values, E, P, b=1): + # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to + # the largest `lambda`. If `b=0`, it returns the other valid pair. + if b: + lambda_value = max(lambda_values) + else: + lambda_value = min(lambda_values) + for beta_value in beta_values: + if endomorphism(E, P, beta_value) == lambda_value*P: + return [beta_value, lambda_value] + +def shorter(v, u): + # Returns the shorter of the two vectors in the L2 norm. + if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): + return v + else: + return u; + +def generate_short_basis(n, l): + # Generates a basis of short vectors in Z^2 for the kernel of the map + # (i, j) -> i+l*j (mod n) + next_r, r = l, n + next_t, t = 1, 0 + + while r >= sqrt(n): + v2 = [r, -t] + q = r // next_r + r, next_r = next_r, r - q*next_r + t, next_t = next_t, t - q*next_t + v1 = [r, -t] + v2 = shorter(v2, [next_r, -next_t]) + return (v1, v2) + +def print_for_rust(): + # Prints `beta` and `basis` in five lines + beta_values = generate_cubic_root(K) + lambda_values = generate_cubic_root(EK) + pair = valid_pair(beta_values, lambda_values, E, G) + basis = generate_short_basis(order_subgroup, int(pair[1])) + output = [pair[0], basis[0][0], basis[0][1], basis[1][0], basis[1][1]] + print('\n'.join(f'{w}' for w in output)) + +def main(): + print_for_rust() + +if __name__ == '__main__': + main() diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values b/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values new file mode 100644 index 000000000..ce1938cc7 --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values @@ -0,0 +1,5 @@ +793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350 +1 +-228988810152649578064853576960394133503 +228988810152649578064853576960394133504 +1 \ No newline at end of file diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage new file mode 100644 index 000000000..b5a2cac00 --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage @@ -0,0 +1,70 @@ +# BN254 parameters taken from https://neuromancer.sk/std/bn/bn254. + +p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 +K = GF(p) +a = K(0x0000000000000000000000000000000000000000000000000000000000000000) +b = K(0x0000000000000000000000000000000000000000000000000000000000000003) +E = EllipticCurve(K, (a, b)) +G = E(1, 2) +order_subgroup = 21888242871839275222246405745257275088548364400416034343698204186575808495617 +cofactor = 0x01 +E.set_order(order_subgroup * cofactor) +EK = GF(order_subgroup) + +def generate_cubic_root(field): + # Given a finite field, its primitive cubic roots of unity. + R. = field[] + f = x^2+x+1 + return [f.roots()[0][0], f.roots()[1][0]] + +def endomorphism(E, P, factor): + # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. + return E(factor*P[0], P[1], P[2]) + +def valid_pair(beta_values, lambda_values, E, P, b=1): + # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to + # the largest `lambda`. If `b=0`, it returns the other valid pair. + if b: + lambda_value = max(lambda_values) + else: + lambda_value = min(lambda_values) + for beta_value in beta_values: + if endomorphism(E, P, beta_value) == lambda_value*P: + return [beta_value, lambda_value] + +def shorter(v, u): + # Returns the shorter of the two vectors in the L2 norm. + if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): + return v + else: + return u; + +def generate_short_basis(n, l): + # Generates a basis of short vectors in Z^2 for the kernel of the map + # (i, j) -> i+l*j (mod n) + next_r, r = l, n + next_t, t = 1, 0 + + while r >= sqrt(n): + v2 = [r, -t] + q = r // next_r + r, next_r = next_r, r - q*next_r + t, next_t = next_t, t - q*next_t + v1 = [r, -t] + v2 = shorter(v2, [next_r, -next_t]) + return (v1, v2) + +def print_for_rust(): + # Prints `beta` and `basis` in five lines + beta_values = generate_cubic_root(K) + lambda_values = generate_cubic_root(EK) + pair = valid_pair(beta_values, lambda_values, E, G) + basis = generate_short_basis(order_subgroup, int(pair[1])) + output = [pair[0], basis[0][0], basis[0][1], basis[1][0], basis[1][1]] + print('\n'.join(f'{w}' for w in output)) + +def main(): + print_for_rust() + +if __name__ == '__main__': + main() diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values b/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values new file mode 100644 index 000000000..c58947169 --- /dev/null +++ b/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values @@ -0,0 +1,5 @@ +21888242871839275220042445260109153167277707414472061641714758635765020556616 +147946756881789319000765030803803410728 +-9931322734385697763 +9931322734385697763 +147946756881789319010696353538189108491 \ No newline at end of file From 80ff693a87b6dfc516a920a16d6ee6564791fe26 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 8 Sep 2022 14:42:28 -0400 Subject: [PATCH 11/33] sort Signed-off-by: Francisco Hernandez Iglesias --- manta-pay/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manta-pay/Cargo.toml b/manta-pay/Cargo.toml index 414171212..1503d9616 100644 --- a/manta-pay/Cargo.toml +++ b/manta-pay/Cargo.toml @@ -116,8 +116,8 @@ indexmap = { version = "1.8.2", optional = true, default-features = false } manta-accounting = { path = "../manta-accounting", default-features = false } manta-crypto = { path = "../manta-crypto", default-features = false } manta-parameters = { path = "../manta-parameters", optional = true, default-features = false } -num-bigint = { version = "0.4.3", default-features = false } manta-util = { path = "../manta-util", default-features = false } +num-bigint = { version = "0.4.3", default-features = false } parking_lot = { version = "0.12.1", optional = true, default-features = false } rand_chacha = { version = "0.3.1", default-features = false } rayon = { version = "1.5.1", optional = true, default-features = false } From e9ddac17be04e23c0d207719c10162afb6599846 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 8 Sep 2022 14:56:15 -0400 Subject: [PATCH 12/33] reorganized files Signed-off-by: Francisco Hernandez Iglesias --- fake_text_file.txt | 1 - manta-crypto/src/arkworks/{glv/mod.rs => glv.rs} | 0 .../src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage | 2 +- 3 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 fake_text_file.txt rename manta-crypto/src/arkworks/{glv/mod.rs => glv.rs} (100%) diff --git a/fake_text_file.txt b/fake_text_file.txt deleted file mode 100644 index 43f93f822..000000000 --- a/fake_text_file.txt +++ /dev/null @@ -1 +0,0 @@ -UGHHHH \ No newline at end of file diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv.rs similarity index 100% rename from manta-crypto/src/arkworks/glv/mod.rs rename to manta-crypto/src/arkworks/glv.rs diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage index b5a2cac00..a6f792e83 100644 --- a/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage +++ b/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage @@ -1,4 +1,4 @@ -# BN254 parameters taken from https://neuromancer.sk/std/bn/bn254. +# BN254 parameters taken from https://github.com/ethereum/py_pairing/blob/master/py_ecc/bn128/bn128_curve.py. p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 K = GF(p) From 749d5c730239a7e5ef5f31cc50b28beafce295a3 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 8 Sep 2022 20:48:21 -0400 Subject: [PATCH 13/33] Simultaneous multiplication algorithm Signed-off-by: Francisco Hernandez Iglesias --- manta-benchmark/Cargo.toml | 7 ++ manta-benchmark/benches/benchmark.rs | 172 +++++++++++++++++++++++++++ manta-benchmark/benches/ecc.rs | 24 ++-- manta-crypto/src/arkworks/glv.rs | 68 ++++++++--- 4 files changed, 242 insertions(+), 29 deletions(-) create mode 100644 manta-benchmark/benches/benchmark.rs diff --git a/manta-benchmark/Cargo.toml b/manta-benchmark/Cargo.toml index 0c663b6a0..e1b872c52 100644 --- a/manta-benchmark/Cargo.toml +++ b/manta-benchmark/Cargo.toml @@ -43,8 +43,13 @@ harness = false name = "reclaim" harness = false +[[bench]] +name = "benchmark" +harness = false + [dependencies] ark-bls12-381 = { version = "0.3.0", default-features = false } +ark-bn254 = { version = "0.3.0", optional = true, default-features = false, features = ["curve", "scalar_field"] } ark-ec = { version = "0.3.0", default-features = false } ark-ff = { version = "0.3.0", default-features = false } getrandom = { version = "0.2.6", default-features = false, features = ["js"] } @@ -52,9 +57,11 @@ instant = { version = "0.1.12", default-features = false, features = [ "wasm-bin manta-accounting = { path = "../manta-accounting", default-features = false, features = ["test"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["getrandom", "test"] } manta-pay = { path = "../manta-pay", default-features = false, features = ["groth16", "test"] } +num-bigint = { version = "0.4.3", default-features = false } wasm-bindgen = { version = "0.2.82", default-features = false } wasm-bindgen-test = { version = "0.3.30", default-features = false } web-sys = { version = "0.3.59", default-features = false, features = ["console"] } [dev-dependencies] +ark-bn254 = { version = "0.3.0", default-features = false, features = ["curve", "scalar_field"] } criterion = { version = "0.3.4", default-features = false } diff --git a/manta-benchmark/benches/benchmark.rs b/manta-benchmark/benches/benchmark.rs new file mode 100644 index 000000000..57cf39f1e --- /dev/null +++ b/manta-benchmark/benches/benchmark.rs @@ -0,0 +1,172 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Benchmark trait + +use ark_bls12_381::G1Affine as BLSAffine; +use ark_ec::{AffineCurve, ProjectiveCurve}; +use criterion::{ + black_box, criterion_group, criterion_main, measurement::Measurement, BenchmarkGroup, Criterion, +}; +use manta_benchmark::ecc; +use manta_crypto::{ + arkworks::{ + ff::{Field, UniformRand}, + glv::{AffineCurveExt, GLVParameters}, + }, + rand::{OsRng, RngCore}, +}; +use num_bigint::{BigInt, BigUint}; +use std::{ + fs::File, + io::{BufRead, BufReader}, + str::FromStr, +}; + +/// Benchmark trait +pub trait Benchmark { + const NAME: &'static str; + + type Output; + + type Parameters; + + fn setup(rng: &mut R, parameters: Self::Parameters) -> Self + where + R: RngCore + ?Sized; + + fn benchmark(&self) -> Self::Output; + + #[inline] + fn define_benchmark(&self, group: &mut BenchmarkGroup) + where + M: Measurement, + { + group.bench_function(Self::NAME, |b| b.iter(|| black_box(self.benchmark()))); + } +} + +pub struct GLVMutiplication +where + C: AffineCurveExt, +{ + glv: GLVParameters, + + scalar: C::ScalarField, + + point: C, +} + +impl Benchmark for GLVMutiplication +where + C: AffineCurveExt, +{ + const NAME: &'static str = "GLV Multiplication"; + + type Parameters = &'static str; + + type Output = C; + + #[inline] + fn setup(rng: &mut R, parameters: Self::Parameters) -> Self + where + R: RngCore + ?Sized, + { + let scalar = C::ScalarField::rand(rng); + let point = C::Projective::rand(rng).into_affine(); + let file = File::open(parameters).expect("Could not open file."); + let reader = BufReader::new(file); + let mut glv_strings: Vec = Vec::with_capacity(5); + for parameter in reader.lines() { + glv_strings.push(parameter.unwrap()); + } + let glv_parameters: Vec<&str> = glv_strings.iter().map(|s| &s[..]).collect(); + let beta = C::BaseField::from_random_bytes( + &glv_parameters[0].parse::().unwrap().to_bytes_le(), + ) + .unwrap(); + let base_v1 = ( + BigInt::from_str(glv_parameters[1]).unwrap(), + BigInt::from_str(glv_parameters[2]).unwrap(), + ); + let base_v2 = ( + BigInt::from_str(glv_parameters[3]).unwrap(), + BigInt::from_str(glv_parameters[4]).unwrap(), + ); + let glv = GLVParameters::::new_unchecked(beta, base_v1, base_v2); + Self { glv, scalar, point } + } + + #[inline] + fn benchmark(&self) -> Self::Output { + self.glv.scalar_mul(&self.point, &self.scalar) + } +} + +pub struct PointAndScalar +where + C: AffineCurve, +{ + scalar: C::ScalarField, + + point: C, +} + +impl Benchmark for PointAndScalar +where + C: AffineCurve, +{ + const NAME: &'static str = "Scalar multiplication"; + + type Parameters = (); + + type Output = C; + + #[inline] + fn setup(rng: &mut R, parameters: Self::Parameters) -> Self + where + R: RngCore + ?Sized, + { + let _ = parameters; + let scalar = C::ScalarField::rand(rng); + let point = C::Projective::rand(rng).into_affine(); + Self { scalar, point } + } + + #[inline] + fn benchmark(&self) -> Self::Output { + ecc::affine_scalar_mul(&self.point, self.scalar).into_affine() + } +} + +#[inline] +fn benchmark_glv(c: &mut Criterion) { + let mut group = c.benchmark_group("glv"); + let mut rng = OsRng; + let glv_setup = black_box(GLVMutiplication::::setup( + &mut rng, + "../manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values", + )); + let scalar_setup = PointAndScalar { + scalar: glv_setup.scalar, + point: glv_setup.point, + }; + glv_setup.define_benchmark(&mut group); + scalar_setup.define_benchmark(&mut group); +} + +criterion_group!(glv, benchmark_glv); +criterion_main!(glv); diff --git a/manta-benchmark/benches/ecc.rs b/manta-benchmark/benches/ecc.rs index ae309e145..8bfbe7143 100644 --- a/manta-benchmark/benches/ecc.rs +++ b/manta-benchmark/benches/ecc.rs @@ -16,7 +16,7 @@ //! Elliptic Curve Cryptography Benchmarks -use ark_bls12_381::{G1Affine, G1Projective}; +use ark_bls12_381::{G1Affine as BLSAffine, G1Projective as BLSProjective}; use core::iter::repeat_with; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use manta_benchmark::ecc; @@ -25,7 +25,7 @@ use manta_crypto::rand::OsRng; fn affine_affine_addition(c: &mut Criterion) { let mut group = c.benchmark_group("bench"); let mut rng = OsRng; - let mut lhs = black_box(ecc::sample_affine_point::(&mut rng)); + let mut lhs = black_box(ecc::sample_affine_point::(&mut rng)); let rhs = black_box(ecc::sample_affine_point(&mut rng)); group.bench_function("affine-affine addition", |b| { b.iter(|| { @@ -37,7 +37,7 @@ fn affine_affine_addition(c: &mut Criterion) { fn projective_affine_addition(c: &mut Criterion) { let mut group = c.benchmark_group("bench"); let mut rng = OsRng; - let mut lhs = black_box(ecc::sample_projective_point::(&mut rng)); + let mut lhs = black_box(ecc::sample_projective_point::(&mut rng)); let rhs = black_box(ecc::sample_affine_point(&mut rng)); group.bench_function("projective-affine addition", |b| { b.iter(|| { @@ -49,8 +49,8 @@ fn projective_affine_addition(c: &mut Criterion) { fn projective_projective_addition(c: &mut Criterion) { let mut group = c.benchmark_group("bench"); let mut rng = OsRng; - let mut lhs = black_box(ecc::sample_projective_point::(&mut rng)); - let rhs = black_box(ecc::sample_projective_point::(&mut rng)); + let mut lhs = black_box(ecc::sample_projective_point::(&mut rng)); + let rhs = black_box(ecc::sample_projective_point::(&mut rng)); group.bench_function("projective-projective addition", |b| { b.iter(|| { let _ = black_box(ecc::projective_projective_add_assign(&mut lhs, rhs)); @@ -61,8 +61,8 @@ fn projective_projective_addition(c: &mut Criterion) { fn affine_scalar_multiplication(c: &mut Criterion) { let mut group = c.benchmark_group("bench"); let mut rng = OsRng; - let point = black_box(ecc::sample_affine_point::(&mut rng)); - let scalar = black_box(ecc::sample_scalar::(&mut rng)); + let point = black_box(ecc::sample_affine_point::(&mut rng)); + let scalar = black_box(ecc::sample_scalar::(&mut rng)); group.bench_function("affine-scalar multiplication", |b| { b.iter(|| { let _ = black_box(ecc::affine_scalar_mul(&point, scalar)); @@ -73,8 +73,8 @@ fn affine_scalar_multiplication(c: &mut Criterion) { fn projective_scalar_multiplication(c: &mut Criterion) { let mut group = c.benchmark_group("bench"); let mut rng = OsRng; - let mut point = black_box(ecc::sample_projective_point::(&mut rng)); - let scalar = black_box(ecc::sample_scalar::(&mut rng)); + let mut point = black_box(ecc::sample_projective_point::(&mut rng)); + let scalar = black_box(ecc::sample_scalar::(&mut rng)); group.bench_function("projective-scalar multiplication", |b| { b.iter(|| { let _ = black_box(ecc::projective_scalar_mul_assign(&mut point, scalar)); @@ -85,7 +85,7 @@ fn projective_scalar_multiplication(c: &mut Criterion) { fn projective_to_affine_normalization(c: &mut Criterion) { let mut group = c.benchmark_group("bench"); let mut rng = OsRng; - let point = black_box(ecc::sample_projective_point::(&mut rng)); + let point = black_box(ecc::sample_projective_point::(&mut rng)); group.bench_function("projective to affine normalization", |b| { b.iter(|| { let _ = black_box(ecc::projective_to_affine_normalization(&point)); @@ -96,7 +96,7 @@ fn projective_to_affine_normalization(c: &mut Criterion) { fn batch_vector_projective_to_affine_normalization(c: &mut Criterion) { let mut group = c.benchmark_group("bench"); let mut rng = OsRng; - let points = repeat_with(|| ecc::sample_projective_point::(&mut rng)) + let points = repeat_with(|| ecc::sample_projective_point::(&mut rng)) .take(1 << 16) .collect::>(); let points_slice = black_box(points.as_slice()); @@ -112,7 +112,7 @@ fn batch_vector_projective_to_affine_normalization(c: &mut Criterion) { fn naive_vector_projective_to_affine_normalization(c: &mut Criterion) { let mut group = c.benchmark_group("bench"); let mut rng = OsRng; - let points = repeat_with(|| ecc::sample_projective_point::(&mut rng)) + let points = repeat_with(|| ecc::sample_projective_point::(&mut rng)) .take(1 << 16) .collect::>(); let points_slice = black_box(points.as_slice()); diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv.rs index a3f9b1ba5..dbc36b2d0 100644 --- a/manta-crypto/src/arkworks/glv.rs +++ b/manta-crypto/src/arkworks/glv.rs @@ -23,6 +23,7 @@ use crate::arkworks::{ }, ff::PrimeField, }; +use alloc::vec::Vec; use ark_ff::BigInteger; use num_bigint::{BigInt, Sign}; @@ -36,6 +37,11 @@ pub trait AffineCurveExt: AffineCurve { /// Builds [`Self`] from `x` and `y`. fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self; + + /// Applies the GLV endomorphism to `self` + fn glv_endomorphism(&self, beta: &Self::BaseField) -> Self { + Self::from_xy_unchecked(*self.x() * beta, *self.y()) + } } impl

AffineCurveExt for short_weierstrass_jacobian::GroupAffine

@@ -130,34 +136,62 @@ where ) } - /// Multiplies `point` by `scalar` using the GLV method. + /// Generate scalars and points for the simultaneous multiple + /// point multiplication #[inline] - pub fn scalar_mul(&self, point: &C, scalar: &C::ScalarField) -> C + fn scalars_and_points(&self, point: &C, scalar: &C::ScalarField) -> (Vec, Vec, C, C) where C: AffineCurveExt, { + // TODO: make sure both output vectors have the same length. I guess into_repr and + // to_bits_be() do that already? let (k1, k2) = decompose_scalar(scalar, self.basis().0, self.basis().1); let (k1_sign, k1) = k1.into_parts(); - let k1_scalar = C::ScalarField::from_le_bytes_mod_order(&k1.to_bytes_le()); let p1 = match k1_sign { - Sign::Minus => -point.mul(k1_scalar.into_repr()), - _ => point.mul(k1_scalar.into_repr()), + Sign::Minus => -*point, + _ => *point, }; let (k2_sign, k2) = k2.into_parts(); - let k2_scalar = C::ScalarField::from_le_bytes_mod_order(&k2.to_bytes_le()); let p2 = match k2_sign { - Sign::Minus => -glv_endomorphism(point, &self.beta).mul(k2_scalar.into_repr()), - _ => glv_endomorphism(point, &self.beta).mul(k2_scalar.into_repr()), + Sign::Minus => -point.glv_endomorphism(&self.beta), + _ => point.glv_endomorphism(&self.beta), }; - (p1 + p2).into_affine() + ( + C::ScalarField::from_le_bytes_mod_order(&k1.to_bytes_le()) + .into_repr() + .to_bits_be(), + C::ScalarField::from_le_bytes_mod_order(&k2.to_bytes_le()) + .into_repr() + .to_bits_be(), + p1, + p2, + ) } -} -/// Multiplies the `x` coordinate of `point` by `beta`. -#[inline] -fn glv_endomorphism(point: &C, beta: &C::BaseField) -> C -where - C: AffineCurveExt, -{ - C::from_xy_unchecked(*point.x() * beta, *point.y()) + /// Executes a simulatenous multiple point multiplication without windowing. + #[inline] + fn simultaneous_multiple_point_multiplication(u: Vec, v: Vec, p: C, q: C) -> C { + // TODO: implement windowing. + let mut table = Vec::with_capacity(4); + table.push(C::zero()); + table.push(p); + table.push(q); + table.push(p + q); + let mut r = C::zero(); + for i in 0..u.len() { + r = ProjectiveCurve::double(&r.into_projective()).into_affine(); + r = r + table[u[i] as usize + 2 * (v[i] as usize)] + } + r + } + + /// Multiplies `point` by `scalar` using the GLV method. + #[inline] + pub fn scalar_mul(&self, point: &C, scalar: &C::ScalarField) -> C + where + C: AffineCurveExt, + { + let (k1, k2, p1, p2) = self.scalars_and_points(point, scalar); + Self::simultaneous_multiple_point_multiplication(k1, k2, p1, p2) + } } From a13f37cc7128c6a12c9eeb347ecaf4ec2633bf79 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 8 Sep 2022 20:56:44 -0400 Subject: [PATCH 14/33] small correction Signed-off-by: Francisco Hernandez Iglesias --- manta-crypto/src/arkworks/glv.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv.rs index dbc36b2d0..872256269 100644 --- a/manta-crypto/src/arkworks/glv.rs +++ b/manta-crypto/src/arkworks/glv.rs @@ -24,6 +24,7 @@ use crate::arkworks::{ ff::PrimeField, }; use alloc::vec::Vec; +use ark_ec::group::Group; use ark_ff::BigInteger; use num_bigint::{BigInt, Sign}; @@ -139,7 +140,7 @@ where /// Generate scalars and points for the simultaneous multiple /// point multiplication #[inline] - fn scalars_and_points(&self, point: &C, scalar: &C::ScalarField) -> (Vec, Vec, C, C) + fn scalars_and_points(&self, point: &C, scalar: &C::ScalarField) -> (Vec, Vec, C::Projective, C::Projective) where C: AffineCurveExt, { @@ -163,26 +164,26 @@ where C::ScalarField::from_le_bytes_mod_order(&k2.to_bytes_le()) .into_repr() .to_bits_be(), - p1, - p2, + p1.into_projective(), + p2.into_projective(), ) } /// Executes a simulatenous multiple point multiplication without windowing. #[inline] - fn simultaneous_multiple_point_multiplication(u: Vec, v: Vec, p: C, q: C) -> C { + fn simultaneous_multiple_point_multiplication(u: Vec, v: Vec, p: C::Projective, q: C::Projective) -> C { // TODO: implement windowing. let mut table = Vec::with_capacity(4); - table.push(C::zero()); + table.push(C::zero().into_projective()); table.push(p); table.push(q); table.push(p + q); - let mut r = C::zero(); + let mut r = C::zero().into_projective(); for i in 0..u.len() { - r = ProjectiveCurve::double(&r.into_projective()).into_affine(); + ProjectiveCurve::double_in_place(& mut r); r = r + table[u[i] as usize + 2 * (v[i] as usize)] } - r + r.into_affine() } /// Multiplies `point` by `scalar` using the GLV method. From 4a8c1fac00875f038fe1688e2de014b0a4479358 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 8 Sep 2022 20:57:06 -0400 Subject: [PATCH 15/33] small correction Signed-off-by: Francisco Hernandez Iglesias --- manta-crypto/src/arkworks/glv.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv.rs index 872256269..c76e3dcce 100644 --- a/manta-crypto/src/arkworks/glv.rs +++ b/manta-crypto/src/arkworks/glv.rs @@ -24,7 +24,6 @@ use crate::arkworks::{ ff::PrimeField, }; use alloc::vec::Vec; -use ark_ec::group::Group; use ark_ff::BigInteger; use num_bigint::{BigInt, Sign}; From c7b337c80f3121ffb991c5b68fa229d5f339ea1e Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Fri, 9 Sep 2022 17:24:56 -0400 Subject: [PATCH 16/33] HasGLV Trait Signed-off-by: Francisco Hernandez Iglesias --- manta-benchmark/Cargo.toml | 5 +- manta-benchmark/benches/ecc.rs | 17 +- manta-benchmark/{benches => src}/benchmark.rs | 51 +++--- manta-benchmark/src/lib.rs | 1 + manta-crypto/src/arkworks/glv.rs | 147 +++++++++++++++++- manta-pay/src/crypto/ecc/arkworks.rs | 4 +- 6 files changed, 186 insertions(+), 39 deletions(-) rename manta-benchmark/{benches => src}/benchmark.rs (78%) diff --git a/manta-benchmark/Cargo.toml b/manta-benchmark/Cargo.toml index 411e7547c..10904f005 100644 --- a/manta-benchmark/Cargo.toml +++ b/manta-benchmark/Cargo.toml @@ -43,13 +43,10 @@ harness = false name = "reclaim" harness = false -[[bench]] -name = "benchmark" -harness = false - [dependencies] ark-ec = { version = "0.3.0", default-features = false } ark-ff = { version = "0.3.0", default-features = false } +criterion = { version = "0.3.4", default-features = false } getrandom = { version = "0.2.6", default-features = false, features = ["js"] } instant = { version = "0.1.12", default-features = false, features = [ "wasm-bindgen" ] } manta-accounting = { path = "../manta-accounting", default-features = false, features = ["test"] } diff --git a/manta-benchmark/benches/ecc.rs b/manta-benchmark/benches/ecc.rs index 6b520a569..2a86e7873 100644 --- a/manta-benchmark/benches/ecc.rs +++ b/manta-benchmark/benches/ecc.rs @@ -18,7 +18,10 @@ use core::iter::repeat_with; use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use manta_benchmark::ecc; +use manta_benchmark::{ + benchmark::{Benchmark, GLVMutiplicationSetup}, + ecc, +}; use manta_crypto::{ arkworks::bls12_381::{G1Affine as BLSAffine, G1Projective as BLSProjective}, rand::OsRng, @@ -135,8 +138,20 @@ fn naive_vector_projective_to_affine_normalization(c: &mut Criterion) { }); } +#[inline] +fn glv_scalar_multiplication(c: &mut Criterion) { + let mut group = c.benchmark_group("glv"); + let mut rng = OsRng; + let glv_setup = black_box(GLVMutiplicationSetup::::setup( + &mut rng, + "../manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values", + )); + glv_setup.define_benchmark(&mut group); +} + criterion_group!( ecc, + glv_scalar_multiplication, affine_affine_addition, projective_affine_addition, projective_projective_addition, diff --git a/manta-benchmark/benches/benchmark.rs b/manta-benchmark/src/benchmark.rs similarity index 78% rename from manta-benchmark/benches/benchmark.rs rename to manta-benchmark/src/benchmark.rs index 57cf39f1e..69556d277 100644 --- a/manta-benchmark/benches/benchmark.rs +++ b/manta-benchmark/src/benchmark.rs @@ -16,18 +16,15 @@ //! Benchmark trait -use ark_bls12_381::G1Affine as BLSAffine; +use crate::ecc; use ark_ec::{AffineCurve, ProjectiveCurve}; -use criterion::{ - black_box, criterion_group, criterion_main, measurement::Measurement, BenchmarkGroup, Criterion, -}; -use manta_benchmark::ecc; +use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; use manta_crypto::{ arkworks::{ ff::{Field, UniformRand}, glv::{AffineCurveExt, GLVParameters}, }, - rand::{OsRng, RngCore}, + rand::RngCore, }; use num_bigint::{BigInt, BigUint}; use std::{ @@ -38,18 +35,24 @@ use std::{ /// Benchmark trait pub trait Benchmark { + /// Benchmark Name const NAME: &'static str; + /// Benchmark Output Type type Output; + /// Benchmark Parameters type Parameters; + /// Setup Function fn setup(rng: &mut R, parameters: Self::Parameters) -> Self where R: RngCore + ?Sized; + /// Benchmark Function fn benchmark(&self) -> Self::Output; + /// Benchmark Definition Function #[inline] fn define_benchmark(&self, group: &mut BenchmarkGroup) where @@ -59,22 +62,26 @@ pub trait Benchmark { } } -pub struct GLVMutiplication +/// GLV Multiplication Setup +pub struct GLVMutiplicationSetup where C: AffineCurveExt, { + /// GLV Parameters glv: GLVParameters, + /// Scalar scalar: C::ScalarField, + /// Curve Point point: C, } -impl Benchmark for GLVMutiplication +impl Benchmark for GLVMutiplicationSetup where C: AffineCurveExt, { - const NAME: &'static str = "GLV Multiplication"; + const NAME: &'static str = "GLV scalar multiplication"; type Parameters = &'static str; @@ -116,16 +123,19 @@ where } } -pub struct PointAndScalar +/// Scalar Multiplication Setup +pub struct ScalarAffineSetup where C: AffineCurve, { + /// Scalar scalar: C::ScalarField, + /// Curve Point point: C, } -impl Benchmark for PointAndScalar +impl Benchmark for ScalarAffineSetup where C: AffineCurve, { @@ -151,22 +161,3 @@ where ecc::affine_scalar_mul(&self.point, self.scalar).into_affine() } } - -#[inline] -fn benchmark_glv(c: &mut Criterion) { - let mut group = c.benchmark_group("glv"); - let mut rng = OsRng; - let glv_setup = black_box(GLVMutiplication::::setup( - &mut rng, - "../manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values", - )); - let scalar_setup = PointAndScalar { - scalar: glv_setup.scalar, - point: glv_setup.point, - }; - glv_setup.define_benchmark(&mut group); - scalar_setup.define_benchmark(&mut group); -} - -criterion_group!(glv, benchmark_glv); -criterion_main!(glv); diff --git a/manta-benchmark/src/lib.rs b/manta-benchmark/src/lib.rs index d3d104599..bb4714c73 100644 --- a/manta-benchmark/src/lib.rs +++ b/manta-benchmark/src/lib.rs @@ -31,6 +31,7 @@ use manta_pay::{ }; use wasm_bindgen::prelude::wasm_bindgen; +pub mod benchmark; pub mod ecc; /// Context Type diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv.rs index bc9599daf..c1684f809 100644 --- a/manta-crypto/src/arkworks/glv.rs +++ b/manta-crypto/src/arkworks/glv.rs @@ -16,6 +16,8 @@ //! Arkworks Elliptic Curve Implementation +use core::str::FromStr; + use crate::arkworks::{ ec::{ models::{short_weierstrass_jacobian, SWModelParameters}, @@ -24,8 +26,16 @@ use crate::arkworks::{ ff::PrimeField, }; use alloc::vec::Vec; -use ark_ff::BigInteger; -use num_bigint::{BigInt, Sign}; +use ark_ff::{BigInteger, Field}; +use num_bigint::{BigInt, BigUint, Sign}; + +#[cfg(feature = "ark-bls12-381")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "ark-bls12-381")))] +use crate::arkworks::bls12_381; + +#[cfg(feature = "ark-bn254")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "ark-bn254")))] +use crate::arkworks::bn254; /// Affine Curve Extension pub trait AffineCurveExt: AffineCurve { @@ -118,6 +128,15 @@ where } } + /// Creates a new instance of [`GLVParameters`] from the curve parameters. + #[inline] + pub fn new() -> Self + where + C: HasGLV, + { + C::glv_parameters() + } + /// Returns a reference to `beta`. pub fn beta(&self) -> &C::BaseField { &self.beta @@ -204,3 +223,127 @@ where Self::simultaneous_multiple_point_multiplication(k1, k2, p1, p2) } } + +/// HasGLV Trait +pub trait HasGLV: AffineCurve { + /// Generates [`GLVParameters`]. + fn glv_parameters() -> GLVParameters; +} + +impl HasGLV for bls12_381::G1Affine { + /// Generates a [`GLVParameters`] instance from the precomputed parameters + /// for `bls12_381::G1Affine`. + #[inline] + fn glv_parameters() -> GLVParameters { + let beta = ::BaseField::from_random_bytes( + &"793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350" + .parse::() + .unwrap() + .to_bytes_le() + ) + .unwrap(); + let base_v1 = ( + BigInt::from_str("1").unwrap(), + BigInt::from_str("-228988810152649578064853576960394133503").unwrap(), + ); + let base_v2 = ( + BigInt::from_str("228988810152649578064853576960394133504").unwrap(), + BigInt::from_str("1").unwrap(), + ); + GLVParameters::::new_unchecked(beta, base_v1, base_v2) + } +} + +impl HasGLV for bn254::G1Affine { + /// Generates a [`GLVParameters`] instance from the precomputed parameters + /// for `bn254::G1Affine`. + #[inline] + fn glv_parameters() -> GLVParameters { + let beta = ::BaseField::from_random_bytes( + &"21888242871839275220042445260109153167277707414472061641714758635765020556616" + .parse::() + .unwrap() + .to_bytes_le(), + ) + .unwrap(); + let base_v1 = ( + BigInt::from_str("147946756881789319000765030803803410728").unwrap(), + BigInt::from_str("-9931322734385697763").unwrap(), + ); + let base_v2 = ( + BigInt::from_str("9931322734385697763").unwrap(), + BigInt::from_str("147946756881789319010696353538189108491").unwrap(), + ); + GLVParameters::::new_unchecked(beta, base_v1, base_v2) + } +} + +#[cfg(test)] +pub mod test { + use std::{ + fs::File, + io::{BufRead, BufReader}, + }; + + use rand::RngCore; + + use ark_ff::UniformRand; + use rand_core::OsRng; + + use super::*; + /// Checks that the GLV implementation on the curve `C` with the parameters given in `file` + /// is correct. + #[inline] + fn glv_is_correct(file_path: &str, rng: &mut R) + where + C: AffineCurveExt, + R: RngCore + ?Sized, + { + let file = File::open(file_path).expect("Could not open file."); + let reader = BufReader::new(file); + let mut glv_strings: Vec = Vec::with_capacity(5); + for parameter in reader.lines() { + glv_strings.push(parameter.unwrap()); + } + let glv_parameters: Vec<&str> = glv_strings.iter().map(|s| &s[..]).collect(); + let scalar = C::ScalarField::rand(rng); + let point = C::Projective::rand(rng).into_affine(); + let beta = C::BaseField::from_random_bytes( + &glv_parameters[0].parse::().unwrap().to_bytes_le(), + ) + .unwrap(); + let base_v1 = ( + BigInt::from_str(glv_parameters[1]).unwrap(), + BigInt::from_str(glv_parameters[2]).unwrap(), + ); + let base_v2 = ( + BigInt::from_str(glv_parameters[3]).unwrap(), + BigInt::from_str(glv_parameters[4]).unwrap(), + ); + let glv = GLVParameters::::new_unchecked(beta, base_v1, base_v2); + assert_eq!( + glv.scalar_mul(&point, &scalar), + point.mul(scalar).into_affine() + ); + } + + /// Checks the implementation of GLV for BLS is correct. + #[test] + pub fn glv_bls_is_correct() { + let mut rng = OsRng; + glv_is_correct::( + "../manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values", + &mut rng, + ) + } + + /// Checks the implementation of GLV for BN is correct. + #[test] + pub fn glv_bn_is_correct() { + let mut rng = OsRng; + glv_is_correct::( + "../manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values", + &mut rng, + ); + } +} diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index bfcb61ff8..e19720c37 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -712,8 +712,8 @@ mod test { println!("fixed base mul constraint: {:?}", ctr3 - ctr2); } - pub type BN = ark_bn254::G1Affine; - pub type BLS = ark_bls12_381::G1Affine; + pub type BN = manta_crypto::arkworks::bn254::G1Affine; + pub type BLS = manta_crypto::arkworks::bls12_381::G1Affine; /// Checks that the GLV implementation on the curve `C` with the parameters given in `file` /// is correct. From 3aad8870bc4c223ff956daf30c6d9402552dc7dd Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 12 Sep 2022 14:13:48 +0200 Subject: [PATCH 17/33] HasGLV trait generates the GLV parameters Signed-off-by: Francisco Hernandez Iglesias --- manta-benchmark/benches/ecc.rs | 5 +- manta-benchmark/src/benchmark.rs | 94 ++++--------------- manta-crypto/Cargo.toml | 2 + .../src/arkworks/{glv.rs => glv/mod.rs} | 76 ++++++++------- manta-pay/src/crypto/ecc/arkworks.rs | 73 +------------- 5 files changed, 65 insertions(+), 185 deletions(-) rename manta-crypto/src/arkworks/{glv.rs => glv/mod.rs} (85%) diff --git a/manta-benchmark/benches/ecc.rs b/manta-benchmark/benches/ecc.rs index 2a86e7873..d4a7da4bb 100644 --- a/manta-benchmark/benches/ecc.rs +++ b/manta-benchmark/benches/ecc.rs @@ -142,10 +142,7 @@ fn naive_vector_projective_to_affine_normalization(c: &mut Criterion) { fn glv_scalar_multiplication(c: &mut Criterion) { let mut group = c.benchmark_group("glv"); let mut rng = OsRng; - let glv_setup = black_box(GLVMutiplicationSetup::::setup( - &mut rng, - "../manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values", - )); + let glv_setup = black_box(GLVMutiplicationSetup::::setup(&mut rng, ())); glv_setup.define_benchmark(&mut group); } diff --git a/manta-benchmark/src/benchmark.rs b/manta-benchmark/src/benchmark.rs index 69556d277..72d83c06d 100644 --- a/manta-benchmark/src/benchmark.rs +++ b/manta-benchmark/src/benchmark.rs @@ -16,22 +16,16 @@ //! Benchmark trait -use crate::ecc; -use ark_ec::{AffineCurve, ProjectiveCurve}; +use ark_ec::ProjectiveCurve; use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; use manta_crypto::{ arkworks::{ - ff::{Field, UniformRand}, - glv::{AffineCurveExt, GLVParameters}, + ff::UniformRand, + glv::{AffineCurveExt, GLVParameters, HasGLV}, }, rand::RngCore, }; -use num_bigint::{BigInt, BigUint}; -use std::{ - fs::File, - io::{BufRead, BufReader}, - str::FromStr, -}; +use std::marker::PhantomData; /// Benchmark trait pub trait Benchmark { @@ -63,9 +57,9 @@ pub trait Benchmark { } /// GLV Multiplication Setup -pub struct GLVMutiplicationSetup +pub struct GLVMutiplicationSetup where - C: AffineCurveExt, + C: AffineCurveExt + HasGLV, { /// GLV Parameters glv: GLVParameters, @@ -75,46 +69,35 @@ where /// Curve Point point: C, + + /// Type Parameter Marker + __: PhantomData, } -impl Benchmark for GLVMutiplicationSetup +impl Benchmark for GLVMutiplicationSetup where - C: AffineCurveExt, + C: AffineCurveExt + HasGLV, { const NAME: &'static str = "GLV scalar multiplication"; - type Parameters = &'static str; + type Parameters = (); type Output = C; #[inline] - fn setup(rng: &mut R, parameters: Self::Parameters) -> Self + fn setup(rng: &mut R, (): Self::Parameters) -> Self where R: RngCore + ?Sized, { + let glv = C::glv_parameters(); let scalar = C::ScalarField::rand(rng); let point = C::Projective::rand(rng).into_affine(); - let file = File::open(parameters).expect("Could not open file."); - let reader = BufReader::new(file); - let mut glv_strings: Vec = Vec::with_capacity(5); - for parameter in reader.lines() { - glv_strings.push(parameter.unwrap()); + Self { + glv, + scalar, + point, + __: PhantomData, } - let glv_parameters: Vec<&str> = glv_strings.iter().map(|s| &s[..]).collect(); - let beta = C::BaseField::from_random_bytes( - &glv_parameters[0].parse::().unwrap().to_bytes_le(), - ) - .unwrap(); - let base_v1 = ( - BigInt::from_str(glv_parameters[1]).unwrap(), - BigInt::from_str(glv_parameters[2]).unwrap(), - ); - let base_v2 = ( - BigInt::from_str(glv_parameters[3]).unwrap(), - BigInt::from_str(glv_parameters[4]).unwrap(), - ); - let glv = GLVParameters::::new_unchecked(beta, base_v1, base_v2); - Self { glv, scalar, point } } #[inline] @@ -122,42 +105,3 @@ where self.glv.scalar_mul(&self.point, &self.scalar) } } - -/// Scalar Multiplication Setup -pub struct ScalarAffineSetup -where - C: AffineCurve, -{ - /// Scalar - scalar: C::ScalarField, - - /// Curve Point - point: C, -} - -impl Benchmark for ScalarAffineSetup -where - C: AffineCurve, -{ - const NAME: &'static str = "Scalar multiplication"; - - type Parameters = (); - - type Output = C; - - #[inline] - fn setup(rng: &mut R, parameters: Self::Parameters) -> Self - where - R: RngCore + ?Sized, - { - let _ = parameters; - let scalar = C::ScalarField::rand(rng); - let point = C::Projective::rand(rng).into_affine(); - Self { scalar, point } - } - - #[inline] - fn benchmark(&self) -> Self::Output { - ecc::affine_scalar_mul(&self.point, self.scalar).into_affine() - } -} diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index bf64fb74b..1c95439b9 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -27,6 +27,8 @@ maintenance = { status = "actively-developed" } [features] # Arkworks Backend arkworks = [ + "ark-bls12-381", + "ark-bn254", "ark-ec", "ark-ff", "ark-r1cs-std", diff --git a/manta-crypto/src/arkworks/glv.rs b/manta-crypto/src/arkworks/glv/mod.rs similarity index 85% rename from manta-crypto/src/arkworks/glv.rs rename to manta-crypto/src/arkworks/glv/mod.rs index c1684f809..df5cbe324 100644 --- a/manta-crypto/src/arkworks/glv.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -25,7 +25,7 @@ use crate::arkworks::{ }, ff::PrimeField, }; -use alloc::vec::Vec; +use alloc::{vec, vec::Vec}; use ark_ff::{BigInteger, Field}; use num_bigint::{BigInt, BigUint, Sign}; @@ -82,9 +82,6 @@ pub fn decompose_scalar(k: &F, v: (&BigInt, &BigInt), u: (&BigInt, &BigInt)) where F: PrimeField, { - // NOTE: We first find rational solutions to `(k,0) = q1v + q2u` - // We can re-write this problem as a matrix `A(q1,q2) = (k,0)` - // so that `(q1,q2) = A^-1(k,0)`. let k = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); let q1 = (u.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); let q2 = (-v.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); @@ -93,6 +90,7 @@ where (k1, k2) } +#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] /// GLV Parameters pub struct GLVParameters where @@ -155,8 +153,8 @@ where ) } - /// Generate scalars and points for the simultaneous multiple - /// point multiplication + /// Generates scalars and points for the simultaneous multiple + /// point multiplication. #[inline] fn scalars_and_points( &self, @@ -199,16 +197,11 @@ where p: C::Projective, q: C::Projective, ) -> C { - // TODO: implement windowing. - let mut table = Vec::with_capacity(4); - table.push(C::zero().into_projective()); - table.push(p); - table.push(q); - table.push(p + q); + let table = vec![C::zero().into_projective(), p, q, p + q]; let mut r = C::zero().into_projective(); for i in 0..u.len() { ProjectiveCurve::double_in_place(&mut r); - r = r + table[u[i] as usize + 2 * (v[i] as usize)] + r += table[u[i] as usize + 2 * (v[i] as usize)] } r.into_affine() } @@ -280,24 +273,20 @@ impl HasGLV for bn254::G1Affine { #[cfg(test)] pub mod test { + use super::*; + use ark_ff::UniformRand; + use rand::RngCore; + use rand_core::OsRng; use std::{ fs::File, io::{BufRead, BufReader}, }; - use rand::RngCore; - - use ark_ff::UniformRand; - use rand_core::OsRng; - - use super::*; - /// Checks that the GLV implementation on the curve `C` with the parameters given in `file` - /// is correct. + /// Extracts the GLV parameters from a file. #[inline] - fn glv_is_correct(file_path: &str, rng: &mut R) + fn extract_glv_parameters(file_path: &str) -> GLVParameters where C: AffineCurveExt, - R: RngCore + ?Sized, { let file = File::open(file_path).expect("Could not open file."); let reader = BufReader::new(file); @@ -306,8 +295,6 @@ pub mod test { glv_strings.push(parameter.unwrap()); } let glv_parameters: Vec<&str> = glv_strings.iter().map(|s| &s[..]).collect(); - let scalar = C::ScalarField::rand(rng); - let point = C::Projective::rand(rng).into_affine(); let beta = C::BaseField::from_random_bytes( &glv_parameters[0].parse::().unwrap().to_bytes_le(), ) @@ -320,7 +307,34 @@ pub mod test { BigInt::from_str(glv_parameters[3]).unwrap(), BigInt::from_str(glv_parameters[4]).unwrap(), ); - let glv = GLVParameters::::new_unchecked(beta, base_v1, base_v2); + GLVParameters::::new_unchecked(beta, base_v1, base_v2) + } + + /// Checks the GLV parameters of BLS12 and BN254 match the hardcoded sage outputs. + #[test] + fn glv_parameters_match() { + let bls_hardcoded_parameters = extract_glv_parameters::( + "../manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values", + ); + let bn_hardcoded_parameters = extract_glv_parameters::( + "../manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values", + ); + let bls_parameters = bls12_381::G1Affine::glv_parameters(); + let bn_parameters = bn254::G1Affine::glv_parameters(); + assert_eq!(bls_hardcoded_parameters, bls_parameters); + assert_eq!(bn_hardcoded_parameters, bn_parameters); + } + + /// Checks the GLV scalar multiplication gives the expected result for the curve `C`. + #[inline] + fn glv_is_correct(rng: &mut R) + where + C: AffineCurveExt + HasGLV, + R: RngCore + ?Sized, + { + let scalar = C::ScalarField::rand(rng); + let point = C::Projective::rand(rng).into_affine(); + let glv = C::glv_parameters(); assert_eq!( glv.scalar_mul(&point, &scalar), point.mul(scalar).into_affine() @@ -331,19 +345,13 @@ pub mod test { #[test] pub fn glv_bls_is_correct() { let mut rng = OsRng; - glv_is_correct::( - "../manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values", - &mut rng, - ) + glv_is_correct::(&mut rng) } /// Checks the implementation of GLV for BN is correct. #[test] pub fn glv_bn_is_correct() { let mut rng = OsRng; - glv_is_correct::( - "../manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values", - &mut rng, - ); + glv_is_correct::(&mut rng); } } diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index e19720c37..80ccfaee3 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -669,25 +669,13 @@ where mod test { use super::*; use crate::config::Bls12_381_Edwards; - use core::str::FromStr; use manta_crypto::{ algebra::{test::window_correctness, PrecomputedBaseTable, ScalarMul}, - arkworks::{ - algebra::scalar_bits, - ec::ProjectiveCurve, - ff::{Field, UniformRand}, - glv::{AffineCurveExt, GLVParameters}, - r1cs_std::groups::curves::twisted_edwards::AffineVar, - }, + arkworks::{algebra::scalar_bits, r1cs_std::groups::curves::twisted_edwards::AffineVar}, constraint::measure::Measure, eclair::bool::AssertEq, rand::OsRng, }; - use num_bigint::{BigInt, BigUint}; - use std::{ - fs::File, - io::{BufRead, BufReader}, - }; /// Checks if the fixed base multiplcation is correct. #[test] @@ -712,65 +700,6 @@ mod test { println!("fixed base mul constraint: {:?}", ctr3 - ctr2); } - pub type BN = manta_crypto::arkworks::bn254::G1Affine; - pub type BLS = manta_crypto::arkworks::bls12_381::G1Affine; - - /// Checks that the GLV implementation on the curve `C` with the parameters given in `file` - /// is correct. - #[inline] - fn glv_is_correct(file_path: &str, rng: &mut R) - where - C: AffineCurveExt, - R: RngCore + ?Sized, - { - let file = File::open(file_path).expect("Could not open file."); - let reader = BufReader::new(file); - let mut glv_strings: Vec = Vec::with_capacity(5); - for parameter in reader.lines() { - glv_strings.push(parameter.unwrap()); - } - let glv_parameters: Vec<&str> = glv_strings.iter().map(|s| &s[..]).collect(); - let scalar = C::ScalarField::rand(rng); - let point = C::Projective::rand(rng).into_affine(); - let beta = C::BaseField::from_random_bytes( - &glv_parameters[0].parse::().unwrap().to_bytes_le(), - ) - .unwrap(); - let base_v1 = ( - BigInt::from_str(glv_parameters[1]).unwrap(), - BigInt::from_str(glv_parameters[2]).unwrap(), - ); - let base_v2 = ( - BigInt::from_str(glv_parameters[3]).unwrap(), - BigInt::from_str(glv_parameters[4]).unwrap(), - ); - let glv = GLVParameters::::new_unchecked(beta, base_v1, base_v2); - assert_eq!( - glv.scalar_mul(&point, &scalar), - point.mul(scalar).into_affine() - ); - } - - /// Checks the implementation of GLV for BLS is correct. - #[test] - pub fn glv_bls_is_correct() { - let mut rng = OsRng; - glv_is_correct::( - "../manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values", - &mut rng, - ) - } - - /// Checks the implementation of GLV for BN is correct. - #[test] - pub fn glv_bn_is_correct() { - let mut rng = OsRng; - glv_is_correct::( - "../manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values", - &mut rng, - ); - } - /// Checks if the windowed multiplication is correct in the native compiler. #[test] fn windowed_mul_is_correct() { From 534120f6b39ec0449f2498daf79df83f0dcc353e Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 12 Sep 2022 14:50:20 +0200 Subject: [PATCH 18/33] Moved precomputed values folder --- .../ecc/precomputed_glv_values/.gitignore | 2 - .../bls_beta_basis.sage | 70 ------------------- .../ecc/precomputed_glv_values/bls_values | 5 -- .../precomputed_glv_values/bn_beta_basis.sage | 70 ------------------- .../ecc/precomputed_glv_values/bn_values | 5 -- 5 files changed, 152 deletions(-) delete mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/.gitignore delete mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/bls_beta_basis.sage delete mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values delete mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage delete mode 100644 manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/.gitignore b/manta-pay/src/crypto/ecc/precomputed_glv_values/.gitignore deleted file mode 100644 index c0d193c6e..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_glv_values/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bls_beta_basis.sage.py -bn_beta_basis.sage.py diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_beta_basis.sage deleted file mode 100644 index 27ff70458..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_beta_basis.sage +++ /dev/null @@ -1,70 +0,0 @@ -# BLS12-381 parameters taken from https://neuromancer.sk/std/bls/BLS12-381. - -p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab -K = GF(p) -a = K(0x00) -b = K(0x04) -E = EllipticCurve(K, (a, b)) -G = E(0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB, 0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1) -order_subgroup = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 -cofactor = 0x396C8C005555E1568C00AAAB0000AAAB -E.set_order(order_subgroup * cofactor) -EK = GF(order_subgroup) - -def generate_cubic_root(field): - # Given a finite field, its primitive cubic roots of unity. - R. = field[] - f = x^2+x+1 - return [f.roots()[0][0], f.roots()[1][0]] - -def endomorphism(E, P, factor): - # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. - return E(factor*P[0], P[1], P[2]) - -def valid_pair(beta_values, lambda_values, E, P, b=1): - # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to - # the largest `lambda`. If `b=0`, it returns the other valid pair. - if b: - lambda_value = max(lambda_values) - else: - lambda_value = min(lambda_values) - for beta_value in beta_values: - if endomorphism(E, P, beta_value) == lambda_value*P: - return [beta_value, lambda_value] - -def shorter(v, u): - # Returns the shorter of the two vectors in the L2 norm. - if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): - return v - else: - return u; - -def generate_short_basis(n, l): - # Generates a basis of short vectors in Z^2 for the kernel of the map - # (i, j) -> i+l*j (mod n) - next_r, r = l, n - next_t, t = 1, 0 - - while r >= sqrt(n): - v2 = [r, -t] - q = r // next_r - r, next_r = next_r, r - q*next_r - t, next_t = next_t, t - q*next_t - v1 = [r, -t] - v2 = shorter(v2, [next_r, -next_t]) - return (v1, v2) - -def print_for_rust(): - # Prints `beta` and `basis` in five lines - beta_values = generate_cubic_root(K) - lambda_values = generate_cubic_root(EK) - pair = valid_pair(beta_values, lambda_values, E, G) - basis = generate_short_basis(order_subgroup, int(pair[1])) - output = [pair[0], basis[0][0], basis[0][1], basis[1][0], basis[1][1]] - print('\n'.join(f'{w}' for w in output)) - -def main(): - print_for_rust() - -if __name__ == '__main__': - main() diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values b/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values deleted file mode 100644 index ce1938cc7..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_glv_values/bls_values +++ /dev/null @@ -1,5 +0,0 @@ -793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350 -1 --228988810152649578064853576960394133503 -228988810152649578064853576960394133504 -1 \ No newline at end of file diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage b/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage deleted file mode 100644 index a6f792e83..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_beta_basis.sage +++ /dev/null @@ -1,70 +0,0 @@ -# BN254 parameters taken from https://github.com/ethereum/py_pairing/blob/master/py_ecc/bn128/bn128_curve.py. - -p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 -K = GF(p) -a = K(0x0000000000000000000000000000000000000000000000000000000000000000) -b = K(0x0000000000000000000000000000000000000000000000000000000000000003) -E = EllipticCurve(K, (a, b)) -G = E(1, 2) -order_subgroup = 21888242871839275222246405745257275088548364400416034343698204186575808495617 -cofactor = 0x01 -E.set_order(order_subgroup * cofactor) -EK = GF(order_subgroup) - -def generate_cubic_root(field): - # Given a finite field, its primitive cubic roots of unity. - R. = field[] - f = x^2+x+1 - return [f.roots()[0][0], f.roots()[1][0]] - -def endomorphism(E, P, factor): - # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. - return E(factor*P[0], P[1], P[2]) - -def valid_pair(beta_values, lambda_values, E, P, b=1): - # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to - # the largest `lambda`. If `b=0`, it returns the other valid pair. - if b: - lambda_value = max(lambda_values) - else: - lambda_value = min(lambda_values) - for beta_value in beta_values: - if endomorphism(E, P, beta_value) == lambda_value*P: - return [beta_value, lambda_value] - -def shorter(v, u): - # Returns the shorter of the two vectors in the L2 norm. - if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): - return v - else: - return u; - -def generate_short_basis(n, l): - # Generates a basis of short vectors in Z^2 for the kernel of the map - # (i, j) -> i+l*j (mod n) - next_r, r = l, n - next_t, t = 1, 0 - - while r >= sqrt(n): - v2 = [r, -t] - q = r // next_r - r, next_r = next_r, r - q*next_r - t, next_t = next_t, t - q*next_t - v1 = [r, -t] - v2 = shorter(v2, [next_r, -next_t]) - return (v1, v2) - -def print_for_rust(): - # Prints `beta` and `basis` in five lines - beta_values = generate_cubic_root(K) - lambda_values = generate_cubic_root(EK) - pair = valid_pair(beta_values, lambda_values, E, G) - basis = generate_short_basis(order_subgroup, int(pair[1])) - output = [pair[0], basis[0][0], basis[0][1], basis[1][0], basis[1][1]] - print('\n'.join(f'{w}' for w in output)) - -def main(): - print_for_rust() - -if __name__ == '__main__': - main() diff --git a/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values b/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values deleted file mode 100644 index c58947169..000000000 --- a/manta-pay/src/crypto/ecc/precomputed_glv_values/bn_values +++ /dev/null @@ -1,5 +0,0 @@ -21888242871839275220042445260109153167277707414472061641714758635765020556616 -147946756881789319000765030803803410728 --9931322734385697763 -9931322734385697763 -147946756881789319010696353538189108491 \ No newline at end of file From 14b18383afa382786ed0be2301269c835a8efb2f Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 12 Sep 2022 14:53:47 +0200 Subject: [PATCH 19/33] Moved precomputed folder Signed-off-by: Francisco Hernandez Iglesias --- .../glv/precomputed_glv_values/.gitignore | 2 + .../bls_beta_basis.sage | 70 +++++++++++++++++++ .../glv/precomputed_glv_values/bls_values | 5 ++ .../precomputed_glv_values/bn_beta_basis.sage | 70 +++++++++++++++++++ .../glv/precomputed_glv_values/bn_values | 5 ++ 5 files changed, 152 insertions(+) create mode 100644 manta-crypto/src/arkworks/glv/precomputed_glv_values/.gitignore create mode 100644 manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_beta_basis.sage create mode 100644 manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values create mode 100644 manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_beta_basis.sage create mode 100644 manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/.gitignore b/manta-crypto/src/arkworks/glv/precomputed_glv_values/.gitignore new file mode 100644 index 000000000..c0d193c6e --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/.gitignore @@ -0,0 +1,2 @@ +bls_beta_basis.sage.py +bn_beta_basis.sage.py diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_beta_basis.sage b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_beta_basis.sage new file mode 100644 index 000000000..27ff70458 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_beta_basis.sage @@ -0,0 +1,70 @@ +# BLS12-381 parameters taken from https://neuromancer.sk/std/bls/BLS12-381. + +p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab +K = GF(p) +a = K(0x00) +b = K(0x04) +E = EllipticCurve(K, (a, b)) +G = E(0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB, 0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1) +order_subgroup = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 +cofactor = 0x396C8C005555E1568C00AAAB0000AAAB +E.set_order(order_subgroup * cofactor) +EK = GF(order_subgroup) + +def generate_cubic_root(field): + # Given a finite field, its primitive cubic roots of unity. + R. = field[] + f = x^2+x+1 + return [f.roots()[0][0], f.roots()[1][0]] + +def endomorphism(E, P, factor): + # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. + return E(factor*P[0], P[1], P[2]) + +def valid_pair(beta_values, lambda_values, E, P, b=1): + # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to + # the largest `lambda`. If `b=0`, it returns the other valid pair. + if b: + lambda_value = max(lambda_values) + else: + lambda_value = min(lambda_values) + for beta_value in beta_values: + if endomorphism(E, P, beta_value) == lambda_value*P: + return [beta_value, lambda_value] + +def shorter(v, u): + # Returns the shorter of the two vectors in the L2 norm. + if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): + return v + else: + return u; + +def generate_short_basis(n, l): + # Generates a basis of short vectors in Z^2 for the kernel of the map + # (i, j) -> i+l*j (mod n) + next_r, r = l, n + next_t, t = 1, 0 + + while r >= sqrt(n): + v2 = [r, -t] + q = r // next_r + r, next_r = next_r, r - q*next_r + t, next_t = next_t, t - q*next_t + v1 = [r, -t] + v2 = shorter(v2, [next_r, -next_t]) + return (v1, v2) + +def print_for_rust(): + # Prints `beta` and `basis` in five lines + beta_values = generate_cubic_root(K) + lambda_values = generate_cubic_root(EK) + pair = valid_pair(beta_values, lambda_values, E, G) + basis = generate_short_basis(order_subgroup, int(pair[1])) + output = [pair[0], basis[0][0], basis[0][1], basis[1][0], basis[1][1]] + print('\n'.join(f'{w}' for w in output)) + +def main(): + print_for_rust() + +if __name__ == '__main__': + main() diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values new file mode 100644 index 000000000..ce1938cc7 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values @@ -0,0 +1,5 @@ +793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350 +1 +-228988810152649578064853576960394133503 +228988810152649578064853576960394133504 +1 \ No newline at end of file diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_beta_basis.sage b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_beta_basis.sage new file mode 100644 index 000000000..a6f792e83 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_beta_basis.sage @@ -0,0 +1,70 @@ +# BN254 parameters taken from https://github.com/ethereum/py_pairing/blob/master/py_ecc/bn128/bn128_curve.py. + +p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 +K = GF(p) +a = K(0x0000000000000000000000000000000000000000000000000000000000000000) +b = K(0x0000000000000000000000000000000000000000000000000000000000000003) +E = EllipticCurve(K, (a, b)) +G = E(1, 2) +order_subgroup = 21888242871839275222246405745257275088548364400416034343698204186575808495617 +cofactor = 0x01 +E.set_order(order_subgroup * cofactor) +EK = GF(order_subgroup) + +def generate_cubic_root(field): + # Given a finite field, its primitive cubic roots of unity. + R. = field[] + f = x^2+x+1 + return [f.roots()[0][0], f.roots()[1][0]] + +def endomorphism(E, P, factor): + # Multiplies the x-coordinate of the point `P` on the elliptic curve `E` by `factor`. + return E(factor*P[0], P[1], P[2]) + +def valid_pair(beta_values, lambda_values, E, P, b=1): + # It returns the [`beta_value`, `lambda_value`] valid pair corresponding to + # the largest `lambda`. If `b=0`, it returns the other valid pair. + if b: + lambda_value = max(lambda_values) + else: + lambda_value = min(lambda_values) + for beta_value in beta_values: + if endomorphism(E, P, beta_value) == lambda_value*P: + return [beta_value, lambda_value] + +def shorter(v, u): + # Returns the shorter of the two vectors in the L2 norm. + if sqrt(v[0]*v[0] + v[1]*v[1]) < sqrt(u[0]*u[0] + u[1]*u[1]): + return v + else: + return u; + +def generate_short_basis(n, l): + # Generates a basis of short vectors in Z^2 for the kernel of the map + # (i, j) -> i+l*j (mod n) + next_r, r = l, n + next_t, t = 1, 0 + + while r >= sqrt(n): + v2 = [r, -t] + q = r // next_r + r, next_r = next_r, r - q*next_r + t, next_t = next_t, t - q*next_t + v1 = [r, -t] + v2 = shorter(v2, [next_r, -next_t]) + return (v1, v2) + +def print_for_rust(): + # Prints `beta` and `basis` in five lines + beta_values = generate_cubic_root(K) + lambda_values = generate_cubic_root(EK) + pair = valid_pair(beta_values, lambda_values, E, G) + basis = generate_short_basis(order_subgroup, int(pair[1])) + output = [pair[0], basis[0][0], basis[0][1], basis[1][0], basis[1][1]] + print('\n'.join(f'{w}' for w in output)) + +def main(): + print_for_rust() + +if __name__ == '__main__': + main() diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values new file mode 100644 index 000000000..c58947169 --- /dev/null +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values @@ -0,0 +1,5 @@ +21888242871839275220042445260109153167277707414472061641714758635765020556616 +147946756881789319000765030803803410728 +-9931322734385697763 +9931322734385697763 +147946756881789319010696353538189108491 \ No newline at end of file From 5bcabb1c62096236aa823178ba43194a6753f938 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 12 Sep 2022 15:15:32 +0200 Subject: [PATCH 20/33] clean-up Signed-off-by: Francisco Hernandez Iglesias --- .DS_Store | Bin 8196 -> 0 bytes manta-benchmark/Cargo.toml | 1 - manta-benchmark/src/benchmark.rs | 6 +++--- manta-crypto/src/arkworks/glv/mod.rs | 11 ++++------- manta-pay/.DS_Store | Bin 6148 -> 0 bytes manta-pay/Cargo.toml | 2 -- manta-pay/src/.DS_Store | Bin 6148 -> 0 bytes manta-pay/src/crypto/.DS_Store | Bin 6148 -> 0 bytes manta-pay/src/crypto/ecc/.DS_Store | Bin 6148 -> 0 bytes 9 files changed, 7 insertions(+), 13 deletions(-) delete mode 100644 .DS_Store delete mode 100644 manta-pay/.DS_Store delete mode 100644 manta-pay/src/.DS_Store delete mode 100644 manta-pay/src/crypto/.DS_Store delete mode 100644 manta-pay/src/crypto/ecc/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 598f7c04b6788952ee3763588b3d1f38fd323f16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeI1-)_?|6vmIYZcX=xRT@aUL5jrf7-gVI6E|Jg0+j|s>wpVDC230+EsLurSv5_Q zdJXTuD{#w`@Ge}zXFIE6ue+PjB<#vQj&pv;&R09BQzBxuwELK7jffm%VatmsrX+D* z8Za$5*^ro>Zh-6R9J_CDE8zA)9nt|csYY*6Ysx6o z=x+wSOwZxHhaTJD8uW_Z;AltGjedU{(c(Mjl*_b)>uk0MG?K1A-|!zq<50ZN0H`sMi*jrXYsrb9=v6<4SC z&V+t>dP$=@(Bq5-7z;Nzp%oHE;Mq9365V`j>Uje;4#d?eg7S z9wlB7^@b7%x;?mjd>=$zKC1CF>c*07sS{4gDYeUM=jWT-TkG!A%I3wod%nF{LH)_r z#YM@v_u$d9gZ6QF67jFl4T)tBHd!fuSH~nx^1_79|BAn5$aME{!Q+RW|Tl)UmP}Q`a-DKqKZ6SKV(g7xWP^%p%R# zKK~~Z!B(sSH>$v_ing{0+qnMy|Bd!(gINWv0=G*6R;ah?HH_)7I r{Km>k1cls=!^-VA?Bowa)Lpm=rkdHYvS>lFF9M_twy+BPQw9D4;4MF7 diff --git a/manta-benchmark/Cargo.toml b/manta-benchmark/Cargo.toml index 10904f005..dda6e7f5c 100644 --- a/manta-benchmark/Cargo.toml +++ b/manta-benchmark/Cargo.toml @@ -58,5 +58,4 @@ wasm-bindgen-test = { version = "0.3.30", default-features = false } web-sys = { version = "0.3.59", default-features = false, features = ["console"] } [dev-dependencies] -ark-bn254 = { version = "0.3.0", default-features = false, features = ["curve", "scalar_field"] } criterion = { version = "0.3.4", default-features = false } diff --git a/manta-benchmark/src/benchmark.rs b/manta-benchmark/src/benchmark.rs index 72d83c06d..3bb9d349f 100644 --- a/manta-benchmark/src/benchmark.rs +++ b/manta-benchmark/src/benchmark.rs @@ -38,15 +38,15 @@ pub trait Benchmark { /// Benchmark Parameters type Parameters; - /// Setup Function + /// Generates a randomized instance of `Self` from `parameters`. fn setup(rng: &mut R, parameters: Self::Parameters) -> Self where R: RngCore + ?Sized; - /// Benchmark Function + /// A function of `self` which will be benchmarked. fn benchmark(&self) -> Self::Output; - /// Benchmark Definition Function + /// Defines a benchmark from `benchmark`. #[inline] fn define_benchmark(&self, group: &mut BenchmarkGroup) where diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index df5cbe324..b6626897b 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -75,13 +75,13 @@ where } /// Given a scalar `k` and basis vectors `v` and `u` finds integer scalars `k1` and `k2`, -/// so that `(k, 0)` is close to `k1v + k2u` -/// TODO: Check the bit length of BitInt v.s. BaseField or ScalarField. See if there is any overflow issue. +/// so that `(k, 0)` is close to `k1v + k2u`. #[inline] pub fn decompose_scalar(k: &F, v: (&BigInt, &BigInt), u: (&BigInt, &BigInt)) -> (BigInt, BigInt) where F: PrimeField, { + // TODO: Check the bit length of BitInt v.s. BaseField or ScalarField. See if there is any overflow issue. let k = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); let q1 = (u.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); let q2 = (-v.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); @@ -219,13 +219,12 @@ where /// HasGLV Trait pub trait HasGLV: AffineCurve { - /// Generates [`GLVParameters`]. + /// Generates [`GLVParameters`] from some precomputed parameters encoded + /// in the marker type `M`. fn glv_parameters() -> GLVParameters; } impl HasGLV for bls12_381::G1Affine { - /// Generates a [`GLVParameters`] instance from the precomputed parameters - /// for `bls12_381::G1Affine`. #[inline] fn glv_parameters() -> GLVParameters { let beta = ::BaseField::from_random_bytes( @@ -248,8 +247,6 @@ impl HasGLV for bls12_381::G1Affine { } impl HasGLV for bn254::G1Affine { - /// Generates a [`GLVParameters`] instance from the precomputed parameters - /// for `bn254::G1Affine`. #[inline] fn glv_parameters() -> GLVParameters { let beta = ::BaseField::from_random_bytes( diff --git a/manta-pay/.DS_Store b/manta-pay/.DS_Store deleted file mode 100644 index 701869f04ee64eb04a829b5ecb6f6e8d57a03bfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO>fgc5S>jzV^bmJK&4)gEOD(u2&huU#Z8k#CE!paH~gzJI5=K2LI;pr0R(V|e$sG1Q3K^pZ}I zH=@@R(P)GHV}tF}8JNd3q*uT$o{w}rLp|EaXi|w8oo}$d-^@zp<&~T3&*Uo4%Bt7< zr5erFy`8q#_IACG(Pur6s<@h!gLwL$TW_?^lT|%V-e!~exbyHt7gd}Ulc`C_(g`RZ z-epCq=L0<}($eHcw!`y1f85z$Ec!=>2f_1Re|Zorj`}^+pB*ljzPI=I$&0h`m;AEO z-!OBS!h2%ufx{K>%G{d2M$;nK#RVcO_KGDa3Wx%t!0jmDzAoPG?F=WQhytR(9a4b5 z4*{GpbXZ$7pAHn}2mov$Yz%e&UF4j=Vd${7h#r`-sX&{m+z~_Bbi@P43mw)LZ8|A; z_)zZ3%AHV@xjM!V44qVHQA$xj6j)cFX`3D1|3`m6|F0)WOB4_V?vw(mHH?M>EXnPy yTZ`kpHh_PEvoWu>c%6cZ*^0sCt#}`94Do;~z|diB5fPaD2pAcp5C#6J0)GI|LwMN$ diff --git a/manta-pay/Cargo.toml b/manta-pay/Cargo.toml index 52ead82eb..612a7d7b9 100644 --- a/manta-pay/Cargo.toml +++ b/manta-pay/Cargo.toml @@ -114,7 +114,6 @@ manta-accounting = { path = "../manta-accounting", default-features = false } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["rand_chacha"] } manta-parameters = { path = "../manta-parameters", optional = true, default-features = false } manta-util = { path = "../manta-util", default-features = false } -num-bigint = { version = "0.4.3", default-features = false } parking_lot = { version = "0.12.1", optional = true, default-features = false } scale-codec = { package = "parity-scale-codec", version = "3.1.2", optional = true, default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.1.2", optional = true, default-features = false, features = ["derive"] } @@ -125,6 +124,5 @@ tokio-tungstenite = { version = "0.17.2", optional = true, default-features = fa ws_stream_wasm = { version = "0.7.3", optional = true, default-features = false } [dev-dependencies] -ark-bn254 = { version = "0.3.0", default-features = false, features = ["curve", "scalar_field"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["getrandom"] } manta-pay = { path = ".", default-features = false, features = ["download", "groth16", "scale", "scale-std", "std", "test"] } diff --git a/manta-pay/src/.DS_Store b/manta-pay/src/.DS_Store deleted file mode 100644 index c58d1a4107d782e00ecb4443757bad9cd1780e01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO>fgM7=GP`F5Q^a14z3dMdCV*QqZJ{ODN;Ol^{3(D#=<#w9KyZL4~SHIm3V8 zFL33T@LxE=^V*)&WQEHlgeJd|{rKa3UdK-yJ0>DAuBP{i21Mi|F?!p`HW>GFx?~;O zauX;xhB`?ym7vDqoH+%Y0{^=L{Oxurp_JsatnvLmM$f@7ZF&-YIw3`p-oy8l4k)Lh z#rW1@^uWmJ6V0h4)$|p2{^px3in-lMz9;i6Ez05Whv;;@8@(-m%ir7!#CCfOKvs@F>=?pG!UZrxX7GqV(X`#81>G1o0e=^ux zE=Na)`@zHEXtf_Kk48h39~`b$egF2|dyk$^&a!icHe#k2p~92J7$xPE(cwc&@yOIKS z?fN@cisHyl0jI!qRDkz~0EscQSR2$^2QqyH0D5TFhO++o2L{{#3@z3M(E<~O3N%z< zuNcDK9fYByKeYa}K|?2@M@AewvamN4VXqz{(C#EcgD!UpI0c#tbWL@@=l|0`-~XE= zS91zD1+J9>!aI(R$C#2mTQ5zH&)NX#9TFS+)dn>MnLUnmfsf)nByH#mxBv_-)&|i6 Qb3X!F2A4Sn{;2}L0VA@?tpET3 diff --git a/manta-pay/src/crypto/.DS_Store b/manta-pay/src/crypto/.DS_Store deleted file mode 100644 index 0ec4bba4bb3520808e60ed6b8acd230518303050..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO>Yx15FIC>by6Ya08%eVD{-w#2&huUWeM$pD~sR&DC}leu0r1#2o}e~ z0qiG7%Vk&IfB5LxtMOTJuJl*4DiS!yjNEm21>az}HGhdpRcQ4IEgang6AE0EbU{-v zm@}8Fyod*gyUyMYogwRj4v|%@#qvn2vFGS9-5UFIEmmR%8oy(PS)`luXz`q{_l>HT zTg!m^ugkq#%Ya|FXTURX69arc1W?A%VPnx89VpBb0N6pZ5!n2>z&U}#&|zZ{9*D51 zK$|Mu6GPZ^vla)=`9%1E5}zEOD*c5KyIxiyO*;YhBSpsf=A)VAb(Pu~Q$SNIt{I zaOF$*9eA_5K{SN}LaJ0WBh9|q-I-bMTYJ|_L~1-wpAij+$b&L=dMJJ)+|PPTI<93C zs7ww`GrFRR_JAVyfdO8-KE-C;8v1qpsyBtcObVUAgI|v$=-ziDu!y#30{_&k^}6qu zHQ&cH#RwT)B4Pr2PBm&NMU+s1_a&lhJVSx@jMj3gC;yTwX{xE4!`Eb5!wA}RjukK!Gu5w!bk00W1uMYKTVN5Ie^g)nfZ4Ez8cwS`0g From 02a0083f85997d1f3d92e3e7785ee8af9e817da4 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 12 Sep 2022 15:18:03 +0200 Subject: [PATCH 21/33] changelog Signed-off-by: Francisco Hernandez Iglesias --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85039811c..05d276a20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] ### Added +- [\#211](https://github.com/Manta-Network/manta-rs/pull/211) GLV scalar multiplication implementation - [\#237](https://github.com/Manta-Network/manta-rs/pull/237) Public input fuzzing tests for transfer protocol - [\#215](https://github.com/Manta-Network/manta-rs/pull/215) Add windowed multiplication algorithm for groups - [\#213](https://github.com/Manta-Network/manta-rs/pull/197) Add Ceremony Utilities From 5d4a1fe403eaa215403c5b7255fbf6fa20e88dd2 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 12 Sep 2022 16:45:14 +0200 Subject: [PATCH 22/33] switched from Fileread to include Signed-off-by: Francisco Hernandez Iglesias --- manta-crypto/src/arkworks/glv/mod.rs | 26 +++++-------------- .../bls_beta_basis.sage | 2 +- .../glv/precomputed_glv_values/bls_values | 6 +---- .../precomputed_glv_values/bn_beta_basis.sage | 2 +- .../glv/precomputed_glv_values/bn_values | 6 +---- 5 files changed, 11 insertions(+), 31 deletions(-) diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index b6626897b..f7592b997 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -271,27 +271,16 @@ impl HasGLV for bn254::G1Affine { #[cfg(test)] pub mod test { use super::*; + use crate::rand::RngCore; use ark_ff::UniformRand; - use rand::RngCore; use rand_core::OsRng; - use std::{ - fs::File, - io::{BufRead, BufReader}, - }; /// Extracts the GLV parameters from a file. #[inline] - fn extract_glv_parameters(file_path: &str) -> GLVParameters + fn extract_glv_parameters(glv_parameters: [&str; 5]) -> GLVParameters where C: AffineCurveExt, { - let file = File::open(file_path).expect("Could not open file."); - let reader = BufReader::new(file); - let mut glv_strings: Vec = Vec::with_capacity(5); - for parameter in reader.lines() { - glv_strings.push(parameter.unwrap()); - } - let glv_parameters: Vec<&str> = glv_strings.iter().map(|s| &s[..]).collect(); let beta = C::BaseField::from_random_bytes( &glv_parameters[0].parse::().unwrap().to_bytes_le(), ) @@ -310,12 +299,11 @@ pub mod test { /// Checks the GLV parameters of BLS12 and BN254 match the hardcoded sage outputs. #[test] fn glv_parameters_match() { - let bls_hardcoded_parameters = extract_glv_parameters::( - "../manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values", - ); - let bn_hardcoded_parameters = extract_glv_parameters::( - "../manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values", - ); + let bls_hardcoded_parameters = extract_glv_parameters::(include!( + "precomputed_glv_values/bls_values" + )); + let bn_hardcoded_parameters = + extract_glv_parameters::(include!("precomputed_glv_values/bn_values")); let bls_parameters = bls12_381::G1Affine::glv_parameters(); let bn_parameters = bn254::G1Affine::glv_parameters(); assert_eq!(bls_hardcoded_parameters, bls_parameters); diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_beta_basis.sage b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_beta_basis.sage index 27ff70458..cdd66370c 100644 --- a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_beta_basis.sage +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_beta_basis.sage @@ -61,7 +61,7 @@ def print_for_rust(): pair = valid_pair(beta_values, lambda_values, E, G) basis = generate_short_basis(order_subgroup, int(pair[1])) output = [pair[0], basis[0][0], basis[0][1], basis[1][0], basis[1][1]] - print('\n'.join(f'{w}' for w in output)) + print("[\"" + '\", \"'.join(f'{w}' for w in output) + "\"]") def main(): print_for_rust() diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values index ce1938cc7..02573066c 100644 --- a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bls_values @@ -1,5 +1 @@ -793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350 -1 --228988810152649578064853576960394133503 -228988810152649578064853576960394133504 -1 \ No newline at end of file +["793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350", "1", "-228988810152649578064853576960394133503", "228988810152649578064853576960394133504", "1"] diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_beta_basis.sage b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_beta_basis.sage index a6f792e83..8d602c9f1 100644 --- a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_beta_basis.sage +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_beta_basis.sage @@ -61,7 +61,7 @@ def print_for_rust(): pair = valid_pair(beta_values, lambda_values, E, G) basis = generate_short_basis(order_subgroup, int(pair[1])) output = [pair[0], basis[0][0], basis[0][1], basis[1][0], basis[1][1]] - print('\n'.join(f'{w}' for w in output)) + print("[\"" + '\", \"'.join(f'{w}' for w in output) + "\"]") def main(): print_for_rust() diff --git a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values index c58947169..31404fce3 100644 --- a/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values +++ b/manta-crypto/src/arkworks/glv/precomputed_glv_values/bn_values @@ -1,5 +1 @@ -21888242871839275220042445260109153167277707414472061641714758635765020556616 -147946756881789319000765030803803410728 --9931322734385697763 -9931322734385697763 -147946756881789319010696353538189108491 \ No newline at end of file +["21888242871839275220042445260109153167277707414472061641714758635765020556616", "147946756881789319000765030803803410728", "-9931322734385697763", "9931322734385697763", "147946756881789319010696353538189108491"] From 74635da946a5ecb61b16c32ea0e1845bce29302f Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 12 Sep 2022 18:47:18 +0200 Subject: [PATCH 23/33] comments addressed Signed-off-by: Francisco Hernandez Iglesias --- manta-benchmark/src/benchmark.rs | 10 +++------- manta-crypto/src/arkworks/glv/mod.rs | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/manta-benchmark/src/benchmark.rs b/manta-benchmark/src/benchmark.rs index 3bb9d349f..4a8d36688 100644 --- a/manta-benchmark/src/benchmark.rs +++ b/manta-benchmark/src/benchmark.rs @@ -81,7 +81,6 @@ where const NAME: &'static str = "GLV scalar multiplication"; type Parameters = (); - type Output = C; #[inline] @@ -89,13 +88,10 @@ where where R: RngCore + ?Sized, { - let glv = C::glv_parameters(); - let scalar = C::ScalarField::rand(rng); - let point = C::Projective::rand(rng).into_affine(); Self { - glv, - scalar, - point, + glv: C::glv_parameters(), + scalar: C::ScalarField::rand(rng), + point: C::Projective::rand(rng).into_affine(), __: PhantomData, } } diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index f7592b997..1c00afee9 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -16,8 +16,6 @@ //! Arkworks Elliptic Curve Implementation -use core::str::FromStr; - use crate::arkworks::{ ec::{ models::{short_weierstrass_jacobian, SWModelParameters}, @@ -27,28 +25,28 @@ use crate::arkworks::{ }; use alloc::{vec, vec::Vec}; use ark_ff::{BigInteger, Field}; +use core::str::FromStr; use num_bigint::{BigInt, BigUint, Sign}; #[cfg(feature = "ark-bls12-381")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "ark-bls12-381")))] use crate::arkworks::bls12_381; #[cfg(feature = "ark-bn254")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "ark-bn254")))] use crate::arkworks::bn254; /// Affine Curve Extension pub trait AffineCurveExt: AffineCurve { - /// Gets `x` coordinate. + /// Returns the `x` coordinate of `self`. fn x(&self) -> &Self::BaseField; - /// Gets `y` coordinate. + /// Returns the `y` coordinate of `self`. fn y(&self) -> &Self::BaseField; /// Builds [`Self`] from `x` and `y`. fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self; /// Applies the GLV endomorphism to `self` + #[inline] fn glv_endomorphism(&self, beta: &Self::BaseField) -> Self { Self::from_xy_unchecked(*self.x() * beta, *self.y()) } @@ -224,6 +222,8 @@ pub trait HasGLV: AffineCurve { fn glv_parameters() -> GLVParameters; } +#[cfg(feature = "ark-bls12-381")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "ark-bls12-381")))] impl HasGLV for bls12_381::G1Affine { #[inline] fn glv_parameters() -> GLVParameters { @@ -246,6 +246,8 @@ impl HasGLV for bls12_381::G1Affine { } } +#[cfg(feature = "ark-bn254")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "ark-bn254")))] impl HasGLV for bn254::G1Affine { #[inline] fn glv_parameters() -> GLVParameters { @@ -268,6 +270,7 @@ impl HasGLV for bn254::G1Affine { } } +/// Testing Suite #[cfg(test)] pub mod test { use super::*; @@ -329,14 +332,12 @@ pub mod test { /// Checks the implementation of GLV for BLS is correct. #[test] pub fn glv_bls_is_correct() { - let mut rng = OsRng; - glv_is_correct::(&mut rng) + glv_is_correct::(&mut OsRng) } /// Checks the implementation of GLV for BN is correct. #[test] pub fn glv_bn_is_correct() { - let mut rng = OsRng; - glv_is_correct::(&mut rng); + glv_is_correct::(&mut OsRng); } } From e6c546d6e266da3222bd3b49beb7129bde7942a1 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 19 Sep 2022 11:51:49 +0200 Subject: [PATCH 24/33] some comments addressed Signed-off-by: Francisco Hernandez Iglesias --- manta-benchmark/Cargo.toml | 1 - manta-benchmark/benches/ecc.rs | 2 +- manta-benchmark/src/benchmark.rs | 7 ++++--- manta-crypto/src/arkworks/glv/mod.rs | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/manta-benchmark/Cargo.toml b/manta-benchmark/Cargo.toml index dda6e7f5c..a47f691e0 100644 --- a/manta-benchmark/Cargo.toml +++ b/manta-benchmark/Cargo.toml @@ -52,7 +52,6 @@ instant = { version = "0.1.12", default-features = false, features = [ "wasm-bin manta-accounting = { path = "../manta-accounting", default-features = false, features = ["test"] } manta-crypto = { path = "../manta-crypto", default-features = false, features = ["ark-bls12-381", "getrandom", "test"] } manta-pay = { path = "../manta-pay", default-features = false, features = ["groth16", "test"] } -num-bigint = { version = "0.4.3", default-features = false } wasm-bindgen = { version = "0.2.82", default-features = false } wasm-bindgen-test = { version = "0.3.30", default-features = false } web-sys = { version = "0.3.59", default-features = false, features = ["console"] } diff --git a/manta-benchmark/benches/ecc.rs b/manta-benchmark/benches/ecc.rs index d4a7da4bb..fd74e49bc 100644 --- a/manta-benchmark/benches/ecc.rs +++ b/manta-benchmark/benches/ecc.rs @@ -140,7 +140,7 @@ fn naive_vector_projective_to_affine_normalization(c: &mut Criterion) { #[inline] fn glv_scalar_multiplication(c: &mut Criterion) { - let mut group = c.benchmark_group("glv"); + let mut group = c.benchmark_group("bench"); let mut rng = OsRng; let glv_setup = black_box(GLVMutiplicationSetup::::setup(&mut rng, ())); glv_setup.define_benchmark(&mut group); diff --git a/manta-benchmark/src/benchmark.rs b/manta-benchmark/src/benchmark.rs index 4a8d36688..00c207099 100644 --- a/manta-benchmark/src/benchmark.rs +++ b/manta-benchmark/src/benchmark.rs @@ -62,7 +62,7 @@ where C: AffineCurveExt + HasGLV, { /// GLV Parameters - glv: GLVParameters, + glv_parameters: GLVParameters, /// Scalar scalar: C::ScalarField, @@ -89,7 +89,7 @@ where R: RngCore + ?Sized, { Self { - glv: C::glv_parameters(), + glv_parameters: C::glv_parameters(), scalar: C::ScalarField::rand(rng), point: C::Projective::rand(rng).into_affine(), __: PhantomData, @@ -98,6 +98,7 @@ where #[inline] fn benchmark(&self) -> Self::Output { - self.glv.scalar_mul(&self.point, &self.scalar) + self.glv_parameters + .scalar_mul(&black_box(self.point), &black_box(self.scalar)) } } diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index 1c00afee9..b31b1e1a3 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -73,7 +73,8 @@ where } /// Given a scalar `k` and basis vectors `v` and `u` finds integer scalars `k1` and `k2`, -/// so that `(k, 0)` is close to `k1v + k2u`. +/// so that `(k, 0)` is close to `k1v + k2u`, meaning the norm of the difference `||(k,0) - (k1v + k2u)||` +/// is at most `max(||v||, ||u||)`. #[inline] pub fn decompose_scalar(k: &F, v: (&BigInt, &BigInt), u: (&BigInt, &BigInt)) -> (BigInt, BigInt) where From 698e3e6add3d47b2c1824c224ce677266f6d4409 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Mon, 19 Sep 2022 12:35:17 +0200 Subject: [PATCH 25/33] all comments addressed Signed-off-by: Francisco Hernandez Iglesias --- manta-crypto/src/arkworks/glv/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index b31b1e1a3..a24c8b06c 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -80,7 +80,6 @@ pub fn decompose_scalar(k: &F, v: (&BigInt, &BigInt), u: (&BigInt, &BigInt)) where F: PrimeField, { - // TODO: Check the bit length of BitInt v.s. BaseField or ScalarField. See if there is any overflow issue. let k = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); let q1 = (u.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); let q2 = (-v.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); @@ -163,8 +162,6 @@ where where C: AffineCurveExt, { - // TODO: make sure both output vectors have the same length. I guess into_repr and - // to_bits_be() do that already? let (k1, k2) = decompose_scalar(scalar, self.basis().0, self.basis().1); let (k1_sign, k1) = k1.into_parts(); let p1 = match k1_sign { From 8d05967f9e712af58347cfcf371602d4a403b6e3 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Tue, 20 Sep 2022 14:21:17 +0200 Subject: [PATCH 26/33] some comments addressed Signed-off-by: Francisco Hernandez Iglesias --- manta-benchmark/benches/ecc.rs | 8 +++--- manta-benchmark/src/benchmark.rs | 6 ++--- manta-crypto/Cargo.toml | 2 -- manta-crypto/src/arkworks/glv/mod.rs | 37 +++++++++++++++++----------- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/manta-benchmark/benches/ecc.rs b/manta-benchmark/benches/ecc.rs index fd74e49bc..3fae96fce 100644 --- a/manta-benchmark/benches/ecc.rs +++ b/manta-benchmark/benches/ecc.rs @@ -140,15 +140,12 @@ fn naive_vector_projective_to_affine_normalization(c: &mut Criterion) { #[inline] fn glv_scalar_multiplication(c: &mut Criterion) { - let mut group = c.benchmark_group("bench"); - let mut rng = OsRng; - let glv_setup = black_box(GLVMutiplicationSetup::::setup(&mut rng, ())); - glv_setup.define_benchmark(&mut group); + black_box(GLVMutiplicationSetup::::setup(&mut OsRng, ())) + .define_benchmark(&mut c.benchmark_group("bench")); } criterion_group!( ecc, - glv_scalar_multiplication, affine_affine_addition, projective_affine_addition, projective_projective_addition, @@ -157,5 +154,6 @@ criterion_group!( projective_to_affine_normalization, batch_vector_projective_to_affine_normalization, naive_vector_projective_to_affine_normalization, + glv_scalar_multiplication, ); criterion_main!(ecc); diff --git a/manta-benchmark/src/benchmark.rs b/manta-benchmark/src/benchmark.rs index 00c207099..5ab744364 100644 --- a/manta-benchmark/src/benchmark.rs +++ b/manta-benchmark/src/benchmark.rs @@ -17,6 +17,7 @@ //! Benchmark trait use ark_ec::ProjectiveCurve; +use core::marker::PhantomData; use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; use manta_crypto::{ arkworks::{ @@ -25,7 +26,6 @@ use manta_crypto::{ }, rand::RngCore, }; -use std::marker::PhantomData; /// Benchmark trait pub trait Benchmark { @@ -74,9 +74,9 @@ where __: PhantomData, } -impl Benchmark for GLVMutiplicationSetup +impl Benchmark for GLVMutiplicationSetup where - C: AffineCurveExt + HasGLV, + C: AffineCurveExt + HasGLV, { const NAME: &'static str = "GLV scalar multiplication"; diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index 1c95439b9..b2988793d 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -51,8 +51,6 @@ serde = [ # Standard Library std = [ - "ark-bls12-381?/std", - "ark-bn254?/std", "ark-ec?/std", "ark-ed-on-bls12-381?/std", "ark-ed-on-bn254?/std", diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index a24c8b06c..4edaf1081 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -45,7 +45,7 @@ pub trait AffineCurveExt: AffineCurve { /// Builds [`Self`] from `x` and `y`. fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self; - /// Applies the GLV endomorphism to `self` + /// Applies the GLV endomorphism to `self`. #[inline] fn glv_endomorphism(&self, beta: &Self::BaseField) -> Self { Self::from_xy_unchecked(*self.x() * beta, *self.y()) @@ -88,8 +88,9 @@ where (k1, k2) } -#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] /// GLV Parameters +#[derive(derivative::Derivative)] +#[derivative(Clone, Debug, Default, Eq, Hash, PartialEq)] pub struct GLVParameters where C: AffineCurve, @@ -134,16 +135,19 @@ where } /// Returns a reference to `beta`. + #[inline] pub fn beta(&self) -> &C::BaseField { &self.beta } /// Returns `beta`, dropping `self`. + #[inline] pub fn into_beta(self) -> C::BaseField { self.beta } /// Returns a reference to the basis elements. + #[inline] pub fn basis(&self) -> ((&BigInt, &BigInt), (&BigInt, &BigInt)) { ( (&self.base_v1.0, &self.base_v1.1), @@ -196,7 +200,7 @@ where let table = vec![C::zero().into_projective(), p, q, p + q]; let mut r = C::zero().into_projective(); for i in 0..u.len() { - ProjectiveCurve::double_in_place(&mut r); + r.double_in_place(); r += table[u[i] as usize + 2 * (v[i] as usize)] } r.into_affine() @@ -240,7 +244,7 @@ impl HasGLV for bls12_381::G1Affine { BigInt::from_str("228988810152649578064853576960394133504").unwrap(), BigInt::from_str("1").unwrap(), ); - GLVParameters::::new_unchecked(beta, base_v1, base_v2) + GLVParameters::new_unchecked(beta, base_v1, base_v2) } } @@ -276,9 +280,9 @@ pub mod test { use ark_ff::UniformRand; use rand_core::OsRng; - /// Extracts the GLV parameters from a file. + /// Parses the GLV parameters from strings. #[inline] - fn extract_glv_parameters(glv_parameters: [&str; 5]) -> GLVParameters + pub fn parse_glv_parameters(glv_parameters: [&str; 5]) -> GLVParameters where C: AffineCurveExt, { @@ -299,21 +303,26 @@ pub mod test { /// Checks the GLV parameters of BLS12 and BN254 match the hardcoded sage outputs. #[test] - fn glv_parameters_match() { - let bls_hardcoded_parameters = extract_glv_parameters::(include!( + fn bls_glv_parameters_match() { + let bls_hardcoded_parameters = parse_glv_parameters::(include!( "precomputed_glv_values/bls_values" )); - let bn_hardcoded_parameters = - extract_glv_parameters::(include!("precomputed_glv_values/bn_values")); let bls_parameters = bls12_381::G1Affine::glv_parameters(); - let bn_parameters = bn254::G1Affine::glv_parameters(); assert_eq!(bls_hardcoded_parameters, bls_parameters); + } + + /// Checks the GLV parameters of BN254 match the hardcoded sage outputs. + #[test] + fn bn_glv_parameters_match() { + let bn_hardcoded_parameters = + parse_glv_parameters::(include!("precomputed_glv_values/bn_values")); + let bn_parameters = bn254::G1Affine::glv_parameters(); assert_eq!(bn_hardcoded_parameters, bn_parameters); } /// Checks the GLV scalar multiplication gives the expected result for the curve `C`. #[inline] - fn glv_is_correct(rng: &mut R) + pub fn glv_is_correct(rng: &mut R) where C: AffineCurveExt + HasGLV, R: RngCore + ?Sized, @@ -329,13 +338,13 @@ pub mod test { /// Checks the implementation of GLV for BLS is correct. #[test] - pub fn glv_bls_is_correct() { + fn glv_bls_is_correct() { glv_is_correct::(&mut OsRng) } /// Checks the implementation of GLV for BN is correct. #[test] - pub fn glv_bn_is_correct() { + fn glv_bn_is_correct() { glv_is_correct::(&mut OsRng); } } From 8c4689f8dc249532dd9c7cd3509588052bf2dd1e Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Tue, 20 Sep 2022 16:07:45 +0200 Subject: [PATCH 27/33] Comments addressed Signed-off-by: Francisco Hernandez Iglesias --- manta-benchmark/benches/ecc.rs | 2 +- .../src/{benchmark.rs => benchmark/glv.rs} | 32 +----------- manta-benchmark/src/benchmark/mod.rs | 51 +++++++++++++++++++ manta-crypto/src/arkworks/glv/mod.rs | 49 +++++++++++++----- 4 files changed, 90 insertions(+), 44 deletions(-) rename manta-benchmark/src/{benchmark.rs => benchmark/glv.rs} (70%) create mode 100644 manta-benchmark/src/benchmark/mod.rs diff --git a/manta-benchmark/benches/ecc.rs b/manta-benchmark/benches/ecc.rs index 3fae96fce..f065d34b6 100644 --- a/manta-benchmark/benches/ecc.rs +++ b/manta-benchmark/benches/ecc.rs @@ -19,7 +19,7 @@ use core::iter::repeat_with; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use manta_benchmark::{ - benchmark::{Benchmark, GLVMutiplicationSetup}, + benchmark::{glv::GLVMutiplicationSetup, Benchmark}, ecc, }; use manta_crypto::{ diff --git a/manta-benchmark/src/benchmark.rs b/manta-benchmark/src/benchmark/glv.rs similarity index 70% rename from manta-benchmark/src/benchmark.rs rename to manta-benchmark/src/benchmark/glv.rs index 5ab744364..8bfb4c657 100644 --- a/manta-benchmark/src/benchmark.rs +++ b/manta-benchmark/src/benchmark/glv.rs @@ -16,9 +16,10 @@ //! Benchmark trait +use crate::benchmark::Benchmark; use ark_ec::ProjectiveCurve; use core::marker::PhantomData; -use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; +use criterion::black_box; use manta_crypto::{ arkworks::{ ff::UniformRand, @@ -27,35 +28,6 @@ use manta_crypto::{ rand::RngCore, }; -/// Benchmark trait -pub trait Benchmark { - /// Benchmark Name - const NAME: &'static str; - - /// Benchmark Output Type - type Output; - - /// Benchmark Parameters - type Parameters; - - /// Generates a randomized instance of `Self` from `parameters`. - fn setup(rng: &mut R, parameters: Self::Parameters) -> Self - where - R: RngCore + ?Sized; - - /// A function of `self` which will be benchmarked. - fn benchmark(&self) -> Self::Output; - - /// Defines a benchmark from `benchmark`. - #[inline] - fn define_benchmark(&self, group: &mut BenchmarkGroup) - where - M: Measurement, - { - group.bench_function(Self::NAME, |b| b.iter(|| black_box(self.benchmark()))); - } -} - /// GLV Multiplication Setup pub struct GLVMutiplicationSetup where diff --git a/manta-benchmark/src/benchmark/mod.rs b/manta-benchmark/src/benchmark/mod.rs new file mode 100644 index 000000000..ee0c4cbaa --- /dev/null +++ b/manta-benchmark/src/benchmark/mod.rs @@ -0,0 +1,51 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Benchmark trait + +use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; +use manta_crypto::rand::RngCore; + +pub mod glv; + +/// Benchmark trait +pub trait Benchmark { + /// Benchmark Name + const NAME: &'static str; + + /// Benchmark Output Type + type Output; + + /// Benchmark Parameters + type Parameters; + + /// Generates a randomized instance of `Self` from `parameters`. + fn setup(rng: &mut R, parameters: Self::Parameters) -> Self + where + R: RngCore + ?Sized; + + /// A function of `self` which will be benchmarked. + fn benchmark(&self) -> Self::Output; + + /// Defines a benchmark from `benchmark`. + #[inline] + fn define_benchmark(&self, group: &mut BenchmarkGroup) + where + M: Measurement, + { + group.bench_function(Self::NAME, |b| b.iter(|| black_box(self.benchmark()))); + } +} diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index 4edaf1081..6ea16ca71 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -18,7 +18,10 @@ use crate::arkworks::{ ec::{ - models::{short_weierstrass_jacobian, SWModelParameters}, + models::{ + short_weierstrass_jacobian, twisted_edwards_extended, SWModelParameters, + TEModelParameters, + }, AffineCurve, ProjectiveCurve, }, ff::PrimeField, @@ -44,12 +47,6 @@ pub trait AffineCurveExt: AffineCurve { /// Builds [`Self`] from `x` and `y`. fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self; - - /// Applies the GLV endomorphism to `self`. - #[inline] - fn glv_endomorphism(&self, beta: &Self::BaseField) -> Self { - Self::from_xy_unchecked(*self.x() * beta, *self.y()) - } } impl

AffineCurveExt for short_weierstrass_jacobian::GroupAffine

@@ -72,6 +69,26 @@ where } } +impl

AffineCurveExt for twisted_edwards_extended::GroupAffine

+where + P: TEModelParameters, +{ + #[inline] + fn x(&self) -> &Self::BaseField { + &self.x + } + + #[inline] + fn y(&self) -> &Self::BaseField { + &self.y + } + + #[inline] + fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { + Self::new(x, y) + } +} + /// Given a scalar `k` and basis vectors `v` and `u` finds integer scalars `k1` and `k2`, /// so that `(k, 0)` is close to `k1v + k2u`, meaning the norm of the difference `||(k,0) - (k1v + k2u)||` /// is at most `max(||v||, ||u||)`. @@ -158,13 +175,13 @@ where /// Generates scalars and points for the simultaneous multiple /// point multiplication. #[inline] - fn scalars_and_points( + fn scalars_and_points( &self, point: &C, scalar: &C::ScalarField, ) -> (Vec, Vec, C::Projective, C::Projective) where - C: AffineCurveExt, + C: HasGLV, { let (k1, k2) = decompose_scalar(scalar, self.basis().0, self.basis().1); let (k1_sign, k1) = k1.into_parts(); @@ -208,9 +225,9 @@ where /// Multiplies `point` by `scalar` using the GLV method. #[inline] - pub fn scalar_mul(&self, point: &C, scalar: &C::ScalarField) -> C + pub fn scalar_mul(&self, point: &C, scalar: &C::ScalarField) -> C where - C: AffineCurveExt, + C: HasGLV, { let (k1, k2, p1, p2) = self.scalars_and_points(point, scalar); Self::simultaneous_multiple_point_multiplication(k1, k2, p1, p2) @@ -218,10 +235,16 @@ where } /// HasGLV Trait -pub trait HasGLV: AffineCurve { +pub trait HasGLV: AffineCurveExt { /// Generates [`GLVParameters`] from some precomputed parameters encoded /// in the marker type `M`. fn glv_parameters() -> GLVParameters; + + /// Applies the GLV endomorphism to `self`. + #[inline] + fn glv_endomorphism(&self, beta: &Self::BaseField) -> Self { + Self::from_xy_unchecked(*self.x() * beta, *self.y()) + } } #[cfg(feature = "ark-bls12-381")] @@ -268,7 +291,7 @@ impl HasGLV for bn254::G1Affine { BigInt::from_str("9931322734385697763").unwrap(), BigInt::from_str("147946756881789319010696353538189108491").unwrap(), ); - GLVParameters::::new_unchecked(beta, base_v1, base_v2) + GLVParameters::new_unchecked(beta, base_v1, base_v2) } } From 6831e2a12d4dd8bef8866cfa6fd81dd88e72fb0b Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Tue, 20 Sep 2022 17:35:09 +0200 Subject: [PATCH 28/33] load parameters from file directly Signed-off-by: Francisco Hernandez Iglesias --- manta-crypto/src/arkworks/glv/mod.rs | 95 +++++++--------------------- 1 file changed, 23 insertions(+), 72 deletions(-) diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index 6ea16ca71..9e2434a9c 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -252,22 +252,7 @@ pub trait HasGLV: AffineCurveExt { impl HasGLV for bls12_381::G1Affine { #[inline] fn glv_parameters() -> GLVParameters { - let beta = ::BaseField::from_random_bytes( - &"793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350" - .parse::() - .unwrap() - .to_bytes_le() - ) - .unwrap(); - let base_v1 = ( - BigInt::from_str("1").unwrap(), - BigInt::from_str("-228988810152649578064853576960394133503").unwrap(), - ); - let base_v2 = ( - BigInt::from_str("228988810152649578064853576960394133504").unwrap(), - BigInt::from_str("1").unwrap(), - ); - GLVParameters::new_unchecked(beta, base_v1, base_v2) + parse_glv_parameters::(include!("precomputed_glv_values/bls_values")) } } @@ -276,25 +261,31 @@ impl HasGLV for bls12_381::G1Affine { impl HasGLV for bn254::G1Affine { #[inline] fn glv_parameters() -> GLVParameters { - let beta = ::BaseField::from_random_bytes( - &"21888242871839275220042445260109153167277707414472061641714758635765020556616" - .parse::() - .unwrap() - .to_bytes_le(), - ) - .unwrap(); - let base_v1 = ( - BigInt::from_str("147946756881789319000765030803803410728").unwrap(), - BigInt::from_str("-9931322734385697763").unwrap(), - ); - let base_v2 = ( - BigInt::from_str("9931322734385697763").unwrap(), - BigInt::from_str("147946756881789319010696353538189108491").unwrap(), - ); - GLVParameters::new_unchecked(beta, base_v1, base_v2) + parse_glv_parameters::(include!("precomputed_glv_values/bn_values")) } } +/// Parses the GLV parameters from strings. +#[inline] +pub fn parse_glv_parameters(glv_parameters: [&str; 5]) -> GLVParameters +where + C: AffineCurveExt, +{ + let beta = C::BaseField::from_random_bytes( + &glv_parameters[0].parse::().unwrap().to_bytes_le(), + ) + .unwrap(); + let base_v1 = ( + BigInt::from_str(glv_parameters[1]).unwrap(), + BigInt::from_str(glv_parameters[2]).unwrap(), + ); + let base_v2 = ( + BigInt::from_str(glv_parameters[3]).unwrap(), + BigInt::from_str(glv_parameters[4]).unwrap(), + ); + GLVParameters::::new_unchecked(beta, base_v1, base_v2) +} + /// Testing Suite #[cfg(test)] pub mod test { @@ -303,46 +294,6 @@ pub mod test { use ark_ff::UniformRand; use rand_core::OsRng; - /// Parses the GLV parameters from strings. - #[inline] - pub fn parse_glv_parameters(glv_parameters: [&str; 5]) -> GLVParameters - where - C: AffineCurveExt, - { - let beta = C::BaseField::from_random_bytes( - &glv_parameters[0].parse::().unwrap().to_bytes_le(), - ) - .unwrap(); - let base_v1 = ( - BigInt::from_str(glv_parameters[1]).unwrap(), - BigInt::from_str(glv_parameters[2]).unwrap(), - ); - let base_v2 = ( - BigInt::from_str(glv_parameters[3]).unwrap(), - BigInt::from_str(glv_parameters[4]).unwrap(), - ); - GLVParameters::::new_unchecked(beta, base_v1, base_v2) - } - - /// Checks the GLV parameters of BLS12 and BN254 match the hardcoded sage outputs. - #[test] - fn bls_glv_parameters_match() { - let bls_hardcoded_parameters = parse_glv_parameters::(include!( - "precomputed_glv_values/bls_values" - )); - let bls_parameters = bls12_381::G1Affine::glv_parameters(); - assert_eq!(bls_hardcoded_parameters, bls_parameters); - } - - /// Checks the GLV parameters of BN254 match the hardcoded sage outputs. - #[test] - fn bn_glv_parameters_match() { - let bn_hardcoded_parameters = - parse_glv_parameters::(include!("precomputed_glv_values/bn_values")); - let bn_parameters = bn254::G1Affine::glv_parameters(); - assert_eq!(bn_hardcoded_parameters, bn_parameters); - } - /// Checks the GLV scalar multiplication gives the expected result for the curve `C`. #[inline] pub fn glv_is_correct(rng: &mut R) From bb26a96933b2b82a0b2481d0ed5d816ad1a4bb23 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Tue, 20 Sep 2022 17:41:11 +0200 Subject: [PATCH 29/33] removed unnecessary features Signed-off-by: Francisco Hernandez Iglesias --- manta-crypto/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index b2988793d..f85f3ec30 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -27,8 +27,6 @@ maintenance = { status = "actively-developed" } [features] # Arkworks Backend arkworks = [ - "ark-bls12-381", - "ark-bn254", "ark-ec", "ark-ff", "ark-r1cs-std", From 93fc201ec476c5104e90f809861a51318f86b985 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 20 Oct 2022 21:23:13 +0200 Subject: [PATCH 30/33] comments addressed Signed-off-by: Francisco Hernandez Iglesias --- manta-benchmark/benches/ecc.rs | 5 +- manta-benchmark/src/benchmark/mod.rs | 51 --------------- manta-benchmark/src/{benchmark => }/glv.rs | 6 +- manta-benchmark/src/lib.rs | 34 +++++++++- manta-crypto/Cargo.toml | 3 +- manta-crypto/src/arkworks/ec.rs | 72 +++++++++++++++++++++ manta-crypto/src/arkworks/glv/mod.rs | 75 +++------------------- manta-crypto/src/arkworks/mod.rs | 2 +- 8 files changed, 119 insertions(+), 129 deletions(-) delete mode 100644 manta-benchmark/src/benchmark/mod.rs rename manta-benchmark/src/{benchmark => }/glv.rs (94%) create mode 100644 manta-crypto/src/arkworks/ec.rs diff --git a/manta-benchmark/benches/ecc.rs b/manta-benchmark/benches/ecc.rs index f065d34b6..f76dcbb53 100644 --- a/manta-benchmark/benches/ecc.rs +++ b/manta-benchmark/benches/ecc.rs @@ -18,10 +18,7 @@ use core::iter::repeat_with; use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use manta_benchmark::{ - benchmark::{glv::GLVMutiplicationSetup, Benchmark}, - ecc, -}; +use manta_benchmark::{ecc, glv::GLVMutiplicationSetup, Benchmark}; use manta_crypto::{ arkworks::bls12_381::{G1Affine as BLSAffine, G1Projective as BLSProjective}, rand::OsRng, diff --git a/manta-benchmark/src/benchmark/mod.rs b/manta-benchmark/src/benchmark/mod.rs deleted file mode 100644 index ee0c4cbaa..000000000 --- a/manta-benchmark/src/benchmark/mod.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2019-2022 Manta Network. -// This file is part of manta-rs. -// -// manta-rs is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// manta-rs is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with manta-rs. If not, see . - -//! Benchmark trait - -use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; -use manta_crypto::rand::RngCore; - -pub mod glv; - -/// Benchmark trait -pub trait Benchmark { - /// Benchmark Name - const NAME: &'static str; - - /// Benchmark Output Type - type Output; - - /// Benchmark Parameters - type Parameters; - - /// Generates a randomized instance of `Self` from `parameters`. - fn setup(rng: &mut R, parameters: Self::Parameters) -> Self - where - R: RngCore + ?Sized; - - /// A function of `self` which will be benchmarked. - fn benchmark(&self) -> Self::Output; - - /// Defines a benchmark from `benchmark`. - #[inline] - fn define_benchmark(&self, group: &mut BenchmarkGroup) - where - M: Measurement, - { - group.bench_function(Self::NAME, |b| b.iter(|| black_box(self.benchmark()))); - } -} diff --git a/manta-benchmark/src/benchmark/glv.rs b/manta-benchmark/src/glv.rs similarity index 94% rename from manta-benchmark/src/benchmark/glv.rs rename to manta-benchmark/src/glv.rs index 8bfb4c657..d8039b542 100644 --- a/manta-benchmark/src/benchmark/glv.rs +++ b/manta-benchmark/src/glv.rs @@ -16,14 +16,14 @@ //! Benchmark trait -use crate::benchmark::Benchmark; -use ark_ec::ProjectiveCurve; +use crate::Benchmark; use core::marker::PhantomData; use criterion::black_box; use manta_crypto::{ arkworks::{ + ec::{AffineCurveExt, ProjectiveCurve}, ff::UniformRand, - glv::{AffineCurveExt, GLVParameters, HasGLV}, + glv::{GLVParameters, HasGLV}, }, rand::RngCore, }; diff --git a/manta-benchmark/src/lib.rs b/manta-benchmark/src/lib.rs index bb4714c73..dad2c2c99 100644 --- a/manta-benchmark/src/lib.rs +++ b/manta-benchmark/src/lib.rs @@ -20,8 +20,9 @@ #![forbid(rustdoc::broken_intra_doc_links)] #![forbid(missing_docs)] +use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; use manta_accounting::transfer::test::assert_valid_proof; -use manta_crypto::rand::{OsRng, Rand}; +use manta_crypto::rand::{OsRng, Rand, RngCore}; use manta_pay::{ config::{ MultiProvingContext, MultiVerifyingContext, Parameters, TransferPost, UtxoAccumulatorModel, @@ -31,8 +32,37 @@ use manta_pay::{ }; use wasm_bindgen::prelude::wasm_bindgen; -pub mod benchmark; pub mod ecc; +pub mod glv; + +/// Benchmark trait +pub trait Benchmark { + /// Benchmark Name + const NAME: &'static str; + + /// Benchmark Output Type + type Output; + + /// Benchmark Parameters + type Parameters; + + /// Generates a randomized instance of `Self` from `parameters`. + fn setup(rng: &mut R, parameters: Self::Parameters) -> Self + where + R: RngCore + ?Sized; + + /// A function of `self` which will be benchmarked. + fn benchmark(&self) -> Self::Output; + + /// Defines a benchmark from `benchmark`. + #[inline] + fn define_benchmark(&self, group: &mut BenchmarkGroup) + where + M: Measurement, + { + group.bench_function(Self::NAME, |b| b.iter(|| black_box(self.benchmark()))); + } +} /// Context Type #[wasm_bindgen] diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index 20fe1cd69..b041d9e69 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -32,6 +32,7 @@ arkworks = [ "ark-r1cs-std", "ark-relations", "ark-serialize", + "num-bigint" ] # Dalek Cryptography Backend @@ -77,7 +78,7 @@ ark-serialize = { version = "0.3.0", optional = true, default-features = false, derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } ed25519-dalek = { version = "1.0.1", optional = true, default-features = false, features = ["u64_backend"] } manta-util = { path = "../manta-util", default-features = false, features = ["alloc"] } -num-bigint = { version = "0.4.3", default-features = false } +num-bigint = { version = "0.4.3", optional=true, default-features = false } rand = { version = "0.8.4", optional = true, default-features = false, features = ["alloc"] } rand_chacha = { version = "0.3.1", optional = true, default-features = false } rand_core = { version = "0.6.3", default-features = false } diff --git a/manta-crypto/src/arkworks/ec.rs b/manta-crypto/src/arkworks/ec.rs new file mode 100644 index 000000000..dcefd2495 --- /dev/null +++ b/manta-crypto/src/arkworks/ec.rs @@ -0,0 +1,72 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Arkworks Elliptic Curves Backend + +#[doc(inline)] +pub use ark_ec::*; + +/// Affine Curve Extension +pub trait AffineCurveExt: AffineCurve { + /// Returns the `x` coordinate of `self`. + fn x(&self) -> &Self::BaseField; + + /// Returns the `y` coordinate of `self`. + fn y(&self) -> &Self::BaseField; + + /// Builds [`Self`] from `x` and `y`. + fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self; +} + +impl

AffineCurveExt for short_weierstrass_jacobian::GroupAffine

+where + P: SWModelParameters, +{ + #[inline] + fn x(&self) -> &Self::BaseField { + &self.x + } + + #[inline] + fn y(&self) -> &Self::BaseField { + &self.y + } + + #[inline] + fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { + Self::new(x, y, false) + } +} + +impl

AffineCurveExt for twisted_edwards_extended::GroupAffine

+where + P: TEModelParameters, +{ + #[inline] + fn x(&self) -> &Self::BaseField { + &self.x + } + + #[inline] + fn y(&self) -> &Self::BaseField { + &self.y + } + + #[inline] + fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { + Self::new(x, y) + } +} diff --git a/manta-crypto/src/arkworks/glv/mod.rs b/manta-crypto/src/arkworks/glv/mod.rs index 9e2434a9c..3067a9341 100644 --- a/manta-crypto/src/arkworks/glv/mod.rs +++ b/manta-crypto/src/arkworks/glv/mod.rs @@ -17,17 +17,10 @@ //! Arkworks Elliptic Curve Implementation use crate::arkworks::{ - ec::{ - models::{ - short_weierstrass_jacobian, twisted_edwards_extended, SWModelParameters, - TEModelParameters, - }, - AffineCurve, ProjectiveCurve, - }, - ff::PrimeField, + ec::{AffineCurve, AffineCurveExt, ProjectiveCurve}, + ff::{BigInteger, Field, PrimeField}, }; use alloc::{vec, vec::Vec}; -use ark_ff::{BigInteger, Field}; use core::str::FromStr; use num_bigint::{BigInt, BigUint, Sign}; @@ -37,58 +30,6 @@ use crate::arkworks::bls12_381; #[cfg(feature = "ark-bn254")] use crate::arkworks::bn254; -/// Affine Curve Extension -pub trait AffineCurveExt: AffineCurve { - /// Returns the `x` coordinate of `self`. - fn x(&self) -> &Self::BaseField; - - /// Returns the `y` coordinate of `self`. - fn y(&self) -> &Self::BaseField; - - /// Builds [`Self`] from `x` and `y`. - fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self; -} - -impl

AffineCurveExt for short_weierstrass_jacobian::GroupAffine

-where - P: SWModelParameters, -{ - #[inline] - fn x(&self) -> &Self::BaseField { - &self.x - } - - #[inline] - fn y(&self) -> &Self::BaseField { - &self.y - } - - #[inline] - fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { - Self::new(x, y, false) - } -} - -impl

AffineCurveExt for twisted_edwards_extended::GroupAffine

-where - P: TEModelParameters, -{ - #[inline] - fn x(&self) -> &Self::BaseField { - &self.x - } - - #[inline] - fn y(&self) -> &Self::BaseField { - &self.y - } - - #[inline] - fn from_xy_unchecked(x: Self::BaseField, y: Self::BaseField) -> Self { - Self::new(x, y) - } -} - /// Given a scalar `k` and basis vectors `v` and `u` finds integer scalars `k1` and `k2`, /// so that `(k, 0)` is close to `k1v + k2u`, meaning the norm of the difference `||(k,0) - (k1v + k2u)||` /// is at most `max(||v||, ||u||)`. @@ -98,10 +39,11 @@ where F: PrimeField, { let k = BigInt::from_bytes_be(Sign::Plus, &k.into_repr().to_bytes_be()); - let q1 = (u.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); - let q2 = (-v.1 * &k) / ((v.0 * u.1) - (v.1 * u.0)); + let det = (v.0 * u.1) - (v.1 * u.0); + let q1 = (u.1 * &k) / &det; + let q2 = (-v.1 * &k) / det; let k1 = k - &q1 * v.0 - &q2 * u.0; - let k2 = 0 - q1 * v.1 - q2 * u.1; + let k2 = -q1 * v.1 - q2 * u.1; (k1, k2) } @@ -290,15 +232,14 @@ where #[cfg(test)] pub mod test { use super::*; - use crate::rand::RngCore; + use crate::rand::{OsRng, RngCore}; use ark_ff::UniformRand; - use rand_core::OsRng; /// Checks the GLV scalar multiplication gives the expected result for the curve `C`. #[inline] pub fn glv_is_correct(rng: &mut R) where - C: AffineCurveExt + HasGLV, + C: HasGLV, R: RngCore + ?Sized, { let scalar = C::ScalarField::rand(rng); diff --git a/manta-crypto/src/arkworks/mod.rs b/manta-crypto/src/arkworks/mod.rs index 88d7f42ee..34608e71c 100644 --- a/manta-crypto/src/arkworks/mod.rs +++ b/manta-crypto/src/arkworks/mod.rs @@ -16,7 +16,6 @@ //! Arkworks Backend -pub use ark_ec as ec; pub use ark_r1cs_std as r1cs_std; pub use ark_relations as relations; @@ -34,6 +33,7 @@ pub use ark_ed_on_bn254 as ed_on_bn254; pub mod algebra; pub mod constraint; +pub mod ec; pub mod ff; pub mod glv; pub mod pairing; From 7c4c6dae02b533d52680010c93a2f9a815de2e26 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Thu, 20 Oct 2022 22:28:01 +0200 Subject: [PATCH 31/33] cargo sort Signed-off-by: Francisco Hernandez Iglesias --- manta-crypto/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index b041d9e69..0d3a33f40 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -78,7 +78,7 @@ ark-serialize = { version = "0.3.0", optional = true, default-features = false, derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } ed25519-dalek = { version = "1.0.1", optional = true, default-features = false, features = ["u64_backend"] } manta-util = { path = "../manta-util", default-features = false, features = ["alloc"] } -num-bigint = { version = "0.4.3", optional=true, default-features = false } +num-bigint = { version = "0.4.3", optional = true, default-features = false } rand = { version = "0.8.4", optional = true, default-features = false, features = ["alloc"] } rand_chacha = { version = "0.3.1", optional = true, default-features = false } rand_core = { version = "0.6.3", default-features = false } From 71db28aa06ba0098ba2995568200ed12d0d59bf1 Mon Sep 17 00:00:00 2001 From: Francisco Hernandez Iglesias Date: Fri, 21 Oct 2022 12:59:44 +0200 Subject: [PATCH 32/33] clippy Signed-off-by: Francisco Hernandez Iglesias --- manta-crypto/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index 0d3a33f40..9ff91b97f 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -84,4 +84,4 @@ rand_chacha = { version = "0.3.1", optional = true, default-features = false } rand_core = { version = "0.6.3", default-features = false } [dev-dependencies] -manta-crypto = { path = ".", default-features = false, features = ["ark-bn254", "getrandom"] } +manta-crypto = { path = ".", default-features = false, features = ["ark-bls12-381", "ark-bn254", "getrandom"] } From 93f2765d22678a6cf81442cbb0838b742166bd64 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 27 Oct 2022 14:54:01 -0400 Subject: [PATCH 33/33] Update CHANGELOG.md Signed-off-by: Brandon H. Gomes --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a029f8fad..c946c137e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] ### Added - [\#211](https://github.com/Manta-Network/manta-rs/pull/211) GLV scalar multiplication implementation -- [\#267](https://github.com/Manta-Network/manta-rs/pull/267) Add trusted setup client downloader ### Changed