galois.GF

galois.GF(order, irreducible_poly=None, primitive_element=None, verify=True, compile=None, display=None)

Factory function to construct a Galois field array class for \(\mathrm{GF}(p^m)\).

Parameters
  • order (int) – The order \(p^m\) of the field \(\mathrm{GF}(p^m)\). The order must be a prime power.

  • irreducible_poly (int, str, tuple, list, numpy.ndarray, galois.Poly, optional) –

    Optionally specify an irreducible polynomial of degree \(m\) over \(\mathrm{GF}(p)\) that will define the Galois field arithmetic.

    • None (default): Uses the Conway polynomial \(C_{p,m}\), see galois.conway_poly().

    • int: The integer representation of the irreducible polynomial.

    • str: The irreducible polynomial expressed as a string, e.g. "x^2 + 1".

    • tuple, list, numpy.ndarray: The irreducible polynomial coefficients in degree-descending order.

    • galois.Poly: The irreducible polynomial as a polynomial object.

  • primitive_element (int, str, tuple, list, numpy.ndarray, galois.Poly, optional) –

    Optionally specify a primitive element of the field \(\mathrm{GF}(p^m)\). This value is used when building the log/anti-log lookup tables and when computing np.log(). A primitive element is a generator of the multiplicative group of the field. For prime fields \(\mathrm{GF}(p)\), the primitive element must be an integer and is a primitive root modulo \(p\). For extension fields \(\mathrm{GF}(p^m)\), the primitive element is a polynomial of degree less than \(m\) over \(\mathrm{GF}(p)\).

    For prime fields:

    For extension fields:

    • None (default): Uses the lexicographically-minimal primitive element, see galois.primitive_element().

    • int: The integer representation of the primitive element.

    • str: The primitive element expressed as a string, e.g. "x + 1".

    • tuple, list, numpy.ndarray: The primitive element’s polynomial coefficients in degree-descending order.

    • galois.Poly: The primitive element as a polynomial object.

  • verify (bool, optional) – Indicates whether to verify that the specified irreducible polynomial is in fact irreducible and whether the specified primitive element is in fact a generator of the multiplicative group. The default is True. For large fields and irreducible polynomials that are already known to be irreducible (which may take a long time to verify), this argument can be set to False. If the default irreducible polynomial and primitive element are used, no verification is performed because the defaults are guaranteed to be irreducible and a multiplicative generator, respectively.

  • compile (str, optional) –

    The ufunc calculation mode. This can be modified after class construction with the galois.FieldClass.compile() method.

    • None (default): For newly-created classes, None corresponds to "auto". For Galois field array classes of this type that were previously created, None does not modify the current ufunc compilation mode.

    • "auto": Selects “jit-lookup” for fields with order less than \(2^{20}\), “jit-calculate” for larger fields, and “python-calculate” for fields whose elements cannot be represented with numpy.int64.

    • "jit-lookup": JIT compiles arithmetic ufuncs to use Zech log, log, and anti-log lookup tables for efficient computation. In the few cases where explicit calculation is faster than table lookup, explicit calculation is used.

    • "jit-calculate": JIT compiles arithmetic ufuncs to use explicit calculation. The “jit-calculate” mode is designed for large fields that cannot or should not store lookup tables in RAM. Generally, the “jit-calculate” mode is slower than “jit-lookup”.

    • "python-calculate": Uses pure-python ufuncs with explicit calculation. This is reserved for fields whose elements cannot be represented with numpy.int64 and instead use numpy.object_ with python int (which has arbitrary precision).

  • display (str, optional) –

    The field element display representation. This can be modified after class consstruction with the galois.FieldClass.display() method.

    • None (default): For newly-created classes, None corresponds to the integer representation ("int"). For Galois field array classes of this type that were previously created, None does not modify the current display mode.

    • "int": The element displayed as the integer representation of the polynomial. For example, \(2x^2 + x + 2\) is an element of \(\mathrm{GF}(3^3)\) and is equivalent to the integer \(23 = 2 \cdot 3^2 + 3 + 2\).

    • "poly": The element as a polynomial over \(\mathrm{GF}(p)\) of degree less than \(m\). For example, \(2x^2 + x + 2\) is an element of \(\mathrm{GF}(3^3)\).

    • "power": The element as a power of the primitive element, see galois.FieldClass.primitive_element. For example, \(2x^2 + x + 2 = \alpha^5\) in \(\mathrm{GF}(3^3)\) with irreducible polynomial \(x^3 + 2x + 1\) and primitive element \(\alpha = x\).

Returns

A Galois field array class for \(\mathrm{GF}(p^m)\). If this class has already been created, a reference to that class is returned.

Return type

galois.FieldClass

Notes

The created class is a subclass of galois.FieldArray and an instance of galois.FieldClass. The galois.FieldArray inheritance provides the numpy.ndarray functionality and some additional methods on Galois field arrays, such as galois.FieldArray.row_reduce(). The galois.FieldClass metaclass provides a variety of class attributes and methods relating to the finite field, such as the galois.FieldClass.display() method to change the field element display representation.

