Class GF256AES

java.lang.Object
org.bouncycastle.math.raw.GF256AES

public class GF256AES extends Object
Constant-time GF(2^8) primitives over the AES reduction polynomial x^8 + x^4 + x^3 + x + 1 (0x11b).

The AES suffix names that specific irreducible polynomial: GF(2^8) is a single field up to isomorphism but admits many representations, and the AES choice is by far the most common (also used by SM4, GHASH's sibling fields, etc.). The polynomial alone pins down the arithmetic — e.g. Rainbow's GF(2^8) uses a tower basis whose products differ, so it deliberately does not share this class. Callers relying on the AES element encoding should depend on the name, not just "GF(256)".

Shared home for the word-parallel bitsliced scalar-times-vector multiply used by the multivariate / MPC-in-the-head schemes (SDitH, UOV, ...). Companion to GF16 for the GF(2^4) nibble field.

  • Method Summary

    Modifier and Type
    Method
    Description
    static int
    inv(int a)
    Constant-time GF(256) multiplicative inverse over 0x11b via the Fermat addition chain a^254 = a^-1 (since a^255 = 1 for nonzero a).
    static int
    mul(int a, int b)
    Constant-time GF(256) scalar multiply over the AES polynomial 0x11b: returns a * b.
    static long
    mulFx8(int s, long v)
    Word-parallel constant-time GF(256) scalar-times-vector multiply: returns s * v where v packs eight GF(256) elements, one per byte lane, and the result packs the eight products in the same lanes.
    static int
    sqr(int a)
    Constant-time GF(256) squaring over 0x11b.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • mul

      public static int mul(int a, int b)
      Constant-time GF(256) scalar multiply over the AES polynomial 0x11b: returns a * b. There is no table lookup and no data-dependent branch — safe to feed secret operands. This is the scalar companion of mulFx8(int, long) and is byte-identical to the per-scheme forms it replaces (UOV's mul256, SDitH's mulNaive, MQOM's gf256Mult).
    • sqr

      public static int sqr(int a)
      Constant-time GF(256) squaring over 0x11b. Squaring is GF(2)-linear, so a^2 is just the bit-spread of a (interleave a zero between each bit), reduced mod 0x11b.
    • inv

      public static int inv(int a)
      Constant-time GF(256) multiplicative inverse over 0x11b via the Fermat addition chain a^254 = a^-1 (since a^255 = 1 for nonzero a). The chain maps 0 -> 0, so no data-dependent zero check is needed and none is done: branching on zero-ness would leak whether a (secret-derived) value was singular. No table is used. The seven squarings go through the dedicated sqr(int); the four genuine products through mul(int, int).
    • mulFx8

      public static long mulFx8(int s, long v)
      Word-parallel constant-time GF(256) scalar-times-vector multiply: returns s * v where v packs eight GF(256) elements, one per byte lane, and the result packs the eight products in the same lanes.

      Algorithm: s*v = XOR_k s_k (x^k . v) over the 8 bits s_k of the scalar, where x^k . v is k-fold GF(256) doubling (xtime) of every lane. xtime is the branchless SWAR step ((v<<1) & 0xFE..) ^ ((v>>>7 & 0x01..) * 0x1b), and each scalar bit selects via the mask -(s_k) (0 or -1). No table and no data-dependent branch, so it is safe to feed secret scalars (the operand of a secret-share multiply-accumulate).