fix bug in interpolation (#29)
zhenfei zhenfei.zhang@hotmail.com
Tue, 31 May 2022 15:01:05 -0400
1 files changed,
49 insertions(+),
6 deletions(-)
M
poly-iop/src/sum_check/verifier.rs
→
poly-iop/src/sum_check/verifier.rs
@@ -281,18 +281,18 @@
/// compute the factorial(a) = 1 * 2 * ... * a #[inline] fn field_factorial<F: PrimeField>(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 @@ /// compute the factorial(a) = 1 * 2 * ... * a
#[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::<Fr>::rand(20 - 1, &mut prng); + let evals = (0..20) + .map(|i| poly.evaluate(&Fr::from(i))) + .collect::<Vec<Fr>>(); + 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::<Fr>::rand(33 - 1, &mut prng); + let evals = (0..33) + .map(|i| poly.evaluate(&Fr::from(i))) + .collect::<Vec<Fr>>(); + 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::<Fr>::rand(64 - 1, &mut prng); + let evals = (0..64) + .map(|i| poly.evaluate(&Fr::from(i))) + .collect::<Vec<Fr>>(); + let query = Fr::rand(&mut prng); + + assert_eq!(poly.evaluate(&query), interpolate_uni_poly(&evals, query)?); + + Ok(()) + } +}