From b6b62162c952fc63f4641ba98a857c3cbcde7417 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 11 Aug 2023 22:00:41 +0200 Subject: [PATCH 01/17] Add `Legendre` trait and macro - Add Legendre macro with norm and legendre symbol computation - Add macro for automatic implementation in prime fields --- src/legendre.rs | 35 +++++++++++++++++++++++++++++++++++ src/lib.rs | 2 ++ 2 files changed, 37 insertions(+) create mode 100644 src/legendre.rs diff --git a/src/legendre.rs b/src/legendre.rs new file mode 100644 index 00000000..33289354 --- /dev/null +++ b/src/legendre.rs @@ -0,0 +1,35 @@ +use ff::{Field, PrimeField}; + +pub trait Legendre: Field { + type BasePrimeField: PrimeField; + + // This is (p-1)/2 where p is the modulus of the base prime field + fn legendre_exp() -> &'static Vec; + + fn norm(&self) -> &Self::BasePrimeField; + + fn legendre(&self) -> Self::BasePrimeField { + self.norm().pow(Self::legendre_exp()) + } +} + +#[macro_export] +macro_rules! prime_field_legendre { + ($field:ident ) => { + + lazy_static::lazy_static! { + static ref LE_AS_BIGUINT: BigUint = BigUint::from_bytes_le((-<$field as ff::Field>::ONE).to_repr().as_ref())/2usize ; + static ref LEGENDRE_EXP: Vec = LE_AS_BIGUINT.to_u64_digits(); + } + impl crate::legendre::Legendre for $field { + type BasePrimeField = Self; + + fn legendre_exp() -> &'static Vec { + &*LEGENDRE_EXP + } + fn norm(&self) -> &Self::BasePrimeField { + &self + } + } + }; +} diff --git a/src/lib.rs b/src/lib.rs index b75d7143..3fa8e98f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,7 @@ mod arithmetic; pub mod hash_to_curve; +#[macro_use] +pub mod legendre; pub mod serde; pub mod bn256; From d9052ac65dea9f6e2d08f30ecfc3d8ab862938d9 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 11 Aug 2023 22:02:24 +0200 Subject: [PATCH 02/17] Add legendre macro call for prime fields --- src/pasta/mod.rs | 3 +++ src/secp256k1/fp.rs | 3 +++ src/secp256k1/fq.rs | 3 +++ src/secp256r1/fp.rs | 18 ++++++++++++++++++ src/secp256r1/fq.rs | 4 +++- 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/pasta/mod.rs b/src/pasta/mod.rs index 164697b5..807609b4 100644 --- a/src/pasta/mod.rs +++ b/src/pasta/mod.rs @@ -38,6 +38,9 @@ const ENDO_PARAMS_EP: EndoParameters = EndoParameters { endo!(Eq, Fp, ENDO_PARAMS_EQ); endo!(Ep, Fq, ENDO_PARAMS_EP); +// prime_field_legendre!(Fp); +// prime_field_legendre!(Fq); + #[test] fn test_endo() { use ff::Field; diff --git a/src/secp256k1/fp.rs b/src/secp256k1/fp.rs index 01fecf84..ff7edde3 100644 --- a/src/secp256k1/fp.rs +++ b/src/secp256k1/fp.rs @@ -8,6 +8,7 @@ use crate::{ use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; +use num_bigint::BigUint; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -295,6 +296,8 @@ impl WithSmallOrderMulGroup<3> for Fp { const ZETA: Self = ZETA; } +prime_field_legendre!(Fp); + #[cfg(test)] mod test { use super::*; diff --git a/src/secp256k1/fq.rs b/src/secp256k1/fq.rs index d38dc517..77a03019 100644 --- a/src/secp256k1/fq.rs +++ b/src/secp256k1/fq.rs @@ -8,6 +8,7 @@ use crate::{ use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; +use num_bigint::BigUint; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -302,6 +303,8 @@ impl WithSmallOrderMulGroup<3> for Fq { const ZETA: Self = ZETA; } +prime_field_legendre!(Fq); + #[cfg(test)] mod test { use super::*; diff --git a/src/secp256r1/fp.rs b/src/secp256r1/fp.rs index e26f19fc..3284945d 100644 --- a/src/secp256r1/fp.rs +++ b/src/secp256r1/fp.rs @@ -8,6 +8,7 @@ use crate::{ use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; +use num_bigint::BigUint; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -313,6 +314,23 @@ impl WithSmallOrderMulGroup<3> for Fp { const ZETA: Self = ZETA; } +prime_field_legendre!(Fp); +// lazy_static::lazy_static! { +// static ref LE_AS_BIGUINT: BigUint = BigUint::from_bytes_le((-Fp::ONE).to_repr().as_ref())/2usize ; +// static ref LEGENDRE_EXP: Vec = LE_AS_BIGUINT.to_u64_digits(); +// } + +// impl Legendre for Fp { +// type BasePrimeField = Self; + +// fn legendre_exp() -> &'static Vec { +// &*LEGENDRE_EXP +// } +// fn norm(&self) -> &Self::BasePrimeField { +// &self +// } +// } + #[cfg(test)] mod test { use super::*; diff --git a/src/secp256r1/fq.rs b/src/secp256r1/fq.rs index 05fcf1fa..f379c0a5 100644 --- a/src/secp256r1/fq.rs +++ b/src/secp256r1/fq.rs @@ -1,8 +1,8 @@ use crate::arithmetic::{adc, mac, macx, sbb}; use crate::ff::{FromUniformBytes, PrimeField, WithSmallOrderMulGroup}; -use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; +use num_bigint::BigUint; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -298,6 +298,8 @@ impl WithSmallOrderMulGroup<3> for Fq { const ZETA: Self = ZETA; } +prime_field_legendre!(Fq); + #[cfg(test)] mod test { use super::*; From f6ffe4f9c94a874a5f504487075dafd47c48c28f Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 11 Aug 2023 22:06:55 +0200 Subject: [PATCH 03/17] Remove unused imports --- src/legendre.rs | 2 +- src/secp256k1/fp.rs | 1 - src/secp256k1/fq.rs | 1 - src/secp256r1/fp.rs | 1 - src/secp256r1/fq.rs | 1 - 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/legendre.rs b/src/legendre.rs index 33289354..3a7386e9 100644 --- a/src/legendre.rs +++ b/src/legendre.rs @@ -18,7 +18,7 @@ macro_rules! prime_field_legendre { ($field:ident ) => { lazy_static::lazy_static! { - static ref LE_AS_BIGUINT: BigUint = BigUint::from_bytes_le((-<$field as ff::Field>::ONE).to_repr().as_ref())/2usize ; + static ref LE_AS_BIGUINT: num_bigint::BigUint = num_bigint::BigUint::from_bytes_le((-<$field as ff::Field>::ONE).to_repr().as_ref())/2usize ; static ref LEGENDRE_EXP: Vec = LE_AS_BIGUINT.to_u64_digits(); } impl crate::legendre::Legendre for $field { diff --git a/src/secp256k1/fp.rs b/src/secp256k1/fp.rs index ff7edde3..baa3b5c3 100644 --- a/src/secp256k1/fp.rs +++ b/src/secp256k1/fp.rs @@ -8,7 +8,6 @@ use crate::{ use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; -use num_bigint::BigUint; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; diff --git a/src/secp256k1/fq.rs b/src/secp256k1/fq.rs index 77a03019..7d6db77e 100644 --- a/src/secp256k1/fq.rs +++ b/src/secp256k1/fq.rs @@ -8,7 +8,6 @@ use crate::{ use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; -use num_bigint::BigUint; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; diff --git a/src/secp256r1/fp.rs b/src/secp256r1/fp.rs index 3284945d..aa5d4d4f 100644 --- a/src/secp256r1/fp.rs +++ b/src/secp256r1/fp.rs @@ -8,7 +8,6 @@ use crate::{ use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; -use num_bigint::BigUint; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; diff --git a/src/secp256r1/fq.rs b/src/secp256r1/fq.rs index f379c0a5..6dcabea6 100644 --- a/src/secp256r1/fq.rs +++ b/src/secp256r1/fq.rs @@ -2,7 +2,6 @@ use crate::arithmetic::{adc, mac, macx, sbb}; use crate::ff::{FromUniformBytes, PrimeField, WithSmallOrderMulGroup}; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; -use num_bigint::BigUint; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; From 963f3571efd15444ede26fba95efda03503cd4c3 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 11 Aug 2023 22:17:04 +0200 Subject: [PATCH 04/17] Remove leftover --- src/secp256r1/fp.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/secp256r1/fp.rs b/src/secp256r1/fp.rs index aa5d4d4f..e275e9c2 100644 --- a/src/secp256r1/fp.rs +++ b/src/secp256r1/fp.rs @@ -314,21 +314,6 @@ impl WithSmallOrderMulGroup<3> for Fp { } prime_field_legendre!(Fp); -// lazy_static::lazy_static! { -// static ref LE_AS_BIGUINT: BigUint = BigUint::from_bytes_le((-Fp::ONE).to_repr().as_ref())/2usize ; -// static ref LEGENDRE_EXP: Vec = LE_AS_BIGUINT.to_u64_digits(); -// } - -// impl Legendre for Fp { -// type BasePrimeField = Self; - -// fn legendre_exp() -> &'static Vec { -// &*LEGENDRE_EXP -// } -// fn norm(&self) -> &Self::BasePrimeField { -// &self -// } -// } #[cfg(test)] mod test { From a2e764cf241b4eaae48e7b5e8c83913f363330b8 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Sat, 5 Aug 2023 22:19:07 +0200 Subject: [PATCH 05/17] Add `is_quadratic_non_residue` for hash_to_curve --- src/hash_to_curve.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs index 4cef7095..e4751437 100644 --- a/src/hash_to_curve.rs +++ b/src/hash_to_curve.rs @@ -1,9 +1,11 @@ #![allow(clippy::op_ref)] use ff::{Field, FromUniformBytes, PrimeField}; +use num_bigint::BigUint; +use num_traits::Num; use pasta_curves::arithmetic::CurveExt; use static_assertions::const_assert; -use subtle::{ConditionallySelectable, ConstantTimeEq}; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; /// Hashes over a message and writes the output to all of `buf`. /// Modified from https://github.com/zcash/pasta_curves/blob/7e3fc6a4919f6462a32b79dd226cb2587b7961eb/src/hashtocurve.rs#L11. @@ -128,7 +130,7 @@ where // 14. gx1 = gx1 + B let gx1 = gx1 + b; // 15. e1 = is_square(gx1) - let e1 = gx1.sqrt().is_some(); + let e1 = !is_quadratic_non_residue(gx1); // 16. x2 = c2 + tv4 let x2 = c2 + tv4; // 17. gx2 = x2^2 @@ -140,7 +142,7 @@ where // 20. gx2 = gx2 + B let gx2 = gx2 + b; // 21. e2 = is_square(gx2) AND NOT e1 # Avoid short-circuit logic ops - let e2 = gx2.sqrt().is_some() & (!e1); + let e2 = !is_quadratic_non_residue(gx2) & (!e1); // 22. x3 = tv2^2 let x3 = tv2.square(); // 23. x3 = x3 * tv3 @@ -220,3 +222,11 @@ pub(crate) fn svdw_precomputed_constants(z: C::Base) -> [C::Base; 4 [c1, c2, c3, c4] } + +fn is_quadratic_non_residue(e: F) -> Choice { + let modulus: BigUint = + BigUint::from_str_radix(F::MODULUS.strip_prefix("0x").unwrap(), 16).unwrap(); + let exp = (modulus - 1u64) / 2u64; + let ls = e.pow(exp.to_u64_digits()); + ls.ct_eq(&-F::ONE) +} From fc513a43358fc19c2a55fc1c9035a9d131aa1e8b Mon Sep 17 00:00:00 2001 From: David Nevado Date: Sat, 5 Aug 2023 22:22:48 +0200 Subject: [PATCH 06/17] Add `legendre` function --- src/hash_to_curve.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs index e4751437..dff4798b 100644 --- a/src/hash_to_curve.rs +++ b/src/hash_to_curve.rs @@ -223,10 +223,14 @@ pub(crate) fn svdw_precomputed_constants(z: C::Base) -> [C::Base; 4 [c1, c2, c3, c4] } -fn is_quadratic_non_residue(e: F) -> Choice { +fn legendre(e: F) -> F { let modulus: BigUint = BigUint::from_str_radix(F::MODULUS.strip_prefix("0x").unwrap(), 16).unwrap(); let exp = (modulus - 1u64) / 2u64; - let ls = e.pow(exp.to_u64_digits()); + e.pow(exp.to_u64_digits()) +} + +fn is_quadratic_non_residue(e: F) -> Choice { + let ls = legendre(e); ls.ct_eq(&-F::ONE) } From 04ad73db1fbc190640fd9a4b53770a145da33380 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Sat, 5 Aug 2023 23:07:30 +0200 Subject: [PATCH 07/17] Compute modulus separately --- src/hash_to_curve.rs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs index dff4798b..d3f564a1 100644 --- a/src/hash_to_curve.rs +++ b/src/hash_to_curve.rs @@ -100,6 +100,7 @@ where let one = C::Base::ONE; let a = C::a(); let b = C::b(); + let p = modulus::(); // 1. tv1 = u^2 let tv1 = u.square(); @@ -130,7 +131,7 @@ where // 14. gx1 = gx1 + B let gx1 = gx1 + b; // 15. e1 = is_square(gx1) - let e1 = !is_quadratic_non_residue(gx1); + let e1 = !is_quadratic_non_residue(gx1, p.clone()); // 16. x2 = c2 + tv4 let x2 = c2 + tv4; // 17. gx2 = x2^2 @@ -142,7 +143,7 @@ where // 20. gx2 = gx2 + B let gx2 = gx2 + b; // 21. e2 = is_square(gx2) AND NOT e1 # Avoid short-circuit logic ops - let e2 = !is_quadratic_non_residue(gx2) & (!e1); + let e2 = !is_quadratic_non_residue(gx2, p) & (!e1); // 22. x3 = tv2^2 let x3 = tv2.square(); // 23. x3 = x3 * tv3 @@ -223,14 +224,18 @@ pub(crate) fn svdw_precomputed_constants(z: C::Base) -> [C::Base; 4 [c1, c2, c3, c4] } -fn legendre(e: F) -> F { - let modulus: BigUint = - BigUint::from_str_radix(F::MODULUS.strip_prefix("0x").unwrap(), 16).unwrap(); - let exp = (modulus - 1u64) / 2u64; - e.pow(exp.to_u64_digits()) +#[inline] +fn legendre(elem: F, p: BigUint) -> F { + let exp = (p - 1u64) / 2u64; + elem.pow(exp.to_u64_digits()) } -fn is_quadratic_non_residue(e: F) -> Choice { - let ls = legendre(e); - ls.ct_eq(&-F::ONE) +#[inline] +fn is_quadratic_non_residue(e: F, p: BigUint) -> Choice { + legendre(e, p).ct_eq(&-F::ONE) +} + +#[inline] +fn modulus() -> BigUint { + BigUint::from_str_radix(F::MODULUS.strip_prefix("0x").unwrap(), 16).unwrap() } From 6b2777f540aee098d88335fa96fa854067ca1baf Mon Sep 17 00:00:00 2001 From: David Nevado Date: Mon, 7 Aug 2023 15:57:05 +0200 Subject: [PATCH 08/17] Substitute division for shift --- src/hash_to_curve.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs index d3f564a1..8cdde8b6 100644 --- a/src/hash_to_curve.rs +++ b/src/hash_to_curve.rs @@ -226,7 +226,7 @@ pub(crate) fn svdw_precomputed_constants(z: C::Base) -> [C::Base; 4 #[inline] fn legendre(elem: F, p: BigUint) -> F { - let exp = (p - 1u64) / 2u64; + let exp: BigUint = (p - 1u64) >> 1; elem.pow(exp.to_u64_digits()) } From fd4a7c048c85024e67796a8df73616c9fce540e2 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Tue, 8 Aug 2023 12:02:39 +0200 Subject: [PATCH 09/17] Update modulus computation --- src/hash_to_curve.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs index 8cdde8b6..3705d9f5 100644 --- a/src/hash_to_curve.rs +++ b/src/hash_to_curve.rs @@ -2,7 +2,6 @@ use ff::{Field, FromUniformBytes, PrimeField}; use num_bigint::BigUint; -use num_traits::Num; use pasta_curves::arithmetic::CurveExt; use static_assertions::const_assert; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; @@ -100,7 +99,7 @@ where let one = C::Base::ONE; let a = C::a(); let b = C::b(); - let p = modulus::(); + let p_minus_one = mod_minus_one::(); // 1. tv1 = u^2 let tv1 = u.square(); @@ -131,7 +130,7 @@ where // 14. gx1 = gx1 + B let gx1 = gx1 + b; // 15. e1 = is_square(gx1) - let e1 = !is_quadratic_non_residue(gx1, p.clone()); + let e1 = !is_quadratic_non_residue(gx1, p_minus_one.clone()); // 16. x2 = c2 + tv4 let x2 = c2 + tv4; // 17. gx2 = x2^2 @@ -143,7 +142,7 @@ where // 20. gx2 = gx2 + B let gx2 = gx2 + b; // 21. e2 = is_square(gx2) AND NOT e1 # Avoid short-circuit logic ops - let e2 = !is_quadratic_non_residue(gx2, p) & (!e1); + let e2 = !is_quadratic_non_residue(gx2, p_minus_one) & (!e1); // 22. x3 = tv2^2 let x3 = tv2.square(); // 23. x3 = x3 * tv3 @@ -225,17 +224,17 @@ pub(crate) fn svdw_precomputed_constants(z: C::Base) -> [C::Base; 4 } #[inline] -fn legendre(elem: F, p: BigUint) -> F { - let exp: BigUint = (p - 1u64) >> 1; +fn legendre(elem: F, p_minus_one: BigUint) -> F { + let exp: BigUint = p_minus_one >> 1; elem.pow(exp.to_u64_digits()) } #[inline] -fn is_quadratic_non_residue(e: F, p: BigUint) -> Choice { - legendre(e, p).ct_eq(&-F::ONE) +fn is_quadratic_non_residue(e: F, p_minus_one: BigUint) -> Choice { + legendre(e, p_minus_one).ct_eq(&-F::ONE) } #[inline] -fn modulus() -> BigUint { - BigUint::from_str_radix(F::MODULUS.strip_prefix("0x").unwrap(), 16).unwrap() +fn mod_minus_one() -> BigUint { + BigUint::from_bytes_le((-F::ONE).to_repr().as_ref()) } From 6a22a7e0c71bef5817497933787cae740a26bdf8 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 11 Aug 2023 11:49:25 +0200 Subject: [PATCH 10/17] Add quadratic residue check func --- src/hash_to_curve.rs | 6 +++--- src/tests/field.rs | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs index 3705d9f5..e3aeb2c1 100644 --- a/src/hash_to_curve.rs +++ b/src/hash_to_curve.rs @@ -224,17 +224,17 @@ pub(crate) fn svdw_precomputed_constants(z: C::Base) -> [C::Base; 4 } #[inline] -fn legendre(elem: F, p_minus_one: BigUint) -> F { +pub(crate) fn legendre(elem: F, p_minus_one: BigUint) -> F { let exp: BigUint = p_minus_one >> 1; elem.pow(exp.to_u64_digits()) } #[inline] -fn is_quadratic_non_residue(e: F, p_minus_one: BigUint) -> Choice { +pub(crate) fn is_quadratic_non_residue(e: F, p_minus_one: BigUint) -> Choice { legendre(e, p_minus_one).ct_eq(&-F::ONE) } #[inline] -fn mod_minus_one() -> BigUint { +pub(crate) fn mod_minus_one() -> BigUint { BigUint::from_bytes_le((-F::ONE).to_repr().as_ref()) } diff --git a/src/tests/field.rs b/src/tests/field.rs index a064441e..e7f024e6 100644 --- a/src/tests/field.rs +++ b/src/tests/field.rs @@ -1,6 +1,8 @@ -use crate::ff::Field; +use crate::hash_to_curve::is_quadratic_non_residue; use crate::serde::SerdeObject; +use crate::{ff::Field, hash_to_curve::mod_minus_one}; use ark_std::{end_timer, start_timer}; +use ff::PrimeField; use rand::{RngCore, SeedableRng}; use rand_xorshift::XorShiftRng; @@ -287,3 +289,17 @@ where } end_timer!(start); } + +pub fn random_quadratic_residue_test() { + let mut rng = XorShiftRng::from_seed([ + 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, + 0xe5, + ]); + let p_minus_one = mod_minus_one::(); + for _ in 0..100000 { + let elem = F::random(&mut rng); + let is_quad_res_or_zero: bool = elem.sqrt().is_some().into(); + let is_quad_non_res: bool = is_quadratic_non_residue(elem, p_minus_one.clone()).into(); + assert_eq!(!is_quad_non_res, is_quad_res_or_zero) + } +} From 8ed62662532e113cf99c284d2a3865f47cb0babb Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 11 Aug 2023 11:51:03 +0200 Subject: [PATCH 11/17] Add quadratic residue tests --- src/bn256/fq.rs | 5 +++++ src/bn256/fr.rs | 5 +++++ src/pasta/mod.rs | 6 ++++++ src/secp256k1/fp.rs | 5 +++++ src/secp256k1/fq.rs | 4 ++++ src/secp256r1/fp.rs | 5 +++++ src/secp256r1/fq.rs | 5 +++++ 7 files changed, 35 insertions(+) diff --git a/src/bn256/fq.rs b/src/bn256/fq.rs index 0e2fc10f..ac6e6c62 100644 --- a/src/bn256/fq.rs +++ b/src/bn256/fq.rs @@ -393,4 +393,9 @@ mod test { #[cfg(feature = "derive_serde")] crate::tests::field::random_serde_test::("fq".to_string()); } + + #[test] + fn test_quadratic_residue() { + crate::tests::field::random_quadratic_residue_test::(); + } } diff --git a/src/bn256/fr.rs b/src/bn256/fr.rs index cd422d4b..8fc22d23 100644 --- a/src/bn256/fr.rs +++ b/src/bn256/fr.rs @@ -470,4 +470,9 @@ mod test { end_timer!(timer); } + + #[test] + fn test_quadratic_residue() { + crate::tests::field::random_quadratic_residue_test::(); + } } diff --git a/src/pasta/mod.rs b/src/pasta/mod.rs index 807609b4..3582a570 100644 --- a/src/pasta/mod.rs +++ b/src/pasta/mod.rs @@ -74,3 +74,9 @@ fn test_endo() { } } } + +#[test] +fn test_quadratic_residue() { + crate::tests::field::random_quadratic_residue_test::(); + crate::tests::field::random_quadratic_residue_test::(); +} diff --git a/src/secp256k1/fp.rs b/src/secp256k1/fp.rs index baa3b5c3..f6a2a54b 100644 --- a/src/secp256k1/fp.rs +++ b/src/secp256k1/fp.rs @@ -369,4 +369,9 @@ mod test { #[cfg(feature = "derive_serde")] crate::tests::field::random_serde_test::("secp256k1 base".to_string()); } + + #[test] + fn test_quadratic_residue() { + crate::tests::field::random_quadratic_residue_test::(); + } } diff --git a/src/secp256k1/fq.rs b/src/secp256k1/fq.rs index 7d6db77e..304f5f10 100644 --- a/src/secp256k1/fq.rs +++ b/src/secp256k1/fq.rs @@ -376,4 +376,8 @@ mod test { #[cfg(feature = "derive_serde")] crate::tests::field::random_serde_test::("secp256k1 scalar".to_string()); } + #[test] + fn test_quadratic_residue() { + crate::tests::field::random_quadratic_residue_test::(); + } } diff --git a/src/secp256r1/fp.rs b/src/secp256r1/fp.rs index e275e9c2..228e4a67 100644 --- a/src/secp256r1/fp.rs +++ b/src/secp256r1/fp.rs @@ -387,4 +387,9 @@ mod test { #[cfg(feature = "derive_serde")] crate::tests::field::random_serde_test::("secp256r1 base".to_string()); } + + #[test] + fn test_quadratic_residue() { + crate::tests::field::random_quadratic_residue_test::(); + } } diff --git a/src/secp256r1/fq.rs b/src/secp256r1/fq.rs index 6dcabea6..1b98761c 100644 --- a/src/secp256r1/fq.rs +++ b/src/secp256r1/fq.rs @@ -371,4 +371,9 @@ mod test { #[cfg(feature = "derive_serde")] crate::tests::field::random_serde_test::("secp256r1 scalar".to_string()); } + + #[test] + fn test_quadratic_residue() { + crate::tests::field::random_quadratic_residue_test::(); + } } From f5219a4081e57e564b8e390ce86f9ac55d563fa0 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Wed, 16 Aug 2023 19:00:46 +0200 Subject: [PATCH 12/17] Add hash_to_curve bench --- Cargo.toml | 4 ++++ benches/hash_to_curve.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 benches/hash_to_curve.rs diff --git a/Cargo.toml b/Cargo.toml index e0b9d8ba..f29c917e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,3 +63,7 @@ required-features = ["reexport"] [[bench]] name = "group" harness = false + +[[bench]] +name = "hash_to_curve" +harness = false diff --git a/benches/hash_to_curve.rs b/benches/hash_to_curve.rs new file mode 100644 index 00000000..a7dc0655 --- /dev/null +++ b/benches/hash_to_curve.rs @@ -0,0 +1,32 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use halo2curves::bn256::G1; +use halo2curves::secp256k1::Secp256k1; +use pasta_curves::arithmetic::CurveExt; +use rand_core::{OsRng, RngCore}; +use std::iter; + +fn hash_to_secp256k1(c: &mut Criterion) { + hash_to_curve::(c, "Secp256k1"); +} + +fn hash_to_bn256(c: &mut Criterion) { + hash_to_curve::(c, "Bn256"); +} + +fn hash_to_curve(c: &mut Criterion, name: &'static str) { + { + let hasher = G::hash_to_curve("test"); + let mut rng = OsRng; + let message = iter::repeat_with(|| rng.next_u32().to_be_bytes()) + .take(1024) + .flatten() + .collect::>(); + + c.bench_function(&format!("Hash to {}", name), move |b| { + b.iter(|| hasher(black_box(&message))) + }); + } +} + +criterion_group!(benches, hash_to_secp256k1, hash_to_bn256); +criterion_main!(benches); From 38324855b910e5e341b08b0f2108c6b2587e18d8 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Thu, 17 Aug 2023 20:02:02 +0200 Subject: [PATCH 13/17] Implement Legendre trait for all curves --- src/bn256/fq.rs | 31 +++++--------------------- src/bn256/fq2.rs | 53 ++++++++++++++++++++++---------------------- src/bn256/fr.rs | 1 + src/bn256/mod.rs | 7 ------ src/hash_to_curve.rs | 29 ++++++------------------ src/legendre.rs | 31 +++++++++++++++++++------- src/pasta/mod.rs | 4 ++-- src/tests/curve.rs | 5 ++++- src/tests/field.rs | 8 +++---- 9 files changed, 72 insertions(+), 97 deletions(-) diff --git a/src/bn256/fq.rs b/src/bn256/fq.rs index ac6e6c62..e385327a 100644 --- a/src/bn256/fq.rs +++ b/src/bn256/fq.rs @@ -160,27 +160,10 @@ impl Fq { pub const fn size() -> usize { 32 } - - pub fn legendre(&self) -> LegendreSymbol { - // s = self^((modulus - 1) // 2) - // 0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3 - let s = &[ - 0x9e10460b6c3e7ea3u64, - 0xcbc0b548b438e546u64, - 0xdc2822db40c0ac2eu64, - 0x183227397098d014u64, - ]; - let s = self.pow(s); - if s == Self::zero() { - LegendreSymbol::Zero - } else if s == Self::one() { - LegendreSymbol::QuadraticResidue - } else { - LegendreSymbol::QuadraticNonResidue - } - } } +prime_field_legendre!(Fq); + impl ff::Field for Fq { const ZERO: Self = Self::zero(); const ONE: Self = Self::one(); @@ -310,6 +293,7 @@ impl WithSmallOrderMulGroup<3> for Fq { #[cfg(test)] mod test { use super::*; + use crate::legendre::Legendre; use ff::Field; use rand_core::OsRng; @@ -322,7 +306,7 @@ mod test { let a = Fq::random(OsRng); let mut b = a; b = b.square(); - assert_eq!(b.legendre(), LegendreSymbol::QuadraticResidue); + assert_eq!(b.legendre(), Fq::ONE); let b = b.sqrt().unwrap(); let mut negb = b; @@ -335,7 +319,7 @@ mod test { for _ in 0..10000 { let mut b = c; b = b.square(); - assert_eq!(b.legendre(), LegendreSymbol::QuadraticResidue); + assert_eq!(b.legendre(), Fq::ONE); b = b.sqrt().unwrap(); @@ -393,9 +377,4 @@ mod test { #[cfg(feature = "derive_serde")] crate::tests::field::random_serde_test::("fq".to_string()); } - - #[test] - fn test_quadratic_residue() { - crate::tests::field::random_quadratic_residue_test::(); - } } diff --git a/src/bn256/fq2.rs b/src/bn256/fq2.rs index e5a249ee..8c5cc544 100644 --- a/src/bn256/fq2.rs +++ b/src/bn256/fq2.rs @@ -1,6 +1,6 @@ use super::fq::{Fq, NEGATIVE_ONE}; -use super::LegendreSymbol; use crate::ff::{Field, FromUniformBytes, PrimeField, WithSmallOrderMulGroup}; +use crate::legendre::Legendre; use core::convert::TryInto; use core::ops::{Add, Mul, Neg, Sub}; use rand::RngCore; @@ -125,6 +125,29 @@ impl_binops_additive!(Fq2, Fq2); impl_binops_multiplicative!(Fq2, Fq2); impl_sum_prod!(Fq2); +impl Legendre for Fq2 { + type BasePrimeField = Fq; + + #[inline] + fn legendre_exp() -> &'static Vec { + lazy_static::lazy_static! { + // (p-1) / 2 + static ref LEGENDRE_EXP: Vec = + (num_bigint::BigUint::from_bytes_le((-::ONE).to_repr().as_ref())/2usize).to_u64_digits(); + } + &*LEGENDRE_EXP + } + + #[inline] + fn norm(&self) -> Self::BasePrimeField { + let mut t0 = self.c0; + let mut t1 = self.c1; + t0 = t0.square(); + t1 = t1.square(); + t1 + t0 + } +} + impl Fq2 { #[inline] pub const fn zero() -> Fq2 { @@ -174,10 +197,6 @@ impl Fq2 { res } - pub fn legendre(&self) -> LegendreSymbol { - self.norm().legendre() - } - pub fn mul_assign(&mut self, other: &Self) { let mut t1 = self.c0 * other.c0; let mut t0 = self.c0 + self.c1; @@ -299,13 +318,6 @@ impl Fq2 { } /// Norm of Fq2 as extension field in i over Fq - pub fn norm(&self) -> Fq { - let mut t0 = self.c0; - let mut t1 = self.c1; - t0 = t0.square(); - t1 = t1.square(); - t1 + t0 - } pub fn invert(&self) -> CtOption { let mut t1 = self.c1; @@ -696,17 +708,6 @@ fn test_fq2_mul_nonresidue() { } } -#[test] -fn test_fq2_legendre() { - assert_eq!(LegendreSymbol::Zero, Fq2::ZERO.legendre()); - // i^2 = -1 - let mut m1 = Fq2::ONE; - m1 = m1.neg(); - assert_eq!(LegendreSymbol::QuadraticResidue, m1.legendre()); - m1.mul_by_nonresidue(); - assert_eq!(LegendreSymbol::QuadraticNonResidue, m1.legendre()); -} - #[test] pub fn test_sqrt() { let mut rng = XorShiftRng::from_seed([ @@ -716,7 +717,7 @@ pub fn test_sqrt() { for _ in 0..10000 { let a = Fq2::random(&mut rng); - if a.legendre() == LegendreSymbol::QuadraticNonResidue { + if a.legendre() == -Fq::ONE { assert!(bool::from(a.sqrt().is_none())); } } @@ -725,7 +726,7 @@ pub fn test_sqrt() { let a = Fq2::random(&mut rng); let mut b = a; b.square_assign(); - assert_eq!(b.legendre(), LegendreSymbol::QuadraticResidue); + assert_eq!(b.legendre(), Fq::ONE); let b = b.sqrt().unwrap(); let mut negb = b; @@ -738,7 +739,7 @@ pub fn test_sqrt() { for _ in 0..10000 { let mut b = c; b.square_assign(); - assert_eq!(b.legendre(), LegendreSymbol::QuadraticResidue); + assert_eq!(b.legendre(), Fq::ONE); b = b.sqrt().unwrap(); diff --git a/src/bn256/fr.rs b/src/bn256/fr.rs index 8fc22d23..63a3e1e8 100644 --- a/src/bn256/fr.rs +++ b/src/bn256/fr.rs @@ -166,6 +166,7 @@ field_common!( R3 ); impl_sum_prod!(Fr); +prime_field_legendre!(Fr); #[cfg(not(feature = "bn256-table"))] impl_from_u64!(Fr, R2); diff --git a/src/bn256/mod.rs b/src/bn256/mod.rs index 9cd08946..3530b765 100644 --- a/src/bn256/mod.rs +++ b/src/bn256/mod.rs @@ -16,10 +16,3 @@ pub use fq12::*; pub use fq2::*; pub use fq6::*; pub use fr::*; - -#[derive(Debug, PartialEq, Eq)] -pub enum LegendreSymbol { - Zero = 0, - QuadraticResidue = 1, - QuadraticNonResidue = -1, -} diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs index e3aeb2c1..5d51ec75 100644 --- a/src/hash_to_curve.rs +++ b/src/hash_to_curve.rs @@ -1,10 +1,11 @@ #![allow(clippy::op_ref)] use ff::{Field, FromUniformBytes, PrimeField}; -use num_bigint::BigUint; use pasta_curves::arithmetic::CurveExt; use static_assertions::const_assert; -use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; +use subtle::{ConditionallySelectable, ConstantTimeEq}; + +use crate::legendre::Legendre; /// Hashes over a message and writes the output to all of `buf`. /// Modified from https://github.com/zcash/pasta_curves/blob/7e3fc6a4919f6462a32b79dd226cb2587b7961eb/src/hashtocurve.rs#L11. @@ -95,11 +96,11 @@ pub(crate) fn svdw_map_to_curve( ) -> C where C: CurveExt, + C::Base: Legendre, { let one = C::Base::ONE; let a = C::a(); let b = C::b(); - let p_minus_one = mod_minus_one::(); // 1. tv1 = u^2 let tv1 = u.square(); @@ -130,7 +131,7 @@ where // 14. gx1 = gx1 + B let gx1 = gx1 + b; // 15. e1 = is_square(gx1) - let e1 = !is_quadratic_non_residue(gx1, p_minus_one.clone()); + let e1 = !gx1.ct_quadratic_non_residue(); // 16. x2 = c2 + tv4 let x2 = c2 + tv4; // 17. gx2 = x2^2 @@ -142,7 +143,7 @@ where // 20. gx2 = gx2 + B let gx2 = gx2 + b; // 21. e2 = is_square(gx2) AND NOT e1 # Avoid short-circuit logic ops - let e2 = !is_quadratic_non_residue(gx2, p_minus_one) & (!e1); + let e2 = !gx2.ct_quadratic_non_residue() & (!e1); // 22. x3 = tv2^2 let x3 = tv2.square(); // 23. x3 = x3 * tv3 @@ -184,7 +185,7 @@ pub(crate) fn svdw_hash_to_curve<'a, C>( ) -> Box C + 'a> where C: CurveExt, - C::Base: FromUniformBytes<64>, + C::Base: FromUniformBytes<64> + Legendre, { let [c1, c2, c3, c4] = svdw_precomputed_constants::(z); @@ -222,19 +223,3 @@ pub(crate) fn svdw_precomputed_constants(z: C::Base) -> [C::Base; 4 [c1, c2, c3, c4] } - -#[inline] -pub(crate) fn legendre(elem: F, p_minus_one: BigUint) -> F { - let exp: BigUint = p_minus_one >> 1; - elem.pow(exp.to_u64_digits()) -} - -#[inline] -pub(crate) fn is_quadratic_non_residue(e: F, p_minus_one: BigUint) -> Choice { - legendre(e, p_minus_one).ct_eq(&-F::ONE) -} - -#[inline] -pub(crate) fn mod_minus_one() -> BigUint { - BigUint::from_bytes_le((-F::ONE).to_repr().as_ref()) -} diff --git a/src/legendre.rs b/src/legendre.rs index 3a7386e9..4ff41ec2 100644 --- a/src/legendre.rs +++ b/src/legendre.rs @@ -1,4 +1,5 @@ use ff::{Field, PrimeField}; +use subtle::{Choice, ConstantTimeEq}; pub trait Legendre: Field { type BasePrimeField: PrimeField; @@ -6,29 +7,43 @@ pub trait Legendre: Field { // This is (p-1)/2 where p is the modulus of the base prime field fn legendre_exp() -> &'static Vec; - fn norm(&self) -> &Self::BasePrimeField; + fn norm(&self) -> Self::BasePrimeField; + #[inline] fn legendre(&self) -> Self::BasePrimeField { self.norm().pow(Self::legendre_exp()) } + + #[inline] + fn ct_quadratic_residue(&self) -> Choice { + self.legendre().ct_eq(&Self::BasePrimeField::ONE) + } + + #[inline] + fn ct_quadratic_non_residue(&self) -> Choice { + self.legendre().ct_eq(&-Self::BasePrimeField::ONE) + } } #[macro_export] macro_rules! prime_field_legendre { ($field:ident ) => { - - lazy_static::lazy_static! { - static ref LE_AS_BIGUINT: num_bigint::BigUint = num_bigint::BigUint::from_bytes_le((-<$field as ff::Field>::ONE).to_repr().as_ref())/2usize ; - static ref LEGENDRE_EXP: Vec = LE_AS_BIGUINT.to_u64_digits(); - } impl crate::legendre::Legendre for $field { type BasePrimeField = Self; + #[inline] fn legendre_exp() -> &'static Vec { + lazy_static::lazy_static! { + // (p-1) / 2 + static ref LEGENDRE_EXP: Vec = + (num_bigint::BigUint::from_bytes_le((-<$field as ff::Field>::ONE).to_repr().as_ref())/2usize).to_u64_digits(); + } &*LEGENDRE_EXP } - fn norm(&self) -> &Self::BasePrimeField { - &self + + #[inline] + fn norm(&self) -> Self::BasePrimeField { + self.clone() } } }; diff --git a/src/pasta/mod.rs b/src/pasta/mod.rs index 3582a570..078b663e 100644 --- a/src/pasta/mod.rs +++ b/src/pasta/mod.rs @@ -38,8 +38,8 @@ const ENDO_PARAMS_EP: EndoParameters = EndoParameters { endo!(Eq, Fp, ENDO_PARAMS_EQ); endo!(Ep, Fq, ENDO_PARAMS_EP); -// prime_field_legendre!(Fp); -// prime_field_legendre!(Fq); +prime_field_legendre!(Fp); +prime_field_legendre!(Fq); #[test] fn test_endo() { diff --git a/src/tests/curve.rs b/src/tests/curve.rs index 9bb0fe0b..54d23791 100644 --- a/src/tests/curve.rs +++ b/src/tests/curve.rs @@ -2,6 +2,7 @@ use crate::ff::Field; use crate::group::prime::PrimeCurveAffine; +use crate::legendre::Legendre; use crate::tests::fe_from_str; use crate::{group::GroupEncoding, serde::SerdeObject}; use crate::{hash_to_curve, CurveAffine, CurveExt}; @@ -343,7 +344,9 @@ pub fn svdw_map_to_curve_test( z: G::Base, precomputed_constants: [&'static str; 4], test_vector: impl IntoIterator, -) { +) where + ::Base: Legendre, +{ let [c1, c2, c3, c4] = hash_to_curve::svdw_precomputed_constants::(z); assert_eq!([c1, c2, c3, c4], precomputed_constants.map(fe_from_str)); for (u, (x, y)) in test_vector.into_iter() { diff --git a/src/tests/field.rs b/src/tests/field.rs index e7f024e6..b04f801e 100644 --- a/src/tests/field.rs +++ b/src/tests/field.rs @@ -1,6 +1,5 @@ -use crate::hash_to_curve::is_quadratic_non_residue; use crate::serde::SerdeObject; -use crate::{ff::Field, hash_to_curve::mod_minus_one}; +use crate::{ff::Field, legendre::Legendre}; use ark_std::{end_timer, start_timer}; use ff::PrimeField; use rand::{RngCore, SeedableRng}; @@ -290,16 +289,15 @@ where end_timer!(start); } -pub fn random_quadratic_residue_test() { +pub fn random_quadratic_residue_test() { let mut rng = XorShiftRng::from_seed([ 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5, ]); - let p_minus_one = mod_minus_one::(); for _ in 0..100000 { let elem = F::random(&mut rng); let is_quad_res_or_zero: bool = elem.sqrt().is_some().into(); - let is_quad_non_res: bool = is_quadratic_non_residue(elem, p_minus_one.clone()).into(); + let is_quad_non_res: bool = elem.ct_quadratic_non_residue().into(); assert_eq!(!is_quad_non_res, is_quad_res_or_zero) } } From ed460ec9f18c4610c231fc1eaa319c14dd585f8b Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 18 Aug 2023 12:47:45 +0200 Subject: [PATCH 14/17] Move misplaced comment --- src/bn256/fq2.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bn256/fq2.rs b/src/bn256/fq2.rs index 8c5cc544..a1c0c5bf 100644 --- a/src/bn256/fq2.rs +++ b/src/bn256/fq2.rs @@ -138,6 +138,7 @@ impl Legendre for Fq2 { &*LEGENDRE_EXP } + /// Norm of Fq2 as extension field in i over Fq #[inline] fn norm(&self) -> Self::BasePrimeField { let mut t0 = self.c0; @@ -317,8 +318,6 @@ impl Fq2 { self.c1 += &t0; } - /// Norm of Fq2 as extension field in i over Fq - pub fn invert(&self) -> CtOption { let mut t1 = self.c1; t1 = t1.square(); From 78a56d54b790aad99a46417e6e55dc969e0d23e3 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 18 Aug 2023 13:01:17 +0200 Subject: [PATCH 15/17] Add all curves to hash bench --- benches/hash_to_curve.rs | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/benches/hash_to_curve.rs b/benches/hash_to_curve.rs index a7dc0655..76f6733a 100644 --- a/benches/hash_to_curve.rs +++ b/benches/hash_to_curve.rs @@ -1,16 +1,34 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use halo2curves::bn256::G1; -use halo2curves::secp256k1::Secp256k1; use pasta_curves::arithmetic::CurveExt; use rand_core::{OsRng, RngCore}; use std::iter; fn hash_to_secp256k1(c: &mut Criterion) { - hash_to_curve::(c, "Secp256k1"); + hash_to_curve::(c, "Secp256k1"); +} + +fn hash_to_secq256k1(c: &mut Criterion) { + hash_to_curve::(c, "Secq256k1"); +} + +fn hash_to_secp256r1(c: &mut Criterion) { + hash_to_curve::(c, "Secp256r1"); +} + +fn hash_to_pallas(c: &mut Criterion) { + hash_to_curve::(c, "Pallas"); +} + +fn hash_to_vesta(c: &mut Criterion) { + hash_to_curve::(c, "Vesta"); } fn hash_to_bn256(c: &mut Criterion) { - hash_to_curve::(c, "Bn256"); + hash_to_curve::(c, "Bn256"); +} + +fn hash_to_grumpkin(c: &mut Criterion) { + hash_to_curve::(c, "Grumpkin"); } fn hash_to_curve(c: &mut Criterion, name: &'static str) { @@ -28,5 +46,14 @@ fn hash_to_curve(c: &mut Criterion, name: &'static str) { } } -criterion_group!(benches, hash_to_secp256k1, hash_to_bn256); +criterion_group!( + benches, + hash_to_secp256k1, + hash_to_secq256k1, + hash_to_secp256r1, + hash_to_pallas, + hash_to_vesta, + hash_to_bn256, + hash_to_grumpkin, +); criterion_main!(benches); From bdbb2f0ee5f08faf2babef40303684012931a256 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Fri, 18 Aug 2023 20:54:28 +0200 Subject: [PATCH 16/17] fix: add suggestion for legendre_exp --- src/bn256/fq2.rs | 2 +- src/legendre.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bn256/fq2.rs b/src/bn256/fq2.rs index a1c0c5bf..468b018c 100644 --- a/src/bn256/fq2.rs +++ b/src/bn256/fq2.rs @@ -129,7 +129,7 @@ impl Legendre for Fq2 { type BasePrimeField = Fq; #[inline] - fn legendre_exp() -> &'static Vec { + fn legendre_exp() -> &'static [u64] { lazy_static::lazy_static! { // (p-1) / 2 static ref LEGENDRE_EXP: Vec = diff --git a/src/legendre.rs b/src/legendre.rs index 4ff41ec2..6f6fda17 100644 --- a/src/legendre.rs +++ b/src/legendre.rs @@ -5,7 +5,7 @@ pub trait Legendre: Field { type BasePrimeField: PrimeField; // This is (p-1)/2 where p is the modulus of the base prime field - fn legendre_exp() -> &'static Vec; + fn legendre_exp() -> &'static [u64]; fn norm(&self) -> Self::BasePrimeField; @@ -32,7 +32,7 @@ macro_rules! prime_field_legendre { type BasePrimeField = Self; #[inline] - fn legendre_exp() -> &'static Vec { + fn legendre_exp() -> &'static [u64] { lazy_static::lazy_static! { // (p-1) / 2 static ref LEGENDRE_EXP: Vec = From 5e7022cac95cf3fd6a78f0e2e260902dad30cc03 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Tue, 22 Aug 2023 01:37:15 +0200 Subject: [PATCH 17/17] fix: imports after rebase --- src/bn256/fq.rs | 7 +++---- src/bn256/fr.rs | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bn256/fq.rs b/src/bn256/fq.rs index e385327a..0024723a 100644 --- a/src/bn256/fq.rs +++ b/src/bn256/fq.rs @@ -1,11 +1,10 @@ #[cfg(feature = "asm")] use crate::bn256::assembly::field_arithmetic_asm; #[cfg(not(feature = "asm"))] -use crate::{field_arithmetic, field_specific}; +use crate::{arithmetic::macx, field_arithmetic, field_specific}; -use crate::arithmetic::{adc, mac, macx, sbb}; -use crate::bn256::LegendreSymbol; -use crate::ff::{Field, FromUniformBytes, PrimeField, WithSmallOrderMulGroup}; +use crate::arithmetic::{adc, mac, sbb}; +use crate::ff::{FromUniformBytes, PrimeField, WithSmallOrderMulGroup}; use crate::{ field_bits, field_common, impl_add_binop_specify_output, impl_binops_additive, impl_binops_additive_specify_output, impl_binops_multiplicative, diff --git a/src/bn256/fr.rs b/src/bn256/fr.rs index 63a3e1e8..8a57ff9f 100644 --- a/src/bn256/fr.rs +++ b/src/bn256/fr.rs @@ -1,7 +1,7 @@ #[cfg(feature = "asm")] use crate::bn256::assembly::field_arithmetic_asm; #[cfg(not(feature = "asm"))] -use crate::{field_arithmetic, field_specific}; +use crate::{arithmetic::macx, field_arithmetic, field_specific}; #[cfg(feature = "bn256-table")] #[rustfmt::skip] @@ -18,7 +18,7 @@ pub use table::FR_TABLE; #[cfg(not(feature = "bn256-table"))] use crate::impl_from_u64; -use crate::arithmetic::{adc, mac, macx, sbb}; +use crate::arithmetic::{adc, mac, sbb}; use crate::ff::{FromUniformBytes, PrimeField, WithSmallOrderMulGroup}; use crate::{ field_bits, field_common, impl_add_binop_specify_output, impl_binops_additive,