///|
pub(all) suberror CodeError {
Invalid(String)
Shape(String)
Limit(String)
Inconsistent
Incomplete(Int32)
Corrupt(String)
Truncated
}
///|
fn check_symbol(value : Int32) -> Unit raise CodeError {
if value < 0 || value > 255 {
raise Invalid("field element must be in 0..255")
}
}
///|
// Polynomial basis; the ninth bit is reduced by x^8+x^4+x^3+x^2+1.
fn mul(left : Int32, right : Int32) -> Int32 {
let mut a = left
let mut b = right
let mut product = 0
for _ in 0..<8 {
if (b & 1) != 0 {
product = product ^ a
}
b = b >> 1
a = a << 1
if (a & 256) != 0 {
a = a ^ 285
}
}
product
}
///|
fn power(value : Int32, exponent : Int32) -> Int32 {
let mut base = value
let mut n = exponent
let mut result = 1
while n > 0 {
if (n & 1) != 0 {
result = mul(result, base)
}
base = mul(base, base)
n = n >> 1
}
result
}
///|
pub fn gf_add(left : Int32, right : Int32) -> Int32 raise CodeError {
check_symbol(left)
check_symbol(right)
left ^ right
}
///|
pub fn gf_mul(left : Int32, right : Int32) -> Int32 raise CodeError {
check_symbol(left)
check_symbol(right)
mul(left, right)
}
///|
pub fn gf_inverse(value : Int32) -> Int32 raise CodeError {
check_symbol(value)
if value == 0 {
raise Invalid("zero has no multiplicative inverse")
}
power(value, 254)
}
///|
pub fn gf_div(left : Int32, right : Int32) -> Int32 raise CodeError {
check_symbol(left)
mul(left, gf_inverse(right))
}
///|
pub fn gf_pow(value : Int32, exponent : Int32) -> Int32 raise CodeError {
check_symbol(value)
if exponent < 0 {
raise Invalid("negative field exponent")
}
power(value, exponent)
}
///|
pub fn field_polynomial() -> Int32 {
285
}