diff --git a/ec/src/hashing/curve_maps/swu/mod.rs b/ec/src/hashing/curve_maps/swu/mod.rs index a2202d4af..3fca8e090 100644 --- a/ec/src/hashing/curve_maps/swu/mod.rs +++ b/ec/src/hashing/curve_maps/swu/mod.rs @@ -165,7 +165,7 @@ impl MapToCurve> for SWUMap

{ let x_affine = num_x / div; let y_affine = if parity(&y) { -y } else { y }; - let point_on_curve = Affine::

::new(x_affine, y_affine, false); + let point_on_curve = Affine::

::new_unchecked(x_affine, y_affine); assert!( point_on_curve.is_on_curve(), "swu mapped to a point off the curve" diff --git a/ec/src/hashing/curve_maps/wb/mod.rs b/ec/src/hashing/curve_maps/wb/mod.rs index c61005170..31bb67a21 100644 --- a/ec/src/hashing/curve_maps/wb/mod.rs +++ b/ec/src/hashing/curve_maps/wb/mod.rs @@ -47,7 +47,7 @@ pub trait WBParams: SWCurveConfig + Sized { let img_x = x_num.evaluate(&domain_point.x) * v[0]; let img_y = (y_num.evaluate(&domain_point.x) * domain_point.y) * v[1]; - Ok(Affine::new(img_x, img_y, false)) + Ok(Affine::new_unchecked(img_x, img_y)) } } @@ -59,17 +59,10 @@ pub struct WBMap { impl MapToCurve> for WBMap

{ /// Constructs a new map if `P` represents a valid map. fn new() -> Result { - // Verifying that the isogeny maps the generator of the SWU curve into us - let isogenous_curve_generator = Affine::::new( - P::IsogenousCurve::AFFINE_GENERATOR_COEFFS.0, - P::IsogenousCurve::AFFINE_GENERATOR_COEFFS.1, - false, - ); - - match P::isogeny_map(isogenous_curve_generator) { + match P::isogeny_map(P::IsogenousCurve::GENERATOR) { Ok(point_on_curve) => { if !point_on_curve.is_on_curve() { - return Err(HashToCurveError::MapToCurveError(format!("the isogeny maps the generator of its domain: {} into {} which does not belong to its codomain.",isogenous_curve_generator, point_on_curve))); + return Err(HashToCurveError::MapToCurveError(format!("the isogeny maps the generator of its domain: {} into {} which does not belong to its codomain.",P::IsogenousCurve::GENERATOR, point_on_curve))); } }, Err(e) => return Err(e), diff --git a/ec/src/hashing/tests/mod.rs b/ec/src/hashing/tests/mod.rs index 1e904a894..7f59ccc9f 100644 --- a/ec/src/hashing/tests/mod.rs +++ b/ec/src/hashing/tests/mod.rs @@ -1,4 +1,3 @@ -use crate::hashing::HashToCurve; use crate::{ hashing::{ curve_maps::{ @@ -6,13 +5,16 @@ use crate::{ wb::{WBMap, WBParams}, }, map_to_curve_hasher::{MapToCurve, MapToCurveBasedHasher}, + HashToCurve, }, models::short_weierstrass::SWCurveConfig, short_weierstrass::Affine, CurveConfig, }; -use ark_ff::field_hashers::DefaultFieldHasher; -use ark_ff::{biginteger::BigInteger64, fields::Fp64, BigInt, MontBackend, MontFp}; +use ark_ff::{ + biginteger::BigInteger64, field_hashers::DefaultFieldHasher, fields::Fp64, BigInt, MontBackend, + MontFp, +}; use ark_ff::SquareRootField; use ark_std::vec::Vec; @@ -31,7 +33,7 @@ impl ark_ff::MontConfig<1> for F127Config { // sage: FF(3)^63 // 126 #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: F127 = MontFp!(F127, "126"); + const TWO_ADIC_ROOT_OF_UNITY: F127 = MontFp!("126"); /// MODULUS = 127 #[rustfmt::skip] @@ -42,14 +44,14 @@ impl ark_ff::MontConfig<1> for F127Config { // Montgomery conversion 3 * 2 = 6 % 127 /// GENERATOR = 3 #[rustfmt::skip] - const GENERATOR: F127 = MontFp!(F127, "6"); + const GENERATOR: F127 = MontFp!("6"); // T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T // For T coprime to 2 } -const F127_ZERO: F127 = MontFp!(F127, "0"); -const F127_ONE: F127 = MontFp!(F127, "1"); +const F127_ZERO: F127 = MontFp!("0"); +const F127_ONE: F127 = MontFp!("1"); struct TestSWUMapToCurveParams; @@ -82,17 +84,16 @@ impl SWCurveConfig for TestSWUMapToCurveParams { /// COEFF_B = 1 #[rustfmt::skip] - const COEFF_B: F127 = MontFp!(F127, "63"); + const COEFF_B: F127 = MontFp!("63"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = - (MontFp!(F127, "62"), MontFp!(F127, "70")); + const GENERATOR: Affine = Affine::new_unchecked(MontFp!("62"), MontFp!("70")); } impl SWUParams for TestSWUMapToCurveParams { - const XI: F127 = MontFp!(F127, "-1"); - const ZETA: F127 = MontFp!(F127, "3"); - const XI_ON_ZETA_SQRT: F127 = MontFp!(F127, "13"); + const XI: F127 = MontFp!("-1"); + const ZETA: F127 = MontFp!("3"); + const XI_ON_ZETA_SQRT: F127 = MontFp!("13"); } /// test that MontFp make a none zero element out of 1 @@ -197,25 +198,24 @@ impl CurveConfig for TestSWU127MapToIsogenousCurveParams { /// Field of size 127 impl SWCurveConfig for TestSWU127MapToIsogenousCurveParams { /// COEFF_A = 109 - const COEFF_A: F127 = MontFp!(F127, "109"); + const COEFF_A: F127 = MontFp!("109"); /// COEFF_B = 124 #[rustfmt::skip] - const COEFF_B: F127 = MontFp!(F127, "124"); + const COEFF_B: F127 = MontFp!("124"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = - (MontFp!(F127, "84"), MontFp!(F127, "2")); + const GENERATOR: Affine = Affine::new_unchecked(MontFp!("84"), MontFp!("2")); } /// SWU parameters for E_isogenous impl SWUParams for TestSWU127MapToIsogenousCurveParams { /// NON-SQUARE = - 1 - const XI: F127 = MontFp!(F127, "-1"); + const XI: F127 = MontFp!("-1"); /// A Primitive Root of unity = 3 - const ZETA: F127 = MontFp!(F127, "3"); + const ZETA: F127 = MontFp!("3"); /// sqrt(Xi/Zeta) - const XI_ON_ZETA_SQRT: F127 = MontFp!(F127, "13"); + const XI_ON_ZETA_SQRT: F127 = MontFp!("13"); } /// The struct defining our parameters for the target curve of hashing @@ -239,11 +239,10 @@ impl SWCurveConfig for TestWBF127MapToCurveParams { /// COEFF_B = 3 #[rustfmt::skip] - const COEFF_B: F127 = MontFp!(F127, "3"); + const COEFF_B: F127 = MontFp!("3"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = - (MontFp!(F127, "62"), MontFp!(F127, "70")); + const GENERATOR: Affine = Affine::new_unchecked(MontFp!("62"), MontFp!("70")); } /// E_isogenous : Elliptic Curve defined by y^2 = x^3 + 109*x + 124 over Finite @@ -256,89 +255,91 @@ impl SWCurveConfig for TestWBF127MapToCurveParams { /// 4)/(x^12 - 13*x^11 + 11*x^10 - 33*x^9 - 30*x^8 + 30*x^7 + 34*x^6 - 44*x^5 + /// 63*x^4 - 20*x^3 - 10*x^2 + 31*x + 2) /// -/// psi_y: (10*x^18*y + 59*x^17*y + 41*x^16*y + 48*x^15*y - 7*x^14*y + 6*x^13*y + -/// 5*x^12*y + 62*x^11*y + 12*x^10*y + 36*x^9*y - 49*x^8*y - 18*x^7*y - 63*x^6*y +/// psi_y: (10*x^18*y + 59*x^17*y + 41*x^16*y + 48*x^15*y - 7*x^14*y + 6*x^13*y +/// + 5*x^12*y + 62*x^11*y + 12*x^10*y + 36*x^9*y - 49*x^8*y - 18*x^7*y - +/// 63*x^6*y /// - 43*x^5*y - 60*x^4*y - 18*x^3*y + 30*x^2*y - 57*x*y - 34*y)/(x^18 + 44*x^17 -/// - 63*x^16 + 52*x^15 + 3*x^14 + 38*x^13 - 30*x^12 + 11*x^11 - 42*x^10 - 13*x^9 +/// - 63*x^16 + 52*x^15 + 3*x^14 + 38*x^13 - 30*x^12 + 11*x^11 - 42*x^10 - +/// 13*x^9 /// - 46*x^8 - 61*x^7 - 16*x^6 - 55*x^5 + 18*x^4 + 23*x^3 - 24*x^2 - 18*x + 32) impl WBParams for TestWBF127MapToCurveParams { type IsogenousCurve = TestSWU127MapToIsogenousCurveParams; const PHI_X_NOM: &'static [::BaseField] = &[ - MontFp!(F127, "4"), - MontFp!(F127, "63"), - MontFp!(F127, "23"), - MontFp!(F127, "39"), - MontFp!(F127, "-14"), - MontFp!(F127, "23"), - MontFp!(F127, "-32"), - MontFp!(F127, "32"), - MontFp!(F127, "-13"), - MontFp!(F127, "40"), - MontFp!(F127, "34"), - MontFp!(F127, "10"), - MontFp!(F127, "-21"), - MontFp!(F127, "-57"), + MontFp!("4"), + MontFp!("63"), + MontFp!("23"), + MontFp!("39"), + MontFp!("-14"), + MontFp!("23"), + MontFp!("-32"), + MontFp!("32"), + MontFp!("-13"), + MontFp!("40"), + MontFp!("34"), + MontFp!("10"), + MontFp!("-21"), + MontFp!("-57"), ]; const PHI_X_DEN: &'static [::BaseField] = &[ - MontFp!(F127, "2"), - MontFp!(F127, "31"), - MontFp!(F127, "-10"), - MontFp!(F127, "-20"), - MontFp!(F127, "63"), - MontFp!(F127, "-44"), - MontFp!(F127, "34"), - MontFp!(F127, "30"), - MontFp!(F127, "-30"), - MontFp!(F127, "-33"), - MontFp!(F127, "11"), - MontFp!(F127, "-13"), - MontFp!(F127, "1"), + MontFp!("2"), + MontFp!("31"), + MontFp!("-10"), + MontFp!("-20"), + MontFp!("63"), + MontFp!("-44"), + MontFp!("34"), + MontFp!("30"), + MontFp!("-30"), + MontFp!("-33"), + MontFp!("11"), + MontFp!("-13"), + MontFp!("1"), ]; const PHI_Y_NOM: &'static [::BaseField] = &[ - MontFp!(F127, "-34"), - MontFp!(F127, "-57"), - MontFp!(F127, "30"), - MontFp!(F127, "-18"), - MontFp!(F127, "-60"), - MontFp!(F127, "-43"), - MontFp!(F127, "-63"), - MontFp!(F127, "-18"), - MontFp!(F127, "-49"), - MontFp!(F127, "36"), - MontFp!(F127, "12"), - MontFp!(F127, "62"), - MontFp!(F127, "5"), - MontFp!(F127, "6"), - MontFp!(F127, "-7"), - MontFp!(F127, "48"), - MontFp!(F127, "41"), - MontFp!(F127, "59"), - MontFp!(F127, "10"), + MontFp!("-34"), + MontFp!("-57"), + MontFp!("30"), + MontFp!("-18"), + MontFp!("-60"), + MontFp!("-43"), + MontFp!("-63"), + MontFp!("-18"), + MontFp!("-49"), + MontFp!("36"), + MontFp!("12"), + MontFp!("62"), + MontFp!("5"), + MontFp!("6"), + MontFp!("-7"), + MontFp!("48"), + MontFp!("41"), + MontFp!("59"), + MontFp!("10"), ]; const PHI_Y_DEN: &'static [::BaseField] = &[ - MontFp!(F127, "32"), - MontFp!(F127, "-18"), - MontFp!(F127, "-24"), - MontFp!(F127, "23"), - MontFp!(F127, "18"), - MontFp!(F127, "-55"), - MontFp!(F127, "-16"), - MontFp!(F127, "-61"), - MontFp!(F127, "-46"), - MontFp!(F127, "-13"), - MontFp!(F127, "-42"), - MontFp!(F127, "11"), - MontFp!(F127, "-30"), - MontFp!(F127, "38"), - MontFp!(F127, "3"), - MontFp!(F127, "52"), - MontFp!(F127, "-63"), - MontFp!(F127, "44"), - MontFp!(F127, "1"), + MontFp!("32"), + MontFp!("-18"), + MontFp!("-24"), + MontFp!("23"), + MontFp!("18"), + MontFp!("-55"), + MontFp!("-16"), + MontFp!("-61"), + MontFp!("-46"), + MontFp!("-13"), + MontFp!("-42"), + MontFp!("11"), + MontFp!("-30"), + MontFp!("38"), + MontFp!("3"), + MontFp!("52"), + MontFp!("-63"), + MontFp!("44"), + MontFp!("1"), ]; } diff --git a/ec/src/lib.rs b/ec/src/lib.rs index 4cf19714e..f795272c6 100644 --- a/ec/src/lib.rs +++ b/ec/src/lib.rs @@ -204,8 +204,8 @@ pub trait ProjectiveCurve: fn double_in_place(&mut self) -> &mut Self; /// Converts self into the affine representation. - fn into_affine(&self) -> Self::Affine { - (*self).into() + fn into_affine(self) -> Self::Affine { + self.into() } /// Sets `self` to be `self + other`, where `other: Self::Affine`. @@ -267,15 +267,15 @@ pub trait AffineCurve: + MulAssign; // needed due to https://github.com/rust-lang/rust/issues/69640 /// Returns the x and y coordinates of this affine point - fn xy(&self) -> (Self::BaseField, Self::BaseField); + fn xy(&self) -> Option<(&Self::BaseField, &Self::BaseField)>; /// Returns a fixed generator of unknown exponent. #[must_use] fn prime_subgroup_generator() -> Self; /// Converts self into the projective representation. - fn into_projective(&self) -> Self::Projective { - (*self).into() + fn into_projective(self) -> Self::Projective { + self.into() } /// Returns a group element if the set of bytes forms a valid group element, diff --git a/ec/src/models/bls12/g2.rs b/ec/src/models/bls12/g2.rs index 90c562af4..336dfcfe6 100644 --- a/ec/src/models/bls12/g2.rs +++ b/ec/src/models/bls12/g2.rs @@ -1,8 +1,8 @@ -use ark_std::vec::Vec; - -use ark_ff::fields::{BitIteratorBE, Field, Fp2}; - -use num_traits::{One, Zero}; +use ark_ff::{ + fields::{BitIteratorBE, Field, Fp2}, + Zero, +}; +use ark_std::{vec::Vec, One}; use crate::{ bls12::{Bls12Parameters, TwistType}, @@ -51,34 +51,36 @@ impl Default for G2Prepared

{ impl From> for G2Prepared

{ fn from(q: G2Affine

) -> Self { let two_inv = P::Fp::one().double().inverse().unwrap(); - if q.is_zero() { - return Self { + match q.is_zero() { + true => G2Prepared { ell_coeffs: vec![], infinity: true, - }; - } - - let mut ell_coeffs = vec![]; - let mut r = G2HomProjective { - x: q.x, - y: q.y, - z: Fp2::one(), - }; - - for i in BitIteratorBE::new(P::X).skip(1) { - ell_coeffs.push(doubling_step::

(&mut r, &two_inv)); - - if i { - ell_coeffs.push(addition_step::

(&mut r, &q)); - } - } - - Self { - ell_coeffs, - infinity: false, + }, + false => { + let mut ell_coeffs = vec![]; + let mut r = G2HomProjective { + x: q.x, + y: q.y, + z: Fp2::one(), + }; + + for i in BitIteratorBE::new(P::X).skip(1) { + ell_coeffs.push(doubling_step::

(&mut r, &two_inv)); + + if i { + ell_coeffs.push(addition_step::

(&mut r, &q)); + } + } + + Self { + ell_coeffs, + infinity: false, + } + }, } } } + impl G2Prepared

{ pub fn is_zero(&self) -> bool { self.infinity @@ -118,10 +120,11 @@ fn addition_step( r: &mut G2HomProjective, q: &G2Affine, ) -> EllCoeff> { + let (&qx, &qy) = q.xy().unwrap(); // Formula for line function when working with // homogeneous projective coordinates. - let theta = r.y - &(q.y * &r.z); - let lambda = r.x - &(q.x * &r.z); + let theta = r.y - &(qy * &r.z); + let lambda = r.x - &(qx * &r.z); let c = theta.square(); let d = lambda.square(); let e = lambda * &d; @@ -131,7 +134,7 @@ fn addition_step( r.x = lambda * &h; r.y = theta * &(g - &h) - &(e * &r.y); r.z *= &e; - let j = theta * &q.x - &(lambda * &q.y); + let j = theta * &qx - &(lambda * &qy); match B::TWIST_TYPE { TwistType::M => (j, -theta, lambda), diff --git a/ec/src/models/bls12/mod.rs b/ec/src/models/bls12/mod.rs index f580ec440..1ad90d72b 100644 --- a/ec/src/models/bls12/mod.rs +++ b/ec/src/models/bls12/mod.rs @@ -1,6 +1,6 @@ use crate::{ models::{short_weierstrass::SWCurveConfig, CurveConfig}, - PairingEngine, + AffineCurve, PairingEngine, }; use ark_ff::fields::{ fp12_2over3over2::{Fp12, Fp12Config}, @@ -62,16 +62,17 @@ impl Bls12

{ let mut c0 = coeffs.0; let mut c1 = coeffs.1; let mut c2 = coeffs.2; + let (px, py) = p.xy().unwrap(); match P::TWIST_TYPE { TwistType::M => { - c2.mul_assign_by_fp(&p.y); - c1.mul_assign_by_fp(&p.x); + c2.mul_assign_by_fp(py); + c1.mul_assign_by_fp(px); f.mul_by_014(&c0, &c1, &c2); }, TwistType::D => { - c0.mul_assign_by_fp(&p.y); - c1.mul_assign_by_fp(&p.x); + c0.mul_assign_by_fp(py); + c1.mul_assign_by_fp(px); f.mul_by_034(&c0, &c1, &c2); }, } diff --git a/ec/src/models/bn/g2.rs b/ec/src/models/bn/g2.rs index 8684ff1f1..7c3a487fd 100644 --- a/ec/src/models/bn/g2.rs +++ b/ec/src/models/bn/g2.rs @@ -51,56 +51,58 @@ impl Default for G2Prepared

{ impl From> for G2Prepared

{ fn from(q: G2Affine

) -> Self { let two_inv = P::Fp::one().double().inverse().unwrap(); - if q.is_zero() { - return Self { + match q.is_zero() { + true => G2Prepared { ell_coeffs: vec![], infinity: true, - }; - } - - let mut ell_coeffs = vec![]; - let mut r = G2HomProjective { - x: q.x, - y: q.y, - z: Fp2::one(), - }; - - let negq = -q; - - for i in (1..P::ATE_LOOP_COUNT.len()).rev() { - ell_coeffs.push(doubling_step::

(&mut r, &two_inv)); - - let bit = P::ATE_LOOP_COUNT[i - 1]; - - match bit { - 1 => { - ell_coeffs.push(addition_step::

(&mut r, &q)); - }, - -1 => { - ell_coeffs.push(addition_step::

(&mut r, &negq)); - }, - _ => continue, - } - } - - let q1 = mul_by_char::

(q); - let mut q2 = mul_by_char::

(q1); - - if P::X_IS_NEGATIVE { - r.y = -r.y; - } - - q2.y = -q2.y; - - ell_coeffs.push(addition_step::

(&mut r, &q1)); - ell_coeffs.push(addition_step::

(&mut r, &q2)); - - Self { - ell_coeffs, - infinity: false, + }, + false => { + let mut ell_coeffs = vec![]; + let mut r = G2HomProjective { + x: q.x, + y: q.y, + z: Fp2::one(), + }; + + let negq = -q; + + for i in (1..P::ATE_LOOP_COUNT.len()).rev() { + ell_coeffs.push(doubling_step::

(&mut r, &two_inv)); + + let bit = P::ATE_LOOP_COUNT[i - 1]; + + match bit { + 1 => { + ell_coeffs.push(addition_step::

(&mut r, &q)); + }, + -1 => { + ell_coeffs.push(addition_step::

(&mut r, &negq)); + }, + _ => continue, + } + } + + let q1 = mul_by_char::

(q); + let mut q2 = mul_by_char::

(q1); + + if P::X_IS_NEGATIVE { + r.y = -r.y; + } + + q2.y = -q2.y; + + ell_coeffs.push(addition_step::

(&mut r, &q1)); + ell_coeffs.push(addition_step::

(&mut r, &q2)); + + Self { + ell_coeffs, + infinity: false, + } + }, } } } + impl G2Prepared

{ pub fn is_zero(&self) -> bool { self.infinity diff --git a/ec/src/models/short_weierstrass.rs b/ec/src/models/short_weierstrass.rs index a697338a4..6297cca27 100644 --- a/ec/src/models/short_weierstrass.rs +++ b/ec/src/models/short_weierstrass.rs @@ -36,8 +36,8 @@ pub trait SWCurveConfig: super::CurveConfig { const COEFF_A: Self::BaseField; /// Coefficient `b` of the curve equation. const COEFF_B: Self::BaseField; - /// Coefficients of the base point of the curve - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField); + /// Generator of the prime-order subgroup. + const GENERATOR: Affine; /// Helper method for computing `elem * Self::COEFF_A`. /// @@ -126,14 +126,12 @@ pub trait SWCurveConfig: super::CurveConfig { Hash(bound = "P: SWCurveConfig") )] #[must_use] -// DISCUSS these shouldn't be public and instead we should have functions -// encapsulating the attributes pub struct Affine { - /// X coordinate of the point represented as a field element + #[doc(hidden)] pub x: P::BaseField, - /// Y coordinate of the point represented as a field element + #[doc(hidden)] pub y: P::BaseField, - /// Flag determining if the point is in infinity + #[doc(hidden)] pub infinity: bool, } @@ -151,20 +149,47 @@ impl PartialEq> for Projective

{ impl Display for Affine

{ fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - if self.infinity { - write!(f, "Affine(Infinity)") - } else { - write!(f, "Affine(x={}, y={})", self.x, self.y) + match self.infinity { + true => write!(f, "infinity"), + false => write!(f, "({}, {})", self.x, self.y), } } } impl Affine

{ - // DISCUSS The function shouldn't take infinity as parameter but instead accept - // only `(x,y)` so we have another const function `Affine::infinity` - // that takes no parameters - pub fn new(x: P::BaseField, y: P::BaseField, infinity: bool) -> Self { - Self { x, y, infinity } + /// Constructs a group element from x and y coordinates. + /// Performs checks to ensure that the point is on the curve and is in the right subgroup. + pub fn new(x: P::BaseField, y: P::BaseField) -> Self { + let point = Self { + x, + y, + infinity: false, + }; + assert!(point.is_on_curve()); + assert!(point.is_in_correct_subgroup_assuming_on_curve()); + point + } + + /// Constructs a group element from x and y coordinates. + /// + /// # Warning + /// + /// Does *not* perform any checks to ensure the point is in the curve or + /// is in the right subgroup. + pub const fn new_unchecked(x: P::BaseField, y: P::BaseField) -> Self { + Self { + x, + y, + infinity: false, + } + } + + pub const fn identity() -> Self { + Self { + x: P::BaseField::ZERO, + y: P::BaseField::ZERO, + infinity: true, + } } /// Attempts to construct an affine point given an x-coordinate. The @@ -186,24 +211,21 @@ impl Affine

{ let negy = -y; let y = if (y < negy) ^ greatest { y } else { negy }; - Self::new(x, y, false) + Self::new_unchecked(x, y) }) } /// Checks if `self` is a valid point on the curve. pub fn is_on_curve(&self) -> bool { - if self.is_zero() { - true - } else { - // Check that the point is on the curve - let y2 = self.y.square(); + if !self.infinity { // Rust does not optimise away addition with zero - let x3b = if P::COEFF_A.is_zero() { - P::add_b(&(self.x.square() * &self.x)) - } else { - P::add_b(&((self.x.square() * &self.x) + &P::mul_by_a(&self.x))) + let mut x3b = P::add_b(&(self.x.square() * self.x)); + if !P::COEFF_A.is_zero() { + x3b += &P::mul_by_a(&self.x); }; - y2 == x3b + self.y.square() == x3b + } else { + true } } } @@ -233,13 +255,13 @@ impl Zero for Affine

{ /// by setting the `infinity` flag to true. #[inline] fn zero() -> Self { - Self::new(P::BaseField::zero(), P::BaseField::one(), true) + Self::identity() } /// Checks if `self` is the point at infinity. #[inline] fn is_zero(&self) -> bool { - self.infinity + self == &Self::zero() } } @@ -280,16 +302,13 @@ impl AffineCurve for Affine

{ type ScalarField = P::ScalarField; type Projective = Projective

; - fn xy(&self) -> (Self::BaseField, Self::BaseField) { - (self.x, self.y) + fn xy(&self) -> Option<(&Self::BaseField, &Self::BaseField)> { + (!self.infinity).then(|| (&self.x, &self.y)) } + #[inline] fn prime_subgroup_generator() -> Self { - Self::new( - P::AFFINE_GENERATOR_COEFFS.0, - P::AFFINE_GENERATOR_COEFFS.1, - false, - ) + P::GENERATOR } fn from_random_bytes(bytes: &[u8]) -> Option { @@ -321,7 +340,6 @@ impl AffineCurve for Affine

{ /// Performs cofactor clearing. /// The default method is simply to multiply by the cofactor. /// Some curves can implement a more efficient algorithm. - #[must_use] fn clear_cofactor(&self) -> Self { P::clear_cofactor(self) } @@ -333,12 +351,9 @@ impl Neg for Affine

{ /// If `self.is_zero()`, returns `self` (`== Self::zero()`). /// Else, returns `(x, -y)`, where `self = (x, y)`. #[inline] - fn neg(self) -> Self { - if !self.is_zero() { - Self::new(self.x, -self.y, false) - } else { - self - } + fn neg(mut self) -> Self { + self.y = -self.y; + self } } @@ -441,9 +456,20 @@ impl Default for Projective

{ } impl Projective

{ - pub fn new(x: P::BaseField, y: P::BaseField, z: P::BaseField) -> Self { + /// Construct a new group element without checking whether the coordinates + /// specify a point in the subgroup. + pub const fn new_unchecked(x: P::BaseField, y: P::BaseField, z: P::BaseField) -> Self { Self { x, y, z } } + + /// Construct a new group element in a way while enforcing that points are in + /// the prime-order subgroup. + pub fn new(x: P::BaseField, y: P::BaseField, z: P::BaseField) -> Self { + let p = Self::new_unchecked(x, y, z).into_affine(); + assert!(p.is_on_curve()); + assert!(p.is_in_correct_subgroup_assuming_on_curve()); + p.into() + } } impl Zeroize for Projective

{ @@ -458,7 +484,7 @@ impl Zero for Projective

{ /// Returns the point at infinity, which always has Z = 0. #[inline] fn zero() -> Self { - Self::new( + Self::new_unchecked( P::BaseField::one(), P::BaseField::one(), P::BaseField::zero(), @@ -594,69 +620,70 @@ impl ProjectiveCurve for Projective

{ /// efficient [formula](http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl) /// to compute `self + other`. fn add_assign_mixed(&mut self, other: &Affine

) { - if other.is_zero() { - return; - } - - if self.is_zero() { - self.x = other.x; - self.y = other.y; - self.z = P::BaseField::one(); - return; - } - - // Z1Z1 = Z1^2 - let z1z1 = self.z.square(); - - // U2 = X2*Z1Z1 - let u2 = other.x * &z1z1; - - // S2 = Y2*Z1*Z1Z1 - let s2 = (other.y * &self.z) * &z1z1; - - if self.x == u2 && self.y == s2 { - // The two points are equal, so we double. - self.double_in_place(); - } else { - // If we're adding -a and a together, self.z becomes zero as H becomes zero. - - // H = U2-X1 - let h = u2 - &self.x; - - // HH = H^2 - let hh = h.square(); - - // I = 4*HH - let mut i = hh; - i.double_in_place().double_in_place(); - - // J = H*I - let mut j = h * &i; - - // r = 2*(S2-Y1) - let r = (s2 - &self.y).double(); - - // V = X1*I - let v = self.x * &i; - - // X3 = r^2 - J - 2*V - self.x = r.square(); - self.x -= &j; - self.x -= &v; - self.x -= &v; - - // Y3 = r*(V-X3)-2*Y1*J - j *= &self.y; // J = 2*Y1*J - j.double_in_place(); - self.y = v - &self.x; - self.y *= &r; - self.y -= &j; - - // Z3 = (Z1+H)^2-Z1Z1-HH - self.z += &h; - self.z.square_in_place(); - self.z -= &z1z1; - self.z -= &hh; + match other.is_zero() { + true => {}, + false => { + if self.is_zero() { + self.x = other.x; + self.y = other.y; + self.z = P::BaseField::one(); + return; + } + + // Z1Z1 = Z1^2 + let z1z1 = self.z.square(); + + // U2 = X2*Z1Z1 + let u2 = z1z1 * other.x; + + // S2 = Y2*Z1*Z1Z1 + let s2 = (self.z * other.y) * &z1z1; + + if self.x == u2 && self.y == s2 { + // The two points are equal, so we double. + self.double_in_place(); + } else { + // If we're adding -a and a together, self.z becomes zero as H becomes zero. + + // H = U2-X1 + let h = u2 - &self.x; + + // HH = H^2 + let hh = h.square(); + + // I = 4*HH + let mut i = hh; + i.double_in_place().double_in_place(); + + // J = H*I + let mut j = h * &i; + + // r = 2*(S2-Y1) + let r = (s2 - &self.y).double(); + + // V = X1*I + let v = self.x * &i; + + // X3 = r^2 - J - 2*V + self.x = r.square(); + self.x -= &j; + self.x -= &v; + self.x -= &v; + + // Y3 = r*(V-X3)-2*Y1*J + j *= &self.y; // J = 2*Y1*J + j.double_in_place(); + self.y = v - &self.x; + self.y *= &r; + self.y -= &j; + + // Z3 = (Z1+H)^2-Z1Z1-HH + self.z += &h; + self.z.square_in_place(); + self.z -= &z1z1; + self.z -= &hh; + } + }, } } @@ -670,12 +697,9 @@ impl Neg for Projective

{ type Output = Self; #[inline] - fn neg(self) -> Self { - if !self.is_zero() { - Self::new(self.x, -self.y, self.z) - } else { - self - } + fn neg(mut self) -> Self { + self.y = -self.y; + self } } @@ -783,10 +807,13 @@ impl MulAssign for Projective

{ impl From> for Projective

{ #[inline] fn from(p: Affine

) -> Projective

{ - if p.is_zero() { - Self::zero() - } else { - Self::new(p.x, p.y, P::BaseField::one()) + match p.infinity { + true => Self::zero(), + false => Self { + x: p.x, + y: p.y, + z: P::BaseField::one(), + }, } } } @@ -800,7 +827,7 @@ impl From> for Affine

{ Affine::zero() } else if p.z.is_one() { // If Z is one, the point is already normalized. - Affine::new(p.x, p.y, false) + Affine::new_unchecked(p.x, p.y) } else { // Z is nonzero, so it must have an inverse in a field. let zinv = p.z.inverse().unwrap(); @@ -812,7 +839,7 @@ impl From> for Affine

{ // Y/Z^3 let y = p.y * &(zinv_squared * &zinv); - Affine::new(x, y, false) + Affine::new_unchecked(x, y) } } } @@ -821,14 +848,11 @@ impl CanonicalSerialize for Affine

{ #[allow(unused_qualifications)] #[inline] fn serialize(&self, writer: W) -> Result<(), SerializationError> { - if self.is_zero() { - let flags = SWFlags::infinity(); - // Serialize 0. - P::BaseField::zero().serialize_with_flags(writer, flags) - } else { - let flags = SWFlags::from_y_sign(self.y > -self.y); - self.x.serialize_with_flags(writer, flags) - } + let (x, flags) = match self.infinity { + true => (P::BaseField::zero(), SWFlags::infinity()), + false => (self.x, SWFlags::from_y_sign(self.y > -self.y)), + }; + x.serialize_with_flags(writer, flags) } #[inline] @@ -839,19 +863,25 @@ impl CanonicalSerialize for Affine

{ #[allow(unused_qualifications)] #[inline] fn serialize_uncompressed(&self, mut writer: W) -> Result<(), SerializationError> { - let flags = if self.is_zero() { - SWFlags::infinity() - } else { - SWFlags::default() + let (x, y, flags) = match self.infinity { + true => ( + P::BaseField::zero(), + P::BaseField::zero(), + SWFlags::infinity(), + ), + false => (self.x, self.y, SWFlags::from_y_sign(self.y > -self.y)), }; - self.x.serialize(&mut writer)?; - self.y.serialize_with_flags(&mut writer, flags)?; + x.serialize(&mut writer)?; + y.serialize_with_flags(&mut writer, flags)?; Ok(()) } #[inline] fn uncompressed_size(&self) -> usize { - self.x.serialized_size() + self.y.serialized_size_with_flags::() + // The size of the serialization is independent of the values + // of `x` and `y`, and depends only on the size of the modulus. + P::BaseField::zero().serialized_size() + + P::BaseField::zero().serialized_size_with_flags::() } } @@ -917,8 +947,10 @@ impl CanonicalDeserialize for Affine

{ let x: P::BaseField = CanonicalDeserialize::deserialize(&mut reader)?; let (y, flags): (P::BaseField, SWFlags) = CanonicalDeserializeWithFlags::deserialize_with_flags(&mut reader)?; - let p = Affine::

::new(x, y, flags.is_infinity()); - Ok(p) + match flags.is_infinity() { + true => Ok(Self::zero()), + false => Ok(Self::new_unchecked(x, y)), + } } } @@ -948,12 +980,12 @@ where { #[inline] fn to_field_elements(&self) -> Option> { - let mut x_fe = self.x.to_field_elements()?; - let y_fe = self.y.to_field_elements()?; - let infinity_fe = self.infinity.to_field_elements()?; - x_fe.extend_from_slice(&y_fe); - x_fe.extend_from_slice(&infinity_fe); - Some(x_fe) + let mut x = self.x.to_field_elements()?; + let y = self.y.to_field_elements()?; + let infinity = self.infinity.to_field_elements()?; + x.extend_from_slice(&y); + x.extend_from_slice(&infinity); + Some(x) } } diff --git a/ec/src/models/twisted_edwards.rs b/ec/src/models/twisted_edwards.rs index 0767f27f8..27ed607c9 100644 --- a/ec/src/models/twisted_edwards.rs +++ b/ec/src/models/twisted_edwards.rs @@ -33,8 +33,8 @@ pub trait TECurveConfig: super::CurveConfig { const COEFF_A: Self::BaseField; /// Coefficient `d` of the curve equation. const COEFF_D: Self::BaseField; - /// Coefficients of the base point of the curve - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField); + /// Generator of the prime-order subgroup. + const GENERATOR: Affine; /// Model parameters for the Montgomery curve that is birationally /// equivalent to this curve. @@ -135,10 +135,21 @@ impl Display for Affine

{ } impl Affine

{ - pub fn new(x: P::BaseField, y: P::BaseField) -> Self { + /// Construct a new group element without checking whether the coordinates + /// specify a point in the subgroup. + pub const fn new_unchecked(x: P::BaseField, y: P::BaseField) -> Self { Self { x, y } } + /// Construct a new group element in a way while enforcing that points are in + /// the prime-order subgroup. + pub fn new(x: P::BaseField, y: P::BaseField) -> Self { + let p = Self::new_unchecked(x, y); + assert!(p.is_on_curve()); + assert!(p.is_in_correct_subgroup_assuming_on_curve()); + p + } + /// Attempts to construct an affine point given an y-coordinate. The /// point is not guaranteed to be in the prime order subgroup. /// @@ -163,7 +174,7 @@ impl Affine

{ .map(|x| { let negx = -x; let x = if (x < negx) ^ greatest { x } else { negx }; - Self::new(x, y) + Self::new_unchecked(x, y) }) } @@ -189,7 +200,7 @@ impl Affine

{ impl Zero for Affine

{ fn zero() -> Self { - Self::new(P::BaseField::zero(), P::BaseField::one()) + Self::new_unchecked(P::BaseField::zero(), P::BaseField::one()) } fn is_zero(&self) -> bool { @@ -203,11 +214,12 @@ impl AffineCurve for Affine

{ type ScalarField = P::ScalarField; type Projective = Projective

; - fn xy(&self) -> (Self::BaseField, Self::BaseField) { - (self.x, self.y) + fn xy(&self) -> Option<(&Self::BaseField, &Self::BaseField)> { + (!self.is_zero()).then(|| (&self.x, &self.y)) } + fn prime_subgroup_generator() -> Self { - Self::new(P::AFFINE_GENERATOR_COEFFS.0, P::AFFINE_GENERATOR_COEFFS.1) + P::GENERATOR } fn from_random_bytes(bytes: &[u8]) -> Option { @@ -236,7 +248,6 @@ impl AffineCurve for Affine

{ /// Performs cofactor clearing. /// The default method is simply to multiply by the cofactor. /// Some curves can implement a more efficient algorithm. - #[must_use] fn clear_cofactor(&self) -> Self { P::clear_cofactor(self) } @@ -255,7 +266,7 @@ impl Neg for Affine

{ type Output = Self; fn neg(self) -> Self { - Self::new(-self.x, self.y) + Self::new_unchecked(-self.x, self.y) } } @@ -412,9 +423,25 @@ impl Default for Projective

{ } impl Projective

{ - pub fn new(x: P::BaseField, y: P::BaseField, t: P::BaseField, z: P::BaseField) -> Self { + /// Construct a new group element without checking whether the coordinates + /// specify a point in the subgroup. + pub const fn new_unchecked( + x: P::BaseField, + y: P::BaseField, + t: P::BaseField, + z: P::BaseField, + ) -> Self { Self { x, y, t, z } } + + /// Construct a new group element in a way while enforcing that points are in + /// the prime-order subgroup. + pub fn new(x: P::BaseField, y: P::BaseField, t: P::BaseField, z: P::BaseField) -> Self { + let p = Self::new_unchecked(x, y, t, z).into_affine(); + assert!(p.is_on_curve()); + assert!(p.is_in_correct_subgroup_assuming_on_curve()); + p.into() + } } impl Zeroize for Projective

{ // The phantom data does not contain element-specific data @@ -429,7 +456,7 @@ impl Zeroize for Projective

{ impl Zero for Projective

{ fn zero() -> Self { - Self::new( + Self::new_unchecked( P::BaseField::zero(), P::BaseField::one(), P::BaseField::zero(), @@ -638,7 +665,7 @@ impl MulAssign for Projective

{ // with Z = 1. impl From> for Projective

{ fn from(p: Affine

) -> Projective

{ - Self::new(p.x, p.y, p.x * &p.y, P::BaseField::one()) + Self::new_unchecked(p.x, p.y, p.x * &p.y, P::BaseField::one()) } } @@ -650,13 +677,13 @@ impl From> for Affine

{ Affine::zero() } else if p.z.is_one() { // If Z is one, the point is already normalized. - Affine::new(p.x, p.y) + Affine::new_unchecked(p.x, p.y) } else { // Z is nonzero, so it must have an inverse in a field. let z_inv = p.z.inverse().unwrap(); let x = p.x * &z_inv; let y = p.y * &z_inv; - Affine::new(x, y) + Affine::new_unchecked(x, y) } } } @@ -687,7 +714,7 @@ where if point.len() != 2 { return Err(()); } - let point = Self::new(point[0], point[1]); + let point = Self::new_unchecked(point[0], point[1]); if !point.is_on_curve() { Err(()) @@ -817,7 +844,7 @@ impl CanonicalDeserialize for Affine

{ let x: P::BaseField = CanonicalDeserialize::deserialize(&mut reader)?; let y: P::BaseField = CanonicalDeserialize::deserialize(&mut reader)?; - let p = Affine::

::new(x, y); + let p = Affine::

::new_unchecked(x, y); Ok(p) } } @@ -889,7 +916,7 @@ impl Affine

{ y2.and_then(|y2| y2.sqrt()).map(|y| { let negy = -y; let y = if (y < negy) ^ greatest { y } else { negy }; - Self::new(x, y) + Self::new_unchecked(x, y) }) } /// This method is implemented for backwards compatibility with the old diff --git a/ff-macros/src/lib.rs b/ff-macros/src/lib.rs index 8fb8fdaab..1e95a12d3 100644 --- a/ff-macros/src/lib.rs +++ b/ff-macros/src/lib.rs @@ -65,9 +65,11 @@ pub fn to_sign_and_limbs(input: TokenStream) -> TokenStream { /// /// The attributes available to this macro are /// * `modulus`: Specify the prime modulus underlying this prime field. -/// * `generator`: Specify the generator of the multiplicative subgroup of this prime field. This value must be a quadratic non-residue in the field. -/// * `small_subgroup_base` and `small_subgroup_power` (optional): If the field has insufficient two-adicity, specify an additional subgroup of size `small_subgroup_base.pow(small_subgroup_power)`. -// +/// * `generator`: Specify the generator of the multiplicative subgroup of this +/// prime field. This value must be a quadratic non-residue in the field. +/// * `small_subgroup_base` and `small_subgroup_power` (optional): If the field +/// has insufficient two-adicity, specify an additional subgroup of size +/// `small_subgroup_base.pow(small_subgroup_power)`. // This code was adapted from the `PrimeField` Derive Macro in ff-derive. #[proc_macro_derive( MontConfig, @@ -83,8 +85,8 @@ pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream { .parse() .expect("Modulus should be a number"); - // We may be provided with a generator of p - 1 order. It is required that this generator be quadratic - // nonresidue. + // We may be provided with a generator of p - 1 order. It is required that this + // generator be quadratic nonresidue. let generator: BigUint = fetch_attr("generator", &ast.attrs) .expect("Please supply a generator attribute") .parse() @@ -96,8 +98,8 @@ pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let small_subgroup_power: Option = fetch_attr("small_subgroup_power", &ast.attrs) .map(|s| s.parse().expect("small_subgroup_power should be a number")); - // The arithmetic in this library only works if the modulus*2 is smaller than the backing - // representation. Compute the number of limbs we need. + // The arithmetic in this library only works if the modulus*2 is smaller than + // the backing representation. Compute the number of limbs we need. let mut limbs = 1usize; { let mod2 = (&modulus) << 1; // modulus * 2 @@ -118,7 +120,7 @@ pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let remaining_subgroup_size = match (small_subgroup_base, small_subgroup_power) { (Some(base), Some(power)) => Some(&trace / BigUint::from(base).pow(power)), (None, None) => None, - (_, _) => panic!("Must specify both `small_subgroup_base` and `small_subgroup_power`"), + (..) => panic!("Must specify both `small_subgroup_base` and `small_subgroup_power`"), }; let two_adic_root_of_unity = generator.modpow(&trace, &modulus); let large_subgroup_generator = remaining_subgroup_size @@ -135,15 +137,15 @@ pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream { const MODULUS: ark_ff::BigInt<#limbs> = ark_ff::BigInt!(#modulus); - const GENERATOR: ark_ff::fields::Fp, #limbs> = ark_ff::MontFp!(ark_ff::fields::Fp, #limbs>, #generator); + const GENERATOR: ark_ff::fields::Fp, #limbs> = ark_ff::MontFp!(#generator); - const TWO_ADIC_ROOT_OF_UNITY: ark_ff::fields::Fp, #limbs> = ark_ff::MontFp!(ark_ff::fields::Fp, #limbs>, #two_adic_root_of_unity); + const TWO_ADIC_ROOT_OF_UNITY: ark_ff::fields::Fp, #limbs> = ark_ff::MontFp!(#two_adic_root_of_unity); const SMALL_SUBGROUP_BASE: Option = Some(#small_subgroup_base); const SMALL_SUBGROUP_BASE_ADICITY: Option = Some(#small_subgroup_power); - const LARGE_SUBGROUP_ROOT_OF_UNITY: Option, #limbs>> = Some(ark_ff::MontFp!(ark_ff::fields::Fp, #limbs>, #large_subgroup_generator)); + const LARGE_SUBGROUP_ROOT_OF_UNITY: Option, #limbs>> = Some(ark_ff::MontFp!(#large_subgroup_generator)); } } } else { @@ -153,9 +155,9 @@ pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream { const MODULUS: ark_ff::BigInt<#limbs> = ark_ff::BigInt!(#modulus); - const GENERATOR: ark_ff::fields::Fp, #limbs> = ark_ff::MontFp!(ark_ff::fields::Fp, #limbs>, #generator); + const GENERATOR: ark_ff::fields::Fp, #limbs> = ark_ff::MontFp!(#generator); - const TWO_ADIC_ROOT_OF_UNITY: ark_ff::fields::Fp, #limbs> = ark_ff::MontFp!(ark_ff::fields::Fp, #limbs>, #two_adic_root_of_unity); + const TWO_ADIC_ROOT_OF_UNITY: ark_ff::fields::Fp, #limbs> = ark_ff::MontFp!(#two_adic_root_of_unity); } } }.into() diff --git a/ff/src/fields/mod.rs b/ff/src/fields/mod.rs index 3e11ea16c..2479cbb38 100644 --- a/ff/src/fields/mod.rs +++ b/ff/src/fields/mod.rs @@ -132,6 +132,11 @@ pub trait Field: type BasePrimeField: PrimeField; type BasePrimeFieldIter: Iterator; + /// The additive identity of the field. + const ZERO: Self; + /// The multiplicative identity of the field. + const ONE: Self; + /// Returns the characteristic of the field, /// in little-endian representation. fn characteristic() -> &'static [u64] { diff --git a/ff/src/fields/models/cubic_extension.rs b/ff/src/fields/models/cubic_extension.rs index 41e893f31..9c9b70f72 100644 --- a/ff/src/fields/models/cubic_extension.rs +++ b/ff/src/fields/models/cubic_extension.rs @@ -82,28 +82,6 @@ pub struct CubicExtField { pub c2: P::BaseField, } -/// Construct a [`CubicExtField`] element from elements of the base field. This should -/// be used primarily for constructing constant field elements; in a non-const -/// context, [`CubicExtField::new`] is preferable. -/// -/// # Usage -/// ```rust -/// # use ark_test_curves::CubicExt; -/// # use ark_test_curves::mnt6_753 as ark_mnt6_753; -/// use ark_mnt6_753::{FQ_ZERO, FQ_ONE, Fq3}; -/// const ONE: Fq3 = CubicExt!(FQ_ONE, FQ_ZERO, FQ_ZERO); -/// ``` -#[macro_export] -macro_rules! CubicExt { - ($c0:expr, $c1:expr, $c2:expr $(,)?) => { - $crate::CubicExtField { - c0: $c0, - c1: $c1, - c2: $c2, - } - }; -} - impl CubicExtField

{ /// Create a new field element from coefficients `c0`, `c1` and `c2` /// so that the result is of the form `c0 + c1 * X + c2 * X^2`. @@ -125,7 +103,7 @@ impl CubicExtField

{ /// // `Fp6` a degree-3 extension over `Fp2`. /// let c: CubicExtField = Fp6::new(c0, c1, c2); /// ``` - pub fn new(c0: P::BaseField, c1: P::BaseField, c2: P::BaseField) -> Self { + pub const fn new(c0: P::BaseField, c1: P::BaseField, c2: P::BaseField) -> Self { Self { c0, c1, c2 } } @@ -186,6 +164,9 @@ type BaseFieldIter

= <

::BaseField as Field>::BasePrimeFi impl Field for CubicExtField

{ type BasePrimeField = P::BasePrimeField; type BasePrimeFieldIter = Chain, Chain, BaseFieldIter

>>; + const ZERO: Self = Self::new(P::BaseField::ZERO, P::BaseField::ZERO, P::BaseField::ZERO); + + const ONE: Self = Self::new(P::BaseField::ONE, P::BaseField::ZERO, P::BaseField::ZERO); fn extension_degree() -> u64 { 3 * P::BaseField::extension_degree() diff --git a/ff/src/fields/models/fp/mod.rs b/ff/src/fields/models/fp/mod.rs index 319c29e24..b4993578a 100644 --- a/ff/src/fields/models/fp/mod.rs +++ b/ff/src/fields/models/fp/mod.rs @@ -139,11 +139,13 @@ pub trait FpConfig: Send + Sync + 'static + Sized { } } - /// Construct a field element from an integer in the range `0..(Self::MODULUS - 1)`. - /// Returns `None` if the integer is outside this range. + /// Construct a field element from an integer in the range + /// `0..(Self::MODULUS - 1)`. Returns `None` if the integer is outside + /// this range. fn from_bigint(other: BigInt) -> Option>; - /// Convert a field element to an integer in the range `0..(Self::MODULUS - 1)`. + /// Convert a field element to an integer in the range `0..(Self::MODULUS - + /// 1)`. fn into_bigint(other: Fp) -> BigInt; } @@ -179,15 +181,6 @@ pub type Fp704

= Fp; pub type Fp768

= Fp; pub type Fp832

= Fp; -impl Fp { - /// Construct a new prime element directly from its underlying - /// [`struct@BigInt`] data type. - #[inline] - pub const fn new(element: BigInt) -> Self { - Self(element, PhantomData) - } -} - impl, const N: usize> Fp { #[inline(always)] pub(crate) fn is_less_than_modulus(&self) -> bool { @@ -240,6 +233,9 @@ impl, const N: usize> Field for Fp { type BasePrimeField = Self; type BasePrimeFieldIter = iter::Once; + const ZERO: Self = P::ZERO; + const ONE: Self = P::ONE; + fn extension_degree() -> u64 { 1 } @@ -418,9 +414,9 @@ impl, const N: usize> Ord for Fp { } } -/// Note that this implementation of `PartialOrd` compares field elements viewing -/// them as integers in the range 0, 1, ..., `P::MODULUS` - 1. However, other -/// implementations of `PrimeField` might choose a different ordering, and +/// Note that this implementation of `PartialOrd` compares field elements +/// viewing them as integers in the range 0, 1, ..., `P::MODULUS` - 1. However, +/// other implementations of `PrimeField` might choose a different ordering, and /// as such, users should use this `PartialOrd` for applications where /// any ordering suffices (like in a BTreeMap), and not in applications /// where a particular ordering is required. @@ -557,7 +553,10 @@ impl, const N: usize> ark_std::rand::distributions::Distribution< #[inline] fn sample(&self, rng: &mut R) -> Fp { loop { - let mut tmp = Fp::new(rng.sample(ark_std::rand::distributions::Standard)); + let mut tmp = Fp( + rng.sample(ark_std::rand::distributions::Standard), + PhantomData, + ); let shave_bits = Fp::::num_bits_to_shave(); // Mask away the unused bits at the beginning. assert!(shave_bits <= 64); @@ -725,7 +724,7 @@ impl, const N: usize> Neg for Fp { if !self.is_zero() { let mut tmp = P::MODULUS; tmp.sub_with_borrow(&self.0); - Fp::new(tmp) + Fp(tmp, PhantomData) } else { self } diff --git a/ff/src/fields/models/fp/montgomery_backend.rs b/ff/src/fields/models/fp/montgomery_backend.rs index f51cbfedb..d339676a8 100644 --- a/ff/src/fields/models/fp/montgomery_backend.rs +++ b/ff/src/fields/models/fp/montgomery_backend.rs @@ -9,8 +9,8 @@ use ark_ff_macros::unroll_for_loops; /// /// # Note /// Manual implementation of this trait is not recommended unless one wishes -/// to specialize arithmetic methods. Instead, the [`MontConfig`][`ark_ff_macros::MontConfig`] -/// derive macro should be used. +/// to specialize arithmetic methods. Instead, the +/// [`MontConfig`][`ark_ff_macros::MontConfig`] derive macro should be used. pub trait MontConfig: 'static + Sync + Send + Sized { /// The modulus of the field. const MODULUS: BigInt; @@ -130,7 +130,7 @@ pub trait MontConfig: 'static + Sync + Send + Sized { } } else { // Alternative implementation - *a = a.mul_without_reduce(b, &Self::MODULUS, Self::INV); + *a = a.mul_without_reduce(b); } a.subtract_modulus(); } @@ -221,7 +221,7 @@ pub trait MontConfig: 'static + Sync + Send + Sized { let mut u = a.0; let mut v = Self::MODULUS; - let mut b = Fp::new(Self::R2); // Avoids unnecessary reduction step. + let mut b = Fp::new_unchecked(Self::R2); // Avoids unnecessary reduction step. let mut c = Fp::zero(); while u != one && v != one { @@ -265,11 +265,11 @@ pub trait MontConfig: 'static + Sync + Send + Sized { } fn from_bigint(r: BigInt) -> Option, N>> { - let mut r = Fp::new(r); + let mut r = Fp::new_unchecked(r); if r.is_zero() { Some(r) } else if r.is_less_than_modulus() { - r *= &Fp::new(Self::R2); + r *= &Fp::new_unchecked(Self::R2); Some(r) } else { None @@ -321,9 +321,10 @@ pub const fn can_use_no_carry_optimization(modulus: &BigInt) !(first_bit_set || all_bits_set) } -/// Construct a [`Fp, N>`] element from a literal string. This should -/// be used primarily for constructing constant field elements; in a non-const -/// context, [`Fp::from_str`](`ark_std::str::FromStr::from_str`) is preferable. +/// Construct a [`Fp, N>`] element from a literal string. This +/// should be used primarily for constructing constant field elements; in a +/// non-const context, [`Fp::from_str`](`ark_std::str::FromStr::from_str`) is +/// preferable. /// /// # Panics /// @@ -339,8 +340,8 @@ pub const fn can_use_no_carry_optimization(modulus: &BigInt) /// # use ark_test_curves::bls12_381 as ark_bls12_381; /// # use ark_std::str::FromStr; /// use ark_bls12_381::Fq; -/// const ONE: Fq = MontFp!(Fq, "1"); -/// const NEG_ONE: Fq = MontFp!(Fq, "-1"); +/// const ONE: Fq = MontFp!("1"); +/// const NEG_ONE: Fq = MontFp!("-1"); /// /// fn check_correctness() { /// assert_eq!(ONE, Fq::one()); @@ -350,15 +351,9 @@ pub const fn can_use_no_carry_optimization(modulus: &BigInt) /// ``` #[macro_export] macro_rules! MontFp { - ($name:ty, $c0:expr) => {{ - use $crate::PrimeField; + ($c0:expr) => {{ let (is_positive, limbs) = $crate::ark_ff_macros::to_sign_and_limbs!($c0); - $crate::Fp::const_from_str( - &limbs, - is_positive, - <$name>::R2, - &<$name as PrimeField>::MODULUS, - ) + $crate::Fp::from_sign_and_limbs(is_positive, &limbs) }}; } @@ -366,7 +361,7 @@ pub use ark_ff_macros::MontConfig; pub use MontFp; -pub struct MontBackend(PhantomData); +pub struct MontBackend, const N: usize>(PhantomData); impl, const N: usize> FpConfig for MontBackend { /// The modulus of the field. @@ -379,11 +374,11 @@ impl, const N: usize> FpConfig for MontBackend { /// Additive identity of the field, i.e. the element `e` /// such that, for all elements `f` of the field, `e + f = f`. - const ZERO: Fp = Fp::new(BigInt([0u64; N])); + const ZERO: Fp = Fp::new_unchecked(BigInt([0u64; N])); /// Multiplicative identity of the field, i.e. the element `e` /// such that, for all elements `f` of the field, `e * f = f`. - const ONE: Fp = Fp::new(T::R); + const ONE: Fp = Fp::new_unchecked(T::R); const TWO_ADICITY: u32 = Self::MODULUS.two_adic_valuation(); const TWO_ADIC_ROOT_OF_UNITY: Fp = T::TWO_ADIC_ROOT_OF_UNITY; @@ -435,60 +430,64 @@ impl, const N: usize> FpConfig for MontBackend { } } -impl Fp, N> { +impl, const N: usize> Fp, N> { + /// Construct a new field element from its underlying + /// [`struct@BigInt`] data type. + #[inline] + pub const fn new(element: BigInt) -> Self { + let mut r = Self(element, PhantomData); + if r.const_is_zero() { + r + } else { + r = r.mul(&Fp(T::R2, PhantomData)); + r + } + } + + /// Construct a new field element from its underlying + /// [`struct@BigInt`] data type. + /// + /// Unlike [`Self::new`], this method does not perform Montgomery reduction. + /// Thus, this method should be used only when constructing + /// an element from an integer that has already been put in + /// Montgomery form. + #[inline] + pub const fn new_unchecked(element: BigInt) -> Self { + Self(element, PhantomData) + } + const fn const_is_zero(&self) -> bool { self.0.const_is_zero() } #[doc(hidden)] - const fn const_neg(self, modulus: &BigInt) -> Self { + const fn const_neg(self) -> Self { if !self.const_is_zero() { - Self::new(Self::sub_with_borrow(modulus, &self.0)) + Self::new_unchecked(Self::sub_with_borrow(&T::MODULUS, &self.0)) } else { self } } - /// Interpret a string of decimal numbers as a prime field element. - /// Does not accept unnecessary leading zeroes or a blank string. + /// Interpret a set of limbs (along with a sign) as a field element. /// For *internal* use only; please use the `ark_ff::MontFp` macro instead /// of this method #[doc(hidden)] - pub const fn const_from_str( - limbs: &[u64], - is_positive: bool, - r2: BigInt, - modulus: &BigInt, - ) -> Self { + pub const fn from_sign_and_limbs(is_positive: bool, limbs: &[u64]) -> Self { let mut repr = BigInt::([0; N]); - assert!(repr.0.len() == N); + assert!(limbs.len() <= N); crate::const_for!((i in 0..(limbs.len())) { repr.0[i] = limbs[i]; }); - let res = Self::const_from_bigint(repr, r2, modulus); + let res = Self::new(repr); if is_positive { res } else { - res.const_neg(modulus) + res.const_neg() } } - #[inline] - pub(crate) const fn const_from_bigint( - repr: BigInt, - r2: BigInt, - modulus: &BigInt, - ) -> Self { - let mut r = Self::new(repr); - if r.const_is_zero() { - r - } else { - r = r.const_mul(&Fp(r2, PhantomData), modulus); - r - } - } - - const fn mul_without_reduce(mut self, other: &Self, modulus: &BigInt, inv: u64) -> Self { + const fn mul_without_reduce(mut self, other: &Self) -> Self { let (mut lo, mut hi) = ([0u64; N], [0u64; N]); crate::const_for!((i in 0..N) { let mut carry = 0; @@ -505,15 +504,15 @@ impl Fp, N> { // Montgomery reduction let mut carry2 = 0; crate::const_for!((i in 0..N) { - let tmp = lo[i].wrapping_mul(inv); + let tmp = lo[i].wrapping_mul(T::INV); let mut carry = 0; - mac_with_carry!(lo[i], tmp, modulus.0[0], &mut carry); + mac_with_carry!(lo[i], tmp, T::MODULUS.0[0], &mut carry); crate::const_for!((j in 1..N) { let k = i + j; if k >= N { - hi[k - N] = mac_with_carry!(hi[k - N], tmp, modulus.0[j], &mut carry); + hi[k - N] = mac_with_carry!(hi[k - N], tmp, T::MODULUS.0[j], &mut carry); } else { - lo[k] = mac_with_carry!(lo[k], tmp, modulus.0[j], &mut carry); + lo[k] = mac_with_carry!(lo[k], tmp, T::MODULUS.0[j], &mut carry); } }); hi[i] = adc!(hi[i], carry2, &mut carry); @@ -526,21 +525,16 @@ impl Fp, N> { self } - const fn const_mul_without_reduce(self, other: &Self, modulus: &BigInt) -> Self { - let inv = inv(modulus); - self.mul_without_reduce(other, modulus, inv) - } - - const fn const_mul(mut self, other: &Self, modulus: &BigInt) -> Self { - self = self.const_mul_without_reduce(other, modulus); - self.const_reduce(modulus) + const fn mul(mut self, other: &Self) -> Self { + self = self.mul_without_reduce(other); + self.const_reduce() } - const fn const_is_valid(&self, modulus: &BigInt) -> bool { + const fn const_is_valid(&self) -> bool { crate::const_for!((i in 0..N) { - if (self.0).0[(N - i - 1)] < modulus.0[(N - i - 1)] { + if (self.0).0[(N - i - 1)] < T::MODULUS.0[(N - i - 1)] { return true - } else if (self.0).0[(N - i - 1)] > modulus.0[(N - i - 1)] { + } else if (self.0).0[(N - i - 1)] > T::MODULUS.0[(N - i - 1)] { return false } }); @@ -548,9 +542,9 @@ impl Fp, N> { } #[inline] - const fn const_reduce(mut self, modulus: &BigInt) -> Self { - if !self.const_is_valid(modulus) { - self.0 = Self::sub_with_borrow(&self.0, modulus); + const fn const_reduce(mut self) -> Self { + if !self.const_is_valid() { + self.0 = Self::sub_with_borrow(&self.0, &T::MODULUS); } self } diff --git a/ff/src/fields/models/fp3.rs b/ff/src/fields/models/fp3.rs index d81ac0af9..91f75236b 100644 --- a/ff/src/fields/models/fp3.rs +++ b/ff/src/fields/models/fp3.rs @@ -69,8 +69,6 @@ impl Fp3

{ /// # Examples /// /// ``` - /// - /// # use ark_test_curves::CubicExt; /// # use ark_std::test_rng; /// # use ark_std::UniformRand; /// # use ark_test_curves::mnt6_753 as ark_mnt6_753; diff --git a/ff/src/fields/models/quadratic_extension.rs b/ff/src/fields/models/quadratic_extension.rs index c9c9dacce..731043e62 100644 --- a/ff/src/fields/models/quadratic_extension.rs +++ b/ff/src/fields/models/quadratic_extension.rs @@ -142,24 +142,6 @@ pub struct QuadExtField { pub c1: P::BaseField, } -/// Construct a [`QuadExtField`] element from elements of the base field. This should -/// be used primarily for constructing constant field elements; in a non-const -/// context, [`QuadExtField::new`] is preferable. -/// -/// # Usage -/// ```rust -/// # use ark_test_curves::QuadExt; -/// # use ark_test_curves::bls12_381 as ark_bls12_381; -/// use ark_bls12_381::{FQ_ZERO, FQ_ONE, Fq2}; -/// const ONE: Fq2 = QuadExt!(FQ_ONE, FQ_ZERO); -/// ``` -#[macro_export] -macro_rules! QuadExt { - ($c0:expr, $c1:expr $(,)?) => { - $crate::QuadExtField { c0: $c0, c1: $c1 } - }; -} - impl QuadExtField

{ /// Create a new field element from coefficients `c0` and `c1`, /// so that the result is of the form `c0 + c1 * X`. @@ -175,7 +157,7 @@ impl QuadExtField

{ /// // `Fp2` a degree-2 extension over `Fp`. /// let c: Fp2 = Fp2::new(c0, c1); /// ``` - pub fn new(c0: P::BaseField, c1: P::BaseField) -> Self { + pub const fn new(c0: P::BaseField, c1: P::BaseField) -> Self { Self { c0, c1 } } @@ -250,11 +232,14 @@ impl One for QuadExtField

{ } type BaseFieldIter

= <

::BaseField as Field>::BasePrimeFieldIter; + impl Field for QuadExtField

{ type BasePrimeField = P::BasePrimeField; - type BasePrimeFieldIter = Chain, BaseFieldIter

>; + const ZERO: Self = Self::new(P::BaseField::ZERO, P::BaseField::ZERO); + const ONE: Self = Self::new(P::BaseField::ONE, P::BaseField::ZERO); + fn extension_degree() -> u64 { 2 * P::BaseField::extension_degree() } diff --git a/poly/src/domain/mixed_radix.rs b/poly/src/domain/mixed_radix.rs index 800e51d66..ccb3d000e 100644 --- a/poly/src/domain/mixed_radix.rs +++ b/poly/src/domain/mixed_radix.rs @@ -76,7 +76,7 @@ impl EvaluationDomain for MixedRadixEvaluationDomain { let two_adicity = k_adicity(2, num_coeffs); let two_part = 2u64.checked_pow(two_adicity)?; - let size = u64::try_from(num_coeffs).unwrap(); + let size = num_coeffs; let log_size_of_group = two_adicity; if num_coeffs != q_part * two_part { diff --git a/poly/src/domain/radix2/mod.rs b/poly/src/domain/radix2/mod.rs index e09ed67d8..65e75ec78 100644 --- a/poly/src/domain/radix2/mod.rs +++ b/poly/src/domain/radix2/mod.rs @@ -188,9 +188,9 @@ impl EvaluationDomain for Radix2EvaluationDomain { let mut l_i = z_h_at_tau.inverse().unwrap() * v_0_inv; let mut negative_cur_elem = -domain_offset; let mut lagrange_coefficients_inverse = vec![F::zero(); size]; - for i in 0..size { + for coeff in &mut lagrange_coefficients_inverse { let r_i = tau + negative_cur_elem; - lagrange_coefficients_inverse[i] = l_i * r_i; + *coeff = l_i * r_i; // Increment l_i and negative_cur_elem l_i *= &self.group_gen_inv; negative_cur_elem *= &self.group_gen; diff --git a/poly/src/evaluations/multivariate/multilinear/dense.rs b/poly/src/evaluations/multivariate/multilinear/dense.rs index f3bfa8239..0a8441458 100644 --- a/poly/src/evaluations/multivariate/multilinear/dense.rs +++ b/poly/src/evaluations/multivariate/multilinear/dense.rs @@ -182,15 +182,13 @@ impl AddAssign for DenseMultilinearExtension { } } -impl<'a, 'b, F: Field> AddAssign<&'a DenseMultilinearExtension> - for DenseMultilinearExtension -{ +impl<'a, F: Field> AddAssign<&'a DenseMultilinearExtension> for DenseMultilinearExtension { fn add_assign(&mut self, other: &'a DenseMultilinearExtension) { *self = &*self + other; } } -impl<'a, 'b, F: Field> AddAssign<(F, &'a DenseMultilinearExtension)> +impl<'a, F: Field> AddAssign<(F, &'a DenseMultilinearExtension)> for DenseMultilinearExtension { fn add_assign(&mut self, (f, other): (F, &'a DenseMultilinearExtension)) { @@ -235,9 +233,7 @@ impl SubAssign for DenseMultilinearExtension { } } -impl<'a, 'b, F: Field> SubAssign<&'a DenseMultilinearExtension> - for DenseMultilinearExtension -{ +impl<'a, F: Field> SubAssign<&'a DenseMultilinearExtension> for DenseMultilinearExtension { fn sub_assign(&mut self, other: &'a DenseMultilinearExtension) { *self = &*self - other; } diff --git a/poly/src/evaluations/multivariate/multilinear/sparse.rs b/poly/src/evaluations/multivariate/multilinear/sparse.rs index f9faed1e7..09c249e21 100644 --- a/poly/src/evaluations/multivariate/multilinear/sparse.rs +++ b/poly/src/evaluations/multivariate/multilinear/sparse.rs @@ -278,15 +278,13 @@ impl AddAssign for SparseMultilinearExtension { } } -impl<'a, 'b, F: Field> AddAssign<&'a SparseMultilinearExtension> - for SparseMultilinearExtension -{ +impl<'a, F: Field> AddAssign<&'a SparseMultilinearExtension> for SparseMultilinearExtension { fn add_assign(&mut self, other: &'a SparseMultilinearExtension) { *self = &*self + other; } } -impl<'a, 'b, F: Field> AddAssign<(F, &'a SparseMultilinearExtension)> +impl<'a, F: Field> AddAssign<(F, &'a SparseMultilinearExtension)> for SparseMultilinearExtension { fn add_assign(&mut self, (f, other): (F, &'a SparseMultilinearExtension)) { @@ -347,9 +345,7 @@ impl SubAssign for SparseMultilinearExtension { } } -impl<'a, 'b, F: Field> SubAssign<&'a SparseMultilinearExtension> - for SparseMultilinearExtension -{ +impl<'a, F: Field> SubAssign<&'a SparseMultilinearExtension> for SparseMultilinearExtension { fn sub_assign(&mut self, other: &'a SparseMultilinearExtension) { *self = &*self - other; } diff --git a/poly/src/polynomial/multivariate/mod.rs b/poly/src/polynomial/multivariate/mod.rs index 04e63c030..6905e09cb 100644 --- a/poly/src/polynomial/multivariate/mod.rs +++ b/poly/src/polynomial/multivariate/mod.rs @@ -62,15 +62,12 @@ impl SparseTerm { fn combine(term: &[(usize, usize)]) -> Vec<(usize, usize)> { let mut term_dedup: Vec<(usize, usize)> = Vec::new(); for (var, pow) in term { - match term_dedup.last_mut() { - Some(prev) => { - if prev.0 == *var { - prev.1 += pow; - continue; - } - }, - _ => {}, - }; + if let Some(prev) = term_dedup.last_mut() { + if prev.0 == *var { + prev.1 += pow; + continue; + } + } term_dedup.push((*var, *pow)); } term_dedup diff --git a/poly/src/polynomial/multivariate/sparse.rs b/poly/src/polynomial/multivariate/sparse.rs index 72b3523b5..994c34b8b 100644 --- a/poly/src/polynomial/multivariate/sparse.rs +++ b/poly/src/polynomial/multivariate/sparse.rs @@ -99,8 +99,7 @@ impl DenseMVPolynomial for SparsePolynomial { /// Outputs an `l`-variate polynomial which is the sum of `l` `d`-degree /// univariate polynomials where each coefficient is sampled uniformly at random. fn rand(d: usize, l: usize, rng: &mut R) -> Self { - let mut random_terms = Vec::new(); - random_terms.push((F::rand(rng), SparseTerm::new(vec![]))); + let mut random_terms = vec![(F::rand(rng), SparseTerm::new(vec![]))]; for var in 0..l { for deg in 1..=d { random_terms.push((F::rand(rng), SparseTerm::new(vec![(var, deg)]))); @@ -214,22 +213,20 @@ impl<'a, 'b, F: Field, T: Term> Add<&'a SparsePolynomial> for &'b SparsePo } } -impl<'a, 'b, F: Field, T: Term> AddAssign<&'a SparsePolynomial> for SparsePolynomial { +impl<'a, F: Field, T: Term> AddAssign<&'a SparsePolynomial> for SparsePolynomial { fn add_assign(&mut self, other: &'a SparsePolynomial) { *self = &*self + other; } } -impl<'a, 'b, F: Field, T: Term> AddAssign<(F, &'a SparsePolynomial)> - for SparsePolynomial -{ +impl<'a, F: Field, T: Term> AddAssign<(F, &'a SparsePolynomial)> for SparsePolynomial { fn add_assign(&mut self, (f, other): (F, &'a SparsePolynomial)) { let other = Self { num_vars: other.num_vars, terms: other .terms .iter() - .map(|(coeff, term)| (*coeff * &f, term.clone())) + .map(|(coeff, term)| (*coeff * f, term.clone())) .collect(), }; // Note the call to `Add` will remove also any duplicates @@ -259,7 +256,7 @@ impl<'a, 'b, F: Field, T: Term> Sub<&'a SparsePolynomial> for &'b SparsePo } } -impl<'a, 'b, F: Field, T: Term> SubAssign<&'a SparsePolynomial> for SparsePolynomial { +impl<'a, F: Field, T: Term> SubAssign<&'a SparsePolynomial> for SparsePolynomial { #[inline] fn sub_assign(&mut self, other: &'a SparsePolynomial) { *self = &*self - other; diff --git a/poly/src/polynomial/univariate/dense.rs b/poly/src/polynomial/univariate/dense.rs index b8e2f28ed..8d4761f25 100644 --- a/poly/src/polynomial/univariate/dense.rs +++ b/poly/src/polynomial/univariate/dense.rs @@ -332,7 +332,7 @@ impl<'a, 'b, F: Field> Add<&'a SparsePolynomial> for &'b DensePolynomial { } } -impl<'a, 'b, F: Field> AddAssign<&'a DensePolynomial> for DensePolynomial { +impl<'a, F: Field> AddAssign<&'a DensePolynomial> for DensePolynomial { fn add_assign(&mut self, other: &'a DensePolynomial) { if self.is_zero() { self.coeffs.truncate(0); @@ -359,7 +359,7 @@ impl<'a, 'b, F: Field> AddAssign<&'a DensePolynomial> for DensePolynomial } } -impl<'a, 'b, F: Field> AddAssign<(F, &'a DensePolynomial)> for DensePolynomial { +impl<'a, F: Field> AddAssign<(F, &'a DensePolynomial)> for DensePolynomial { fn add_assign(&mut self, (f, other): (F, &'a DensePolynomial)) { if self.is_zero() { self.coeffs.truncate(0); @@ -494,7 +494,7 @@ impl<'a, 'b, F: Field> Sub<&'a SparsePolynomial> for &'b DensePolynomial { } } -impl<'a, 'b, F: Field> SubAssign<&'a DensePolynomial> for DensePolynomial { +impl<'a, F: Field> SubAssign<&'a DensePolynomial> for DensePolynomial { #[inline] fn sub_assign(&mut self, other: &'a DensePolynomial) { if self.is_zero() { @@ -560,7 +560,7 @@ impl<'a, 'b, F: Field> Div<&'a DensePolynomial> for &'b DensePolynomial { } } -impl<'a, 'b, F: Field> Mul for &'b DensePolynomial { +impl<'b, F: Field> Mul for &'b DensePolynomial { type Output = DensePolynomial; #[inline] diff --git a/poly/src/polynomial/univariate/mod.rs b/poly/src/polynomial/univariate/mod.rs index 974f939d5..a0410a96c 100644 --- a/poly/src/polynomial/univariate/mod.rs +++ b/poly/src/polynomial/univariate/mod.rs @@ -44,9 +44,9 @@ impl<'a, F: Field> From<&'a SparsePolynomial> for DenseOrSparsePolynomial<'a, } } -impl<'a, F: Field> Into> for DenseOrSparsePolynomial<'a, F> { - fn into(self) -> DensePolynomial { - match self { +impl<'a, F: Field> From> for DensePolynomial { + fn from(other: DenseOrSparsePolynomial<'a, F>) -> DensePolynomial { + match other { DPolynomial(p) => p.into_owned(), SPolynomial(p) => p.into_owned().into(), } diff --git a/poly/src/polynomial/univariate/sparse.rs b/poly/src/polynomial/univariate/sparse.rs index 6e0636561..193b5bbc7 100644 --- a/poly/src/polynomial/univariate/sparse.rs +++ b/poly/src/polynomial/univariate/sparse.rs @@ -160,14 +160,14 @@ impl<'a, 'b, F: Field> Add<&'a SparsePolynomial> for &'b SparsePolynomial } } -impl<'a, 'b, F: Field> AddAssign<&'a SparsePolynomial> for SparsePolynomial { +impl<'a, F: Field> AddAssign<&'a SparsePolynomial> for SparsePolynomial { // TODO: Reduce number of clones fn add_assign(&mut self, other: &'a SparsePolynomial) { self.coeffs = (self.clone() + other.clone()).coeffs; } } -impl<'a, 'b, F: Field> AddAssign<(F, &'a SparsePolynomial)> for SparsePolynomial { +impl<'a, F: Field> AddAssign<(F, &'a SparsePolynomial)> for SparsePolynomial { // TODO: Reduce number of clones fn add_assign(&mut self, (f, other): (F, &'a SparsePolynomial)) { self.coeffs = (self.clone() + other.clone()).coeffs; @@ -189,7 +189,7 @@ impl Neg for SparsePolynomial { } } -impl<'a, 'b, F: Field> SubAssign<&'a SparsePolynomial> for SparsePolynomial { +impl<'a, F: Field> SubAssign<&'a SparsePolynomial> for SparsePolynomial { // TODO: Reduce number of clones #[inline] fn sub_assign(&mut self, other: &'a SparsePolynomial) { @@ -198,7 +198,7 @@ impl<'a, 'b, F: Field> SubAssign<&'a SparsePolynomial> for SparsePolynomial Mul for &'b SparsePolynomial { +impl<'b, F: Field> Mul for &'b SparsePolynomial { type Output = SparsePolynomial; #[inline] @@ -294,13 +294,13 @@ impl SparsePolynomial { } } -impl Into> for SparsePolynomial { - fn into(self) -> DensePolynomial { - let mut other = vec![F::zero(); self.degree() + 1]; - for (i, coeff) in self.coeffs { - other[i] = coeff; +impl From> for DensePolynomial { + fn from(other: SparsePolynomial) -> Self { + let mut result = vec![F::zero(); other.degree() + 1]; + for (i, coeff) in other.coeffs { + result[i] = coeff; } - DensePolynomial::from_coefficients_vec(other) + DensePolynomial::from_coefficients_vec(result) } } @@ -308,9 +308,9 @@ impl From> for SparsePolynomial { fn from(dense_poly: DensePolynomial) -> SparsePolynomial { let coeffs = dense_poly.coeffs(); let mut sparse_coeffs = Vec::<(usize, F)>::new(); - for i in 0..coeffs.len() { - if !coeffs[i].is_zero() { - sparse_coeffs.push((i, coeffs[i])); + for (i, coeff) in coeffs.iter().enumerate() { + if !coeff.is_zero() { + sparse_coeffs.push((i, *coeff)); } } SparsePolynomial::from_coefficients_vec(sparse_coeffs) diff --git a/test-curves/src/bls12_381/fq.rs b/test-curves/src/bls12_381/fq.rs index c3b97ef4d..6315b3a32 100644 --- a/test-curves/src/bls12_381/fq.rs +++ b/test-curves/src/bls12_381/fq.rs @@ -6,13 +6,16 @@ use ark_ff::fields::{Fp384, MontBackend}; pub struct FqConfig; pub type Fq = Fp384>; -pub const FQ_ONE: Fq = ark_ff::MontFp!(Fq, "1"); -pub const FQ_ZERO: Fq = ark_ff::MontFp!(Fq, "0"); +pub const FQ_ONE: Fq = ark_ff::MontFp!("1"); +pub const FQ_ZERO: Fq = ark_ff::MontFp!("0"); #[cfg(test)] mod tests { + use core::marker::PhantomData; + use super::*; - use ark_ff::BigInt; + use ark_ff::{BigInt, FpConfig, One}; + #[test] fn test_constants() { use ark_ff::{MontConfig, PrimeField}; @@ -85,14 +88,20 @@ mod tests { // 2758230843577277949620073511305048635578704962089743514587482222134842183668501798417467556318533664893264801977679 assert_eq!( FqConfig::GENERATOR, - Fq::new(BigInt::new([ - 0x321300000006554f, - 0xb93c0018d6c40005, - 0x57605e0db0ddbb51, - 0x8b256521ed1f9bcb, - 0x6cf28d7901622c03, - 0x11ebab9dbb81e28c, - ])) + ark_ff::Fp( + BigInt::new([ + 0x321300000006554f, + 0xb93c0018d6c40005, + 0x57605e0db0ddbb51, + 0x8b256521ed1f9bcb, + 0x6cf28d7901622c03, + 0x11ebab9dbb81e28c, + ]), + PhantomData + ) ); + + assert_eq!(FQ_ONE, Fq::one()); + assert_eq!(FQ_ONE, >::ONE); } } diff --git a/test-curves/src/bls12_381/fq12.rs b/test-curves/src/bls12_381/fq12.rs index 63dda963d..de8a23ec4 100644 --- a/test-curves/src/bls12_381/fq12.rs +++ b/test-curves/src/bls12_381/fq12.rs @@ -1,5 +1,5 @@ use crate::bls12_381::*; -use ark_ff::{fields::*, CubicExt, MontFp, QuadExt}; +use ark_ff::{fields::*, MontFp}; pub type Fq12 = Fp12; @@ -9,68 +9,65 @@ pub struct Fq12Config; impl Fp12Config for Fq12Config { type Fp6Config = Fq6Config; - const NONRESIDUE: Fq6 = CubicExt!(FQ2_ZERO, FQ2_ONE, FQ2_ZERO); + const NONRESIDUE: Fq6 = Fq6::new(FQ2_ZERO, FQ2_ONE, FQ2_ZERO); const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[ // Fp2::NONRESIDUE^(((q^0) - 1) / 6) - QuadExt!( - MontFp!(Fq, "1"), - MontFp!(Fq, "0"), - ), + Fp2::new(MontFp!("1"), MontFp!("0")), // Fp2::NONRESIDUE^(((q^1) - 1) / 6) - QuadExt!( - MontFp!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"), - MontFp!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"), + Fp2::new( + MontFp!("3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"), + MontFp!("151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"), ), // Fp2::NONRESIDUE^(((q^2) - 1) / 6) - QuadExt!( - MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"), - MontFp!(Fq, "0"), + Fp2::new( + MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"), + MontFp!("0"), ), // Fp2::NONRESIDUE^(((q^3) - 1) / 6) - QuadExt!( - MontFp!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), - MontFp!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"), + Fp2::new( + MontFp!("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), + MontFp!("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"), ), // Fp2::NONRESIDUE^(((q^4) - 1) / 6) - QuadExt!( - MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), - MontFp!(Fq, "0"), + Fp2::new( + MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), + MontFp!("0"), ), // Fp2::NONRESIDUE^(((q^5) - 1) / 6) - QuadExt!( - MontFp!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"), - MontFp!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"), + Fp2::new( + MontFp!("3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"), + MontFp!("877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"), ), // Fp2::NONRESIDUE^(((q^6) - 1) / 6) - QuadExt!( - MontFp!(Fq, "-1"), - MontFp!(Fq, "0"), + Fp2::new( + MontFp!("-1"), + MontFp!("0"), ), // Fp2::NONRESIDUE^(((q^7) - 1) / 6) - QuadExt!( - MontFp!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"), - MontFp!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"), + Fp2::new( + MontFp!("151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"), + MontFp!("3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"), ), // Fp2::NONRESIDUE^(((q^8) - 1) / 6) - QuadExt!( - MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), - MontFp!(Fq, "0"), + Fp2::new( + MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), + MontFp!("0"), ), // Fp2::NONRESIDUE^(((q^9) - 1) / 6) - QuadExt!( - MontFp!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"), - MontFp!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), + Fp2::new( + MontFp!("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"), + MontFp!("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), ), // Fp2::NONRESIDUE^(((q^10) - 1) / 6) - QuadExt!( - MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"), - MontFp!(Fq, "0"), + Fp2::new( + MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"), + MontFp!("0"), ), // Fp2::NONRESIDUE^(((q^11) - 1) / 6) - QuadExt!( - MontFp!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"), - MontFp!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"), + Fp2::new( + MontFp!("877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"), + MontFp!("3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"), ), ]; } diff --git a/test-curves/src/bls12_381/fq2.rs b/test-curves/src/bls12_381/fq2.rs index d73546ab6..f22e85a34 100644 --- a/test-curves/src/bls12_381/fq2.rs +++ b/test-curves/src/bls12_381/fq2.rs @@ -1,5 +1,5 @@ use crate::bls12_381::*; -use ark_ff::{fields::*, MontFp, QuadExt}; +use ark_ff::{fields::*, MontFp}; pub type Fq2 = Fp2; @@ -10,15 +10,15 @@ impl Fp2Config for Fq2Config { /// NONRESIDUE = -1 #[rustfmt::skip] - const NONRESIDUE: Fq = MontFp!(Fq, "-1"); + const NONRESIDUE: Fq = MontFp!("-1"); /// Coefficients for the Frobenius automorphism. #[rustfmt::skip] const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[ // Fq(-1)**(((q^0) - 1) / 2) - MontFp!(Fq, "1"), + MontFp!("1"), // Fq(-1)**(((q^1) - 1) / 2) - MontFp!(Fq, "-1"), + MontFp!("-1"), ]; #[inline(always)] @@ -27,5 +27,5 @@ impl Fp2Config for Fq2Config { } } -pub const FQ2_ZERO: Fq2 = QuadExt!(FQ_ZERO, FQ_ZERO); -pub const FQ2_ONE: Fq2 = QuadExt!(FQ_ONE, FQ_ZERO); +pub const FQ2_ZERO: Fq2 = Fq2::new(FQ_ZERO, FQ_ZERO); +pub const FQ2_ONE: Fq2 = Fq2::new(FQ_ONE, FQ_ZERO); diff --git a/test-curves/src/bls12_381/fq6.rs b/test-curves/src/bls12_381/fq6.rs index 09312ee8b..d85d1cc71 100644 --- a/test-curves/src/bls12_381/fq6.rs +++ b/test-curves/src/bls12_381/fq6.rs @@ -1,5 +1,5 @@ use crate::bls12_381::*; -use ark_ff::{fields::*, MontFp, QuadExt}; +use ark_ff::{fields::*, MontFp}; pub type Fq6 = Fp6; @@ -10,71 +10,71 @@ impl Fp6Config for Fq6Config { type Fp2Config = Fq2Config; /// NONRESIDUE = (U + 1) - const NONRESIDUE: Fq2 = QuadExt!(MontFp!(Fq, "1"), MontFp!(Fq, "1")); + const NONRESIDUE: Fq2 = Fq2::new(MontFp!("1"), MontFp!("1")); #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[ // Fp2::NONRESIDUE^(((q^0) - 1) / 3) - QuadExt!(MontFp!(Fq, "1"), MontFp!(Fq, "0")), + Fq2::new(MontFp!("1"), MontFp!("0")), // Fp2::NONRESIDUE^(((q^1) - 1) / 3) - QuadExt!( - MontFp!(Fq, "0"), - MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), + Fq2::new( + MontFp!("0"), + MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), ), // Fp2::NONRESIDUE^(((q^2) - 1) / 3) - QuadExt!( - MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), - MontFp!(Fq, "0"), + Fq2::new( + MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), + MontFp!("0"), ), // Fp2::NONRESIDUE^(((q^3) - 1) / 3) - QuadExt!( - MontFp!(Fq, "0"), - MontFp!(Fq, "1"), + Fq2::new( + MontFp!("0"), + MontFp!("1"), ), // Fp2::NONRESIDUE^(((q^4) - 1) / 3) - QuadExt!( - MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), - MontFp!(Fq, "0"), + Fq2::new( + MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), + MontFp!("0"), ), // Fp2::NONRESIDUE^(((q^5) - 1) / 3) - QuadExt!( - MontFp!(Fq, "0"), - MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), + Fq2::new( + MontFp!("0"), + MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), ), ]; #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[ // Fq2(u + 1)**(((2q^0) - 2) / 3) - QuadExt!( - MontFp!(Fq, "1"), - MontFp!(Fq, "0"), + Fq2::new( + MontFp!("1"), + MontFp!("0"), ), // Fq2(u + 1)**(((2q^1) - 2) / 3) - QuadExt!( - MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"), - MontFp!(Fq, "0"), + Fq2::new( + MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"), + MontFp!("0"), ), // Fq2(u + 1)**(((2q^2) - 2) / 3) - QuadExt!( - MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), - MontFp!(Fq, "0"), + Fq2::new( + MontFp!("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), + MontFp!("0"), ), // Fq2(u + 1)**(((2q^3) - 2) / 3) - QuadExt!( - MontFp!(Fq, "-1"), - MontFp!(Fq, "0"), + Fq2::new( + MontFp!("-1"), + MontFp!("0"), ), // Fq2(u + 1)**(((2q^4) - 2) / 3) - QuadExt!( - MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), - MontFp!(Fq, "0"), + Fq2::new( + MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), + MontFp!("0"), ), // Fq2(u + 1)**(((2q^5) - 2) / 3) - QuadExt!( - MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"), - MontFp!(Fq, "0"), + Fq2::new( + MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"), + MontFp!("0"), ), ]; diff --git a/test-curves/src/bls12_381/g1.rs b/test-curves/src/bls12_381/g1.rs index 2a1df17bb..8b045ce56 100644 --- a/test-curves/src/bls12_381/g1.rs +++ b/test-curves/src/bls12_381/g1.rs @@ -21,20 +21,19 @@ impl CurveConfig for Parameters { /// COFACTOR_INV = COFACTOR^{-1} mod r /// = 52435875175126190458656871551744051925719901746859129887267498875565241663483 #[rustfmt::skip] - const COFACTOR_INV: Fr = MontFp!(Fr, "52435875175126190458656871551744051925719901746859129887267498875565241663483"); + const COFACTOR_INV: Fr = MontFp!("52435875175126190458656871551744051925719901746859129887267498875565241663483"); } impl short_weierstrass::SWCurveConfig for Parameters { /// COEFF_A = 0 - const COEFF_A: Fq = MontFp!(Fq, "0"); + const COEFF_A: Fq = MontFp!("0"); /// COEFF_B = 4 #[rustfmt::skip] - const COEFF_B: Fq = MontFp!(Fq, "4"); + const COEFF_B: Fq = MontFp!("4"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = - (G1_GENERATOR_X, G1_GENERATOR_Y); + const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y); #[inline(always)] fn mul_by_a(_: &Self::BaseField) -> Self::BaseField { @@ -56,12 +55,12 @@ impl short_weierstrass::SWCurveConfig for Parameters { /// G1_GENERATOR_X = /// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 #[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507"); +pub const G1_GENERATOR_X: Fq = MontFp!("3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507"); /// G1_GENERATOR_Y = /// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569 #[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569"); +pub const G1_GENERATOR_Y: Fq = MontFp!("1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569"); #[cfg(test)] mod test { diff --git a/test-curves/src/bls12_381/g2.rs b/test-curves/src/bls12_381/g2.rs index 7d6484b62..4359ae7dd 100644 --- a/test-curves/src/bls12_381/g2.rs +++ b/test-curves/src/bls12_381/g2.rs @@ -5,7 +5,7 @@ use ark_ec::{ short_weierstrass::{self, Affine}, AffineCurve, }; -use ark_ff::{BigInt, Field, MontFp, QuadExt, Zero}; +use ark_ff::{BigInt, Field, MontFp, Zero}; pub type G2Affine = bls12::G2Affine; pub type G2Projective = bls12::G2Projective; @@ -36,21 +36,19 @@ impl CurveConfig for Parameters { /// 26652489039290660355457965112010883481355318854675681319708643586776743290055 #[rustfmt::skip] const COFACTOR_INV: Fr = MontFp!( - Fr, "26652489039290660355457965112010883481355318854675681319708643586776743290055" ); } impl short_weierstrass::SWCurveConfig for Parameters { /// COEFF_A = [0, 0] - const COEFF_A: Fq2 = QuadExt!(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,); + const COEFF_A: Fq2 = Fq2::new(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A); /// COEFF_B = [4, 4] - const COEFF_B: Fq2 = QuadExt!(g1::Parameters::COEFF_B, g1::Parameters::COEFF_B,); + const COEFF_B: Fq2 = Fq2::new(g1::Parameters::COEFF_B, g1::Parameters::COEFF_B); /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = - (G2_GENERATOR_X, G2_GENERATOR_Y); + const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y); #[inline(always)] fn mul_by_a(_: &Self::BaseField) -> Self::BaseField { @@ -74,58 +72,55 @@ impl short_weierstrass::SWCurveConfig for Parameters { } } -pub const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); -pub const G2_GENERATOR_Y: Fq2 = QuadExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1); +pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); +pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1); /// G2_GENERATOR_X_C0 = /// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160 #[rustfmt::skip] -pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160"); +pub const G2_GENERATOR_X_C0: Fq = MontFp!("352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160"); /// G2_GENERATOR_X_C1 = /// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 #[rustfmt::skip] -pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758"); +pub const G2_GENERATOR_X_C1: Fq = MontFp!("3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758"); /// G2_GENERATOR_Y_C0 = /// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905 #[rustfmt::skip] -pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905"); +pub const G2_GENERATOR_Y_C0: Fq = MontFp!("1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905"); /// G2_GENERATOR_Y_C1 = /// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582 #[rustfmt::skip] -pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582"); +pub const G2_GENERATOR_Y_C1: Fq = MontFp!("927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582"); // psi(x,y) = (x**p * PSI_X, y**p * PSI_Y) is the Frobenius composed // with the quadratic twist and its inverse // PSI_X = 1/(u+1)^((p-1)/3) -pub const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = QuadExt!( +pub const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = Fq2::new( FQ_ZERO, MontFp!( - Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437" ) ); // PSI_Y = 1/(u+1)^((p-1)/2) -pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = QuadExt!( +pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = Fq2::new( MontFp!( - Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), MontFp!( - Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257") ); pub fn p_power_endomorphism(p: &Affine) -> Affine { // The p-power endomorphism for G2 is defined as follows: - // 1. Note that G2 is defined on curve E': y^2 = x^3 + 4(u+1). To map a point (x, y) in E' to (s, t) in E, - // one set s = x / ((u+1) ^ (1/3)), t = y / ((u+1) ^ (1/2)), because E: y^2 = x^3 + 4. - // 2. Apply the Frobenius endomorphism (s, t) => (s', t'), another point on curve E, - // where s' = s^p, t' = t^p. - // 3. Map the point from E back to E'; that is, + // 1. Note that G2 is defined on curve E': y^2 = x^3 + 4(u+1). To map a point + // (x, y) in E' to (s, t) in E, one set s = x / ((u+1) ^ (1/3)), t = y / + // ((u+1) ^ (1/2)), because E: y^2 = x^3 + 4. 2. Apply the Frobenius + // endomorphism (s, t) => (s', t'), another point on curve E, where s' = + // s^p, t' = t^p. 3. Map the point from E back to E'; that is, // one set x' = s' * ((u+1) ^ (1/3)), y' = t' * ((u+1) ^ (1/2)). // // To sum up, it maps diff --git a/test-curves/src/bn384_small_two_adicity/fq.rs b/test-curves/src/bn384_small_two_adicity/fq.rs index 84639e045..c363620d8 100644 --- a/test-curves/src/bn384_small_two_adicity/fq.rs +++ b/test-curves/src/bn384_small_two_adicity/fq.rs @@ -8,5 +8,5 @@ use ark_ff::fields::{Fp384, MontBackend}; pub struct FqConfig; pub type Fq = Fp384>; -pub const FQ_ONE: Fq = ark_ff::MontFp!(Fq, "1"); -pub const FQ_ZERO: Fq = ark_ff::MontFp!(Fq, "0"); +pub const FQ_ONE: Fq = ark_ff::MontFp!("1"); +pub const FQ_ZERO: Fq = ark_ff::MontFp!("0"); diff --git a/test-curves/src/bn384_small_two_adicity/fr.rs b/test-curves/src/bn384_small_two_adicity/fr.rs index ca51ae9e0..9473f2029 100644 --- a/test-curves/src/bn384_small_two_adicity/fr.rs +++ b/test-curves/src/bn384_small_two_adicity/fr.rs @@ -8,5 +8,5 @@ use ark_ff::fields::{Fp384, MontBackend}; pub struct FrConfig; pub type Fr = Fp384>; -pub const FR_ONE: Fr = ark_ff::MontFp!(Fr, "1"); -pub const FR_ZERO: Fr = ark_ff::MontFp!(Fr, "0"); +pub const FR_ONE: Fr = ark_ff::MontFp!("1"); +pub const FR_ZERO: Fr = ark_ff::MontFp!("0"); diff --git a/test-curves/src/bn384_small_two_adicity/g1.rs b/test-curves/src/bn384_small_two_adicity/g1.rs index 8223b1992..e468e6776 100644 --- a/test-curves/src/bn384_small_two_adicity/g1.rs +++ b/test-curves/src/bn384_small_two_adicity/g1.rs @@ -25,14 +25,13 @@ impl CurveConfig for Parameters { impl short_weierstrass::SWCurveConfig for Parameters { /// COEFF_A = 0 - const COEFF_A: Fq = ark_ff::MontFp!(Fq, "0"); + const COEFF_A: Fq = ark_ff::MontFp!("0"); /// COEFF_B = 17 - const COEFF_B: Fq = ark_ff::MontFp!(Fq, "17"); + const COEFF_B: Fq = ark_ff::MontFp!("17"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = - (G1_GENERATOR_X, G1_GENERATOR_Y); + const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y); #[inline(always)] fn mul_by_a(_: &Self::BaseField) -> Self::BaseField { @@ -41,7 +40,7 @@ impl short_weierstrass::SWCurveConfig for Parameters { } /// G1_GENERATOR_X = -1 -pub const G1_GENERATOR_X: Fq = ark_ff::MontFp!(Fq, "-1"); +pub const G1_GENERATOR_X: Fq = ark_ff::MontFp!("-1"); /// G1_GENERATOR_Y = 4 -pub const G1_GENERATOR_Y: Fq = ark_ff::MontFp!(Fq, "4"); +pub const G1_GENERATOR_Y: Fq = ark_ff::MontFp!("4"); diff --git a/test-curves/src/mnt4_753/fr.rs b/test-curves/src/mnt4_753/fr.rs index 5136a119d..c249e1d49 100644 --- a/test-curves/src/mnt4_753/fr.rs +++ b/test-curves/src/mnt4_753/fr.rs @@ -8,4 +8,4 @@ pub type Fr = Fp768>; #[small_subgroup_power = "2"] pub struct FrConfig; -pub const FR_ONE: Fr = ark_ff::MontFp!(Fr, "1"); +pub const FR_ONE: Fr = ark_ff::MontFp!("1"); diff --git a/test-curves/src/mnt4_753/g1.rs b/test-curves/src/mnt4_753/g1.rs index 0955fea53..278e4410f 100644 --- a/test-curves/src/mnt4_753/g1.rs +++ b/test-curves/src/mnt4_753/g1.rs @@ -27,16 +27,15 @@ impl CurveConfig for Parameters { impl short_weierstrass::SWCurveConfig for Parameters { /// COEFF_A = 2 #[rustfmt::skip] - const COEFF_A: Fq = MontFp!(Fq, "2"); + const COEFF_A: Fq = MontFp!("2"); /// COEFF_B = 0x01373684A8C9DCAE7A016AC5D7748D3313CD8E39051C596560835DF0C9E50A5B59B882A92C78DC537E51A16703EC9855C77FC3D8BB21C8D68BB8CFB9DB4B8C8FBA773111C36C8B1B4E8F1ECE940EF9EAAD265458E06372009C9A0491678EF4 /// = 28798803903456388891410036793299405764940372360099938340752576406393880372126970068421383312482853541572780087363938442377933706865252053507077543420534380486492786626556269083255657125025963825610840222568694137138741554679540 #[rustfmt::skip] - const COEFF_B: Fq = MontFp!(Fq, "28798803903456388891410036793299405764940372360099938340752576406393880372126970068421383312482853541572780087363938442377933706865252053507077543420534380486492786626556269083255657125025963825610840222568694137138741554679540"); + const COEFF_B: Fq = MontFp!("28798803903456388891410036793299405764940372360099938340752576406393880372126970068421383312482853541572780087363938442377933706865252053507077543420534380486492786626556269083255657125025963825610840222568694137138741554679540"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) - const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = - (G1_GENERATOR_X, G1_GENERATOR_Y); + const GENERATOR: G1Affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y); } // Generator of G1 @@ -44,8 +43,8 @@ impl short_weierstrass::SWCurveConfig for Parameters { // Y = 6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648, /// G1_GENERATOR_X = #[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "7790163481385331313124631546957228376128961350185262705123068027727518350362064426002432450801002268747950550964579198552865939244360469674540925037890082678099826733417900510086646711680891516503232107232083181010099241949569"); +pub const G1_GENERATOR_X: Fq = MontFp!("7790163481385331313124631546957228376128961350185262705123068027727518350362064426002432450801002268747950550964579198552865939244360469674540925037890082678099826733417900510086646711680891516503232107232083181010099241949569"); /// G1_GENERATOR_Y = #[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648"); +pub const G1_GENERATOR_Y: Fq = MontFp!("6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648"); diff --git a/test-curves/src/mnt6_753/fq3.rs b/test-curves/src/mnt6_753/fq3.rs index ce314a591..ab74e49f4 100644 --- a/test-curves/src/mnt6_753/fq3.rs +++ b/test-curves/src/mnt6_753/fq3.rs @@ -1,7 +1,7 @@ use crate::mnt6_753::fq::Fq; use ark_ff::{ fields::fp3::{Fp3, Fp3Config}, - CubicExt, MontFp, + MontFp, }; pub type Fq3 = Fp3; @@ -12,7 +12,7 @@ impl Fp3Config for Fq3Config { type Fp = Fq; #[rustfmt::skip] - const NONRESIDUE: Fq = MontFp!(Fq, "11"); + const NONRESIDUE: Fq = MontFp!("11"); const TWO_ADICITY: u32 = 30; @@ -57,8 +57,8 @@ impl Fp3Config for Fq3Config { /// (11^T, 0, 0) #[rustfmt::skip] - const QUADRATIC_NONRESIDUE_TO_T: Fq3 = CubicExt!( - MontFp!(Fq, "22168644070733283197994897338612733221095941481265408161807376791727499343083607817089033595478370212662133368413166734396127674284827734481031659015434501966360165723728649019457855887066657739809176476252080335185730833468062"), + const QUADRATIC_NONRESIDUE_TO_T: Fq3 = Fq3::new( + MontFp!("22168644070733283197994897338612733221095941481265408161807376791727499343083607817089033595478370212662133368413166734396127674284827734481031659015434501966360165723728649019457855887066657739809176476252080335185730833468062"), FQ_ZERO, FQ_ZERO, ); @@ -70,8 +70,8 @@ impl Fp3Config for Fq3Config { #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[ FQ_ONE, - MontFp!(Fq, "24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052132"), - MontFp!(Fq, "17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107868"), + MontFp!("24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052132"), + MontFp!("17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107868"), ]; // c2 = {c1[0], c1[2], c1[1]} @@ -83,5 +83,5 @@ impl Fp3Config for Fq3Config { ]; } -pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); -pub const FQ_ONE: Fq = MontFp!(Fq, "1"); +pub const FQ_ZERO: Fq = MontFp!("0"); +pub const FQ_ONE: Fq = MontFp!("1");