pub struct GF28 {
log: [u8; 256],
exp: [u8; 256],
}
impl GF28 {
pub fn new() -> Self {
let mut log = [0u8; 256];
let mut exp = [0u8; 256];
let mut x = 1u16;
for i in 0..255 {
exp[i] = x as u8;
log[x as usize] = i as u8;
x <<= 1; if x & 0x100 != 0 { x ^= 0x11D; }
}
exp[255] = exp[0];
Self { log, exp }
}
pub fn mul(&self, a: u8, b: u8) -> u8 {
if a == 0 || b == 0 {
return 0;
}
let log_a = self.log[a as usize] as usize;
let log_b = self.log[b as usize] as usize;
self.exp[(log_a + log_b) % 255]
}
pub fn exp(&self, power: usize) -> u8 {
self.exp[power % 255]
}
#[inline]
pub fn add(&self, a: u8, b: u8) -> u8 {
a ^ b }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_gf_multiplication() {
let gf = GF28::new();
assert_eq!(gf.mul(0, 123), 0);
assert_eq!(gf.mul(45, 0), 0);
assert_eq!(gf.exp(0), 1);
assert_eq!(gf.exp(1), 2);
assert_eq!(gf.exp(8), 29);
assert_eq!(gf.mul(3, 7), 9);
assert_eq!(gf.mul(32, 8), 29);
}
}