Browse Source

Add ToConstraintFieldGadget for ProjectiveVar (#13)

master
Weikeng Chen 4 years ago
committed by GitHub
parent
commit
f4691621ee
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 52 additions and 32 deletions
  1. +4
    -4
      src/bits/uint.rs
  2. +1
    -1
      src/fields/cubic_extension.rs
  3. +1
    -1
      src/fields/fp/cmp.rs
  4. +8
    -6
      src/fields/fp/mod.rs
  5. +1
    -1
      src/fields/quadratic_extension.rs
  6. +2
    -2
      src/groups/curves/short_weierstrass/mnt4/mod.rs
  7. +3
    -3
      src/groups/curves/short_weierstrass/mnt6/mod.rs
  8. +16
    -1
      src/groups/curves/short_weierstrass/mod.rs
  9. +1
    -1
      src/groups/curves/twisted_edwards/mod.rs
  10. +1
    -0
      src/lib.rs
  11. +2
    -2
      src/macros.rs
  12. +4
    -4
      src/pairing/bls12/mod.rs
  13. +4
    -3
      src/pairing/mnt4/mod.rs
  14. +4
    -3
      src/pairing/mnt6/mod.rs

+ 4
- 4
src/bits/uint.rs

@ -103,17 +103,17 @@ macro_rules! make_uint {
for b in bits.iter().rev() { for b in bits.iter().rev() {
value.as_mut().map(|v| *v <<= 1); 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)); 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) => { Ok(b) => {
value.as_mut().map(|v| *v |= $native::from(b)); value.as_mut().map(|v| *v |= $native::from(b));
} }
Err(_) => value = None, Err(_) => value = None,
}, },
&Boolean::Not(ref b) => match b.value() {
Boolean::Not(ref b) => match b.value() {
Ok(b) => { Ok(b) => {
value.as_mut().map(|v| *v |= $native::from(!b)); value.as_mut().map(|v| *v |= $native::from(!b));
} }

+ 1
- 1
src/fields/cubic_extension.rs

@ -276,7 +276,7 @@ where
self.cs(), self.cs(),
|| { || {
self.value() self.value()
.map(|f| f.inverse().unwrap_or(CubicExtField::zero()))
.map(|f| f.inverse().unwrap_or_else(CubicExtField::zero))
}, },
mode, mode,
)?; )?;

+ 1
- 1
src/fields/fp/cmp.rs

