binius_core/protocols/gkr_exp/
compositions.rs

1// Copyright 2025 Irreducible Inc.
2
3use std::fmt::Debug;
4
5use binius_field::{Field, PackedField};
6use binius_math::{ArithExpr, CompositionPoly};
7use binius_utils::bail;
8
9use crate::composition::FixedDimIndexCompositions;
10
11#[derive(Debug)]
12pub enum ExpCompositions<F>
13where
14	F: Field,
15{
16	StaticBase { base_power_static: F },
17	DynamicBase,
18	DynamicBaseLastLayer,
19}
20
21impl<P> CompositionPoly<P> for ExpCompositions<P::Scalar>
22where
23	P: PackedField,
24{
25	fn n_vars(&self) -> usize {
26		match self {
27			Self::StaticBase { .. } | Self::DynamicBaseLastLayer => 2,
28			Self::DynamicBase => 3,
29		}
30	}
31
32	fn degree(&self) -> usize {
33		match self {
34			Self::StaticBase { .. } | Self::DynamicBaseLastLayer => 2,
35			Self::DynamicBase => 4,
36		}
37	}
38
39	fn binary_tower_level(&self) -> usize {
40		0
41	}
42
43	fn expression(&self) -> ArithExpr<P::Scalar> {
44		match self {
45			Self::StaticBase { base_power_static } => {
46				ArithExpr::Var(0)
47					* ((ArithExpr::Const(P::Scalar::ONE) - ArithExpr::Var(1))
48						+ ArithExpr::Var(1) * ArithExpr::Const(*base_power_static))
49			}
50			Self::DynamicBase => {
51				ArithExpr::Pow(Box::new(ArithExpr::Var(0)), 2)
52					* ((ArithExpr::Const(P::Scalar::ONE) - ArithExpr::Var(1))
53						+ ArithExpr::Var(1) * ArithExpr::Var(2))
54			}
55			Self::DynamicBaseLastLayer => {
56				(ArithExpr::Const(P::Scalar::ONE) - ArithExpr::Var(1))
57					+ ArithExpr::Var(1) * ArithExpr::Var(0)
58			}
59		}
60	}
61
62	fn evaluate(&self, query: &[P]) -> Result<P, binius_math::Error> {
63		if query.len() != CompositionPoly::<P>::n_vars(self) {
64			bail!(binius_math::Error::IncorrectQuerySize {
65				expected: CompositionPoly::<P>::n_vars(self)
66			});
67		}
68		match self {
69			Self::StaticBase { base_power_static } => {
70				Ok(query[0] * ((P::one() - query[1]) + query[1] * *base_power_static))
71			}
72			Self::DynamicBase => {
73				Ok(query[0].square() * ((P::one() - query[1]) + query[1] * query[2]))
74			}
75			Self::DynamicBaseLastLayer => Ok((P::one() - query[1]) + query[1] * query[0]),
76		}
77	}
78}
79
80pub type IndexedExpComposition<F> = FixedDimIndexCompositions<ExpCompositions<F>>;