halo2_proofs/
poly.rs
1use crate::arithmetic::parallelize;
6use crate::plonk::Assigned;
7
8use group::ff::{BatchInvert, Field};
9use pasta_curves::arithmetic::FieldExt;
10use std::fmt::Debug;
11use std::marker::PhantomData;
12use std::ops::{Add, Deref, DerefMut, Index, IndexMut, Mul, RangeFrom, RangeFull};
13
14pub mod commitment;
15mod domain;
16mod evaluator;
17pub mod multiopen;
18
19pub use domain::*;
20pub use evaluator::*;
21
22#[derive(Debug)]
25pub enum Error {
26 OpeningError,
28 SamplingError,
30}
31
32pub trait Basis: Copy + Debug + Send + Sync {}
34
35#[derive(Clone, Copy, Debug)]
37pub struct Coeff;
38impl Basis for Coeff {}
39
40#[derive(Clone, Copy, Debug)]
42pub struct LagrangeCoeff;
43impl Basis for LagrangeCoeff {}
44
45#[derive(Clone, Copy, Debug)]
48pub struct ExtendedLagrangeCoeff;
49impl Basis for ExtendedLagrangeCoeff {}
50
51#[derive(Clone, Debug)]
54pub struct Polynomial<F, B> {
55 values: Vec<F>,
56 _marker: PhantomData<B>,
57}
58
59impl<F, B> Index<usize> for Polynomial<F, B> {
60 type Output = F;
61
62 fn index(&self, index: usize) -> &F {
63 self.values.index(index)
64 }
65}
66
67impl<F, B> IndexMut<usize> for Polynomial<F, B> {
68 fn index_mut(&mut self, index: usize) -> &mut F {
69 self.values.index_mut(index)
70 }
71}
72
73impl<F, B> Index<RangeFrom<usize>> for Polynomial<F, B> {
74 type Output = [F];
75
76 fn index(&self, index: RangeFrom<usize>) -> &[F] {
77 self.values.index(index)
78 }
79}
80
81impl<F, B> IndexMut<RangeFrom<usize>> for Polynomial<F, B> {
82 fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut [F] {
83 self.values.index_mut(index)
84 }
85}
86
87impl<F, B> Index<RangeFull> for Polynomial<F, B> {
88 type Output = [F];
89
90 fn index(&self, index: RangeFull) -> &[F] {
91 self.values.index(index)
92 }
93}
94
95impl<F, B> IndexMut<RangeFull> for Polynomial<F, B> {
96 fn index_mut(&mut self, index: RangeFull) -> &mut [F] {
97 self.values.index_mut(index)
98 }
99}
100
101impl<F, B> Deref for Polynomial<F, B> {
102 type Target = [F];
103
104 fn deref(&self) -> &[F] {
105 &self.values[..]
106 }
107}
108
109impl<F, B> DerefMut for Polynomial<F, B> {
110 fn deref_mut(&mut self) -> &mut [F] {
111 &mut self.values[..]
112 }
113}
114
115impl<F, B> Polynomial<F, B> {
116 pub fn iter(&self) -> impl Iterator<Item = &F> {
119 self.values.iter()
120 }
121
122 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut F> {
125 self.values.iter_mut()
126 }
127
128 pub fn num_coeffs(&self) -> usize {
131 self.values.len()
132 }
133}
134
135pub(crate) fn batch_invert_assigned<F: FieldExt>(
136 assigned: Vec<Polynomial<Assigned<F>, LagrangeCoeff>>,
137) -> Vec<Polynomial<F, LagrangeCoeff>> {
138 let mut assigned_denominators: Vec<_> = assigned
139 .iter()
140 .map(|f| {
141 f.iter()
142 .map(|value| value.denominator())
143 .collect::<Vec<_>>()
144 })
145 .collect();
146
147 assigned_denominators
148 .iter_mut()
149 .flat_map(|f| {
150 f.iter_mut()
151 .filter_map(|d| d.as_mut())
154 })
155 .batch_invert();
156
157 assigned
158 .iter()
159 .zip(assigned_denominators.into_iter())
160 .map(|(poly, inv_denoms)| {
161 poly.invert(inv_denoms.into_iter().map(|d| d.unwrap_or_else(F::one)))
162 })
163 .collect()
164}
165
166impl<F: Field> Polynomial<Assigned<F>, LagrangeCoeff> {
167 pub(crate) fn invert(
168 &self,
169 inv_denoms: impl Iterator<Item = F> + ExactSizeIterator,
170 ) -> Polynomial<F, LagrangeCoeff> {
171 assert_eq!(inv_denoms.len(), self.values.len());
172 Polynomial {
173 values: self
174 .values
175 .iter()
176 .zip(inv_denoms.into_iter())
177 .map(|(a, inv_den)| a.numerator() * inv_den)
178 .collect(),
179 _marker: self._marker,
180 }
181 }
182}
183
184impl<'a, F: Field, B: Basis> Add<&'a Polynomial<F, B>> for Polynomial<F, B> {
185 type Output = Polynomial<F, B>;
186
187 fn add(mut self, rhs: &'a Polynomial<F, B>) -> Polynomial<F, B> {
188 parallelize(&mut self.values, |lhs, start| {
189 for (lhs, rhs) in lhs.iter_mut().zip(rhs.values[start..].iter()) {
190 *lhs += *rhs;
191 }
192 });
193
194 self
195 }
196}
197
198impl<'a, F: Field> Polynomial<F, LagrangeCoeff> {
199 pub fn rotate(&self, rotation: Rotation) -> Polynomial<F, LagrangeCoeff> {
201 let mut values = self.values.clone();
202 if rotation.0 < 0 {
203 values.rotate_right((-rotation.0) as usize);
204 } else {
205 values.rotate_left(rotation.0 as usize);
206 }
207 Polynomial {
208 values,
209 _marker: PhantomData,
210 }
211 }
212}
213
214impl<'a, F: Field, B: Basis> Mul<F> for Polynomial<F, B> {
215 type Output = Polynomial<F, B>;
216
217 fn mul(mut self, rhs: F) -> Polynomial<F, B> {
218 parallelize(&mut self.values, |lhs, _| {
219 for lhs in lhs.iter_mut() {
220 *lhs *= rhs;
221 }
222 });
223
224 self
225 }
226}
227
228#[derive(Copy, Clone, Debug, PartialEq)]
232pub struct Rotation(pub i32);
233
234impl Rotation {
235 pub fn cur() -> Rotation {
237 Rotation(0)
238 }
239
240 pub fn prev() -> Rotation {
242 Rotation(-1)
243 }
244
245 pub fn next() -> Rotation {
247 Rotation(1)
248 }
249}