From f4691621ee2e17121090805d278bdcfe8ee4c03a Mon Sep 17 00:00:00 2001 From: Weikeng Chen Date: Thu, 12 Nov 2020 01:41:59 -0800 Subject: [PATCH] Add ToConstraintFieldGadget for ProjectiveVar (#13) --- src/bits/uint.rs | 8 ++++---- src/fields/cubic_extension.rs | 2 +- src/fields/fp/cmp.rs | 2 +- src/fields/fp/mod.rs | 14 ++++++++------ src/fields/quadratic_extension.rs | 2 +- src/groups/curves/short_weierstrass/mnt4/mod.rs | 4 ++-- src/groups/curves/short_weierstrass/mnt6/mod.rs | 6 +++--- src/groups/curves/short_weierstrass/mod.rs | 17 ++++++++++++++++- src/groups/curves/twisted_edwards/mod.rs | 2 +- src/lib.rs | 1 + src/macros.rs | 4 ++-- src/pairing/bls12/mod.rs | 8 ++++---- src/pairing/mnt4/mod.rs | 7 ++++--- src/pairing/mnt6/mod.rs | 7 ++++--- 14 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/bits/uint.rs b/src/bits/uint.rs index 2bafeb2..8c92b31 100644 --- a/src/bits/uint.rs +++ b/src/bits/uint.rs @@ -103,17 +103,17 @@ macro_rules! make_uint { for b in bits.iter().rev() { value.as_mut().map(|v| *v <<= 1); - match b { - &Boolean::Constant(b) => { + match *b { + Boolean::Constant(b) => { value.as_mut().map(|v| *v |= $native::from(b)); } - &Boolean::Is(ref b) => match b.value() { + Boolean::Is(ref b) => match b.value() { Ok(b) => { value.as_mut().map(|v| *v |= $native::from(b)); } Err(_) => value = None, }, - &Boolean::Not(ref b) => match b.value() { + Boolean::Not(ref b) => match b.value() { Ok(b) => { value.as_mut().map(|v| *v |= $native::from(!b)); } diff --git a/src/fields/cubic_extension.rs b/src/fields/cubic_extension.rs index eb3e3d1..5a5f5af 100644 --- a/src/fields/cubic_extension.rs +++ b/src/fields/cubic_extension.rs @@ -276,7 +276,7 @@ where self.cs(), || { self.value() - .map(|f| f.inverse().unwrap_or(CubicExtField::zero())) + .map(|f| f.inverse().unwrap_or_else(CubicExtField::zero)) }, mode, )?; diff --git a/src/fields/fp/cmp.rs b/src/fields/fp/cmp.rs index dcdf036..58f7cf4 100644 --- a/src/fields/fp/cmp.rs +++ b/src/fields/fp/cmp.rs @@ -86,7 +86,7 @@ impl FpVar { let (left, right) = match ordering { Ordering::Less => (self, other), Ordering::Greater => (other, self), - Ordering::Equal => Err(SynthesisError::Unsatisfiable)?, + Ordering::Equal => return Err(SynthesisError::Unsatisfiable), }; let right_for_check = if should_also_check_equality { right + F::one() diff --git a/src/fields/fp/mod.rs b/src/fields/fp/mod.rs index d6e035c..1b96704 100644 --- a/src/fields/fp/mod.rs +++ b/src/fields/fp/mod.rs @@ -224,7 +224,9 @@ impl AllocatedFp { /// This does not create any constraints. #[tracing::instrument(target = "r1cs")] pub fn negate_in_place(&mut self) -> &mut Self { - self.value.as_mut().map(|val| *val = -(*val)); + if let Some(val) = self.value.as_mut() { + *val = -(*val); + } self.variable = self.cs.new_lc(lc!() - self.variable).unwrap(); self } @@ -243,7 +245,7 @@ impl AllocatedFp { #[tracing::instrument(target = "r1cs")] pub fn inverse(&self) -> Result { let inverse = Self::new_witness(self.cs.clone(), || { - Ok(self.value.get()?.inverse().unwrap_or(F::zero())) + Ok(self.value.get()?.inverse().unwrap_or_else(F::zero)) })?; self.cs.enforce_constraint( @@ -595,7 +597,7 @@ impl ThreeBitCondNegLookupGadget for AllocatedFp { b.cs().enforce_constraint( y_lc.clone() + y_lc.clone(), b[2].lc(), - y_lc.clone() - result.variable, + y_lc - result.variable, )?; Ok(result) @@ -625,7 +627,7 @@ impl AllocVar for AllocatedFp { } else { cs.new_witness_variable(value_generator)? }; - Ok(Self::new(value, variable, cs.clone())) + Ok(Self::new(value, variable, cs)) } } } @@ -679,7 +681,7 @@ impl FieldVar for FpVar { (Var(v1), Var(v2), Var(v3)) => v1.mul_equals(v2, v3), (Var(v1), Var(v2), Constant(f)) => { let cs = v1.cs.clone(); - let v3 = AllocatedFp::new_constant(cs.clone(), f).unwrap(); + let v3 = AllocatedFp::new_constant(cs, f).unwrap(); v1.mul_equals(v2, &v3) } } @@ -937,7 +939,7 @@ impl CondSelectGadget for FpVar { Self::Var(v) => v.clone(), }; let false_value = match false_value { - Self::Constant(f) => AllocatedFp::new_constant(cs.clone(), f)?, + Self::Constant(f) => AllocatedFp::new_constant(cs, f)?, Self::Var(v) => v.clone(), }; cond.select(&true_value, &false_value).map(Self::Var) diff --git a/src/fields/quadratic_extension.rs b/src/fields/quadratic_extension.rs index 4107107..28b771d 100644 --- a/src/fields/quadratic_extension.rs +++ b/src/fields/quadratic_extension.rs @@ -284,7 +284,7 @@ where self.cs(), || { self.value() - .map(|f| f.inverse().unwrap_or(QuadExtField::zero())) + .map(|f| f.inverse().unwrap_or_else(QuadExtField::zero)) }, mode, )?; diff --git a/src/groups/curves/short_weierstrass/mnt4/mod.rs b/src/groups/curves/short_weierstrass/mnt4/mod.rs index 49421ed..bd0bdc6 100644 --- a/src/groups/curves/short_weierstrass/mnt4/mod.rs +++ b/src/groups/curves/short_weierstrass/mnt4/mod.rs @@ -94,8 +94,8 @@ impl G1PreparedVar

{ let x_twist = Fp2Var::new(&q.x * P::TWIST.c0, &q.x * P::TWIST.c1); let y_twist = Fp2Var::new(&q.y * P::TWIST.c0, &q.y * P::TWIST.c1); Ok(G1PreparedVar { - x: q.x.clone(), - y: q.y.clone(), + x: q.x, + y: q.y, x_twist, y_twist, }) diff --git a/src/groups/curves/short_weierstrass/mnt6/mod.rs b/src/groups/curves/short_weierstrass/mnt6/mod.rs index 4b6d55e..8234230 100644 --- a/src/groups/curves/short_weierstrass/mnt6/mod.rs +++ b/src/groups/curves/short_weierstrass/mnt6/mod.rs @@ -58,10 +58,10 @@ impl G1PreparedVar

{ let q = q.to_affine()?; let zero = FpVar::::zero(); let x_twist = Fp3Var::new(q.x.clone(), zero.clone(), zero.clone()) * P::TWIST; - let y_twist = Fp3Var::new(q.y.clone(), zero.clone(), zero.clone()) * P::TWIST; + let y_twist = Fp3Var::new(q.y.clone(), zero.clone(), zero) * P::TWIST; let result = G1PreparedVar { - x: q.x.clone(), - y: q.y.clone(), + x: q.x, + y: q.y, x_twist, y_twist, }; diff --git a/src/groups/curves/short_weierstrass/mod.rs b/src/groups/curves/short_weierstrass/mod.rs index 1976708..d736873 100644 --- a/src/groups/curves/short_weierstrass/mod.rs +++ b/src/groups/curves/short_weierstrass/mod.rs @@ -103,6 +103,7 @@ where res.extend_from_slice(&self.x.to_constraint_field()?); res.extend_from_slice(&self.y.to_constraint_field()?); + res.extend_from_slice(&self.infinity.to_constraint_field()?); Ok(res) } @@ -163,7 +164,7 @@ where // Allocate a variable whose value is either `self.z.inverse()` if the inverse exists, // and is zero otherwise. let z_inv = F::new_witness(ark_relations::ns!(cs, "z_inverse"), || { - Ok(self.z.value()?.inverse().unwrap_or(P::BaseField::zero())) + Ok(self.z.value()?.inverse().unwrap_or_else(P::BaseField::zero)) })?; // The inverse exists if `!self.is_zero()`. // This means that `z_inv * self.z = 1` if `self.is_not_zero()`, and @@ -347,6 +348,20 @@ where } } +impl ToConstraintFieldGadget<::BasePrimeField> for ProjectiveVar +where + P: SWModelParameters, + F: FieldVar::BasePrimeField>, + for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, + F: ToConstraintFieldGadget<::BasePrimeField>, +{ + fn to_constraint_field( + &self, + ) -> Result::BasePrimeField>>, SynthesisError> { + self.to_affine()?.to_constraint_field() + } +} + fn mul_by_coeff_a< P: SWModelParameters, F: FieldVar::BasePrimeField>, diff --git a/src/groups/curves/twisted_edwards/mod.rs b/src/groups/curves/twisted_edwards/mod.rs index 9006c58..c41a6e3 100644 --- a/src/groups/curves/twisted_edwards/mod.rs +++ b/src/groups/curves/twisted_edwards/mod.rs @@ -518,7 +518,7 @@ where B: Borrow::BasePrimeField>>, { let scalar_bits_with_base_powers = scalar_bits_with_base_powers - .map(|(bit, base)| (bit.borrow().clone(), (*base).into())) + .map(|(bit, base)| (bit.borrow().clone(), *base)) .collect::)>>(); let zero = TEProjective::zero(); for bits_base_powers in scalar_bits_with_base_powers.chunks(2) { diff --git a/src/lib.rs b/src/lib.rs index 6386584..1c3ed05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ nonstandard_style, rust_2018_idioms )] +#![allow(clippy::op_ref)] #[macro_use] extern crate ark_std; diff --git a/src/macros.rs b/src/macros.rs index 9e62a90..2770a7e 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -50,7 +50,7 @@ macro_rules! impl_bounded_ops { type Output = $type; #[tracing::instrument(target = "r1cs", skip(self))] - #[allow(unused_braces)] + #[allow(unused_braces, clippy::redundant_closure_call)] fn $fn(self, other: Self) -> Self::Output { ($impl)(self, other) } @@ -130,7 +130,7 @@ macro_rules! impl_bounded_ops { type Output = $type; #[tracing::instrument(target = "r1cs", skip(self))] - #[allow(unused_braces)] + #[allow(unused_braces, clippy::redundant_closure_call)] fn $fn(self, other: $native) -> Self::Output { ($constant_impl)(self, other) } diff --git a/src/pairing/bls12/mod.rs b/src/pairing/bls12/mod.rs index ee26801..33454c4 100644 --- a/src/pairing/bls12/mod.rs +++ b/src/pairing/bls12/mod.rs @@ -31,8 +31,8 @@ impl PairingVar

{ let mut c1 = coeffs.1.clone(); let c2 = Fp2V::

::new(p.y.clone(), zero); - c1.c0 = c1.c0 * &p.x; - c1.c1 = c1.c1 * &p.x; + c1.c0 *= &p.x; + c1.c1 *= &p.x; *f = f.mul_by_014(&c0, &c1, &c2)?; Ok(()) } @@ -41,8 +41,8 @@ impl PairingVar

{ let mut c1 = coeffs.0.clone(); let c2 = coeffs.1.clone(); - c1.c0 = c1.c0 * &p.x; - c1.c1 = c1.c1 * &p.x; + c1.c0 *= &p.x; + c1.c1 *= &p.x; *f = f.mul_by_034(&c0, &c1, &c2)?; Ok(()) } diff --git a/src/pairing/mnt4/mod.rs b/src/pairing/mnt4/mod.rs index d8ed2b8..0ddbec5 100644 --- a/src/pairing/mnt4/mod.rs +++ b/src/pairing/mnt4/mod.rs @@ -101,14 +101,15 @@ impl PairingVar

{ let mut f = Fp4G::

::one(); - let mut dbl_idx: usize = 0; let mut add_idx: usize = 0; // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order - for bit in BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT).skip(1) { + for (dbl_idx, bit) in BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT) + .skip(1) + .enumerate() + { let dc = &q.double_coefficients[dbl_idx]; - dbl_idx += 1; let g_rr_at_p = Fp4G::

::new( &dc.c_l - &dc.c_4c - &dc.c_j * &p.x_twist, diff --git a/src/pairing/mnt6/mod.rs b/src/pairing/mnt6/mod.rs index 72b2973..bb849b2 100644 --- a/src/pairing/mnt6/mod.rs +++ b/src/pairing/mnt6/mod.rs @@ -96,14 +96,15 @@ impl PairingVar

{ let mut f = Fp6G::

::one(); - let mut dbl_idx: usize = 0; let mut add_idx: usize = 0; // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order - for bit in BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT).skip(1) { + for (dbl_idx, bit) in BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT) + .skip(1) + .enumerate() + { let dc = &q.double_coefficients[dbl_idx]; - dbl_idx += 1; let g_rr_at_p = Fp6Var::new( &dc.c_l - &dc.c_4c - &dc.c_j * &p.x_twist,