mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-09 07:21:29 +01:00
Add ToConstraintFieldGadget for ProjectiveVar (#13)
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)?;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
)?;
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![allow(clippy::op_ref)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate ark_std;
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user