diff --git a/src/circuit/mont.rs b/src/circuit/mont.rs index 7c484d5..798e041 100644 --- a/src/circuit/mont.rs +++ b/src/circuit/mont.rs @@ -650,109 +650,6 @@ impl MontgomeryPoint { y: yprime }) } - - /// Performs an affine point doubling, not defined for - /// the point of order two (0, 0). - pub fn double( - &self, - mut cs: CS, - params: &E::Params - ) -> Result - where CS: ConstraintSystem - { - // Square x - let xx = self.x.square(&mut cs)?; - - // Compute lambda = (3.xx + 2.A.x + 1) / 2.y - let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || { - let mut t0 = *xx.get_value().get()?; - let mut t1 = t0; - t0.double(); // t0 = 2.xx - t0.add_assign(&t1); // t0 = 3.xx - t1 = *self.x.get_value().get()?; // t1 = x - t1.mul_assign(params.montgomery_2a()); // t1 = 2.A.x - t0.add_assign(&t1); - t0.add_assign(&E::Fr::one()); - t1 = *self.y.get_value().get()?; // t1 = y - t1.double(); // t1 = 2.y - match t1.inverse() { - Some(t1) => { - t0.mul_assign(&t1); - - Ok(t0) - }, - None => { - Err(SynthesisError::DivisionByZero) - } - } - })?; - - // (2.y) * (lambda) = (3.xx + 2.A.x + 1) - let one = CS::one(); - cs.enforce( - || "evaluate lambda", - |lc| lc + self.y.get_variable() - + self.y.get_variable(), - - |lc| lc + lambda.get_variable(), - - |lc| lc + xx.get_variable() - + xx.get_variable() - + xx.get_variable() - + (*params.montgomery_2a(), self.x.get_variable()) - + one - ); - - // Compute x' = (lambda^2) - A - 2.x - let xprime = AllocatedNum::alloc(cs.namespace(|| "xprime"), || { - let mut t0 = *lambda.get_value().get()?; - t0.square(); - t0.sub_assign(params.montgomery_a()); - t0.sub_assign(self.x.get_value().get()?); - t0.sub_assign(self.x.get_value().get()?); - - Ok(t0) - })?; - - // (lambda) * (lambda) = (A + 2.x + x') - cs.enforce( - || "evaluate xprime", - |lc| lc + lambda.get_variable(), - |lc| lc + lambda.get_variable(), - |lc| lc + (*params.montgomery_a(), one) - + self.x.get_variable() - + self.x.get_variable() - + xprime.get_variable() - ); - - // Compute y' = -(y + lambda(x' - x)) - let yprime = AllocatedNum::alloc(cs.namespace(|| "yprime"), || { - let mut t0 = *xprime.get_value().get()?; - t0.sub_assign(self.x.get_value().get()?); - t0.mul_assign(lambda.get_value().get()?); - t0.add_assign(self.y.get_value().get()?); - t0.negate(); - - Ok(t0) - })?; - - // y' + y = lambda(x - x') - cs.enforce( - || "evaluate yprime", - |lc| lc + self.x.get_variable() - - xprime.get_variable(), - - |lc| lc + lambda.get_variable(), - - |lc| lc + yprime.get_variable() - + self.y.get_variable() - ); - - Ok(MontgomeryPoint { - x: xprime, - y: yprime - }) - } } #[cfg(test)] @@ -863,27 +760,6 @@ mod test { } } - #[test] - fn test_doubling_order_2() { - let params = &JubjubBls12::new(); - - let mut cs = TestConstraintSystem::::new(); - - let x = AllocatedNum::alloc(cs.namespace(|| "x"), || { - Ok(Fr::zero()) - }).unwrap(); - let y = AllocatedNum::alloc(cs.namespace(|| "y"), || { - Ok(Fr::zero()) - }).unwrap(); - - let p = MontgomeryPoint { - x: x, - y: y - }; - - assert!(p.double(&mut cs, params).is_err()); - } - #[test] fn test_edwards_fixed_base_multiplication() { let params = &JubjubBls12::new(); @@ -1222,60 +1098,4 @@ mod test { assert_eq!(cs.which_is_unsatisfied(), Some("addition/evaluate lambda")); } } - - #[test] - fn test_montgomery_doubling() { - let params = &JubjubBls12::new(); - let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - - for _ in 0..100 { - let p = loop { - let x: Fr = rng.gen(); - let s: bool = rng.gen(); - - if let Some(p) = montgomery::Point::::get_for_x(x, s, params) { - break p; - } - }; - - let p2 = p.double(params); - - let (x0, y0) = p.into_xy().unwrap(); - let (x1, y1) = p2.into_xy().unwrap(); - - let mut cs = TestConstraintSystem::::new(); - - let x = AllocatedNum::alloc(cs.namespace(|| "x"), || { - Ok(x0) - }).unwrap(); - let y = AllocatedNum::alloc(cs.namespace(|| "y"), || { - Ok(y0) - }).unwrap(); - - let p = MontgomeryPoint { - x: x, - y: y - }; - - let p2 = p.double(cs.namespace(|| "doubling"), params).unwrap(); - - assert!(cs.is_satisfied()); - - assert!(p2.x.get_value().unwrap() == x1); - assert!(p2.y.get_value().unwrap() == y1); - - cs.set("doubling/yprime/num", rng.gen()); - assert_eq!(cs.which_is_unsatisfied(), Some("doubling/evaluate yprime")); - cs.set("doubling/yprime/num", y1); - assert!(cs.is_satisfied()); - - cs.set("doubling/xprime/num", rng.gen()); - assert_eq!(cs.which_is_unsatisfied(), Some("doubling/evaluate xprime")); - cs.set("doubling/xprime/num", x1); - assert!(cs.is_satisfied()); - - cs.set("doubling/lambda/num", rng.gen()); - assert_eq!(cs.which_is_unsatisfied(), Some("doubling/evaluate lambda")); - } - } }