@ -86,7 +86,7 @@ impl FpVar {
let (left, right) = match ordering { let (left, right) = match ordering {
Ordering::Less => (self, other), Ordering::Less => (self, other),
Ordering::Greater => (other, self), Ordering::Greater => (other, self),
Ordering::Equal => Err(SynthesisError::Unsatisfiable)?,
Ordering::Equal => return Err(SynthesisError::Unsatisfiable),
}; };
let right_for_check = if should_also_check_equality { let right_for_check = if should_also_check_equality {
right + F::one() right + F::one()

+ 8
- 6
src/fields/fp/mod.rs

@ -224,7 +224,9 @@ impl AllocatedFp {
/// This does not create any constraints. /// This does not create any constraints.
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
pub fn negate_in_place(&mut self) -> &mut Self { 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.variable = self.cs.new_lc(lc!() - self.variable).unwrap();
self self
} }
@ -243,7 +245,7 @@ impl AllocatedFp {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
pub fn inverse(&self) -> Result<Self, SynthesisError> { pub fn inverse(&self) -> Result<Self, SynthesisError> {
let inverse = Self::new_witness(self.cs.clone(), || { 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( self.cs.enforce_constraint(
@ -595,7 +597,7 @@ impl ThreeBitCondNegLookupGadget for AllocatedFp {
b.cs().enforce_constraint( b.cs().enforce_constraint(
y_lc.clone() + y_lc.clone(), y_lc.clone() + y_lc.clone(),
b[2].lc(), b[2].lc(),
y_lc.clone() - result.variable,
y_lc - result.variable,
)?; )?;
Ok(result) Ok(result)
@ -625,7 +627,7 @@ impl AllocVar for AllocatedFp {
} else { } else {
cs.new_witness_variable(value_generator)? 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), Var(v3)) => v1.mul_equals(v2, v3),
(Var(v1), Var(v2), Constant(f)) => { (Var(v1), Var(v2), Constant(f)) => {
let cs = v1.cs.clone(); 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) v1.mul_equals(v2, &v3)
} }
} }
@ -937,7 +939,7 @@ impl CondSelectGadget for FpVar {
Self::Var(v) => v.clone(), Self::Var(v) => v.clone(),
}; };
let false_value = match false_value { 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(), Self::Var(v) => v.clone(),
}; };
cond.select(&true_value, &false_value).map(Self::Var) cond.select(&true_value, &false_value).map(Self::Var)

+ 1
- 1
src/fields/quadratic_extension.rs

@ -284,7 +284,7 @@ where
self.cs(), self.cs(),
|| { || {
self.value() self.value()
.map(|f| f.inverse().unwrap_or(QuadExtField::zero()))
.map(|f| f.inverse().unwrap_or_else(QuadExtField::zero))
}, },
mode, mode,
)?; )?;

+ 2
- 2
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 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); let y_twist = Fp2Var::new(&q.y * P::TWIST.c0, &q.y * P::TWIST.c1);
Ok(G1PreparedVar { Ok(G1PreparedVar {
x: q.x.clone(),
y: q.y.clone(),
x: q.x,
y: q.y,
x_twist, x_twist,
y_twist, y_twist,
}) })

+ 3
- 3
src/groups/curves/short_weierstrass/mnt6/mod.rs

@ -58,10 +58,10 @@ impl G1PreparedVar

{

let q = q.to_affine()?; let q = q.to_affine()?;
let zero = FpVar::<P::Fp>::zero(); let zero = FpVar::<P::Fp>::zero();
let x_twist = Fp3Var::new(q.x.clone(), zero.clone(), zero.clone()) * P::TWIST; 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 { let result = G1PreparedVar {
x: q.x.clone(),
y: q.y.clone(),
x: q.x,
y: q.y,
x_twist, x_twist,
y_twist, y_twist,
}; };

+ 16
- 1
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.x.to_constraint_field()?);
res.extend_from_slice(&self.y.to_constraint_field()?); res.extend_from_slice(&self.y.to_constraint_field()?);
res.extend_from_slice(&self.infinity.to_constraint_field()?);
Ok(res) Ok(res)
} }
@ -163,7 +164,7 @@ where
// Allocate a variable whose value is either `self.z.inverse()` if the inverse exists, // Allocate a variable whose value is either `self.z.inverse()` if the inverse exists,
// and is zero otherwise. // and is zero otherwise.
let z_inv = F::new_witness(ark_relations::ns!(cs, "z_inverse"), || { 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()`. // The inverse exists if `!self.is_zero()`.
// This means that `z_inv * self.z = 1` if `self.is_not_zero()`, and // This means that `z_inv * self.z = 1` if `self.is_not_zero()`, and
@ -347,6 +348,20 @@ where
} }
} }
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()
}
}
fn mul_by_coeff_a< fn mul_by_coeff_a<
P: SWModelParameters, P: SWModelParameters,
F: FieldVar<P::BaseField, <P::BaseField as Field>::BasePrimeField>, F: FieldVar<P::BaseField, <P::BaseField as Field>::BasePrimeField>,

+ 1
- 1
src/groups/curves/twisted_edwards/mod.rs

@ -518,7 +518,7 @@ where
B: Borrow<Boolean<<P::BaseField as Field>::BasePrimeField>>, B: Borrow<Boolean<<P::BaseField as Field>::BasePrimeField>>,
{ {
let scalar_bits_with_base_powers = scalar_bits_with_base_powers 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>)>>(); .collect::<Vec<(_, TEProjective<P>)>>();
let zero = TEProjective::zero(); let zero = TEProjective::zero();
for bits_base_powers in scalar_bits_with_base_powers.chunks(2) { for bits_base_powers in scalar_bits_with_base_powers.chunks(2) {

+ 1
- 0
src/lib.rs

@ -8,6 +8,7 @@
nonstandard_style, nonstandard_style,
rust_2018_idioms rust_2018_idioms
)] )]
#![allow(clippy::op_ref)]
#[macro_use] #[macro_use]
extern crate ark_std; extern crate ark_std;

+ 2
- 2
src/macros.rs

@ -50,7 +50,7 @@ macro_rules! impl_bounded_ops {
type Output = $type; type Output = $type;
#[tracing::instrument(target = "r1cs", skip(self))] #[tracing::instrument(target = "r1cs", skip(self))]
#[allow(unused_braces)]
#[allow(unused_braces, clippy::redundant_closure_call)]
fn $fn(self, other: Self) -> Self::Output { fn $fn(self, other: Self) -> Self::Output {
($impl)(self, other) ($impl)(self, other)
} }
@ -130,7 +130,7 @@ macro_rules! impl_bounded_ops {
type Output = $type; type Output = $type;
#[tracing::instrument(target = "r1cs", skip(self))] #[tracing::instrument(target = "r1cs", skip(self))]
#[allow(unused_braces)]
#[allow(unused_braces, clippy::redundant_closure_call)]
fn $fn(self, other: $native) -> Self::Output { fn $fn(self, other: $native) -> Self::Output {
($constant_impl)(self, other) ($constant_impl)(self, other)
} }

+ 4
- 4
src/pairing/bls12/mod.rs

@ -31,8 +31,8 @@ impl PairingVar

{

let mut c1 = coeffs.1.clone(); let mut c1 = coeffs.1.clone();
let c2 = Fp2V::<P>::new(p.y.clone(), zero); 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)?; *f = f.mul_by_014(&c0, &c1, &c2)?;
Ok(()) Ok(())
} }
@ -41,8 +41,8 @@ impl PairingVar

{

let mut c1 = coeffs.0.clone(); let mut c1 = coeffs.0.clone();
let c2 = coeffs.1.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)?; *f = f.mul_by_034(&c0, &c1, &c2)?;
Ok(()) Ok(())
} }

+ 4
- 3
src/pairing/mnt4/mod.rs

@ -101,14 +101,15 @@ impl PairingVar

{

let mut f = Fp4G::<P>::one(); let mut f = Fp4G::<P>::one();
let mut dbl_idx: usize = 0;
let mut add_idx: usize = 0; let mut add_idx: usize = 0;
// code below gets executed for all bits (EXCEPT the MSB itself) of // code below gets executed for all bits (EXCEPT the MSB itself) of
// mnt6_param_p (skipping leading zeros) in MSB to LSB order // 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]; let dc = &q.double_coefficients[dbl_idx];
dbl_idx += 1;
let g_rr_at_p = Fp4G::<P>::new( let g_rr_at_p = Fp4G::<P>::new(
&dc.c_l - &dc.c_4c - &dc.c_j * &p.x_twist, &dc.c_l - &dc.c_4c - &dc.c_j * &p.x_twist,

+ 4
- 3
src/pairing/mnt6/mod.rs

@ -96,14 +96,15 @@ impl PairingVar

{

let mut f = Fp6G::<P>::one(); let mut f = Fp6G::<P>::one();
let mut dbl_idx: usize = 0;
let mut add_idx: usize = 0; let mut add_idx: usize = 0;
// code below gets executed for all bits (EXCEPT the MSB itself) of // code below gets executed for all bits (EXCEPT the MSB itself) of
// mnt6_param_p (skipping leading zeros) in MSB to LSB order // 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]; let dc = &q.double_coefficients[dbl_idx];
dbl_idx += 1;
let g_rr_at_p = Fp6Var::new( let g_rr_at_p = Fp6Var::new(
&dc.c_l - &dc.c_4c - &dc.c_j * &p.x_twist, &dc.c_l - &dc.c_4c - &dc.c_j * &p.x_twist,

Loading…
Cancel
Save