diff --git a/src/bls12_381/ec.rs b/src/bls12_381/ec.rs index f441ccab6..f459e0b60 100644 --- a/src/bls12_381/ec.rs +++ b/src/bls12_381/ec.rs @@ -85,6 +85,34 @@ macro_rules! curve_impl { } impl $affine { + /// Attempts to construct an affine point given an x-coordinate. The + /// point is not guaranteed to be in the prime order subgroup. + /// + /// If and only if `greatest` is set will the lexicographically + /// largest y-coordinate be selected. + fn get_point_from_x(x: $basefield, greatest: bool) -> Option<$affine> { + // Compute x^3 + b + let mut x3b = x; + x3b.square(); + x3b.mul_assign(&x); + x3b.add_assign(&$affine::get_coeff_b()); + + x3b.sqrt().map(|y| { + let mut negy = y; + negy.negate(); + + $affine { + x: x, + y: if (y < negy) ^ greatest { + y + } else { + negy + }, + infinity: false + } + }) + } + fn is_on_curve(&self) -> bool { if self.is_zero() { true @@ -781,32 +809,7 @@ pub mod g1 { // Interpret as Fq element. let x = Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?; - // Compute x^3 + b - let mut x3b = x; - x3b.square(); - x3b.mul_assign(&x); - x3b.add_assign(&G1Affine::get_coeff_b()); - - // Attempt to compute y - match x3b.sqrt() { - Some(y) => { - let mut negy = y; - negy.negate(); - - // Get the parity of the sqrt we found. - let parity = y > negy; - - Ok(G1Affine { - x: x, - y: if parity == greatest { y } else { negy }, - infinity: false - }) - }, - None => { - // Point must not be on the curve. - Err(GroupDecodingError::NotOnCurve) - } - } + G1Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve) } } fn from_affine(affine: G1Affine) -> Self { @@ -1307,32 +1310,7 @@ pub mod g2 { c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))? }; - // Compute x^3 + b - let mut x3b = x; - x3b.square(); - x3b.mul_assign(&x); - x3b.add_assign(&G2Affine::get_coeff_b()); - - // Attempt to compute y - match x3b.sqrt() { - Some(y) => { - let mut negy = y; - negy.negate(); - - // Get the parity of the sqrt we found. - let parity = y > negy; - - Ok(G2Affine { - x: x, - y: if parity == greatest { y } else { negy }, - infinity: false - }) - }, - None => { - // Point must not be on the curve. - Err(GroupDecodingError::NotOnCurve) - } - } + G2Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve) } } fn from_affine(affine: G2Affine) -> Self { diff --git a/src/lib.rs b/src/lib.rs index c39615c3a..7acff096b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ -// This library relies on the Rust nightly compiler's `i128_type` feature. -// If that's not okay for you, disable the u128-support feature. (Pass -// --no-default-features for example.) +// If the "u128-support" feature is enabled, this library can use +// more efficient arithmetic. Only available in the nightly compiler. #![cfg_attr(feature = "u128-support", feature(i128_type))] // `clippy` is a code linting tool for improving code quality by catching @@ -618,7 +617,6 @@ use self::arith::*; #[cfg(feature = "u128-support")] mod arith { - /// Calculate a - b - borrow, returning the result and modifying /// the borrow value. #[inline(always)]