mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-05 23:33:07 +00:00
Some cleanup related to the two polynomial APIs
Porting over some code from `old_polynomial`, and changing `ListPolynomialCommitment` to use the newer API. There's one remaining use of `old_polynomial` for long division; I think that can eventually go away when we switch to doing values-only FRI (unless another use comes up).
This commit is contained in:
parent
e44fbb86d0
commit
44a5e0be1b
@ -4,7 +4,6 @@ use crate::fri::{prover::fri_proof, verifier::verify_fri_proof, FriConfig};
|
||||
use crate::merkle_tree::MerkleTree;
|
||||
use crate::plonk_challenger::Challenger;
|
||||
use crate::plonk_common::reduce_with_powers;
|
||||
use crate::polynomial::old_polynomial::Polynomial;
|
||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||
use crate::proof::{FriProof, Hash};
|
||||
use crate::util::{log2_strict, reverse_index_bits_in_place, transpose};
|
||||
@ -84,8 +83,9 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
.polynomials
|
||||
.iter()
|
||||
.rev()
|
||||
.map(|p| p.clone().into())
|
||||
.fold(Polynomial::empty(), |acc, p| acc.scalar_mul(alpha).add(&p));
|
||||
.fold(PolynomialCoeffs::zero(self.degree), |acc, p| {
|
||||
&(&acc * alpha) + &p
|
||||
});
|
||||
// Scale evaluations by `alpha`.
|
||||
let composition_evals = evaluations
|
||||
.iter()
|
||||
@ -118,7 +118,11 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
|
||||
/// Given `points=(x_i)`, `evals=(y_i)` and `poly=P` with `P(x_i)=y_i`, computes the polynomial
|
||||
/// `Q=(P-I)/Z` where `I` interpolates `(x_i, y_i)` and `Z` is the vanishing polynomial on `(x_i)`.
|
||||
fn compute_quotient(points: &[F], evals: &[F], poly: &Polynomial<F>) -> Polynomial<F> {
|
||||
fn compute_quotient(
|
||||
points: &[F],
|
||||
evals: &[F],
|
||||
poly: &PolynomialCoeffs<F>,
|
||||
) -> PolynomialCoeffs<F> {
|
||||
let pairs = points
|
||||
.iter()
|
||||
.zip(evals)
|
||||
@ -126,18 +130,15 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
.collect::<Vec<_>>();
|
||||
debug_assert!(pairs.iter().all(|&(x, e)| poly.eval(x) == e));
|
||||
|
||||
let interpolant: Polynomial<F> = interpolant(&pairs).into();
|
||||
let denominator = points
|
||||
.iter()
|
||||
.fold(Polynomial::from(vec![F::ONE]), |acc, &x| {
|
||||
acc.mul(&vec![-x, F::ONE].into())
|
||||
let interpolant = interpolant(&pairs);
|
||||
let denominator = points.iter().fold(PolynomialCoeffs::one(), |acc, &x| {
|
||||
&acc * &PolynomialCoeffs::new(vec![-x, F::ONE])
|
||||
});
|
||||
let numerator = poly.add(&interpolant.neg());
|
||||
let (mut quotient, rem) = numerator.polynomial_division(&denominator);
|
||||
let numerator = poly - &interpolant;
|
||||
let (mut quotient, rem) = numerator.div_rem(&denominator);
|
||||
debug_assert!(rem.is_zero());
|
||||
|
||||
quotient.pad((quotient.degree() + 1).next_power_of_two());
|
||||
quotient
|
||||
quotient.padded(quotient.degree_plus_one().next_power_of_two())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use std::cmp::max;
|
||||
use std::ops::{Add, Mul, Sub};
|
||||
|
||||
use crate::field::fft::{fft, ifft};
|
||||
use crate::field::field::Field;
|
||||
use crate::polynomial::old_polynomial::Polynomial;
|
||||
use crate::util::log2_strict;
|
||||
use std::slice::Iter;
|
||||
|
||||
/// A polynomial in point-value form.
|
||||
///
|
||||
@ -65,6 +68,14 @@ impl<F: Field> PolynomialCoeffs<F> {
|
||||
Self::new(vec![F::ZERO; len])
|
||||
}
|
||||
|
||||
pub(crate) fn one() -> Self {
|
||||
Self::new(vec![F::ONE])
|
||||
}
|
||||
|
||||
pub(crate) fn is_zero(&self) -> bool {
|
||||
self.coeffs.iter().all(|x| x.is_zero())
|
||||
}
|
||||
|
||||
/// The number of coefficients. This does not filter out any zero coefficients, so it is not
|
||||
/// necessarily related to the degree.
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
@ -93,13 +104,13 @@ impl<F: Field> PolynomialCoeffs<F> {
|
||||
polys.into_iter().map(|p| p.lde(rate_bits)).collect()
|
||||
}
|
||||
|
||||
pub(crate) fn lde(self, rate_bits: usize) -> Self {
|
||||
let original_size = self.len();
|
||||
let lde_size = original_size << rate_bits;
|
||||
let Self { mut coeffs } = self;
|
||||
for _ in 0..(lde_size - original_size) {
|
||||
coeffs.push(F::ZERO);
|
||||
pub(crate) fn lde(&self, rate_bits: usize) -> Self {
|
||||
self.padded(self.len() << rate_bits)
|
||||
}
|
||||
|
||||
pub(crate) fn padded(&self, new_len: usize) -> Self {
|
||||
let mut coeffs = self.coeffs.clone();
|
||||
coeffs.resize(new_len, F::ZERO);
|
||||
Self { coeffs }
|
||||
}
|
||||
|
||||
@ -109,13 +120,20 @@ impl<F: Field> PolynomialCoeffs<F> {
|
||||
}
|
||||
|
||||
/// Degree of the polynomial + 1.
|
||||
fn degree_plus_one(&self) -> usize {
|
||||
pub(crate) fn degree_plus_one(&self) -> usize {
|
||||
(0usize..self.len())
|
||||
.rev()
|
||||
.find(|&i| self.coeffs[i].is_nonzero())
|
||||
.map_or(0, |i| i + 1)
|
||||
}
|
||||
|
||||
pub(crate) fn div_rem(&self, rhs: &Self) -> (Self, Self) {
|
||||
let lhs = Polynomial::from(self.clone());
|
||||
let rhs = Polynomial::from(rhs.clone());
|
||||
let (q, r) = lhs.polynomial_long_division(&rhs);
|
||||
(q.into(), r.into())
|
||||
}
|
||||
|
||||
pub fn fft(self) -> PolynomialValues<F> {
|
||||
fft(self)
|
||||
}
|
||||
@ -137,11 +155,69 @@ impl<F: Field> From<Vec<F>> for PolynomialCoeffs<F> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Add for &PolynomialCoeffs<F> {
|
||||
type Output = PolynomialCoeffs<F>;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
let len = max(self.len(), rhs.len());
|
||||
let mut coeffs = self.coeffs.clone();
|
||||
coeffs.resize(len, F::ZERO);
|
||||
for (i, &c) in rhs.coeffs.iter().enumerate() {
|
||||
coeffs[i] += c;
|
||||
}
|
||||
PolynomialCoeffs::new(coeffs)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Sub for &PolynomialCoeffs<F> {
|
||||
type Output = PolynomialCoeffs<F>;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
let len = max(self.len(), rhs.len());
|
||||
let mut coeffs = self.coeffs.clone();
|
||||
coeffs.resize(len, F::ZERO);
|
||||
for (i, &c) in rhs.coeffs.iter().enumerate() {
|
||||
coeffs[i] -= c;
|
||||
}
|
||||
PolynomialCoeffs::new(coeffs)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Mul<F> for &PolynomialCoeffs<F> {
|
||||
type Output = PolynomialCoeffs<F>;
|
||||
|
||||
fn mul(self, rhs: F) -> Self::Output {
|
||||
let coeffs = self.coeffs.iter().map(|&x| rhs * x).collect();
|
||||
PolynomialCoeffs::new(coeffs)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Mul for &PolynomialCoeffs<F> {
|
||||
type Output = PolynomialCoeffs<F>;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
let new_len = (self.len() + rhs.len()).next_power_of_two();
|
||||
let a = self.padded(new_len);
|
||||
let b = rhs.padded(new_len);
|
||||
let a_evals = a.fft();
|
||||
let b_evals = b.fft();
|
||||
|
||||
let mul_evals: Vec<F> = a_evals
|
||||
.values
|
||||
.into_iter()
|
||||
.zip(b_evals.values)
|
||||
.map(|(pa, pb)| pa * pb)
|
||||
.collect();
|
||||
ifft(mul_evals.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_coset_fft() {
|
||||
type F = CrandallField;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user