mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-08 16:53:07 +00:00
Merge pull request #36 from mir-protocol/poly_port
Some cleanup related to the two polynomial APIs
This commit is contained in:
commit
b7acdb36ca
@ -4,7 +4,6 @@ use crate::fri::{prover::fri_proof, verifier::verify_fri_proof, FriConfig};
|
|||||||
use crate::merkle_tree::MerkleTree;
|
use crate::merkle_tree::MerkleTree;
|
||||||
use crate::plonk_challenger::Challenger;
|
use crate::plonk_challenger::Challenger;
|
||||||
use crate::plonk_common::reduce_with_powers;
|
use crate::plonk_common::reduce_with_powers;
|
||||||
use crate::polynomial::old_polynomial::Polynomial;
|
|
||||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||||
use crate::proof::{FriProof, Hash, OpeningSet};
|
use crate::proof::{FriProof, Hash, OpeningSet};
|
||||||
use crate::util::{log2_strict, reverse_index_bits_in_place, transpose};
|
use crate::util::{log2_strict, reverse_index_bits_in_place, transpose};
|
||||||
@ -98,8 +97,9 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
|||||||
.polynomials
|
.polynomials
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.map(|p| p.clone().into())
|
.fold(PolynomialCoeffs::zero(self.degree), |acc, p| {
|
||||||
.fold(Polynomial::empty(), |acc, p| acc.scalar_mul(alpha).add(&p));
|
&(&acc * alpha) + &p
|
||||||
|
});
|
||||||
// Scale evaluations by `alpha`.
|
// Scale evaluations by `alpha`.
|
||||||
let composition_evals = evaluations
|
let composition_evals = evaluations
|
||||||
.par_iter()
|
.par_iter()
|
||||||
@ -244,7 +244,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
|
/// 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)`.
|
/// `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
|
let pairs = points
|
||||||
.iter()
|
.iter()
|
||||||
.zip(evals)
|
.zip(evals)
|
||||||
@ -252,18 +256,15 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
debug_assert!(pairs.iter().all(|&(x, e)| poly.eval(x) == e));
|
debug_assert!(pairs.iter().all(|&(x, e)| poly.eval(x) == e));
|
||||||
|
|
||||||
let interpolant: Polynomial<F> = interpolant(&pairs).into();
|
let interpolant = interpolant(&pairs);
|
||||||
let denominator = points
|
let denominator = points.iter().fold(PolynomialCoeffs::one(), |acc, &x| {
|
||||||
.iter()
|
&acc * &PolynomialCoeffs::new(vec![-x, F::ONE])
|
||||||
.fold(Polynomial::from(vec![F::ONE]), |acc, &x| {
|
});
|
||||||
acc.mul(&vec![-x, F::ONE].into())
|
let numerator = poly - &interpolant;
|
||||||
});
|
let (mut quotient, rem) = numerator.div_rem(&denominator);
|
||||||
let numerator = poly.add(&interpolant.neg());
|
|
||||||
let (mut quotient, rem) = numerator.polynomial_division(&denominator);
|
|
||||||
debug_assert!(rem.is_zero());
|
debug_assert!(rem.is_zero());
|
||||||
|
|
||||||
quotient.pad((quotient.degree() + 1).next_power_of_two());
|
quotient.padded(quotient.degree_plus_one().next_power_of_two())
|
||||||
quotient
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,8 @@ use std::ops::{Index, IndexMut, RangeBounds};
|
|||||||
use std::slice::{Iter, IterMut, SliceIndex};
|
use std::slice::{Iter, IterMut, SliceIndex};
|
||||||
|
|
||||||
/// Polynomial struct holding a polynomial in coefficient form.
|
/// Polynomial struct holding a polynomial in coefficient form.
|
||||||
|
// TODO: Finish merging this with `PolynomialCoeffs`.
|
||||||
|
#[deprecated]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Polynomial<F: Field>(Vec<F>);
|
pub struct Polynomial<F: Field>(Vec<F>);
|
||||||
|
|
||||||
@ -258,6 +260,10 @@ impl<F: Field> Polynomial<F> {
|
|||||||
/// Returns `(q,r)` the quotient and remainder of the polynomial division of `a` by `b`.
|
/// Returns `(q,r)` the quotient and remainder of the polynomial division of `a` by `b`.
|
||||||
/// Generally slower that the equivalent function `Polynomial::polynomial_division`.
|
/// Generally slower that the equivalent function `Polynomial::polynomial_division`.
|
||||||
pub fn polynomial_long_division(&self, b: &Self) -> (Self, Self) {
|
pub fn polynomial_long_division(&self, b: &Self) -> (Self, Self) {
|
||||||
|
// Trim b.
|
||||||
|
let mut b = b.clone();
|
||||||
|
b.trim();
|
||||||
|
|
||||||
let (a_degree, b_degree) = (self.degree(), b.degree());
|
let (a_degree, b_degree) = (self.degree(), b.degree());
|
||||||
if self.is_zero() {
|
if self.is_zero() {
|
||||||
(Self::zero(1), Self::empty())
|
(Self::zero(1), Self::empty())
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
|
use std::cmp::max;
|
||||||
|
use std::ops::{Add, Mul, Sub};
|
||||||
|
|
||||||
use crate::field::fft::{fft, ifft};
|
use crate::field::fft::{fft, ifft};
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
|
use crate::polynomial::old_polynomial::Polynomial;
|
||||||
use crate::util::log2_strict;
|
use crate::util::log2_strict;
|
||||||
use std::slice::Iter;
|
|
||||||
|
|
||||||
/// A polynomial in point-value form.
|
/// A polynomial in point-value form.
|
||||||
///
|
///
|
||||||
@ -68,6 +71,14 @@ impl<F: Field> PolynomialCoeffs<F> {
|
|||||||
Self::new(vec![F::ZERO; len])
|
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
|
/// The number of coefficients. This does not filter out any zero coefficients, so it is not
|
||||||
/// necessarily related to the degree.
|
/// necessarily related to the degree.
|
||||||
pub(crate) fn len(&self) -> usize {
|
pub(crate) fn len(&self) -> usize {
|
||||||
@ -96,13 +107,13 @@ impl<F: Field> PolynomialCoeffs<F> {
|
|||||||
polys.into_iter().map(|p| p.lde(rate_bits)).collect()
|
polys.into_iter().map(|p| p.lde(rate_bits)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn lde(self, rate_bits: usize) -> Self {
|
pub(crate) fn lde(&self, rate_bits: usize) -> Self {
|
||||||
let original_size = self.len();
|
self.padded(self.len() << rate_bits)
|
||||||
let lde_size = original_size << rate_bits;
|
}
|
||||||
let Self { mut coeffs } = self;
|
|
||||||
for _ in 0..(lde_size - original_size) {
|
pub(crate) fn padded(&self, new_len: usize) -> Self {
|
||||||
coeffs.push(F::ZERO);
|
let mut coeffs = self.coeffs.clone();
|
||||||
}
|
coeffs.resize(new_len, F::ZERO);
|
||||||
Self { coeffs }
|
Self { coeffs }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,13 +123,20 @@ impl<F: Field> PolynomialCoeffs<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Degree of the polynomial + 1.
|
/// Degree of the polynomial + 1.
|
||||||
fn degree_plus_one(&self) -> usize {
|
pub(crate) fn degree_plus_one(&self) -> usize {
|
||||||
(0usize..self.len())
|
(0usize..self.len())
|
||||||
.rev()
|
.rev()
|
||||||
.find(|&i| self.coeffs[i].is_nonzero())
|
.find(|&i| self.coeffs[i].is_nonzero())
|
||||||
.map_or(0, |i| i + 1)
|
.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_division(&rhs);
|
||||||
|
(q.into(), r.into())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fft(self) -> PolynomialValues<F> {
|
pub fn fft(self) -> PolynomialValues<F> {
|
||||||
fft(self)
|
fft(self)
|
||||||
}
|
}
|
||||||
@ -140,11 +158,67 @@ 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 a = self.padded(len).coeffs;
|
||||||
|
let b = rhs.padded(len).coeffs;
|
||||||
|
let coeffs = a.into_iter().zip(b).map(|(x, y)| x + y).collect();
|
||||||
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
|
||||||
use crate::field::crandall_field::CrandallField;
|
use crate::field::crandall_field::CrandallField;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_coset_fft() {
|
fn test_coset_fft() {
|
||||||
type F = CrandallField;
|
type F = CrandallField;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user