mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-01-31 15:52:14 +00:00
Replace Montgomery point interpretation with twisted Edwards.
This commit is contained in:
parent
f00e8a8292
commit
9d49a60f48
@ -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, ¶ms);
|
let p = edwards::Point::<Bls12, _>::rand(rng, ¶ms);
|
||||||
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, ¶ms).unwrap();
|
let p = EdwardsPoint::interpret(&mut cs, &numx, &numy, ¶ms).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, ¶ms).unwrap();
|
EdwardsPoint::interpret(&mut cs, &numx, &numy, ¶ms).unwrap();
|
||||||
|
|
||||||
assert_eq!(cs.which_is_unsatisfied().unwrap(), "on curve check");
|
assert_eq!(cs.which_is_unsatisfied().unwrap(), "on curve check");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user