Skip to content

Commit

Permalink
chore: Implement SubAssign trait for UniPoly
Browse files Browse the repository at this point in the history
  • Loading branch information
storojs72 committed Feb 28, 2024
1 parent 1d7a3cf commit 2017748
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
11 changes: 2 additions & 9 deletions src/provider/hyperkzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,8 @@ where
let mut tmp = Q_x.clone();
tmp *= &D.evaluate(&a);
tmp[0] += &R_x.evaluate(&a);
tmp = UniPoly::new(
tmp
.coeffs
.into_iter()
.map(|coeff| -coeff)
.collect::<Vec<E::Fr>>(),
);
let mut K_x = batched_Pi.clone();
K_x += &tmp;
K_x -= &tmp;
K_x
}
}
Expand Down Expand Up @@ -245,7 +238,7 @@ where
let K_x = Self::compute_k_polynomial(&batched_Pi, &Q_x, &D, &R_x, a);

// TODO: since this is a usual KZG10 we should use it as utility instead
let h = K_x.divide_minus_u(a).unwrap();
let h = K_x.divide_minus_u(a);
let C_H = <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &h.coeffs)
.comm
.to_affine();
Expand Down
2 changes: 1 addition & 1 deletion src/provider/non_hiding_zeromorph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ where
point: &E::Fr,
) -> Result<(UVKZGProof<E>, UVKZGEvaluation<E>), NovaError> {
let prover_param = prover_param.borrow();
let witness_polynomial = polynomial.divide_minus_u(*point).unwrap();
let witness_polynomial = polynomial.divide_minus_u(*point);
let proof = <E::G1 as DlogGroup>::vartime_multiscalar_mul(
witness_polynomial.coeffs.as_slice(),
&prover_param.powers_of_g()[..witness_polynomial.coeffs.len()],
Expand Down
27 changes: 23 additions & 4 deletions src/spartan/polys/univariate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Main components:
//! - `UniPoly`: an univariate dense polynomial in coefficient form (big endian),
//! - `CompressedUniPoly`: a univariate dense polynomial, compressed (omitted linear term), in coefficient form (little endian),
use std::ops::SubAssign;
use std::{
cmp::Ordering,
ops::{AddAssign, Index, IndexMut, MulAssign},
Expand Down Expand Up @@ -76,9 +77,9 @@ impl<Scalar: PrimeField> UniPoly<Scalar> {

/// Divides f(x) by x-a and returns quotient polynomial with no reminder
/// This is a common use case for polynomial divisions in KZG-based PCS.
pub fn divide_minus_u(&self, u: Scalar) -> Option<Self> {
pub fn divide_minus_u(&self, u: Scalar) -> Self {
if self.is_zero() {
Some(Self::zero())
Self::zero()
} else {
// On input f(x) and u compute the witness polynomial used to prove
// that f(u) = v. The main part of this is to compute the
Expand All @@ -101,7 +102,7 @@ impl<Scalar: PrimeField> UniPoly<Scalar> {
for i in (1..d).rev() {
h[i - 1] = self.coeffs[i] + h[i] * u;
}
Some(Self::new(h))
Self::new(h)
}
}

Expand Down Expand Up @@ -260,6 +261,24 @@ impl<Scalar: PrimeField> AddAssign<&Self> for UniPoly<Scalar> {
}
}

impl<Scalar: PrimeField> SubAssign<&Self> for UniPoly<Scalar> {
fn sub_assign(&mut self, rhs: &Self) {
let ordering = self.coeffs.len().cmp(&rhs.coeffs.len());
#[allow(clippy::disallowed_methods)]
for (lhs, rhs) in self.coeffs.iter_mut().zip(&rhs.coeffs) {
*lhs -= rhs;
}
if matches!(ordering, Ordering::Less) {
self
.coeffs
.extend(rhs.coeffs[self.coeffs.len()..].iter().cloned());
}
if matches!(ordering, Ordering::Equal) {
self.truncate_leading_zeros();
}
}
}

impl<Scalar: PrimeField> AsRef<Vec<Scalar>> for UniPoly<Scalar> {
fn as_ref(&self) -> &Vec<Scalar> {
&self.coeffs
Expand Down Expand Up @@ -382,7 +401,7 @@ mod tests {
let divisor = UniPoly::new(vec![-u, Fr::ONE]);

let (q1, _) = dividend.divide_with_q_and_r(&divisor).unwrap();
let q2 = dividend.divide_minus_u(u).unwrap();
let q2 = dividend.divide_minus_u(u);

assert_eq!(q1, q2);
}
Expand Down

0 comments on commit 2017748

Please sign in to comment.