use std::{
marker::PhantomData,
ops::{Add, Mul, MulAssign, Sub},
};
use p3_field::{AbstractField, ExtensionField, Field};
use p3_matrix::{dense::RowMajorMatrixView, stack::VerticalPair};
use super::{Challenge, PackedChallenge, PackedVal, StarkGenericConfig, Val};
use crate::{
air::{EmptyMessageBuilder, MultiTableAirBuilder},
septic_digest::SepticDigest,
};
use p3_air::{
AirBuilder, AirBuilderWithPublicValues, ExtensionBuilder, PairBuilder, PermutationAirBuilder,
};
pub struct ProverConstraintFolder<'a, SC: StarkGenericConfig> {
pub preprocessed:
VerticalPair<RowMajorMatrixView<'a, PackedVal<SC>>, RowMajorMatrixView<'a, PackedVal<SC>>>,
pub main:
VerticalPair<RowMajorMatrixView<'a, PackedVal<SC>>, RowMajorMatrixView<'a, PackedVal<SC>>>,
pub perm: VerticalPair<
RowMajorMatrixView<'a, PackedChallenge<SC>>,
RowMajorMatrixView<'a, PackedChallenge<SC>>,
>,
pub perm_challenges: &'a [PackedChallenge<SC>],
pub local_cumulative_sum: &'a PackedChallenge<SC>,
pub global_cumulative_sum: &'a SepticDigest<Val<SC>>,
pub is_first_row: PackedVal<SC>,
pub is_last_row: PackedVal<SC>,
pub is_transition: PackedVal<SC>,
pub powers_of_alpha: &'a Vec<SC::Challenge>,
pub accumulator: PackedChallenge<SC>,
pub public_values: &'a [Val<SC>],
pub constraint_index: usize,
}
impl<'a, SC: StarkGenericConfig> AirBuilder for ProverConstraintFolder<'a, SC> {
type F = Val<SC>;
type Expr = PackedVal<SC>;
type Var = PackedVal<SC>;
type M =
VerticalPair<RowMajorMatrixView<'a, PackedVal<SC>>, RowMajorMatrixView<'a, PackedVal<SC>>>;
fn main(&self) -> Self::M {
self.main
}
fn is_first_row(&self) -> Self::Expr {
self.is_first_row
}
fn is_last_row(&self) -> Self::Expr {
self.is_last_row
}
fn is_transition_window(&self, size: usize) -> Self::Expr {
if size == 2 {
self.is_transition
} else {
panic!("uni-stark only supports a window size of 2")
}
}
fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
let x: PackedVal<SC> = x.into();
self.accumulator +=
PackedChallenge::<SC>::from_f(self.powers_of_alpha[self.constraint_index]) * x;
self.constraint_index += 1;
}
}
impl<SC: StarkGenericConfig> ExtensionBuilder for ProverConstraintFolder<'_, SC> {
type EF = SC::Challenge;
type ExprEF = PackedChallenge<SC>;
type VarEF = PackedChallenge<SC>;
fn assert_zero_ext<I>(&mut self, x: I)
where
I: Into<Self::ExprEF>,
{
let x: PackedChallenge<SC> = x.into();
self.accumulator +=
PackedChallenge::<SC>::from_f(self.powers_of_alpha[self.constraint_index]) * x;
self.constraint_index += 1;
}
}
impl<'a, SC: StarkGenericConfig> PermutationAirBuilder for ProverConstraintFolder<'a, SC> {
type MP = VerticalPair<
RowMajorMatrixView<'a, PackedChallenge<SC>>,
RowMajorMatrixView<'a, PackedChallenge<SC>>,
>;
type RandomVar = PackedChallenge<SC>;
fn permutation(&self) -> Self::MP {
self.perm
}
fn permutation_randomness(&self) -> &[Self::RandomVar] {
self.perm_challenges
}
}
impl<'a, SC: StarkGenericConfig> MultiTableAirBuilder<'a> for ProverConstraintFolder<'a, SC> {
type LocalSum = PackedChallenge<SC>;
type GlobalSum = Val<SC>;
fn local_cumulative_sum(&self) -> &'a Self::LocalSum {
self.local_cumulative_sum
}
fn global_cumulative_sum(&self) -> &'a SepticDigest<Self::GlobalSum> {
self.global_cumulative_sum
}
}
impl<SC: StarkGenericConfig> PairBuilder for ProverConstraintFolder<'_, SC> {
fn preprocessed(&self) -> Self::M {
self.preprocessed
}
}
impl<SC: StarkGenericConfig> EmptyMessageBuilder for ProverConstraintFolder<'_, SC> {}
impl<SC: StarkGenericConfig> AirBuilderWithPublicValues for ProverConstraintFolder<'_, SC> {
type PublicVar = Self::F;
fn public_values(&self) -> &[Self::PublicVar] {
self.public_values
}
}
pub type VerifierConstraintFolder<'a, SC> = GenericVerifierConstraintFolder<
'a,
Val<SC>,
Challenge<SC>,
Val<SC>,
Challenge<SC>,
Challenge<SC>,
>;
pub struct GenericVerifierConstraintFolder<'a, F, EF, PubVar, Var, Expr> {
pub preprocessed: VerticalPair<RowMajorMatrixView<'a, Var>, RowMajorMatrixView<'a, Var>>,
pub main: VerticalPair<RowMajorMatrixView<'a, Var>, RowMajorMatrixView<'a, Var>>,
pub perm: VerticalPair<RowMajorMatrixView<'a, Var>, RowMajorMatrixView<'a, Var>>,
pub perm_challenges: &'a [Var],
pub local_cumulative_sum: &'a Var,
pub global_cumulative_sum: &'a SepticDigest<PubVar>,
pub is_first_row: Var,
pub is_last_row: Var,
pub is_transition: Var,
pub alpha: Var,
pub accumulator: Expr,
pub public_values: &'a [PubVar],
pub _marker: PhantomData<(F, EF)>,
}
impl<'a, F, EF, PubVar, Var, Expr> AirBuilder
for GenericVerifierConstraintFolder<'a, F, EF, PubVar, Var, Expr>
where
F: Field,
EF: ExtensionField<F>,
Expr: AbstractField
+ From<F>
+ Add<Var, Output = Expr>
+ Add<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<F, Output = Expr>
+ MulAssign<EF>,
Var: Into<Expr>
+ Copy
+ Add<F, Output = Expr>
+ Add<Var, Output = Expr>
+ Add<Expr, Output = Expr>
+ Sub<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<Expr, Output = Expr>
+ Mul<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<Expr, Output = Expr>
+ Send
+ Sync,
PubVar: Into<Expr> + Copy,
{
type F = F;
type Expr = Expr;
type Var = Var;
type M = VerticalPair<RowMajorMatrixView<'a, Var>, RowMajorMatrixView<'a, Var>>;
fn main(&self) -> Self::M {
self.main
}
fn is_first_row(&self) -> Self::Expr {
self.is_first_row.into()
}
fn is_last_row(&self) -> Self::Expr {
self.is_last_row.into()
}
fn is_transition_window(&self, size: usize) -> Self::Expr {
if size == 2 {
self.is_transition.into()
} else {
panic!("uni-stark only supports a window size of 2")
}
}
fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
let x: Expr = x.into();
self.accumulator *= self.alpha.into();
self.accumulator += x;
}
}
impl<F, EF, PubVar, Var, Expr> ExtensionBuilder
for GenericVerifierConstraintFolder<'_, F, EF, PubVar, Var, Expr>
where
F: Field,
EF: ExtensionField<F>,
Expr: AbstractField<F = EF>
+ From<F>
+ Add<Var, Output = Expr>
+ Add<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<F, Output = Expr>
+ MulAssign<EF>,
Var: Into<Expr>
+ Copy
+ Add<F, Output = Expr>
+ Add<Var, Output = Expr>
+ Add<Expr, Output = Expr>
+ Sub<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<Expr, Output = Expr>
+ Mul<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<Expr, Output = Expr>
+ Send
+ Sync,
PubVar: Into<Expr> + Copy,
{
type EF = EF;
type ExprEF = Expr;
type VarEF = Var;
fn assert_zero_ext<I>(&mut self, x: I)
where
I: Into<Self::ExprEF>,
{
self.assert_zero(x);
}
}
impl<'a, F, EF, PubVar, Var, Expr> PermutationAirBuilder
for GenericVerifierConstraintFolder<'a, F, EF, PubVar, Var, Expr>
where
F: Field,
EF: ExtensionField<F>,
Expr: AbstractField<F = EF>
+ From<F>
+ Add<Var, Output = Expr>
+ Add<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<F, Output = Expr>
+ MulAssign<EF>,
Var: Into<Expr>
+ Copy
+ Add<F, Output = Expr>
+ Add<Var, Output = Expr>
+ Add<Expr, Output = Expr>
+ Sub<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<Expr, Output = Expr>
+ Mul<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<Expr, Output = Expr>
+ Send
+ Sync,
PubVar: Into<Expr> + Copy,
{
type MP = VerticalPair<RowMajorMatrixView<'a, Var>, RowMajorMatrixView<'a, Var>>;
type RandomVar = Var;
fn permutation(&self) -> Self::MP {
self.perm
}
fn permutation_randomness(&self) -> &[Self::Var] {
self.perm_challenges
}
}
impl<'a, F, EF, PubVar, Var, Expr> MultiTableAirBuilder<'a>
for GenericVerifierConstraintFolder<'a, F, EF, PubVar, Var, Expr>
where
F: Field,
EF: ExtensionField<F>,
Expr: AbstractField<F = EF>
+ From<F>
+ Add<Var, Output = Expr>
+ Add<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<F, Output = Expr>
+ MulAssign<EF>,
Var: Into<Expr>
+ Copy
+ Add<F, Output = Expr>
+ Add<Var, Output = Expr>
+ Add<Expr, Output = Expr>
+ Sub<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<Expr, Output = Expr>
+ Mul<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<Expr, Output = Expr>
+ Send
+ Sync,
PubVar: Into<Expr> + Copy,
{
type LocalSum = Var;
type GlobalSum = PubVar;
fn local_cumulative_sum(&self) -> &'a Self::LocalSum {
self.local_cumulative_sum
}
fn global_cumulative_sum(&self) -> &'a SepticDigest<Self::GlobalSum> {
self.global_cumulative_sum
}
}
impl<F, EF, PubVar, Var, Expr> PairBuilder
for GenericVerifierConstraintFolder<'_, F, EF, PubVar, Var, Expr>
where
F: Field,
EF: ExtensionField<F>,
Expr: AbstractField<F = EF>
+ From<F>
+ Add<Var, Output = Expr>
+ Add<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<F, Output = Expr>
+ MulAssign<EF>,
Var: Into<Expr>
+ Copy
+ Add<F, Output = Expr>
+ Add<Var, Output = Expr>
+ Add<Expr, Output = Expr>
+ Sub<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<Expr, Output = Expr>
+ Mul<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<Expr, Output = Expr>
+ Send
+ Sync,
PubVar: Into<Expr> + Copy,
{
fn preprocessed(&self) -> Self::M {
self.preprocessed
}
}
impl<F, EF, PubVar, Var, Expr> EmptyMessageBuilder
for GenericVerifierConstraintFolder<'_, F, EF, PubVar, Var, Expr>
where
F: Field,
EF: ExtensionField<F>,
Expr: AbstractField<F = EF>
+ From<F>
+ Add<Var, Output = Expr>
+ Add<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<F, Output = Expr>
+ MulAssign<EF>,
Var: Into<Expr>
+ Copy
+ Add<F, Output = Expr>
+ Add<Var, Output = Expr>
+ Add<Expr, Output = Expr>
+ Sub<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<Expr, Output = Expr>
+ Mul<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<Expr, Output = Expr>
+ Send
+ Sync,
PubVar: Into<Expr> + Copy,
{
}
impl<F, EF, PubVar, Var, Expr> AirBuilderWithPublicValues
for GenericVerifierConstraintFolder<'_, F, EF, PubVar, Var, Expr>
where
F: Field,
EF: ExtensionField<F>,
Expr: AbstractField<F = EF>
+ From<F>
+ Add<Var, Output = Expr>
+ Add<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<F, Output = Expr>
+ MulAssign<EF>,
Var: Into<Expr>
+ Copy
+ Add<F, Output = Expr>
+ Add<Var, Output = Expr>
+ Add<Expr, Output = Expr>
+ Sub<F, Output = Expr>
+ Sub<Var, Output = Expr>
+ Sub<Expr, Output = Expr>
+ Mul<F, Output = Expr>
+ Mul<Var, Output = Expr>
+ Mul<Expr, Output = Expr>
+ Send
+ Sync,
PubVar: Into<Expr> + Copy,
{
type PublicVar = PubVar;
fn public_values(&self) -> &[Self::PublicVar] {
self.public_values
}
}