mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-09 23:41:33 +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() {
|
for b in bits.iter().rev() {
|
||||||
value.as_mut().map(|v| *v <<= 1);
|
value.as_mut().map(|v| *v <<= 1);
|
||||||
|
|
||||||
match b {
|
match *b {
|
||||||
&Boolean::Constant(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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ impl<F: PrimeField> FpVar<F> {
|
|||||||
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()
|
||||||
|
|||||||
@@ -224,7 +224,9 @@ impl<F: PrimeField> AllocatedFp<F> {
|
|||||||
/// 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<F: PrimeField> AllocatedFp<F> {
|
|||||||
#[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<F: PrimeField> ThreeBitCondNegLookupGadget<F> for AllocatedFp<F> {
|
|||||||
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<F: PrimeField> AllocVar<F, F> for AllocatedFp<F> {
|
|||||||
} 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<F: PrimeField> FieldVar<F, F> for FpVar<F> {
|
|||||||
(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<F: PrimeField> CondSelectGadget<F> for FpVar<F> {
|
|||||||
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)
|
||||||
|
|||||||
@@ -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,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -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 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(),
|
x: q.x,
|
||||||
y: q.y.clone(),
|
y: q.y,
|
||||||
x_twist,
|
x_twist,
|
||||||
y_twist,
|
y_twist,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ impl<P: MNT6Parameters> G1PreparedVar<P> {
|
|||||||
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(),
|
x: q.x,
|
||||||
y: q.y.clone(),
|
y: q.y,
|
||||||
x_twist,
|
x_twist,
|
||||||
y_twist,
|
y_twist,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>,
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ impl<P: Bls12Parameters> PairingVar<P> {
|
|||||||
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.c0 *= &p.x;
|
||||||
c1.c1 = c1.c1 * &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<P: Bls12Parameters> PairingVar<P> {
|
|||||||
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.c0 *= &p.x;
|
||||||
c1.c1 = c1.c1 * &p.x;
|
c1.c1 *= &p.x;
|
||||||
*f = f.mul_by_034(&c0, &c1, &c2)?;
|
*f = f.mul_by_034(&c0, &c1, &c2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,14 +101,15 @@ impl<P: MNT4Parameters> PairingVar<P> {
|
|||||||
|
|
||||||
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,
|
||||||
|
|||||||
@@ -96,14 +96,15 @@ impl<P: MNT6Parameters> PairingVar<P> {
|
|||||||
|
|
||||||
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,
|
||||||
|
|||||||
Reference in New Issue
Block a user