use crate::Exceptions;
use crate::common::Result;
#[derive(Debug, Clone)]
pub struct ModulusGF<const MODULUS: usize> {
expTable: [u32; MODULUS],
logTable: [u32; MODULUS],
modulus: u32,
generator: u32,
}
impl<const MODULUS: usize> ModulusGF<MODULUS> {
pub const fn new(generator: u32) -> Self {
let mut expTable = [0u32; MODULUS];
let mut logTable = [0u32; MODULUS];
let mut x = 1;
let mut i = 0;
while i < MODULUS {
expTable[i] = x;
x = (x * generator) % MODULUS as u32;
i += 1;
}
let mut i = 0;
while i < MODULUS - 1 {
logTable[expTable[i] as usize] = i as u32;
i += 1;
}
Self {
expTable,
logTable,
modulus: MODULUS as u32,
generator,
}
}
pub const fn add(&self, a: u32, b: u32) -> u32 {
(a + b) % self.modulus
}
pub const fn subtract(&self, a: u32, b: u32) -> u32 {
(self.modulus + a - b) % self.modulus
}
pub const fn exp(&self, a: u32) -> u32 {
self.expTable[a as usize]
}
pub const fn log(&self, a: u32) -> Result<u32> {
if a == 0 {
Err(Exceptions::ARITHMETIC)
} else {
Ok(self.logTable[a as usize])
}
}
pub const fn inverse(&self, a: u32) -> Result<u32> {
if a == 0 {
Err(Exceptions::ARITHMETIC)
} else {
Ok(self.expTable[self.modulus as usize - self.logTable[a as usize] as usize - 1])
}
}
pub const fn multiply(&self, a: u32, b: u32) -> u32 {
if a == 0 || b == 0 {
0
} else {
self.expTable[(self.logTable[a as usize] + self.logTable[b as usize]) as usize
% (self.modulus - 1) as usize]
}
}
pub const fn getSize(&self) -> u32 {
self.modulus
}
}
impl<const MODULUS: usize> PartialEq for ModulusGF<MODULUS> {
fn eq(&self, other: &Self) -> bool {
self.modulus == other.modulus && self.generator == other.generator
}
}
impl<const MODULUS: usize> Eq for ModulusGF<MODULUS> {}