halo2/src/poly.rs

190 lines
4.9 KiB
Rust
Raw Normal View History

2020-09-07 09:22:25 -07:00
//! Contains utilities for performing arithmetic over univariate polynomials in
//! various forms, including computing commitments to them and provably opening
//! the committed polynomials at arbitrary points.
use crate::arithmetic::{parallelize, Field};
use std::fmt::Debug;
use std::marker::PhantomData;
use std::ops::{Add, Deref, DerefMut, Index, IndexMut, Mul, RangeFrom, RangeFull, Sub};
pub mod commitment;
mod domain;
2020-09-29 00:23:41 -07:00
pub mod multiopen;
2020-09-07 09:22:25 -07:00
pub use domain::*;
/// This is an error that could occur during proving or circuit synthesis.
// TODO: these errors need to be cleaned up
#[derive(Debug)]
pub enum Error {
/// OpeningProof is not well-formed
OpeningError,
/// Caller needs to re-sample a point
SamplingError,
}
2020-09-07 09:22:25 -07:00
/// The basis over which a polynomial is described.
pub trait Basis: Clone + Debug + Send + Sync {}
/// The polynomial is defined as coefficients
#[derive(Clone, Debug)]
pub struct Coeff;
impl Basis for Coeff {}
/// The polynomial is defined as coefficients of Lagrange basis polynomials
#[derive(Clone, Debug)]
pub struct LagrangeCoeff;
impl Basis for LagrangeCoeff {}
/// The polynomial is defined as coefficients of Lagrange basis polynomials in
/// an extended size domain which supports multiplication
#[derive(Clone, Debug)]
pub struct ExtendedLagrangeCoeff;
impl Basis for ExtendedLagrangeCoeff {}
/// Represents a univariate polynomial defined over a field and a particular
/// basis.
#[derive(Clone, Debug)]
pub struct Polynomial<F, B> {
values: Vec<F>,
_marker: PhantomData<B>,
}
impl<F, B> Index<usize> for Polynomial<F, B> {
type Output = F;
fn index(&self, index: usize) -> &F {
self.values.index(index)
}
}
impl<F, B> IndexMut<usize> for Polynomial<F, B> {
fn index_mut(&mut self, index: usize) -> &mut F {
self.values.index_mut(index)
}
}
impl<F, B> Index<RangeFrom<usize>> for Polynomial<F, B> {
type Output = [F];
fn index(&self, index: RangeFrom<usize>) -> &[F] {
self.values.index(index)
}
}
impl<F, B> IndexMut<RangeFrom<usize>> for Polynomial<F, B> {
fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut [F] {
self.values.index_mut(index)
}
}
impl<F, B> Index<RangeFull> for Polynomial<F, B> {
type Output = [F];
fn index(&self, index: RangeFull) -> &[F] {
self.values.index(index)
}
}
impl<F, B> IndexMut<RangeFull> for Polynomial<F, B> {
fn index_mut(&mut self, index: RangeFull) -> &mut [F] {
self.values.index_mut(index)
}
}
impl<F, B> Deref for Polynomial<F, B> {
type Target = [F];
fn deref(&self) -> &[F] {
&self.values[..]
}
}
impl<F, B> DerefMut for Polynomial<F, B> {
fn deref_mut(&mut self) -> &mut [F] {
&mut self.values[..]
}
}
impl<F, B> Polynomial<F, B> {
/// Iterate over the values, which are either in coefficient or evaluation
/// form depending on the basis `B`.
pub fn iter(&self) -> impl Iterator<Item = &F> {
self.values.iter()
}
/// Iterate over the values mutably, which are either in coefficient or
/// evaluation form depending on the basis `B`.
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut F> {
self.values.iter_mut()
}
2020-09-20 12:09:03 -07:00
/// Gets the size of this polynomial in terms of the number of
2020-09-07 09:22:25 -07:00
/// coefficients used to describe it.
2020-09-20 12:09:03 -07:00
pub fn num_coeffs(&self) -> usize {
2020-09-07 09:22:25 -07:00
self.values.len()
}
}
impl<'a, F: Field, B: Basis> Add<&'a Polynomial<F, B>> for Polynomial<F, B> {
type Output = Polynomial<F, B>;
fn add(mut self, rhs: &'a Polynomial<F, B>) -> Polynomial<F, B> {
parallelize(&mut self.values, |lhs, start| {
for (lhs, rhs) in lhs.iter_mut().zip(rhs.values[start..].iter()) {
*lhs += *rhs;
}
});
self
}
}
impl<'a, F: Field, B: Basis> Sub<&'a Polynomial<F, B>> for Polynomial<F, B> {
type Output = Polynomial<F, B>;
fn sub(mut self, rhs: &'a Polynomial<F, B>) -> Polynomial<F, B> {
parallelize(&mut self.values, |lhs, start| {
for (lhs, rhs) in lhs.iter_mut().zip(rhs.values[start..].iter()) {
*lhs -= *rhs;
}
});
self
}
}
impl<'a, F: Field> Mul<&'a Polynomial<F, ExtendedLagrangeCoeff>>
for Polynomial<F, ExtendedLagrangeCoeff>
{
type Output = Polynomial<F, ExtendedLagrangeCoeff>;
fn mul(
mut self,
rhs: &'a Polynomial<F, ExtendedLagrangeCoeff>,
) -> Polynomial<F, ExtendedLagrangeCoeff> {
parallelize(&mut self.values, |lhs, start| {
for (lhs, rhs) in lhs.iter_mut().zip(rhs.values[start..].iter()) {
*lhs *= *rhs;
}
});
self
}
}
impl<'a, F: Field, B: Basis> Mul<F> for Polynomial<F, B> {
type Output = Polynomial<F, B>;
fn mul(mut self, rhs: F) -> Polynomial<F, B> {
parallelize(&mut self.values, |lhs, _| {
for lhs in lhs.iter_mut() {
*lhs *= rhs;
}
});
self
}
}