diff --git a/src/arithmetic.rs b/src/arithmetic.rs index 100e962..010cf47 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -432,7 +432,7 @@ fn log2_floor(num: usize) -> u32 { } /// Returns coefficients of an n - 1 degree polynomial given a set of n points and their evaluations -pub fn interpolate(points: &[F], evals: &[F]) -> Vec { +pub fn lagrange_interpolate(points: &[F], evals: &[F]) -> Vec { assert_eq!(points.len(), evals.len()); if points.len() == 1 { // Constant polynomial @@ -440,19 +440,23 @@ pub fn interpolate(points: &[F], evals: &[F]) -> Vec { } else { let mut interpolation_polys = vec![]; for (j, x_j) in points.iter().enumerate() { - let mut tmp = vec![F::one()]; + let mut tmp: Vec = Vec::with_capacity(points.len() + 1); + let mut product = Vec::with_capacity(points.len() + 1); + tmp.push(F::one()); for (k, x_k) in points.iter().enumerate() { if k != j { // Compute (x_j - x_k)^(-1) let denom = (*x_j - x_k).invert().unwrap(); - let factor = [-denom * x_k, denom]; - let mut product = vec![F::zero(); tmp.len() + factor.len() - 1]; - for (i, a) in tmp.iter().enumerate() { - for (j, b) in factor.iter().enumerate() { - product[i + j] += *a * b; - } + product.resize(tmp.len() + 1, F::zero()); + for (i, (a, b)) in tmp + .iter() + .chain(std::iter::once(&F::zero())) + .zip(std::iter::once(&F::zero()).chain(tmp.iter())) + .enumerate() + { + product[i] = *a * (-denom * x_k) + *b * denom; } - tmp = product; + std::mem::swap(&mut tmp, &mut product); } } interpolation_polys.push(tmp); diff --git a/src/poly/multiopen/prover.rs b/src/poly/multiopen/prover.rs index f35376f..5e90805 100644 --- a/src/poly/multiopen/prover.rs +++ b/src/poly/multiopen/prover.rs @@ -5,8 +5,8 @@ use super::super::{ use super::{Proof, ProverQuery}; use crate::arithmetic::{ - eval_polynomial, get_challenge_scalar, interpolate, kate_division, parallelize, Challenge, - Curve, CurveAffine, Field, + eval_polynomial, get_challenge_scalar, kate_division, lagrange_interpolate, parallelize, + Challenge, Curve, CurveAffine, Field, }; use crate::plonk::hash_point; use crate::transcript::Hasher; @@ -91,7 +91,7 @@ impl Proof { .fold(None, |f_poly, ((points, evals), poly)| { let mut poly = poly.clone()?.values; // TODO: makes implicit asssumption that poly degree is smaller than interpolation poly degree - for (p, r) in poly.iter_mut().zip(interpolate(points, evals)) { + for (p, r) in poly.iter_mut().zip(lagrange_interpolate(points, evals)) { *p -= &r; } let mut poly = points diff --git a/src/poly/multiopen/verifier.rs b/src/poly/multiopen/verifier.rs index 6027609..36ba1aa 100644 --- a/src/poly/multiopen/verifier.rs +++ b/src/poly/multiopen/verifier.rs @@ -4,7 +4,7 @@ use super::super::{ }; use super::{Proof, VerifierQuery}; use crate::arithmetic::{ - eval_polynomial, get_challenge_scalar, interpolate, Challenge, CurveAffine, Field, + eval_polynomial, get_challenge_scalar, lagrange_interpolate, Challenge, CurveAffine, Field, }; use crate::plonk::hash_point; use crate::transcript::Hasher; @@ -80,11 +80,11 @@ impl<'a, C: CurveAffine> Proof { C::Base::from_bytes(&(transcript_scalar.squeeze()).to_bytes()).unwrap(); transcript.absorb(transcript_scalar_point); - // Interpolate polynomial for evaluations at each set + // lagrange_Interpolate polynomial for evaluations at each set let mut r_evals = vec![C::Scalar::zero(); point_sets.len()]; let mut r_polys: Vec> = Vec::with_capacity(point_sets.len()); for (points, evals) in point_sets.clone().iter().zip(q_eval_sets.clone().iter()) { - r_polys.push(interpolate(&points, &evals)); + r_polys.push(lagrange_interpolate(&points, &evals)); } for (r_eval, r_poly) in r_evals.iter_mut().zip(r_polys.iter()) { *r_eval = eval_polynomial(r_poly, x_6);