mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-14 18:55:47 +00:00
Remove Montgomery point doubling implementation in the circuit.
This commit is contained in:
parent
1610bcfbcf
commit
c89d47bb07
@ -650,109 +650,6 @@ impl<E: JubjubEngine> MontgomeryPoint<E> {
|
|||||||
y: yprime
|
y: yprime
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs an affine point doubling, not defined for
|
|
||||||
/// the point of order two (0, 0).
|
|
||||||
pub fn double<CS>(
|
|
||||||
&self,
|
|
||||||
mut cs: CS,
|
|
||||||
params: &E::Params
|
|
||||||
) -> Result<Self, SynthesisError>
|
|
||||||
where CS: ConstraintSystem<E>
|
|
||||||
{
|
|
||||||
// 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)]
|
#[cfg(test)]
|
||||||
@ -863,27 +760,6 @@ mod test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_doubling_order_2() {
|
|
||||||
let params = &JubjubBls12::new();
|
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::<Bls12>::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]
|
#[test]
|
||||||
fn test_edwards_fixed_base_multiplication() {
|
fn test_edwards_fixed_base_multiplication() {
|
||||||
let params = &JubjubBls12::new();
|
let params = &JubjubBls12::new();
|
||||||
@ -1222,60 +1098,4 @@ mod test {
|
|||||||
assert_eq!(cs.which_is_unsatisfied(), Some("addition/evaluate lambda"));
|
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::<Bls12, _>::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::<Bls12>::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"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user