ark_r1cs_std/poly/polynomial/univariate/
dense.rsuse ark_ff::PrimeField;
use ark_relations::r1cs::SynthesisError;
use crate::fields::{fp::FpVar, FieldVar};
use ark_std::vec::Vec;
pub struct DensePolynomialVar<F: PrimeField> {
pub coeffs: Vec<FpVar<F>>,
}
impl<F: PrimeField> DensePolynomialVar<F> {
pub fn from_coefficients_slice(coeffs: &[FpVar<F>]) -> Self {
Self::from_coefficients_vec(coeffs.to_vec())
}
pub fn from_coefficients_vec(coeffs: Vec<FpVar<F>>) -> Self {
Self { coeffs }
}
pub fn evaluate(&self, point: &FpVar<F>) -> Result<FpVar<F>, SynthesisError> {
let mut result: FpVar<F> = FpVar::zero();
let mut curr_pow_x: FpVar<F> = FpVar::one();
for i in 0..self.coeffs.len() {
let term = &curr_pow_x * &self.coeffs[i];
result += &term;
curr_pow_x *= point;
}
Ok(result)
}
}
#[cfg(test)]
mod tests {
use crate::{
alloc::AllocVar, fields::fp::FpVar,
poly::polynomial::univariate::dense::DensePolynomialVar, R1CSVar,
};
use ark_poly::{polynomial::univariate::DensePolynomial, DenseUVPolynomial, Polynomial};
use ark_relations::r1cs::ConstraintSystem;
use ark_std::{test_rng, vec::Vec, UniformRand};
use ark_test_curves::bls12_381::Fr;
#[test]
fn test_evaluate() {
let mut rng = test_rng();
for _ in 0..100 {
let cs = ConstraintSystem::new_ref();
let poly: DensePolynomial<Fr> = DensePolynomial::rand(10, &mut rng);
let poly_var = {
let coeff: Vec<_> = poly
.coeffs
.iter()
.map(|&x| FpVar::new_witness(ns!(cs, "coeff"), || Ok(x)).unwrap())
.collect();
DensePolynomialVar::from_coefficients_vec(coeff)
};
let point = Fr::rand(&mut rng);
let point_var = FpVar::new_witness(ns!(cs, "point"), || Ok(point)).unwrap();
let expected = poly.evaluate(&point);
let actual = poly_var.evaluate(&point_var).unwrap();
assert_eq!(actual.value().unwrap(), expected);
assert!(cs.is_satisfied().unwrap());
}
}
}