Replace Montgomery point interpretation with twisted Edwards.

This commit is contained in:
Sean Bowe 2018-01-29 10:38:18 -07:00
parent f00e8a8292
commit 9d49a60f48
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
1 changed files with 61 additions and 60 deletions

View File

@ -32,6 +32,40 @@ impl<E: JubjubEngine, Var: Copy> EdwardsPoint<E, Var> {
self.x.clone() self.x.clone()
} }
pub fn interpret<CS>(
mut cs: CS,
x: &AllocatedNum<E, Var>,
y: &AllocatedNum<E, Var>,
params: &E::Params
) -> Result<Self, SynthesisError>
where CS: ConstraintSystem<E, Variable=Var>
{
// -x^2 + y^2 = 1 + dx^2y^2
// TODO: This code uses a naive method to determine if the
// point is on the curve, but it could be optimized to three
// constraints.
let x2 = x.square(cs.namespace(|| "x^2"))?;
let y2 = y.square(cs.namespace(|| "y^2"))?;
let x2y2 = x2.mul(cs.namespace(|| "x^2 y^2"), &y2)?;
let one = cs.one();
cs.enforce(
|| "on curve check",
LinearCombination::zero() - x2.get_variable()
+ y2.get_variable(),
LinearCombination::zero() + one,
LinearCombination::zero() + one
+ (*params.edwards_d(), x2y2.get_variable())
);
Ok(EdwardsPoint {
x: x.clone(),
y: y.clone()
})
}
/// Perform addition between any two points /// Perform addition between any two points
pub fn add<CS>( pub fn add<CS>(
&self, &self,
@ -241,34 +275,6 @@ impl<E: JubjubEngine, Var: Copy> MontgomeryPoint<E, Var> {
} }
} }
pub fn interpret<CS>(
mut cs: CS,
x: &AllocatedNum<E, Var>,
y: &AllocatedNum<E, Var>,
params: &E::Params
) -> Result<Self, SynthesisError>
where CS: ConstraintSystem<E, Variable=Var>
{
// y^2 = x^3 + A.x^2 + x
let x2 = x.square(cs.namespace(|| "x^2"))?;
let x3 = x2.mul(cs.namespace(|| "x^3"), x)?;
cs.enforce(
|| "on curve check",
LinearCombination::zero() + y.get_variable(),
LinearCombination::zero() + y.get_variable(),
LinearCombination::zero() + x3.get_variable()
+ (*params.montgomery_a(), x2.get_variable())
+ x.get_variable()
);
Ok(MontgomeryPoint {
x: x.clone(),
y: y.clone()
})
}
/// Performs an affine point addition, not defined for /// Performs an affine point addition, not defined for
/// coincident points. /// coincident points.
pub fn add<CS>( pub fn add<CS>(
@ -528,45 +534,40 @@ mod test {
let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
for _ in 0..100 { for _ in 0..100 {
let p = montgomery::Point::<Bls12, _>::rand(rng, &params); let p = edwards::Point::<Bls12, _>::rand(rng, &params);
let (mut x, mut y) = p.into_xy().unwrap(); let (x, y) = p.into_xy();
{ let mut cs = TestConstraintSystem::<Bls12>::new();
let mut cs = TestConstraintSystem::<Bls12>::new(); let numx = AllocatedNum::alloc(cs.namespace(|| "x"), || {
let numx = AllocatedNum::alloc(cs.namespace(|| "x"), || { Ok(x)
Ok(x) }).unwrap();
}).unwrap(); let numy = AllocatedNum::alloc(cs.namespace(|| "y"), || {
let numy = AllocatedNum::alloc(cs.namespace(|| "y"), || { Ok(y)
Ok(y) }).unwrap();
}).unwrap();
let p = MontgomeryPoint::interpret(&mut cs, &numx, &numy, &params).unwrap(); let p = EdwardsPoint::interpret(&mut cs, &numx, &numy, &params).unwrap();
assert!(cs.is_satisfied()); assert!(cs.is_satisfied());
assert_eq!(p.x.get_value().unwrap(), x); assert_eq!(p.x.get_value().unwrap(), x);
assert_eq!(p.y.get_value().unwrap(), y); assert_eq!(p.y.get_value().unwrap(), y);
}
y.negate(); // Random (x, y) are unlikely to be on the curve.
cs.set("y/num", y); for _ in 0..100 {
assert!(cs.is_satisfied()); let x = rng.gen();
x.negate(); let y = rng.gen();
cs.set("x/num", x);
assert!(!cs.is_satisfied());
}
{ let mut cs = TestConstraintSystem::<Bls12>::new();
let mut cs = TestConstraintSystem::<Bls12>::new(); let numx = AllocatedNum::alloc(cs.namespace(|| "x"), || {
let numx = AllocatedNum::alloc(cs.namespace(|| "x"), || { Ok(x)
Ok(x) }).unwrap();
}).unwrap(); let numy = AllocatedNum::alloc(cs.namespace(|| "y"), || {
let numy = AllocatedNum::alloc(cs.namespace(|| "y"), || { Ok(y)
Ok(y) }).unwrap();
}).unwrap();
MontgomeryPoint::interpret(&mut cs, &numx, &numy, &params).unwrap(); EdwardsPoint::interpret(&mut cs, &numx, &numy, &params).unwrap();
assert_eq!(cs.which_is_unsatisfied().unwrap(), "on curve check"); assert_eq!(cs.which_is_unsatisfied().unwrap(), "on curve check");
}
} }
} }