#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IrreduciblePoly {
pub p: u32,
pub n: u32,
pub coeffs: Vec<u32>,
}
impl IrreduciblePoly {
#[must_use]
pub fn new(p: u32, coeffs: Vec<u32>) -> Self {
Self {
p,
n: coeffs.len() as u32,
coeffs,
}
}
#[must_use]
pub fn field_order(&self) -> u32 {
self.p.pow(self.n)
}
}
pub static IRREDUCIBLE_POLYS: &[(u32, u32, &[u32])] = &[
(2, 2, &[1, 1]),
(2, 3, &[1, 1, 0]),
(2, 4, &[1, 1, 0, 0]),
(2, 5, &[1, 0, 1, 0, 0]),
(2, 6, &[1, 1, 0, 0, 0, 0]),
(2, 7, &[1, 0, 0, 1, 0, 0, 0]),
(2, 8, &[1, 1, 0, 1, 1, 0, 0, 0]),
(3, 2, &[1, 0]),
(3, 3, &[1, 2, 0]),
(3, 4, &[2, 0, 0, 2]),
(5, 2, &[2, 0]),
(5, 3, &[2, 1, 0]),
(7, 2, &[1, 0]),
(11, 2, &[1, 0]),
(13, 2, &[2, 0]),
];
#[must_use]
pub fn get_irreducible_poly(p: u32, n: u32) -> Option<Vec<u32>> {
for &(poly_p, poly_n, coeffs) in IRREDUCIBLE_POLYS {
if poly_p == p && poly_n == n {
return Some(coeffs.to_vec());
}
}
None
}
#[must_use]
pub fn has_irreducible_poly(p: u32, n: u32) -> bool {
get_irreducible_poly(p, n).is_some()
}
#[must_use]
pub fn available_field_orders() -> Vec<u32> {
IRREDUCIBLE_POLYS
.iter()
.map(|&(p, n, _)| p.pow(n))
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_irreducible_poly() {
let poly = get_irreducible_poly(2, 2).unwrap();
assert_eq!(poly, vec![1, 1]);
let poly = get_irreducible_poly(2, 3).unwrap();
assert_eq!(poly, vec![1, 1, 0]);
let poly = get_irreducible_poly(3, 2).unwrap();
assert_eq!(poly, vec![1, 0]);
assert!(get_irreducible_poly(17, 5).is_none());
}
#[test]
fn test_has_irreducible_poly() {
assert!(has_irreducible_poly(2, 2));
assert!(has_irreducible_poly(2, 8));
assert!(has_irreducible_poly(3, 2));
assert!(!has_irreducible_poly(17, 5));
}
#[test]
fn test_available_orders() {
let orders = available_field_orders();
assert!(orders.contains(&4)); assert!(orders.contains(&8)); assert!(orders.contains(&9)); assert!(orders.contains(&256)); }
#[test]
fn test_irreducible_poly_struct() {
let poly = IrreduciblePoly::new(2, vec![1, 1]);
assert_eq!(poly.p, 2);
assert_eq!(poly.n, 2);
assert_eq!(poly.field_order(), 4);
}
}