From e8480a2b2cbf3be5ad7f1f3f994be3fb82471978 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Tue, 20 Feb 2018 18:36:53 -0700 Subject: [PATCH] Utility for witnessing points on the curve. --- src/circuit/ecc.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/circuit/ecc.rs b/src/circuit/ecc.rs index 48e419e83..fbb9b726f 100644 --- a/src/circuit/ecc.rs +++ b/src/circuit/ecc.rs @@ -18,6 +18,7 @@ use super::num::{ }; use ::jubjub::{ + edwards, JubjubEngine, JubjubParams, FixedGenerators @@ -91,6 +92,41 @@ pub fn fixed_base_multiplication( } impl EdwardsPoint { + /// This 'witnesses' a point inside the constraint system. + /// It guarantees the point is on the curve. + pub fn witness( + mut cs: CS, + p: Option>, + params: &E::Params + ) -> Result + where CS: ConstraintSystem + { + let p = p.map(|p| p.into_xy()); + + // Allocate x + let x = AllocatedNum::alloc( + cs.namespace(|| "x"), + || { + Ok(p.get()?.0) + } + )?; + + // Allocate y + let y = AllocatedNum::alloc( + cs.namespace(|| "y"), + || { + Ok(p.get()?.1) + } + )?; + + Self::interpret( + cs.namespace(|| "point interpretation"), + &x, + &y, + params + ) + } + /// This extracts the x-coordinate, which is an injective /// encoding for elements of the prime order subgroup. pub fn into_num(&self) -> AllocatedNum { @@ -723,6 +759,23 @@ mod test { let params = &JubjubBls12::new(); let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); + for _ in 0..100 { + let p = edwards::Point::::rand(rng, ¶ms); + + let mut cs = TestConstraintSystem::::new(); + let q = EdwardsPoint::witness( + &mut cs, + Some(p.clone()), + ¶ms + ).unwrap(); + + let p = p.into_xy(); + + assert!(cs.is_satisfied()); + assert_eq!(q.x.get_value().unwrap(), p.0); + assert_eq!(q.y.get_value().unwrap(), p.1); + } + for _ in 0..100 { let p = edwards::Point::::rand(rng, ¶ms); let (x, y) = p.into_xy();