use core::ops::{AddAssign, Mul};
use miden_core::field::PrimeCharacteristicRing;
use super::MAX_MESSAGE_WIDTH;
pub struct Challenges<EF: PrimeCharacteristicRing> {
pub alpha: EF,
pub beta_powers: [EF; MAX_MESSAGE_WIDTH],
}
impl<EF: PrimeCharacteristicRing> Challenges<EF> {
pub fn new(alpha: EF, beta: EF) -> Self {
let mut beta_powers = core::array::from_fn(|_| EF::ONE);
for i in 1..MAX_MESSAGE_WIDTH {
beta_powers[i] = beta_powers[i - 1].clone() * beta.clone();
}
Self { alpha, beta_powers }
}
#[inline(always)]
pub fn encode<BF, const K: usize>(&self, elems: [BF; K]) -> EF
where
EF: Mul<BF, Output = EF> + AddAssign,
BF: Clone,
{
const { assert!(K <= MAX_MESSAGE_WIDTH, "Message length exceeds beta_powers capacity") };
let mut acc = self.alpha.clone();
for (i, elem) in elems.iter().enumerate() {
acc += self.beta_powers[i].clone() * elem.clone();
}
acc
}
#[inline(always)]
pub fn encode_sparse<BF, const K: usize>(&self, layout: [usize; K], values: [BF; K]) -> EF
where
EF: Mul<BF, Output = EF> + AddAssign,
BF: Clone,
{
let mut acc = self.alpha.clone();
for i in 0..K {
let idx = layout[i];
debug_assert!(
idx < self.beta_powers.len(),
"encode_sparse index {} exceeds beta_powers length ({})",
idx,
self.beta_powers.len()
);
acc += self.beta_powers[idx].clone() * values[i].clone();
}
acc
}
}