Galois field array classes of the same type (order, irreducible polynomial, and primitive element) are singletons. So, calling this class factory with arguments that correspond to the same class will return the same class object.

Examples

Construct various Galois field array class for \(\mathrm{GF}(2)\), \(\mathrm{GF}(2^m)\), \(\mathrm{GF}(p)\), and \(\mathrm{GF}(p^m)\) with the default irreducible polynomials and primitive elements. For the extension fields, notice the irreducible polynomials are primitive and \(x\) is a primitive element.

# Construct a GF(2) class
In [1]: GF2 = galois.GF(2); print(GF2.properties)
GF(2):
  characteristic: 2
  degree: 1
  order: 2
  irreducible_poly: x + 1
  is_primitive_poly: True
  primitive_element: 1

# Construct a GF(2^m) class
In [2]: GF256 = galois.GF(2**8); print(GF256.properties)
GF(2^8):
  characteristic: 2
  degree: 8
  order: 256
  irreducible_poly: x^8 + x^4 + x^3 + x^2 + 1
  is_primitive_poly: True
  primitive_element: x

# Construct a GF(p) class
In [3]: GF3 = galois.GF(3); print(GF3.properties)
GF(3):
  characteristic: 3
  degree: 1
  order: 3
  irreducible_poly: x + 1
  is_primitive_poly: True
  primitive_element: 2

# Construct a GF(p^m) class
In [4]: GF243 = galois.GF(3**5); print(GF243.properties)
GF(3^5):
  characteristic: 3
  degree: 5
  order: 243
  irreducible_poly: x^5 + 2x + 1
  is_primitive_poly: True
  primitive_element: x

Or construct a Galois field array class and specify the irreducible polynomial. Here is an example using the \(\mathrm{GF}(2^8)\) field from AES. Notice the irreducible polynomial is not primitive and \(x\) is not a primitive element.

In [5]: poly = galois.Poly.Degrees([8,4,3,1,0]); poly
Out[5]: Poly(x^8 + x^4 + x^3 + x + 1, GF(2))

In [6]: GF256_AES = galois.GF(2**8, irreducible_poly=poly)

In [7]: print(GF256_AES.properties)
GF(2^8):
  characteristic: 2
  degree: 8
  order: 256
  irreducible_poly: x^8 + x^4 + x^3 + x + 1
  is_primitive_poly: False
  primitive_element: x + 1

Very large fields are also supported but they use numpy.object_ dtypes with python int and, therefore, do not have compiled ufuncs.

# Construct a very large GF(2^m) class
In [8]: GF2m = galois.GF(2**100); print(GF2m.properties)
GF(2^100):
  characteristic: 2
  degree: 100
  order: 1267650600228229401496703205376
  irreducible_poly: x^100 + x^57 + x^56 + x^55 + x^52 + x^48 + x^47 + x^46 + x^45 + x^44 + x^43 + x^41 + x^37 + x^36 + x^35 + x^34 + x^31 + x^30 + x^27 + x^25 + x^24 + x^22 + x^20 + x^19 + x^16 + x^15 + x^11 + x^9 + x^8 + x^6 + x^5 + x^3 + 1
  is_primitive_poly: True
  primitive_element: x

In [9]: GF2m.dtypes, GF2m.ufunc_mode
Out[9]: ([numpy.object_], 'python-calculate')

# Construct a very large GF(p) class
In [10]: GFp = galois.GF(36893488147419103183); print(GFp.properties)
GF(36893488147419103183):
  characteristic: 36893488147419103183
  degree: 1
  order: 36893488147419103183
  irreducible_poly: x + 36893488147419103180
  is_primitive_poly: True
  primitive_element: 3

In [11]: GFp.dtypes, GFp.ufunc_mode
Out[11]: ([numpy.object_], 'python-calculate')

The default display mode for field elements is the integer representation. This can be modified by using the display keyword argument. It can also be changed after class construction by calling the galois.FieldClass.display() method.

In [12]: GF = galois.GF(2**8)

In [13]: GF.Random()
Out[13]: GF(52, order=2^8)

In [14]: GF = galois.GF(2**8, display="poly")

In [15]: GF.Random()
Out[15]: GF(α^5 + α^3 + α, order=2^8)

Galois field array classes of the same type (order, irreducible polynomial, and primitive element) are singletons. So, calling this class factory with arguments that correspond to the same class will return the same field class object.

In [16]: poly1 = galois.Poly([1, 0, 0, 0, 1, 1, 0, 1, 1])

In [17]: poly2 = poly1.integer

In [18]: galois.GF(2**8, irreducible_poly=poly1) is galois.GF(2**8, irreducible_poly=poly2)
Out[18]: True

See galois.FieldArray and galois.FieldClass for more examples of what Galois field arrays can do.