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