///|
/// 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..