pub use strata_core::{Field, Ring, Semiring};
use cyber_hemera::Hash;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Commitment(pub Hash);
impl Commitment {
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
}
#[derive(Clone, Debug)]
pub struct MultilinearPoly<F: Field> {
pub evals: Vec<F>,
pub num_vars: usize,
}
impl<F: Field> MultilinearPoly<F> {
pub fn new(evals: Vec<F>) -> Self {
let n = evals.len();
assert!(
n.is_power_of_two(),
"evaluation table length must be a power of 2"
);
let num_vars = n.trailing_zeros() as usize;
Self { evals, num_vars }
}
pub fn len(&self) -> usize {
self.evals.len()
}
pub fn is_empty(&self) -> bool {
self.evals.is_empty()
}
pub fn evaluate(&self, point: &[F]) -> F {
assert_eq!(point.len(), self.num_vars);
let mut result = F::ZERO;
for (i, &val) in self.evals.iter().enumerate() {
let mut basis = F::ONE;
for (j, &r_j) in point.iter().enumerate() {
let bit = if (i >> j) & 1 == 1 { r_j } else { F::ONE - r_j };
basis = basis * bit;
}
result = result + val * basis;
}
result
}
}
#[derive(Clone, Debug)]
pub enum Opening {
Tensor {
round_commitments: Vec<Commitment>,
final_poly: Vec<u8>,
query_responses: Vec<(usize, Vec<u8>)>,
},
Folding {
round_commitments: Vec<Commitment>,
merkle_paths: Vec<Vec<Hash>>,
final_value: Vec<u8>,
},
Witness {
witness_commitment: Commitment,
witness_opening: Box<Opening>,
certificate: Vec<u8>,
},
}