galois.GF(order: int, *, irreducible_poly: PolyLike | None = None, primitive_element: int | PolyLike | None = None, verify: bool = True, compile: 'auto' | 'jit-lookup' | 'jit-calculate' | 'python-calculate' | None = None, repr: 'int' | 'poly' | 'power' | None = None) type[FieldArray]
galois.GF(characteristic: int, degree: int, *, irreducible_poly: PolyLike | None = None, primitive_element: int | PolyLike | None = None, verify: bool = True, compile: 'auto' | 'jit-lookup' | 'jit-calculate' | 'python-calculate' | None = None, repr: 'int' | 'poly' | 'power' | None = None) type[FieldArray]

Creates a FieldArray subclass 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.

characteristic: int

The characteristic \(p\) of the field \(\mathrm{GF}(p^m)\). The characteristic must be prime.

degree: int

The degree \(m\) of the field \(\mathrm{GF}(p^m)\). The degree must be a positive integer.

irreducible_poly: PolyLike | None = None

Optionally specify an irreducible polynomial of degree \(m\) over \(\mathrm{GF}(p)\) that defines the finite field arithmetic. The default is None which uses the Conway polynomial \(C_{p,m}\), see conway_poly().

primitive_element: int | PolyLike | None = None

Optionally specify a primitive element of the field. This value is used when building the exponential and logarithm lookup tables and as the base of numpy.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\). The default is None which uses primitive_root().

For extension fields \(\mathrm{GF}(p^m)\), the primitive element is a polynomial of degree less than \(m\) over \(\mathrm{GF}(p)\). The default is None which uses primitive_element().

verify: bool = True

Indicates whether to verify that the user-provided irreducible polynomial is in fact irreducible and that the user-provided 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 while to verify), this argument may be set to False.

The default irreducible polynomial and primitive element are never verified because they are already known to be irreducible and a multiplicative generator, respectively.

compile: 'auto' | 'jit-lookup' | 'jit-calculate' | 'python-calculate' | None = None

The ufunc calculation mode. This can be modified after class construction with the compile() method. See Compilation Modes for a further discussion.

  • None (default): For a newly created FieldArray subclass, None corresponds to "auto". If the FieldArray subclass already exists, None does not modify its current 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 intended for fields whose elements cannot be represented with numpy.int64 and instead use numpy.object_ with Python int (which has arbitrary precision). However, this mode can be used for any field, enabling the code to run without Numba JIT compilation.

repr: 'int' | 'poly' | 'power' | None = None

The field element representation. This can be modified after class construction with the repr() method. See Element Representation for a further discussion.

Returns:

A FieldArray subclass for \(\mathrm{GF}(p^m)\).

Notes

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

Examples

Create a FieldArray subclass for each type of finite field.

Construct the binary field.

In [1]: GF = galois.GF(2)

In [2]: print(GF.properties)
Galois Field:
  name: GF(2)
  characteristic: 2
  degree: 1
  order: 2
  irreducible_poly: x + 1
  is_primitive_poly: True
  primitive_element: 1

Construct a prime field.

In [3]: GF = galois.GF(31)

In [4]: print(GF.properties)
Galois Field:
  name: GF(31)
  characteristic: 31
  degree: 1
  order: 31
  irreducible_poly: x + 28
  is_primitive_poly: True
  primitive_element: 3

Construct a binary extension field. Notice the default irreducible polynomial is primitive and \(x\) is a primitive element.

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

In [6]: print(GF.properties)
Galois Field:
  name: 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 prime extension field. Notice the default irreducible polynomial is primitive and \(x\) is a primitive element.

In [7]: GF = galois.GF(3**5)

In [8]: print(GF.properties)
Galois Field:
  name: GF(3^5)
  characteristic: 3
  degree: 5
  order: 243
  irreducible_poly: x^5 + 2x + 1
  is_primitive_poly: True
  primitive_element: x

Create a FieldArray subclass for extension fields and specify their irreducible polynomials.

Construct the \(\mathrm{GF}(2^8)\) field that is used in AES. Notice the irreducible polynomial is not primitive and \(x\) is not a primitive element.

In [9]: GF = galois.GF(2**8, irreducible_poly="x^8 + x^4 + x^3 + x + 1")

In [10]: print(GF.properties)
Galois Field:
  name: 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

Construct \(\mathrm{GF}(3^5)\) with an irreducible, but not primitive, polynomial. Notice that \(x\) is not a primitive element.

In [11]: GF = galois.GF(3**5, irreducible_poly="x^5 + 2x + 2")

In [12]: print(GF.properties)
Galois Field:
  name: GF(3^5)
  characteristic: 3
  degree: 5
  order: 243
  irreducible_poly: x^5 + 2x + 2
  is_primitive_poly: False
  primitive_element: 2x

Finite fields with arbitrarily large orders are supported.

Construct a large prime field.

In [13]: GF = galois.GF(36893488147419103183)

In [14]: print(GF.properties)
Galois Field:
  name: GF(36893488147419103183)
  characteristic: 36893488147419103183
  degree: 1
  order: 36893488147419103183
  irreducible_poly: x + 36893488147419103180
  is_primitive_poly: True
  primitive_element: 3

Construct a large binary extension field.

In [15]: GF = galois.GF(2**100)

In [16]: print(GF.properties)
Galois Field:
  name: 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

The construction of large fields can be sped up by explicitly specifying \(p\) and \(m\). This avoids the need to factor the order \(p^m\).

In [17]: GF = galois.GF(2, 100)

In [18]: print(GF.properties)
Galois Field:
  name: 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

Construct a large prime extension field.

In [19]: GF = galois.GF(109987**4)

In [20]: print(GF.properties)
Galois Field:
  name: GF(109987^4)
  characteristic: 109987
  degree: 4
  order: 146340800268433348561
  irreducible_poly: x^4 + 3x^2 + 100525x + 3
  is_primitive_poly: True
  primitive_element: x

The construction of large fields can be sped up by explicitly specifying \(p\) and \(m\). This avoids the need to factor the order \(p^m\).

In [21]: GF = galois.GF(109987, 4)

In [22]: print(GF.properties)
Galois Field:
  name: GF(109987^4)
  characteristic: 109987
  degree: 4
  order: 146340800268433348561
  irreducible_poly: x^4 + 3x^2 + 100525x + 3
  is_primitive_poly: True
  primitive_element: x