From 931257599dbe64298a2a4a74105dc9bdd94296bf Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 4 Oct 2017 11:43:42 -0600 Subject: [PATCH 1/4] Refactor code for finding affine points from x-coordinates. --- src/bls12_381/ec.rs | 81 +++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/src/bls12_381/ec.rs b/src/bls12_381/ec.rs index f441cca..16c5401 100644 --- a/src/bls12_381/ec.rs +++ b/src/bls12_381/ec.rs @@ -85,6 +85,33 @@ macro_rules! curve_impl { } impl $affine { + /// Constructs an affine point with the lexicographically smallest + /// y-coordinate, given an x-coordinate, so long as the x-coordinate + /// exists on the curve. The point is not guaranteed to be in the + /// prime order subgroup. + fn get_point_from_x(x: $basefield) -> 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 { + y + } else { + negy + }, + infinity: false + } + }) + } + fn is_on_curve(&self) -> bool { if self.is_zero() { true @@ -781,26 +808,13 @@ 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 - }) + match G1Affine::get_point_from_x(x) { + Some(mut p) => { + if greatest { + p.negate(); + } + + Ok(p) }, None => { // Point must not be on the curve. @@ -1307,26 +1321,13 @@ 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 - }) + match G2Affine::get_point_from_x(x) { + Some(mut p) => { + if greatest { + p.negate(); + } + + Ok(p) }, None => { // Point must not be on the curve. From 85b95750e2b0ed6cf7288f4ce16d6e0cb060fdaf Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 4 Oct 2017 14:09:40 -0600 Subject: [PATCH 2/4] Fix comment about u128-support. --- src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c39615c..b02eb2a 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 From 683f21a4d54ecf836c6ba002e903236c91880ffd Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 4 Oct 2017 14:53:42 -0600 Subject: [PATCH 3/4] Remove spurious newline. --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index b02eb2a..7acff09 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -617,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)] From dbac57c27bc4628abe0170d73ea5d2b67193bfff Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Thu, 5 Oct 2017 12:35:04 -0600 Subject: [PATCH 4/4] Further refactoring of get_point_from_x() --- src/bls12_381/ec.rs | 41 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/src/bls12_381/ec.rs b/src/bls12_381/ec.rs index 16c5401..f459e0b 100644 --- a/src/bls12_381/ec.rs +++ b/src/bls12_381/ec.rs @@ -85,11 +85,12 @@ macro_rules! curve_impl { } impl $affine { - /// Constructs an affine point with the lexicographically smallest - /// y-coordinate, given an x-coordinate, so long as the x-coordinate - /// exists on the curve. The point is not guaranteed to be in the - /// prime order subgroup. - fn get_point_from_x(x: $basefield) -> Option<$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(); @@ -102,7 +103,7 @@ macro_rules! curve_impl { $affine { x: x, - y: if y < negy { + y: if (y < negy) ^ greatest { y } else { negy @@ -808,19 +809,7 @@ pub mod g1 { // Interpret as Fq element. let x = Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?; - match G1Affine::get_point_from_x(x) { - Some(mut p) => { - if greatest { - p.negate(); - } - - Ok(p) - }, - 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 { @@ -1321,19 +1310,7 @@ pub mod g2 { c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))? }; - match G2Affine::get_point_from_x(x) { - Some(mut p) => { - if greatest { - p.negate(); - } - - Ok(p) - }, - 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 {