use crate::modules::companion::CompanionMatrix;
use crate::modules::poly_eval::poly_matrix_eval;
use crate::modules::field::Field;
use crate::modules::companion::Mat;
use std::ops::{Add, Mul};
pub struct StreamGenerator {
pub c: CompanionMatrix,
pub t: Mat, pub state: Vec<Field>,
pub k: usize,
}
impl StreamGenerator {
pub fn new(c: CompanionMatrix, t: Mat, state: Vec<Field>) -> Self {
let k = c.k;
assert_eq!(state.len(), k);
assert_eq!(t.len(), k);
assert!(t.iter().all(|row| row.len() == k), "T matrix must be k×k");
StreamGenerator { c, t, state, k }
}
pub fn step(&mut self) -> Field {
let mut out = Field::zero();
for j in 0..self.k {
out = out.add(self.t[0][j].mul(self.state[j]));
}
self.state = self.c.mat_vec_mul(&self.state);
out
}
pub fn generate(&mut self, n: usize) -> Vec<Field> {
let mut v = Vec::with_capacity(n);
for _ in 0..n {
v.push(self.step());
}
v
}
pub fn build_t_from_poly(cm: &CompanionMatrix, g_coeffs: &[u64]) -> Mat {
poly_matrix_eval(g_coeffs, &cm.mat)
}
}
impl Iterator for StreamGenerator {
type Item = Field;
fn next(&mut self) -> Option<Self::Item> {
Some(self.step())
}
}