feat: GF(2^8) Galois 域运算 + 预计算 exp/log 表
This commit is contained in:
+166
-1
@@ -1 +1,166 @@
|
||||
// FIXME: GF(2⁸) Galois 域运算 — Task 2
|
||||
/// GF(2⁸) Galois 域运算
|
||||
/// 本原多项式: x⁸ + x⁴ + x³ + x² + 1 = 0x11D
|
||||
/// 生成元 α = 0x02
|
||||
|
||||
use std::sync::OnceLock;
|
||||
|
||||
fn exp_table() -> &'static [u8; 512] {
|
||||
static TABLE: OnceLock<[u8; 512]> = OnceLock::new();
|
||||
TABLE.get_or_init(|| {
|
||||
let mut table = [0u8; 512];
|
||||
let mut x = 1u8;
|
||||
for i in 0..255 {
|
||||
table[i] = x;
|
||||
table[i + 255] = x; // 双倍长度避免 % 255
|
||||
let next = (x as u16) << 1;
|
||||
x = if next >= 0x100 {
|
||||
(next ^ 0x1D) as u8
|
||||
} else {
|
||||
next as u8
|
||||
};
|
||||
}
|
||||
table[510] = table[255];
|
||||
table[511] = table[256];
|
||||
table
|
||||
})
|
||||
}
|
||||
|
||||
fn log_table() -> &'static [u8; 256] {
|
||||
static TABLE: OnceLock<[u8; 256]> = OnceLock::new();
|
||||
TABLE.get_or_init(|| {
|
||||
let mut table = [0u8; 256];
|
||||
let mut x = 1u8;
|
||||
for i in 0..255 {
|
||||
table[x as usize] = i;
|
||||
let next = (x as u16) << 1;
|
||||
x = if next >= 0x100 {
|
||||
(next ^ 0x1D) as u8
|
||||
} else {
|
||||
next as u8
|
||||
};
|
||||
}
|
||||
table
|
||||
})
|
||||
}
|
||||
|
||||
/// GF(2⁸) 加法 = 异或
|
||||
#[inline]
|
||||
pub fn add(a: u8, b: u8) -> u8 {
|
||||
a ^ b
|
||||
}
|
||||
|
||||
/// GF(2⁸) 减法 = 异或(同加法)
|
||||
#[inline]
|
||||
pub fn sub(a: u8, b: u8) -> u8 {
|
||||
a ^ b
|
||||
}
|
||||
|
||||
/// GF(2⁸) 乘法:a * b
|
||||
pub fn mul(a: u8, b: u8) -> u8 {
|
||||
if a == 0 || b == 0 {
|
||||
return 0;
|
||||
}
|
||||
let log_a = log_table()[a as usize] as usize;
|
||||
let log_b = log_table()[b as usize] as usize;
|
||||
exp_table()[log_a + log_b]
|
||||
}
|
||||
|
||||
/// GF(2⁸) 除法:a / b
|
||||
pub fn div(a: u8, b: u8) -> u8 {
|
||||
if a == 0 {
|
||||
return 0;
|
||||
}
|
||||
if b == 0 {
|
||||
panic!("GF(2⁸) 除以零");
|
||||
}
|
||||
let log_a = log_table()[a as usize] as usize;
|
||||
let log_b = log_table()[b as usize] as usize;
|
||||
let diff = (log_a + 255 - log_b) % 255;
|
||||
exp_table()[diff]
|
||||
}
|
||||
|
||||
/// GF(2⁸) 幂运算:base^exp
|
||||
pub fn pow(base: u8, exp: usize) -> u8 {
|
||||
if exp == 0 {
|
||||
return 1;
|
||||
}
|
||||
if base == 0 {
|
||||
return 0;
|
||||
}
|
||||
let log_b = log_table()[base as usize] as usize;
|
||||
exp_table()[(log_b * exp) % 255]
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_mul_basic() {
|
||||
// 2 * 3 = 6 in GF(2^8)
|
||||
assert_eq!(mul(2, 3), 6);
|
||||
// 0xFF * 0x01 = 0xFF
|
||||
assert_eq!(mul(0xFF, 1), 0xFF);
|
||||
// 任何数乘 0 = 0
|
||||
assert_eq!(mul(0xA5, 0), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mul_commutative() {
|
||||
for a in 0..=255u8 {
|
||||
for b in (a..=255u8).step_by(17) {
|
||||
assert_eq!(mul(a, b), mul(b, a),
|
||||
"交换律失败: {:02X} * {:02X}", a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mul_associative() {
|
||||
let cases = [(3, 5, 7), (0xFF, 2, 4), (1, 1, 1), (0x80, 0x40, 0x20)];
|
||||
for (a, b, c) in cases {
|
||||
assert_eq!(mul(mul(a, b), c), mul(a, mul(b, c)),
|
||||
"结合律失败: {:02X} * {:02X} * {:02X}", a, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_div_inverse() {
|
||||
for a in 1..=255u8 {
|
||||
let inv = div(1, a);
|
||||
assert_eq!(mul(a, inv), 1,
|
||||
"逆元失败: {:02X} * {:02X} != 1", a, inv);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_div_mul_consistency() {
|
||||
for a in 1..=255u8 {
|
||||
for b in (1..=255u8).step_by(17) {
|
||||
let q = div(a, b);
|
||||
assert_eq!(mul(q, b), a,
|
||||
"除乘一致性失败: {:02X} / {:02X} = {:02X}", a, q, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_sub() {
|
||||
for a in 0..=255u8 {
|
||||
for b in 0..=255u8 {
|
||||
assert_eq!(add(a, b), sub(a, b));
|
||||
assert_eq!(sub(add(a, b), b), a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pow() {
|
||||
// α^0 = 1
|
||||
assert_eq!(pow(2, 0), 1);
|
||||
// α^1 = 2
|
||||
assert_eq!(pow(2, 1), 2);
|
||||
// α^7 * α^2 = α^9
|
||||
assert_eq!(mul(pow(2, 7), pow(2, 2)), pow(2, 9));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user