mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-09 23:41:33 +01:00
Make mul_by_inverse use one constraint (#42)
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
- #9 Fix bug in short weierstrass projective curve point's to_affine method
|
- #9 Fix bug in short weierstrass projective curve point's to_affine method
|
||||||
- #29 Fix `to_non_unique_bytes` for `BLS12::G1Prepared`
|
- #29 Fix `to_non_unique_bytes` for `BLS12::G1Prepared`
|
||||||
- #34 Fix `mul_by_inverse` for constants
|
- #34 Fix `mul_by_inverse` for constants
|
||||||
|
- #42 Fix regression in `mul_by_inverse` constraint count
|
||||||
|
|
||||||
## v0.1.0
|
## v0.1.0
|
||||||
|
|
||||||
|
|||||||
@@ -716,21 +716,6 @@ impl<F: PrimeField> FieldVar<F, F> for FpVar<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns (self / denominator), but requires fewer constraints than
|
|
||||||
/// self * denominator.inverse()
|
|
||||||
/// It is up to the caller to ensure that denominator is non-zero,
|
|
||||||
/// since in that case the result is unconstrained.
|
|
||||||
#[tracing::instrument(target = "r1cs")]
|
|
||||||
fn mul_by_inverse(&self, denominator: &Self) -> Result<Self, SynthesisError> {
|
|
||||||
use FpVar::*;
|
|
||||||
match (self, denominator) {
|
|
||||||
(Constant(s), Constant(d)) => Ok(Constant(*s / *d)),
|
|
||||||
(Var(s), Constant(d)) => Ok(Var(s.mul_constant(d.inverse().get()?))),
|
|
||||||
(Constant(s), Var(d)) => Ok(Var(d.inverse()?.mul_constant(*s))),
|
|
||||||
(Var(s), Var(d)) => Ok(Var(d.inverse()?.mul(s))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(target = "r1cs")]
|
#[tracing::instrument(target = "r1cs")]
|
||||||
fn frobenius_map(&self, power: usize) -> Result<Self, SynthesisError> {
|
fn frobenius_map(&self, power: usize) -> Result<Self, SynthesisError> {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use core::{
|
|||||||
ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign},
|
ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{prelude::*, Assignment};
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// This module contains a generic implementation of cubic extension field
|
/// This module contains a generic implementation of cubic extension field
|
||||||
/// variables. That is, it implements the R1CS equivalent of
|
/// variables. That is, it implements the R1CS equivalent of
|
||||||
@@ -155,23 +155,16 @@ pub trait FieldVar<F: Field, ConstraintF: Field>:
|
|||||||
/// Computes `result` such that `self * result == Self::one()`.
|
/// Computes `result` such that `self * result == Self::one()`.
|
||||||
fn inverse(&self) -> Result<Self, SynthesisError>;
|
fn inverse(&self) -> Result<Self, SynthesisError>;
|
||||||
|
|
||||||
/// Returns `(self / denominator)`. but requires fewer constraints than
|
/// Returns `(self / d)`. but requires fewer constraints than `self * d.inverse()`.
|
||||||
/// `self * denominator.inverse()`.
|
/// It is up to the caller to ensure that `d` is non-zero,
|
||||||
/// It is up to the caller to ensure that denominator is non-zero,
|
|
||||||
/// since in that case the result is unconstrained.
|
/// since in that case the result is unconstrained.
|
||||||
fn mul_by_inverse(&self, denominator: &Self) -> Result<Self, SynthesisError> {
|
fn mul_by_inverse(&self, d: &Self) -> Result<Self, SynthesisError> {
|
||||||
if denominator.is_constant() {
|
let d_inv = if self.is_constant() || d.is_constant() {
|
||||||
Ok(denominator.inverse()? * self)
|
d.inverse()?
|
||||||
} else {
|
} else {
|
||||||
let result = Self::new_witness(self.cs(), || {
|
Self::new_witness(self.cs(), || Ok(d.value()?.inverse().unwrap_or(F::zero())))?
|
||||||
let denominator_inv_native = denominator.value()?.inverse().get()?;
|
};
|
||||||
let result = self.value()? * &denominator_inv_native;
|
Ok(d_inv * self)
|
||||||
Ok(result)
|
|
||||||
})?;
|
|
||||||
result.mul_equals(&denominator, &self)?;
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the frobenius map over `self`.
|
/// Computes the frobenius map over `self`.
|
||||||
|
|||||||
Reference in New Issue
Block a user