mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-11 18:23:09 +00:00
76 lines
2.2 KiB
Rust
76 lines
2.2 KiB
Rust
use std::borrow::Borrow;
|
|
|
|
use crate::field::extension_field::Frobenius;
|
|
use crate::field::field::Field;
|
|
use crate::polynomial::polynomial::PolynomialCoeffs;
|
|
|
|
/// When verifying the composition polynomial in FRI we have to compute sums of the form
|
|
/// `(sum_0^k a^i * x_i)/d_0 + (sum_k^r a^i * y_i)/d_1`
|
|
/// The most efficient way to do this is to compute both quotient separately using Horner's method,
|
|
/// scale the second one by `a^(r-1-k)`, and add them up.
|
|
/// This struct abstract away these operations by implementing Horner's method and keeping track
|
|
/// of the number of multiplications by `a` to compute the scaling factor.
|
|
/// See https://github.com/mir-protocol/plonky2/pull/69 for more details and discussions.
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub struct ReducingFactor<F: Field> {
|
|
base: F,
|
|
count: u64,
|
|
}
|
|
|
|
impl<F: Field> ReducingFactor<F> {
|
|
pub fn new(base: F) -> Self {
|
|
Self { base, count: 0 }
|
|
}
|
|
|
|
fn mul(&mut self, x: F) -> F {
|
|
self.count += 1;
|
|
self.base * x
|
|
}
|
|
|
|
fn mul_poly(&mut self, p: &mut PolynomialCoeffs<F>) {
|
|
self.count += 1;
|
|
*p *= self.base;
|
|
}
|
|
|
|
pub fn reduce(&mut self, iter: impl DoubleEndedIterator<Item = impl Borrow<F>>) -> F {
|
|
iter.rev()
|
|
.fold(F::ZERO, |acc, x| self.mul(acc) + *x.borrow())
|
|
}
|
|
|
|
pub fn reduce_polys(
|
|
&mut self,
|
|
polys: impl DoubleEndedIterator<Item = impl Borrow<PolynomialCoeffs<F>>>,
|
|
) -> PolynomialCoeffs<F> {
|
|
polys.rev().fold(PolynomialCoeffs::empty(), |mut acc, x| {
|
|
self.mul_poly(&mut acc);
|
|
acc += x.borrow();
|
|
acc
|
|
})
|
|
}
|
|
|
|
pub fn shift(&mut self, x: F) -> F {
|
|
let tmp = self.base.exp(self.count) * x;
|
|
self.count = 0;
|
|
tmp
|
|
}
|
|
|
|
pub fn shift_poly(&mut self, p: &mut PolynomialCoeffs<F>) {
|
|
*p *= self.base.exp(self.count);
|
|
self.count = 0;
|
|
}
|
|
|
|
pub fn reset(&mut self) {
|
|
self.count = 0;
|
|
}
|
|
|
|
pub fn repeated_frobenius<const D: usize>(&self, count: usize) -> Self
|
|
where
|
|
F: Frobenius<D>,
|
|
{
|
|
Self {
|
|
base: self.base.repeated_frobenius(count),
|
|
count: self.count,
|
|
}
|
|
}
|
|
}
|