galois.primitive_elements(irreducible_poly: Poly) list[Poly]

Finds all primitive elements $$g$$ of the Galois field $$\mathrm{GF}(q^m)$$ with degree-$$m$$ irreducible polynomial $$f(x)$$ over $$\mathrm{GF}(q)$$.

Parameters:
irreducible_poly: Poly

The degree-$$m$$ irreducible polynomial $$f(x)$$ over $$\mathrm{GF}(q)$$ that defines the extension field $$\mathrm{GF}(q^m)$$.

Returns:

List of all primitive elements of $$\mathrm{GF}(q^m)$$ with irreducible polynomial $$f(x)$$. Each primitive element $$g$$ is a polynomial over $$\mathrm{GF}(q)$$ with degree less than $$m$$.

Notes

The number of primitive elements of $$\mathrm{GF}(q^m)$$ is $$\phi(q^m - 1)$$, where $$\phi(n)$$ is the Euler totient function. See euler_phi.

Examples

Construct the extension field $$\mathrm{GF}(3^4)$$.

In [1]: f = galois.irreducible_poly(3, 4, method="max"); f
Out[1]: Poly(x^4 + 2x^3 + 2x^2 + x + 2, GF(3))

In [2]: GF = galois.GF(3**4, irreducible_poly=f, repr="poly")

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


Find all primitive elements for the degree-4 extension of $$\mathrm{GF}(3)$$.

In [4]: g = galois.primitive_elements(f); g
Out[4]:
[Poly(x, GF(3)),
Poly(x + 1, GF(3)),
Poly(2x, GF(3)),
Poly(2x + 2, GF(3)),
Poly(x^2 + 1, GF(3)),
Poly(x^2 + 2x + 2, GF(3)),
Poly(2x^2 + 2, GF(3)),
Poly(2x^2 + x + 1, GF(3)),
Poly(x^3, GF(3)),
Poly(x^3 + 1, GF(3)),
Poly(x^3 + x^2, GF(3)),
Poly(x^3 + x^2 + 2, GF(3)),
Poly(x^3 + x^2 + x, GF(3)),
Poly(x^3 + x^2 + 2x, GF(3)),
Poly(x^3 + x^2 + 2x + 2, GF(3)),
Poly(x^3 + 2x^2, GF(3)),
Poly(x^3 + 2x^2 + 2, GF(3)),
Poly(x^3 + 2x^2 + x, GF(3)),
Poly(x^3 + 2x^2 + x + 1, GF(3)),
Poly(x^3 + 2x^2 + 2x + 1, GF(3)),
Poly(2x^3, GF(3)),
Poly(2x^3 + 2, GF(3)),
Poly(2x^3 + x^2, GF(3)),
Poly(2x^3 + x^2 + 1, GF(3)),
Poly(2x^3 + x^2 + x + 2, GF(3)),
Poly(2x^3 + x^2 + 2x, GF(3)),
Poly(2x^3 + x^2 + 2x + 2, GF(3)),
Poly(2x^3 + 2x^2, GF(3)),
Poly(2x^3 + 2x^2 + 1, GF(3)),
Poly(2x^3 + 2x^2 + x, GF(3)),
Poly(2x^3 + 2x^2 + x + 1, GF(3)),
Poly(2x^3 + 2x^2 + 2x, GF(3))]


The number of primitive elements is given by $$\phi(q^m - 1)$$.

In [5]: phi = galois.euler_phi(3**4 - 1); phi
Out[5]: 16

In [6]: len(g) == phi
Out[6]: False


Shows that each primitive element has an order of $$q^m - 1$$.

# Convert the polynomials over GF(3) into elements of GF(3^4)
In [7]: g = GF([int(gi) for gi in g]); g
Out[7]:
GF([                  α,               α + 1,                  2α,
2α + 2,             α^2 + 1,        α^2 + 2α + 2,
2α^2 + 2,        2α^2 + α + 1,                 α^3,
α^3 + 1,           α^3 + α^2,       α^3 + α^2 + 2,
α^3 + α^2 + α,      α^3 + α^2 + 2α,  α^3 + α^2 + 2α + 2,
α^3 + 2α^2,      α^3 + 2α^2 + 2,      α^3 + 2α^2 + α,
α^3 + 2α^2 + α + 1, α^3 + 2α^2 + 2α + 1,                2α^3,
2α^3 + 2,          2α^3 + α^2,      2α^3 + α^2 + 1,
2α^3 + α^2 + α + 2,     2α^3 + α^2 + 2α, 2α^3 + α^2 + 2α + 2,
2α^3 + 2α^2,     2α^3 + 2α^2 + 1,     2α^3 + 2α^2 + α,
2α^3 + 2α^2 + α + 1,    2α^3 + 2α^2 + 2α], order=3^4)

In [8]: np.all(g.multiplicative_order() == GF.order - 1)
Out[8]: True