From dfb2066a79ec50b07dedbc1914b8a0caabc6b669 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Tue, 31 May 2022 15:01:05 -0400 Subject: [PATCH] fix bug in interpolation (#29) --- poly-iop/src/sum_check/verifier.rs | 55 ++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/poly-iop/src/sum_check/verifier.rs b/poly-iop/src/sum_check/verifier.rs index 2cf6fc3..cf6cb4c 100644 --- a/poly-iop/src/sum_check/verifier.rs +++ b/poly-iop/src/sum_check/verifier.rs @@ -281,18 +281,18 @@ fn interpolate_uni_poly(p_i: &[F], eval_at: F) -> Result(a: usize) -> F { - let mut res = 1u64; - for i in 1..=a { - res *= i as u64; + let mut res = F::one(); + for i in 2..=a { + res *= F::from(i as u64); } - F::from(res) + res } /// compute the factorial(a) = 1 * 2 * ... * a #[inline] fn u128_factorial(a: usize) -> u128 { let mut res = 1u128; - for i in 1..=a { + for i in 2..=a { res *= i as u128; } res @@ -302,8 +302,51 @@ fn u128_factorial(a: usize) -> u128 { #[inline] fn u64_factorial(a: usize) -> u64 { let mut res = 1u64; - for i in 1..=a { + for i in 2..=a { res *= i as u64; } res } + +#[cfg(test)] +mod test { + use super::interpolate_uni_poly; + use crate::errors::PolyIOPErrors; + use ark_bls12_381::Fr; + use ark_poly::{univariate::DensePolynomial, Polynomial, UVPolynomial}; + use ark_std::{vec::Vec, UniformRand}; + + #[test] + fn test_interpolation() -> Result<(), PolyIOPErrors> { + let mut prng = ark_std::test_rng(); + + // test a polynomial with 20 known points, i.e., with degree 19 + let poly = DensePolynomial::::rand(20 - 1, &mut prng); + let evals = (0..20) + .map(|i| poly.evaluate(&Fr::from(i))) + .collect::>(); + let query = Fr::rand(&mut prng); + + assert_eq!(poly.evaluate(&query), interpolate_uni_poly(&evals, query)?); + + // test a polynomial with 33 known points, i.e., with degree 32 + let poly = DensePolynomial::::rand(33 - 1, &mut prng); + let evals = (0..33) + .map(|i| poly.evaluate(&Fr::from(i))) + .collect::>(); + let query = Fr::rand(&mut prng); + + assert_eq!(poly.evaluate(&query), interpolate_uni_poly(&evals, query)?); + + // test a polynomial with 64 known points, i.e., with degree 63 + let poly = DensePolynomial::::rand(64 - 1, &mut prng); + let evals = (0..64) + .map(|i| poly.evaluate(&Fr::from(i))) + .collect::>(); + let query = Fr::rand(&mut prng); + + assert_eq!(poly.evaluate(&query), interpolate_uni_poly(&evals, query)?); + + Ok(()) + } +}