../../.cargo/katex-header.html

plonky2/gadgets/
polynomial.rs

1#[cfg(not(feature = "std"))]
2use alloc::vec::Vec;
3
4use crate::field::extension::Extendable;
5use crate::hash::hash_types::RichField;
6use crate::iop::ext_target::{ExtensionAlgebraTarget, ExtensionTarget};
7use crate::iop::target::Target;
8use crate::plonk::circuit_builder::CircuitBuilder;
9use crate::util::reducing::ReducingFactorTarget;
10
11#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct PolynomialCoeffsExtTarget<const D: usize>(pub Vec<ExtensionTarget<D>>);
13
14impl<const D: usize> PolynomialCoeffsExtTarget<D> {
15    pub fn len(&self) -> usize {
16        self.0.len()
17    }
18
19    pub fn is_empty(&self) -> bool {
20        self.len() == 0
21    }
22
23    pub fn eval_scalar<F: RichField + Extendable<D>>(
24        &self,
25        builder: &mut CircuitBuilder<F, D>,
26        point: Target,
27    ) -> ExtensionTarget<D> {
28        let point = builder.convert_to_ext(point);
29        let mut point = ReducingFactorTarget::new(point);
30        point.reduce(&self.0, builder)
31    }
32
33    pub fn eval<F: RichField + Extendable<D>>(
34        &self,
35        builder: &mut CircuitBuilder<F, D>,
36        point: ExtensionTarget<D>,
37    ) -> ExtensionTarget<D> {
38        let mut point = ReducingFactorTarget::new(point);
39        point.reduce(&self.0, builder)
40    }
41}
42
43#[derive(Debug)]
44pub struct PolynomialCoeffsExtAlgebraTarget<const D: usize>(pub Vec<ExtensionAlgebraTarget<D>>);
45
46impl<const D: usize> PolynomialCoeffsExtAlgebraTarget<D> {
47    pub fn eval_scalar<F>(
48        &self,
49        builder: &mut CircuitBuilder<F, D>,
50        point: ExtensionTarget<D>,
51    ) -> ExtensionAlgebraTarget<D>
52    where
53        F: RichField + Extendable<D>,
54    {
55        let mut acc = builder.zero_ext_algebra();
56        for &c in self.0.iter().rev() {
57            acc = builder.scalar_mul_add_ext_algebra(point, acc, c);
58        }
59        acc
60    }
61
62    pub fn eval<F>(
63        &self,
64        builder: &mut CircuitBuilder<F, D>,
65        point: ExtensionAlgebraTarget<D>,
66    ) -> ExtensionAlgebraTarget<D>
67    where
68        F: RichField + Extendable<D>,
69    {
70        let mut acc = builder.zero_ext_algebra();
71        for &c in self.0.iter().rev() {
72            acc = builder.mul_add_ext_algebra(point, acc, c);
73        }
74        acc
75    }
76
77    /// Evaluate the polynomial at a point given its powers. The first power is the point itself, not 1.
78    pub fn eval_with_powers<F>(
79        &self,
80        builder: &mut CircuitBuilder<F, D>,
81        powers: &[ExtensionAlgebraTarget<D>],
82    ) -> ExtensionAlgebraTarget<D>
83    where
84        F: RichField + Extendable<D>,
85    {
86        debug_assert_eq!(self.0.len(), powers.len() + 1);
87        let acc = self.0[0];
88        self.0[1..]
89            .iter()
90            .zip(powers)
91            .fold(acc, |acc, (&x, &c)| builder.mul_add_ext_algebra(c, x, acc))
92    }
93}