Add ToConstraintFieldGadget for ProjectiveVar (#13)

This commit is contained in:
Weikeng Chen
2020-11-12 01:41:59 -08:00
committed by GitHub
parent 8dca325042
commit f4691621ee
14 changed files with 52 additions and 32 deletions

View File

@@ -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));
}

View File

@@ -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,
)?;

View File

@@ -86,7 +86,7 @@ impl<F: PrimeField> FpVar<F> {
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()

View File

@@ -224,7 +224,9 @@ impl<F: PrimeField> AllocatedFp<F> {
/// 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<F: PrimeField> AllocatedFp<F> {
#[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 @@ impl<F: PrimeField> ThreeBitCondNegLookupGadget<F> for AllocatedFp<F> {
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<F: PrimeField> AllocVar<F, F> for AllocatedFp<F> {
} 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<F: PrimeField> FieldVar<F, F> for FpVar<F> {
(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<F: PrimeField> CondSelectGadget<F> for FpVar<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)

View File

@@ -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,
)?;

View File

@@ -94,8 +94,8 @@ impl<P: MNT4Parameters> G1PreparedVar<P> {
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,
})

View File

@@ -58,10 +58,10 @@ impl<P: MNT6Parameters> G1PreparedVar<P> {
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,
};

View File

@@ -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<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<
P: SWModelParameters,
F: FieldVar<P::BaseField, <P::BaseField as Field>::BasePrimeField>,

View File

@@ -518,7 +518,7 @@ where
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) {

View File

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

View File

@@ -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)
}

View File

@@ -31,8 +31,8 @@ impl<P: Bls12Parameters> PairingVar<P> {
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 @@ impl<P: Bls12Parameters> PairingVar<P> {
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(())
}

View File

@@ -101,14 +101,15 @@ impl<P: MNT4Parameters> PairingVar<P> {
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,

View File

@@ -96,14 +96,15 @@ impl<P: MNT6Parameters> PairingVar<P> {
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,