Add ToConstraintFieldGadget for ProjectiveVar (#13)
jump to
@@ -103,17 +103,17 @@ let mut value = Some(0);
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)); }
@@ -276,7 +276,7 @@ let inverse = Self::new_variable(
self.cs(), || { self.value() - .map(|f| f.inverse().unwrap_or(CubicExtField::zero())) + .map(|f| f.inverse().unwrap_or_else(CubicExtField::zero)) }, mode, )?;
@@ -86,7 +86,7 @@ ) -> Result<(Self, Self), SynthesisError> {
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()
@@ -224,7 +224,9 @@ ///
/// 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 @@ /// This requires *one* constraint.
#[tracing::instrument(target = "r1cs")] pub fn inverse(&self) -> Result<Self, SynthesisError> { 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 @@ + (c[0], Variable::One);
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 @@ cs.new_input_variable(value_generator)?
} else { cs.new_witness_variable(value_generator)? }; - Ok(Self::new(value, variable, cs.clone())) + Ok(Self::new(value, variable, cs)) } } }@@ -679,7 +681,7 @@ } // this multiplication should be free
(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 @@ Self::Constant(f) => AllocatedFp::new_constant(cs.clone(), f)?,
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)
@@ -284,7 +284,7 @@ let inverse = Self::new_variable(
self.cs(), || { self.value() - .map(|f| f.inverse().unwrap_or(QuadExtField::zero())) + .map(|f| f.inverse().unwrap_or_else(QuadExtField::zero)) }, mode, )?;
@@ -94,8 +94,8 @@ let q = q.to_affine()?;
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, })
@@ -58,10 +58,10 @@ pub fn from_group_var(q: &G1Var<P>) -> Result<Self, SynthesisError> {
let q = q.to_affine()?; let zero = FpVar::<P::Fp>::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, };
@@ -103,6 +103,7 @@ let mut res = Vec::<FpVar<<P::BaseField as Field>::BasePrimeField>>::new();
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 @@ let zero_y = F::one();
// 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@@ -344,6 +345,20 @@
#[tracing::instrument(target = "r1cs")] fn negate(&self) -> Result<Self, SynthesisError> { Ok(Self::new(self.x.clone(), self.y.negate()?, self.z.clone())) + } +} + +impl<P, F> ToConstraintFieldGadget<<P::BaseField as Field>::BasePrimeField> for ProjectiveVar<P, F> +where + P: SWModelParameters, + F: FieldVar<P::BaseField, <P::BaseField as Field>::BasePrimeField>, + for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>, + F: ToConstraintFieldGadget<<P::BaseField as Field>::BasePrimeField>, +{ + fn to_constraint_field( + &self, + ) -> Result<Vec<FpVar<<P::BaseField as Field>::BasePrimeField>>, SynthesisError> { + self.to_affine()?.to_constraint_field() } }
@@ -518,7 +518,7 @@ I: Iterator<Item = (B, &'a TEProjective<P>)>,
B: Borrow<Boolean<<P::BaseField as Field>::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::<Vec<(_, TEProjective<P>)>>(); let zero = TEProjective::zero(); for bits_base_powers in scalar_bits_with_base_powers.chunks(2) {
@@ -8,6 +8,7 @@ future_incompatible,
nonstandard_style, rust_2018_idioms )] +#![allow(clippy::op_ref)] #[macro_use] extern crate ark_std;
@@ -50,7 +50,7 @@ {
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 @@ {
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) }
@@ -31,8 +31,8 @@ let c0 = coeffs.0.clone();
let mut c1 = coeffs.1.clone(); let c2 = Fp2V::<P>::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 @@ let c0 = Fp2V::<P>::new(p.y.clone(), zero);
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(()) }
@@ -101,14 +101,15 @@ let l1_coeff = Fp2G::<P>::new(p.x.clone(), FpVar::<P::Fp>::zero()) - &q.x_over_twist;
let mut f = Fp4G::<P>::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::<P>::new( &dc.c_l - &dc.c_4c - &dc.c_j * &p.x_twist,
@@ -96,14 +96,15 @@ let l1_coeff = Fp3Var::new(p.x.clone(), zero.clone(), zero) - &q.x_over_twist;
let mut f = Fp6G::<P>::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,