///|
/// Arithmetic in GF(2^8) with the AES polynomial 0x11B. Bytes are carried
/// as Int in 0..255. Subtraction is addition is XOR, which is what makes
/// the Lagrange interpolation in shamir.mbt lose its minus signs: the
/// weight of point i at zero is the product of x_j times the inverse of
/// x_i XOR x_j.
fn gf_mul(left : Int32, right : Int32) -> Int32 {
let mut product = 0
let mut x = left
let mut y = right
while y > 0 {
if (y & 1) == 1 {
product = product ^ x
}
x = x << 1
if x >= 256 {
x = x ^ 0x11B
}
y = y >> 1
}
product
}
///|
fn gf_pow(base : Int32, exponent : Int32) -> Int32 {
let mut result = 1
let mut square = base
let mut n = exponent
while n > 0 {
if (n & 1) == 1 {
result = gf_mul(result, square)
}
square = gf_mul(square, square)
n = n >> 1
}
result
}
///|
/// The multiplicative inverse by Fermat: a^254, valid for every nonzero a.
fn gf_inv(value : Int32) -> Int32 {
gf_pow(value, 254)
}
///|
/// Horner evaluation of the coefficient list (constant term first) at x.
fn gf_eval(coefficients : Array[Int32], x : Int32) -> Int32 {
let mut acc = 0
for i in 0.. Int32 {
let mut acc = 0
for i in 0..