diff --git a/src/jubjub/montgomery.rs b/src/jubjub/montgomery.rs index 6af0e6d..e827111 100644 --- a/src/jubjub/montgomery.rs +++ b/src/jubjub/montgomery.rs @@ -67,6 +67,36 @@ impl PartialEq for Point { } impl Point { + pub fn get_for_x(x: E::Fr, sign: bool, params: &E::Params) -> Option + { + // given an x on the curve, y^2 = x^3 + A*x^2 + x + + let mut x2 = x; + x2.square(); + + let mut rhs = x2; + rhs.mul_assign(params.montgomery_a()); + rhs.add_assign(&x); + x2.mul_assign(&x); + rhs.add_assign(&x2); + + match rhs.sqrt() { + Some(mut y) => { + if y.into_repr().is_odd() != sign { + y.negate(); + } + + return Some(Point { + x: x, + y: y, + infinity: false, + _marker: PhantomData + }) + }, + None => None + } + } + /// This guarantees the point is in the prime order subgroup pub fn mul_by_cofactor(&self, params: &E::Params) -> Point { @@ -80,30 +110,11 @@ impl Point { pub fn rand(rng: &mut R, params: &E::Params) -> Self { loop { - // given an x on the curve, y^2 = x^3 + A*x^2 + x let x: E::Fr = rng.gen(); - let mut x2 = x; - x2.square(); - - let mut rhs = x2; - rhs.mul_assign(params.montgomery_a()); - rhs.add_assign(&x); - x2.mul_assign(&x); - rhs.add_assign(&x2); - - match rhs.sqrt() { - Some(mut y) => { - if y.into_repr().is_odd() != rng.gen() { - y.negate(); - } - - return Point { - x: x, - y: y, - infinity: false, - _marker: PhantomData - } + match Self::get_for_x(x, rng.gen(), params) { + Some(p) => { + return p }, None => {} }