use alloc::vec::Vec;
use crate::gf;
pub const TABLE_BYTES: usize = 32;
pub fn mul_table32(c: u8, out: &mut [u8; TABLE_BYTES]) {
for j in 0u8..16 {
out[j as usize] = gf::mul(c, j);
out[16 + j as usize] = gf::mul(c, j << 4);
}
}
pub fn init_tables(coeffs: &[u8]) -> Vec<u8> {
let mut out = Vec::with_capacity(coeffs.len() * TABLE_BYTES);
let mut tbl = [0u8; TABLE_BYTES];
for &c in coeffs {
mul_table32(c, &mut tbl);
out.extend_from_slice(&tbl);
}
out
}
#[inline]
pub fn table_mul(tbl: &[u8; TABLE_BYTES], x: u8) -> u8 {
tbl[(x & 0x0f) as usize] ^ tbl[16 + (x >> 4) as usize]
}
pub const GFNI_TABLE_BYTES: usize = 8;
const fn build_affine(c: u8) -> u64 {
let mut m = 0u64;
let mut j = 0;
while j < 8 {
let mut row = 0u8;
let mut i = 0;
while i < 8 {
if crate::gf::mul(c, 1 << i) & (1 << j) != 0 {
row |= 1 << i;
}
i += 1;
}
m |= (row as u64) << (8 * (7 - j));
j += 1;
}
m
}
const fn build_affine_table() -> [u64; 256] {
let mut t = [0u64; 256];
let mut c = 0usize;
while c < 256 {
t[c] = build_affine(c as u8);
c += 1;
}
t
}
pub const AFFINE: [u64; 256] = build_affine_table();
pub fn init_tables_gfni(coeffs: &[u8]) -> Vec<u8> {
let mut out = Vec::with_capacity(coeffs.len() * GFNI_TABLE_BYTES);
for &c in coeffs {
out.extend_from_slice(&AFFINE[c as usize].to_le_bytes());
}
out
}