Finding Primitive Polynomials¶

LEGAL

PrimpolySageMath Version 16.2 - A Program for Computing Primitive Polynomials using Sage Math.
Copyright (C) 1999-2023 by Sean Erik O'Connor.  All Rights Reserved.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see http://www.gnu.org/licenses/.

 The author's address is seanerikoconnor!AT!gmail!DOT!com
 with the !DOT! replaced by . and the !AT! replaced by @

Counting the number of primitive polynomials of degree n modulo p. The probability that a polynomial chosen at random is primitive.¶

In [1]:
def numPolynomials(p,n):
    """"The total number of polynomials of degree n modulo p."""
    return p ^ n
In [2]:
def numPrimitivePolynomials(p,n):
    """"The number of primitive polynomials of degree n modulo p."""
    return euler_phi( p ^ n - 1 ) / n
In [3]:
def probabilityRandomPolynomialIsPrimitive(p,n):
    """"Probability that a polynomial of degree n modulo p chosen at random is primitive."""
    return numPrimitivePolynomials( p, n ) / numPolynomials( p, n )

Let's do a low degree example with a small modulus.¶

In [4]:
p = 5 ; n = 4
In [5]:
numPolynomials(p,n)
Out[5]:
625
In [6]:
numPrimitivePolynomials(p,n)
Out[6]:
48
In [7]:
N(probabilityRandomPolynomialIsPrimitive(p,n),digits=3)
Out[7]:
0.0768

Testing whether a is a primitive root of p¶

In [8]:
def isPrimRoot(a,p):
    """If the smallest n for which a^n = 1 is p-1, then a is a primitive root of p."""
    if Mod(a,p) == 0:
        return False
    elif Mod(a,p).multiplicative_order() == p-1:
        return True
    else:
        return False
In [9]:
isPrimRoot(3,p)
Out[9]:
True

Since 3 is a primitive root of 5, it generates the nonzero elements of GF(5).¶

In [10]:
[Mod(3^i,p) for i in range(1,p)]
Out[10]:
[3, 4, 2, 1]

But 4 is not a primitive root of 5 since its order is only 2 instead of 4.¶

In [11]:
[Mod(4^i,p) for i in range(1,p)]
Out[11]:
[4, 1, 4, 1]
In [12]:
Mod(4,p).multiplicative_order()
Out[12]:
2

Define the ring of polynomials with coefficients over GF(p) with generator x.¶

In [13]:
R.<x>=PolynomialRing(GF(p))
In [14]:
R
Out[14]:
Univariate Polynomial Ring in x over Finite Field of size 5

Testing if polynomials have linear factors.¶

In [15]:
def numPolynomialsWithLinearFactors(p,n):
    """"The number of polynomials of degree n modulo p which have one or more linear factors."""
    if n >= p:
        return p^n - ((p-1)^p) * p^(n-p)
    else:
        var('i') # Define i to be a symbolic variable.
        return sum( -((-1)^i) * binomial( p, i ) * p^(n-i), i, 1, n)
In [16]:
def probRandomPolyHasLinearFactors(p,n):
    """" The probability that a polynomial of degree n modulo p has one or more linear factors."""
    if n >= p:
        return 1 - (1 - 1 / p)^p
    else:
        return numPolynomialsWithLinearFactors(p,n) / (p^n)
In [17]:
def polynomialHasLinearFactor(f):
    """" A test whether a polynomial of degree n modulo p has one or more linear factors."""
    hasRoot=false
    for i in range(0,p):
        if f(i) == 0:
            return True
    return False

An example polynomial of low degree.¶

In [18]:
f = x^4 + x^2 + 2*x + 3 ; pretty_print(f)
\(\displaystyle x^{4} + x^{2} + 2 x + 3\)
In [19]:
numPolynomialsWithLinearFactors(p,n)
Out[19]:
420
In [20]:
N(probRandomPolyHasLinearFactors(p,n),digits=3)
Out[20]:
0.672
In [21]:
polynomialHasLinearFactor(f)
Out[21]:
False

Confirm that f has no linear factors.¶

In [22]:
[f(k) for k in range(0,p)]
Out[22]:
[3, 2, 2, 4, 3]

Confirm that this polynomial with two roots, i.e. two linear factors, does indeed pass the one or more linear factors test.¶

In [23]:
polynomialHasLinearFactor((x-2)*(x-3))
Out[23]:
True

Testing if a polynomial is constant¶

In [24]:
def isConstantPolynomial(f):
    """Is the polynomial constant?"""
    # Get the polynomial coefficients and their number.  For example, if
    #     f = x^4 + x^2 + 2*x + 3 
    #     then f.list() = [3, 2, 1, 0, 1] and f.list()[0] = 3
    coeffList = f.list()
    numCoeff = len( coeffList )
    # Polynomial has only a constant term.
    if numCoeff == 1:
        return True
    else:
        # Otherwise, do the powers x, x^2, ... have even one nonzero coefficient?
        hasNonZeroPowers = False
        for k in range(1, numCoeff):
            if coeffList[ k ] != 0:
                hasNonZeroPowers = True
                break
        # Nope, coefficients of the powers x, x^2, ... are all zero;  polynomial is a constant.
        return not hasNonZeroPowers
In [25]:
help(isConstantPolynomial)
Help on function isConstantPolynomial in module __main__:

isConstantPolynomial(f)
    Is the polynomial constant?

In [26]:
isConstantPolynomial( f )
Out[26]:
False
In [27]:
isConstantPolynomial(3)
Out[27]:
True

Define the quotient ring Q of polynomials modulo f(x) with generator z.¶

We previously defined the variable x to denote the generator for the polynomial ring R with coefficients in GF(p). Sage is smart enough to remember that.¶

In [28]:
Q.<z>=R.quotient( f )
In [29]:
Q
Out[29]:
Univariate Quotient Polynomial Ring in z over Finite Field of size 5 with modulus x^4 + x^2 + 2*x + 3

Powers of z modulo f(x) and p¶

In [30]:
def powersOfXModfp(f,n,p):
    """Compute the powers {z^0, z^p, z^2p, ..., z^(np)} modulo f(x) and p."""
    # Locally define the quotient ring Q of polynomials modulo f(x) and p.
    R.<x>=PolynomialRing(GF(p))
    Q.<z>=R.quotient( f )
    # Return the list of all powers.
    return [z ^ (p * k) for k in range(0,n)]
In [31]:
listOfPowers = powersOfXModfp(f,n,p) ; pretty_print( listOfPowers )
\(\displaystyle \left[1, 4 z^{3} + 3 z^{2} + 2 z, z^{3} + 4 z^{2} + 3, 3 z^{3} + 4 z^{2} + 4 z\right]\)

Irreducibility Testing¶

Compute Q-I where the n rows of matrix Q are the coefficients of the powers z^0, z^p, ..., z^(np) mod f(x) and p.¶

In [32]:
def generateQIMatrix(f,n,p):
    """Generate the Q - I matrix.  Rows of Q are coefficients of the powers z^0, ..., z^(np) modulo f(x), p"""
    # Locally define the quotient ring Q of polynomials modulo f(x) and p.
    R.<x>=PolynomialRing(GF(p))
    Q.<z>=R.quotient( f )
    # Compute the powers {z^0, z^p, z^2p, ..., z^(np)} modulo f(x) and p.
    # e.g. for f = x^4 + x^2 + 2*x + 3 modulo p=5, 
    # listOfPowers = [1, 4*z^3 + 3*z^2 + 2*z, z^3 + 4*z^2 + 3, 3*z^3 + 4*z^2 + 4*z]
    listOfPowers = powersOfXModfp(f,n,p)
    # e.g. row 1 is listOfPowers[1].list() = [0, 2, 3, 4]
    rows = [listOfPowers[k].list() for k in range(0,n)]
    # Define a matrix space of n x n matrices modulo p.
    M = MatrixSpace(GF(p),n,n)
    # Load the rows.
    m = M.matrix( rows )
    # Q-I
    return m - matrix.identity(n)
In [33]:
m = generateQIMatrix(f,n,p) ; pretty_print( m )
\(\displaystyle \left(\begin{array}{rrrr} 0 & 0 & 0 & 0 \\ 0 & 1 & 3 & 4 \\ 3 & 0 & 3 & 1 \\ 0 & 4 & 4 & 2 \end{array}\right)\)

This is the left kernel, i.e. all vectors w satisfying w A = 0¶

In [34]:
k = kernel(m) ; k
Out[34]:
Vector space of degree 4 and dimension 1 over Finite Field of size 5
Basis matrix:
[1 0 0 0]
In [35]:
m.left_nullity()
Out[35]:
1
In [36]:
def hasTwoOrMoreDistinctIrreducibleFactors(f,n,p):
    m=generateQIMatrix(f,n,p)
    return m.left_nullity() >= 2
In [37]:
hasTwoOrMoreDistinctIrreducibleFactors(f,n,p)
Out[37]:
False

Factor the expression r into distinct primes.¶

In [38]:
r=(p^n-1)//(p-1) ; r
Out[38]:
156
In [39]:
factorization = factor(r) ; pretty_print( factorization )
\(\displaystyle 2^{2} \cdot 3 \cdot 13\)

NOTE: Use // for integer divide instead of / or else we'll get a rational number type for the answer even if (p-1) divides (p^n-1).¶

In [40]:
type( 156 / 4 )
Out[40]:
<class 'sage.rings.rational.Rational'>
In [41]:
type( 156 // 4 )
Out[41]:
<class 'sage.rings.integer.Integer'>

Distinct prime factors of r¶

In [42]:
def distinctPrimeFactors(r):
    # Factorization object.  e.g. for r = 156, factor(r) = 2^2 * 3 * 13
    factorization = factor(r)
    # List of prime factors to powers. e.g. list(factor(r)) = [(2, 2), (3, 1), (13, 1)]
    listOfPrimesToPowers = list(factorization)
    # Pull out the prime factors only. e.g. [2, 3, 13]
    distinctPrimeFactors = [listOfPrimesToPowers[k][0] \
                            for k in range(0,len(listOfPrimesToPowers))]
    return distinctPrimeFactors
In [43]:
distinctPrimeFactors(r)
Out[43]:
[2, 3, 13]

Testing whether a polynomial f(x) modulo p is primitive.¶

In [44]:
def isPrimitivePolynomial( f, n, p ):
    """Determine if the nth degree polynomial f(x) modulo p is primitive."""
    isPrimitive = False
    # Polynomial must be at least degree 2 modulo p >= 2
    if p < 2 or n < 2:
        return False
    print( f"Passed step 1:  p={p:d} >=2 and n = {n} >= 2")
    a0=f[0]
    if isPrimRoot( a0 * (-1)^n, p ):
        print( f"Passed step 2:  a0 = {a0} is a primitive root")
        if not polynomialHasLinearFactor(f):
            print( f"Passed step 3:  f(x) = {f} has no linear factors" )
            if not hasTwoOrMoreDistinctIrreducibleFactors(f,n,p):
                print( f"Passed step 4:  f(x) = {f} is either irreducible or irreducible ^ power" )
                R.<x>=PolynomialRing(GF(p))
                Q.<z>=R.quotient( f )
                r=(p^n-1)//(p-1)
                a=z^r
                if isConstantPolynomial(a):
                    print( f"Passed step 5:  a = {a} is constant" )
                    if a == Mod( a0 * (-1)^n, p):
                        print( f"Passed step 6:  a = a0 (-1)^n mod p where a0 = {a0}" )
                        # Tentatively say it's primitive.
                        isPrimitive = True
                        primes = distinctPrimeFactors(r)
                        print( f"Begin step 7:  Testing on prime factors p{0} ... p{len(primes)-1}" )
                        for k in range( 0 , len( primes )):
                            # Skip the test for kth prime pk if (p-1) | pk
                            if Mod( (p-1), primes[k] ) == 0:
                                print( f"  Skip step 7 test since prime p{k} = {primes[k]} divides p-1 = {p-1}")
                            else:
                                # Oops!  Failed the test for prime pk.
                                if isConstantPolynomial( z^(r//primes[k]) ):
                                    print( f"  Failed step 7 since x^m is an integer for prime p{k} = {primes[k]}")
                                    isPrimitive = False
                                else:
                                    print( f"  Passed step 7 since x^m is not an integer for prime p{k} = \
                                    {primes[k]}")
    return isPrimitive

Examples: Primitive and non-primitive polynomials as generators of field elements.¶

A primitive polynomial generates all of the p^n - 1 nonzero field elements.¶

In [45]:
p = 5 ; n = 4
In [46]:
f = x^4 + x^2 + 2*x + 2 ; pretty_print( f )
\(\displaystyle x^{4} + x^{2} + 2 x + 2\)
In [47]:
isPrimitivePolynomial( f, n, p )
Passed step 1:  p=5 >=2 and n = 4 >= 2
Passed step 2:  a0 = 2 is a primitive root
Passed step 3:  f(x) = x^4 + x^2 + 2*x + 2 has no linear factors
Passed step 4:  f(x) = x^4 + x^2 + 2*x + 2 is either irreducible or irreducible ^ power
Passed step 5:  a = 2 is constant
Passed step 6:  a = a0 (-1)^n mod p where a0 = 2
Begin step 7:  Testing on prime factors p0 ... p2
  Skip step 7 test since prime p0 = 2 divides p-1 = 4
  Passed step 7 since x^m is not an integer for prime p1 =                                     3
  Passed step 7 since x^m is not an integer for prime p2 =                                     13
Out[47]:
True
In [48]:
def generateAllNonzeroFieldElements( f, n, p ):
    """Generate all the nonzero finite field elements for GF(p^n) given polynomial f(x),
    which is not necessarily primitive."""
    # Define the quotient ring Q of polynomials modulo f(x) and p.
    R.<x>=PolynomialRing(GF(p))
    Q.<z>=R.quotient( f )
    # A primitive polynomial f generates the nonzero elements of the field:
    # z^m = 1 for m = p^n - 1 but z^m != 1 for 1 <= m <= p^n - 2
    fieldElements = [z^m for m in range(1,p^n)]
    return fieldElements
In [49]:
fieldElements = generateAllNonzeroFieldElements( f, n, p ) ; pretty_print( fieldElements )
\(\displaystyle \left[z, z^{2}, z^{3}, 4 z^{2} + 3 z + 3, 4 z^{3} + 3 z^{2} + 3 z, 3 z^{3} + 4 z^{2} + 2 z + 2, 4 z^{3} + 4 z^{2} + z + 4, 4 z^{3} + 2 z^{2} + z + 2, 2 z^{3} + 2 z^{2} + 4 z + 2, 2 z^{3} + 2 z^{2} + 3 z + 1, 2 z^{3} + z^{2} + 2 z + 1, z^{3} + 2 z + 1, z^{2} + 4 z + 3, z^{3} + 4 z^{2} + 3 z, 4 z^{3} + 2 z^{2} + 3 z + 3, 2 z^{3} + 4 z^{2} + 2, 4 z^{3} + 3 z^{2} + 3 z + 1, 3 z^{3} + 4 z^{2} + 3 z + 2, 4 z^{3} + z + 4, 2 z^{2} + z + 2, 2 z^{3} + z^{2} + 2 z, z^{3} + z + 1, 4 z + 3, 4 z^{2} + 3 z, 4 z^{3} + 3 z^{2}, 3 z^{3} + z^{2} + 2 z + 2, z^{3} + 4 z^{2} + z + 4, 4 z^{3} + 2 z + 3, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4 z + 4, 4 z^{3} + 4 z^{2} + 4 z, 4 z^{3} + 2 z + 2, 3 z^{2} + 4 z + 2, 3 z^{3} + 4 z^{2} + 2 z, 4 z^{3} + 4 z^{2} + 4 z + 4, 4 z^{3} + z + 2, 2 z^{2} + 4 z + 2, 2 z^{3} + 4 z^{2} + 2 z, 4 z^{3} + z + 1, 2 z^{2} + 3 z + 2, 2 z^{3} + 3 z^{2} + 2 z, 3 z^{3} + z + 1, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4 z + 4, z^{3} + 4 z^{2} + 4 z, 4 z^{3} + 3 z^{2} + 3 z + 3, 3 z^{3} + 4 z^{2} + 2, 4 z^{3} + 2 z^{2} + z + 4, 2 z^{3} + 2 z^{2} + z + 2, 2 z^{3} + 4 z^{2} + 3 z + 1, 4 z^{3} + z^{2} + 2 z + 1, z^{3} + 3 z^{2} + 3 z + 2, 3 z^{3} + 2 z^{2} + 3, 2 z^{3} + 2 z^{2} + 2 z + 4, 2 z^{3} + 1, 3 z^{2} + 2 z + 1, 3 z^{3} + 2 z^{2} + z, 2 z^{3} + 3 z^{2} + 4 z + 4, 3 z^{3} + 2 z^{2} + 1, 2 z^{3} + 2 z^{2} + 4, 2 z^{3} + 3 z^{2} + 1, 3 z^{3} + 3 z^{2} + 2 z + 1, 3 z^{3} + 4 z^{2} + 4, 4 z^{3} + 2 z^{2} + 3 z + 4, 2 z^{3} + 4 z^{2} + z + 2, 4 z^{3} + 4 z^{2} + 3 z + 1, 4 z^{3} + 4 z^{2} + 3 z + 2, 4 z^{3} + 4 z^{2} + 4 z + 2, 4 z^{3} + 4 z + 2, 4 z + 2, 4 z^{2} + 2 z, 4 z^{3} + 2 z^{2}, 2 z^{3} + z^{2} + 2 z + 2, z^{3} + 3 z + 1, 2 z^{2} + 4 z + 3, 2 z^{3} + 4 z^{2} + 3 z, 4 z^{3} + z^{2} + z + 1, z^{3} + 2 z^{2} + 3 z + 2, 2 z^{3} + 2 z^{2} + 3, 2 z^{3} + 3 z^{2} + 4 z + 1, 3 z^{3} + 2 z^{2} + 2 z + 1, 2 z^{3} + 4 z^{2} + 4, 4 z^{3} + 3 z^{2} + 1, 3 z^{3} + z^{2} + 3 z + 2, z^{3} + z + 4, 2 z + 3, 2 z^{2} + 3 z, 2 z^{3} + 3 z^{2}, 3 z^{3} + 3 z^{2} + z + 1, 3 z^{3} + 3 z^{2} + 4, 3 z^{3} + 2 z^{2} + 3 z + 4, 2 z^{3} + 3 z + 4, z^{2} + 1, z^{3} + z, 3 z + 3, 3 z^{2} + 3 z, 3 z^{3} + 3 z^{2}, 3 z^{3} + 2 z^{2} + 4 z + 4, 2 z^{3} + z^{2} + 3 z + 4, z^{3} + z^{2} + 1, z^{3} + 4 z^{2} + 4 z + 3, 4 z^{3} + 3 z^{2} + z + 3, 3 z^{3} + 2 z^{2} + 2, 2 z^{3} + 2 z^{2} + z + 4, 2 z^{3} + 4 z^{2} + 1, 4 z^{3} + 3 z^{2} + 2 z + 1, 3 z^{3} + 3 z^{2} + 3 z + 2, 3 z^{3} + z + 4, 3 z^{2} + 3 z + 4, 3 z^{3} + 3 z^{2} + 4 z, 3 z^{3} + z^{2} + 4 z + 4, z^{3} + z^{2} + 3 z + 4, z^{3} + 2 z^{2} + 2 z + 3, 2 z^{3} + z^{2} + z + 3, z^{3} + 4 z^{2} + 4 z + 1, 4 z^{3} + 3 z^{2} + 4 z + 3, 3 z^{3} + 2, 2 z^{2} + z + 4, 2 z^{3} + z^{2} + 4 z, z^{3} + 2 z^{2} + z + 1, 2 z^{3} + 4 z + 3, 2 z^{2} + 4 z + 1, 2 z^{3} + 4 z^{2} + z, 4 z^{3} + 4 z^{2} + z + 1, 4 z^{3} + 2 z^{2} + 3 z + 2, 2 z^{3} + 4 z^{2} + 4 z + 2, 4 z^{3} + 2 z^{2} + 3 z + 1, 2 z^{3} + 4 z^{2} + 3 z + 2, 4 z^{3} + z^{2} + 3 z + 1, z^{3} + 4 z^{2} + 3 z + 2, 4 z^{3} + 2 z^{2} + 3, 2 z^{3} + z^{2} + 2, z^{3} + 3 z^{2} + 3 z + 1, 3 z^{3} + 2 z^{2} + 4 z + 3, 2 z^{3} + z^{2} + 2 z + 4, z^{3} + 1, 4 z^{2} + 4 z + 3, 4 z^{3} + 4 z^{2} + 3 z, 4 z^{3} + 4 z^{2} + 2 z + 2, 4 z^{3} + 3 z^{2} + 4 z + 2, 3 z^{3} + 4 z + 2, z^{2} + z + 4, z^{3} + z^{2} + 4 z, z^{3} + 3 z^{2} + 3 z + 3, 3 z^{3} + 2 z^{2} + z + 3, 2 z^{3} + 3 z^{2} + 2 z + 4, 3 z^{3} + 1, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + z + 1, 2 z^{3} + z^{2} + z, z^{3} + 4 z^{2} + z + 1, 4 z^{3} + 4 z + 3, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + z + 1, 3 z^{3} + z^{2} + z, z^{3} + 3 z^{2} + 4 z + 4, 3 z^{3} + 3 z^{2} + 2 z + 3, 3 z^{3} + 4 z^{2} + 2 z + 4, 4 z^{3} + 4 z^{2} + 3 z + 4, 4 z^{3} + 4 z^{2} + z + 2, 4 z^{3} + 2 z^{2} + 4 z + 2, 2 z^{3} + 4 z + 2, 2 z^{2} + 3 z + 1, 2 z^{3} + 3 z^{2} + z, 3 z^{3} + 4 z^{2} + z + 1, 4 z^{3} + 3 z^{2} + 4, 3 z^{3} + z^{2} + z + 2, z^{3} + 3 z^{2} + z + 4, 3 z^{3} + 2 z + 3, 4 z^{2} + 2 z + 4, 4 z^{3} + 2 z^{2} + 4 z, 2 z^{3} + 2 z + 2, 3 z + 1, 3 z^{2} + z, 3 z^{3} + z^{2}, z^{3} + 2 z^{2} + 4 z + 4, 2 z^{3} + 3 z^{2} + 2 z + 3, 3 z^{3} + 4 z + 1, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3 z + 3, 3 z^{3} + 3 z^{2} + 3 z, 3 z^{3} + 4 z + 4, z^{2} + 3 z + 4, z^{3} + 3 z^{2} + 4 z, 3 z^{3} + 3 z^{2} + 3 z + 3, 3 z^{3} + 2 z + 4, 4 z^{2} + 3 z + 4, 4 z^{3} + 3 z^{2} + 4 z, 3 z^{3} + 2 z + 2, 4 z^{2} + z + 4, 4 z^{3} + z^{2} + 4 z, z^{3} + 2 z + 2, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3 z + 3, 2 z^{3} + 3 z^{2} + 3 z, 3 z^{3} + z^{2} + z + 1, z^{3} + 3 z^{2} + 4, 3 z^{3} + 4 z^{2} + 2 z + 3, 4 z^{3} + 4 z^{2} + 2 z + 4, 4 z^{3} + 3 z^{2} + z + 2, 3 z^{3} + 2 z^{2} + 4 z + 2, 2 z^{3} + z^{2} + z + 4, z^{3} + 4 z^{2} + 1, 4 z^{3} + 4 z^{2} + 4 z + 3, 4 z^{3} + 2, z^{2} + 4 z + 2, z^{3} + 4 z^{2} + 2 z, 4 z^{3} + z^{2} + 3 z + 3, z^{3} + 4 z^{2} + 2, 4 z^{3} + 4 z^{2} + 3, 4 z^{3} + z^{2} + 2, z^{3} + z^{2} + 4 z + 2, z^{3} + 3 z^{2} + 3, 3 z^{3} + 4 z^{2} + z + 3, 4 z^{3} + 3 z^{2} + 2 z + 4, 3 z^{3} + 3 z^{2} + z + 2, 3 z^{3} + 3 z^{2} + z + 4, 3 z^{3} + 3 z^{2} + 3 z + 4, 3 z^{3} + 3 z + 4, 3 z + 4, 3 z^{2} + 4 z, 3 z^{3} + 4 z^{2}, 4 z^{3} + 2 z^{2} + 4 z + 4, 2 z^{3} + z + 2, 4 z^{2} + 3 z + 1, 4 z^{3} + 3 z^{2} + z, 3 z^{3} + 2 z^{2} + 2 z + 2, 2 z^{3} + 4 z^{2} + z + 4, 4 z^{3} + 4 z^{2} + 1, 4 z^{3} + z^{2} + 3 z + 2, z^{3} + 4 z^{2} + 4 z + 2, 4 z^{3} + 3 z^{2} + 3, 3 z^{3} + z^{2} + 2, z^{3} + 2 z^{2} + z + 4, 2 z^{3} + 2 z + 3, 4 z + 1, 4 z^{2} + z, 4 z^{3} + z^{2}, z^{3} + z^{2} + 2 z + 2, z^{3} + z^{2} + 3, z^{3} + 4 z^{2} + z + 3, 4 z^{3} + z + 3, 2 z^{2} + 2, 2 z^{3} + 2 z, z + 1, z^{2} + z, z^{3} + z^{2}, z^{3} + 4 z^{2} + 3 z + 3, 4 z^{3} + 2 z^{2} + z + 3, 2 z^{3} + 2 z^{2} + 2, 2 z^{3} + 3 z^{2} + 3 z + 1, 3 z^{3} + z^{2} + 2 z + 1, z^{3} + 4 z^{2} + 4, 4 z^{3} + 4 z^{2} + 2 z + 3, 4 z^{3} + 3 z^{2} + 2, 3 z^{3} + z^{2} + 4 z + 2, z^{3} + z^{2} + z + 4, z^{3} + 2 z + 3, z^{2} + z + 3, z^{3} + z^{2} + 3 z, z^{3} + 2 z^{2} + 3 z + 3, 2 z^{3} + 2 z^{2} + z + 3, 2 z^{3} + 4 z^{2} + 4 z + 1, 4 z^{3} + 2 z^{2} + 2 z + 1, 2 z^{3} + 3 z^{2} + 3 z + 2, 3 z^{3} + z^{2} + 3 z + 1, z^{3} + 4, 4 z^{2} + 2 z + 3, 4 z^{3} + 2 z^{2} + 3 z, 2 z^{3} + 4 z^{2} + 2 z + 2, 4 z^{3} + 3 z + 1, 4 z^{2} + 3 z + 2, 4 z^{3} + 3 z^{2} + 2 z, 3 z^{3} + 3 z^{2} + 2 z + 2, 3 z^{3} + 4 z^{2} + z + 4, 4 z^{3} + 3 z^{2} + 3 z + 4, 3 z^{3} + 4 z^{2} + z + 2, 4 z^{3} + 3 z^{2} + z + 4, 3 z^{3} + 2 z^{2} + z + 2, 2 z^{3} + 3 z^{2} + z + 4, 3 z^{3} + 4 z^{2} + 1, 4 z^{3} + 2 z^{2} + 4, 2 z^{3} + z^{2} + z + 2, z^{3} + 4 z^{2} + 3 z + 1, 4 z^{3} + 2 z^{2} + 4 z + 3, 2 z^{3} + 2, 3 z^{2} + 3 z + 1, 3 z^{3} + 3 z^{2} + z, 3 z^{3} + 3 z^{2} + 4 z + 4, 3 z^{3} + z^{2} + 3 z + 4, z^{3} + 3 z + 4, 2 z^{2} + 2 z + 3, 2 z^{3} + 2 z^{2} + 3 z, 2 z^{3} + z^{2} + z + 1, z^{3} + 4 z^{2} + 2 z + 1, 4 z^{3} + z^{2} + 4 z + 3, z^{3} + 2, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2 z + 2, 4 z^{3} + 2 z^{2} + 2 z, 2 z^{3} + 3 z^{2} + 2 z + 2, 3 z^{3} + 3 z + 1, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2 z + 2, z^{3} + 2 z^{2} + 2 z, 2 z^{3} + z^{2} + 3 z + 3, z^{3} + z^{2} + 4 z + 1, z^{3} + 3 z^{2} + 4 z + 3, 3 z^{3} + 3 z^{2} + z + 3, 3 z^{3} + 3 z^{2} + 2 z + 4, 3 z^{3} + 4 z^{2} + 3 z + 4, 4 z^{3} + 3 z + 4, 4 z^{2} + z + 2, 4 z^{3} + z^{2} + 2 z, z^{3} + 3 z^{2} + 2 z + 2, 3 z^{3} + z^{2} + 3, z^{3} + 2 z^{2} + 2 z + 4, 2 z^{3} + z^{2} + 2 z + 3, z^{3} + 4 z + 1, 3 z^{2} + 4 z + 3, 3 z^{3} + 4 z^{2} + 3 z, 4 z^{3} + 4 z + 4, z + 2, z^{2} + 2 z, z^{3} + 2 z^{2}, 2 z^{3} + 4 z^{2} + 3 z + 3, 4 z^{3} + z^{2} + 4 z + 1, z^{3} + 3 z + 2, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + z + 1, z^{3} + z^{2} + z, z^{3} + 3 z + 3, 2 z^{2} + z + 3, 2 z^{3} + z^{2} + 3 z, z^{3} + z^{2} + z + 1, z^{3} + 4 z + 3, 3 z^{2} + z + 3, 3 z^{3} + z^{2} + 3 z, z^{3} + 4 z + 4, 3 z^{2} + 2 z + 3, 3 z^{3} + 2 z^{2} + 3 z, 2 z^{3} + 4 z + 4, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + z + 1, 4 z^{3} + z^{2} + z, z^{3} + 2 z^{2} + 2 z + 2, 2 z^{3} + z^{2} + 3, z^{3} + 3 z^{2} + 4 z + 1, 3 z^{3} + 3 z^{2} + 4 z + 3, 3 z^{3} + z^{2} + 2 z + 4, z^{3} + 4 z^{2} + 3 z + 4, 4 z^{3} + 2 z^{2} + 2 z + 3, 2 z^{3} + 3 z^{2} + 2, 3 z^{3} + 3 z^{2} + 3 z + 1, 3 z^{3} + 4, 2 z^{2} + 3 z + 4, 2 z^{3} + 3 z^{2} + 4 z, 3 z^{3} + 2 z^{2} + z + 1, 2 z^{3} + 3 z^{2} + 4, 3 z^{3} + 3 z^{2} + 1, 3 z^{3} + 2 z^{2} + 4, 2 z^{3} + 2 z^{2} + 3 z + 4, 2 z^{3} + z^{2} + 1, z^{3} + 3 z^{2} + 2 z + 1, 3 z^{3} + z^{2} + 4 z + 3, z^{3} + z^{2} + 2 z + 4, z^{3} + z^{2} + 2 z + 3, z^{3} + z^{2} + z + 3, z^{3} + z + 3, z + 3, z^{2} + 3 z, z^{3} + 3 z^{2}, 3 z^{3} + 4 z^{2} + 3 z + 3, 4 z^{3} + 2 z + 4, 3 z^{2} + z + 2, 3 z^{3} + z^{2} + 2 z, z^{3} + 4 z^{2} + 4 z + 4, 4 z^{3} + 3 z^{2} + 2 z + 3, 3 z^{3} + 3 z^{2} + 2, 3 z^{3} + 2 z^{2} + z + 4, 2 z^{3} + 3 z^{2} + 3 z + 4, 3 z^{3} + z^{2} + 1, z^{3} + 2 z^{2} + 4, 2 z^{3} + 4 z^{2} + 2 z + 3, 4 z^{3} + 4 z + 1, 3 z + 2, 3 z^{2} + 2 z, 3 z^{3} + 2 z^{2}, 2 z^{3} + 2 z^{2} + 4 z + 4, 2 z^{3} + 2 z^{2} + 1, 2 z^{3} + 3 z^{2} + 2 z + 1, 3 z^{3} + 2 z + 1, 4 z^{2} + 4, 4 z^{3} + 4 z, 2 z + 2, 2 z^{2} + 2 z, 2 z^{3} + 2 z^{2}, 2 z^{3} + 3 z^{2} + z + 1, 3 z^{3} + 4 z^{2} + 2 z + 1, 4 z^{3} + 4 z^{2} + 4, 4 z^{3} + z^{2} + z + 2, z^{3} + 2 z^{2} + 4 z + 2, 2 z^{3} + 3 z^{2} + 3, 3 z^{3} + 3 z^{2} + 4 z + 1, 3 z^{3} + z^{2} + 4, z^{3} + 2 z^{2} + 3 z + 4, 2 z^{3} + 2 z^{2} + 2 z + 3, 2 z^{3} + 4 z + 1, 2 z^{2} + 2 z + 1, 2 z^{3} + 2 z^{2} + z, 2 z^{3} + 4 z^{2} + z + 1, 4 z^{3} + 4 z^{2} + 2 z + 1, 4 z^{3} + 3 z^{2} + 3 z + 2, 3 z^{3} + 4 z^{2} + 4 z + 2, 4 z^{3} + z^{2} + z + 4, z^{3} + 2 z^{2} + z + 2, 2 z^{3} + 3, 3 z^{2} + 4 z + 1, 3 z^{3} + 4 z^{2} + z, 4 z^{3} + 3 z^{2} + 4 z + 4, 3 z^{3} + z + 2, 3 z^{2} + z + 4, 3 z^{3} + z^{2} + 4 z, z^{3} + z^{2} + 4 z + 4, z^{3} + 3 z^{2} + 2 z + 3, 3 z^{3} + z^{2} + z + 3, z^{3} + 3 z^{2} + 2 z + 4, 3 z^{3} + z^{2} + 2 z + 3, z^{3} + 4 z^{2} + 2 z + 4, 4 z^{3} + z^{2} + 2 z + 3, z^{3} + 3 z^{2} + 2, 3 z^{3} + 4 z^{2} + 3, 4 z^{3} + 2 z^{2} + 2 z + 4, 2 z^{3} + 3 z^{2} + z + 2, 3 z^{3} + 4 z^{2} + 3 z + 1, 4 z^{3} + 4, z^{2} + z + 2, z^{3} + z^{2} + 2 z, z^{3} + z^{2} + 3 z + 3, z^{3} + 2 z^{2} + z + 3, 2 z^{3} + z + 3, 4 z^{2} + 4 z + 1, 4 z^{3} + 4 z^{2} + z, 4 z^{3} + 2 z^{2} + 2 z + 2, 2 z^{3} + 3 z^{2} + 4 z + 2, 3 z^{3} + 2 z^{2} + 3 z + 1, 2 z^{3} + 4, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4 z + 4, 3 z^{3} + 4 z^{2} + 4 z, 4 z^{3} + z^{2} + 4 z + 4, z^{3} + z + 2, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4 z + 4, 2 z^{3} + 4 z^{2} + 4 z, 4 z^{3} + 2 z^{2} + z + 1, 2 z^{3} + 2 z^{2} + 3 z + 2, 2 z^{3} + z^{2} + 3 z + 1, z^{3} + z^{2} + 2 z + 1, z^{3} + z^{2} + 4 z + 3, z^{3} + 3 z^{2} + z + 3, 3 z^{3} + z + 3, 3 z^{2} + 2 z + 4, 3 z^{3} + 2 z^{2} + 4 z, 2 z^{3} + z^{2} + 4 z + 4, z^{3} + 2 z^{2} + 1, 2 z^{3} + 4 z^{2} + 4 z + 3, 4 z^{3} + 2 z^{2} + 4 z + 1, 2 z^{3} + 3 z + 2, z^{2} + 3 z + 1, z^{3} + 3 z^{2} + z, 3 z^{3} + 3 z + 3, 2 z + 4, 2 z^{2} + 4 z, 2 z^{3} + 4 z^{2}, 4 z^{3} + 3 z^{2} + z + 1, 3 z^{3} + 2 z^{2} + 3 z + 2, 2 z^{3} + z + 4, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2 z + 2, 2 z^{3} + 2 z^{2} + 2 z, 2 z^{3} + z + 1, 4 z^{2} + 2 z + 1, 4 z^{3} + 2 z^{2} + z, 2 z^{3} + 2 z^{2} + 2 z + 2, 2 z^{3} + 3 z + 1, z^{2} + 2 z + 1, z^{3} + 2 z^{2} + z, 2 z^{3} + 3 z + 3, z^{2} + 4 z + 1, z^{3} + 4 z^{2} + z, 4 z^{3} + 3 z + 3, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2 z + 2, 3 z^{3} + 2 z^{2} + 2 z, 2 z^{3} + 4 z^{2} + 4 z + 4, 4 z^{3} + 2 z^{2} + 1, 2 z^{3} + z^{2} + 3 z + 2, z^{3} + z^{2} + 3 z + 1, z^{3} + 2 z^{2} + 4 z + 3, 2 z^{3} + 3 z^{2} + z + 3, 3 z^{3} + 4 z^{2} + 4 z + 1, 4 z^{3} + z^{2} + 4, z^{3} + z^{2} + z + 2, z^{3} + 3, 4 z^{2} + z + 3, 4 z^{3} + z^{2} + 3 z, z^{3} + 4 z^{2} + 2 z + 2, 4 z^{3} + z^{2} + 3, z^{3} + z^{2} + 2, z^{3} + 4 z^{2} + 3, 4 z^{3} + 4 z^{2} + z + 3, 4 z^{3} + 2 z^{2} + 2, 2 z^{3} + z^{2} + 4 z + 2, z^{3} + 2 z^{2} + 3 z + 1, 2 z^{3} + 2 z^{2} + 4 z + 3, 2 z^{3} + 2 z^{2} + 4 z + 1, 2 z^{3} + 2 z^{2} + 2 z + 1, 2 z^{3} + 2 z + 1, 2 z + 1, 2 z^{2} + z, 2 z^{3} + z^{2}, z^{3} + 3 z^{2} + z + 1, 3 z^{3} + 4 z + 3, z^{2} + 2 z + 4, z^{3} + 2 z^{2} + 4 z, 2 z^{3} + 3 z^{2} + 3 z + 3, 3 z^{3} + z^{2} + 4 z + 1, z^{3} + z^{2} + 4, z^{3} + 4 z^{2} + 2 z + 3, 4 z^{3} + z^{2} + z + 3, z^{3} + 2 z^{2} + 2, 2 z^{3} + 4 z^{2} + 3, 4 z^{3} + 3 z^{2} + 4 z + 1, 3 z^{3} + 3 z + 2, z + 4, z^{2} + 4 z, z^{3} + 4 z^{2}, 4 z^{3} + 4 z^{2} + 3 z + 3, 4 z^{3} + 4 z^{2} + 2, 4 z^{3} + z^{2} + 4 z + 2, z^{3} + 4 z + 2, 3 z^{2} + 3, 3 z^{3} + 3 z, 4 z + 4, 4 z^{2} + 4 z, 4 z^{3} + 4 z^{2}, 4 z^{3} + z^{2} + 2 z + 2, z^{3} + 3 z^{2} + 4 z + 2, 3 z^{3} + 3 z^{2} + 3, 3 z^{3} + 2 z^{2} + 2 z + 4, 2 z^{3} + 4 z^{2} + 3 z + 4, 4 z^{3} + z^{2} + 1, z^{3} + z^{2} + 3 z + 2, z^{3} + 2 z^{2} + 3, 2 z^{3} + 4 z^{2} + z + 3, 4 z^{3} + 4 z^{2} + 4 z + 1, 4 z^{3} + 3 z + 2, 4 z^{2} + 4 z + 2, 4 z^{3} + 4 z^{2} + 2 z, 4 z^{3} + 3 z^{2} + 2 z + 2, 3 z^{3} + 3 z^{2} + 4 z + 2, 3 z^{3} + z^{2} + z + 4, z^{3} + 3 z^{2} + 3 z + 4, 3 z^{3} + 2 z^{2} + 2 z + 3, 2 z^{3} + 4 z^{2} + 2 z + 4, 4 z^{3} + 1, z^{2} + 3 z + 2, z^{3} + 3 z^{2} + 2 z, 3 z^{3} + z^{2} + 3 z + 3, z^{3} + 2 z + 4, z^{2} + 2 z + 3, z^{3} + 2 z^{2} + 3 z, 2 z^{3} + 2 z^{2} + 3 z + 3, 2 z^{3} + z^{2} + 4 z + 1, z^{3} + 2 z^{2} + 2 z + 1, 2 z^{3} + z^{2} + 4 z + 3, z^{3} + 2 z^{2} + 4 z + 1, 2 z^{3} + 3 z^{2} + 4 z + 3, 3 z^{3} + 2 z^{2} + 4 z + 1, 2 z^{3} + z^{2} + 4, z^{3} + 3 z^{2} + 1, 3 z^{3} + 4 z^{2} + 4 z + 3, 4 z^{3} + z^{2} + 2 z + 4, z^{3} + 3 z^{2} + z + 2, 3 z^{3} + 3, 2 z^{2} + 2 z + 4, 2 z^{3} + 2 z^{2} + 4 z, 2 z^{3} + 2 z^{2} + z + 1, 2 z^{3} + 4 z^{2} + 2 z + 1, 4 z^{3} + 2 z + 1, 3 z^{2} + 3 z + 2, 3 z^{3} + 3 z^{2} + 2 z, 3 z^{3} + 4 z^{2} + 4 z + 4, 4 z^{3} + z^{2} + 3 z + 4, z^{3} + 4 z^{2} + z + 2, 4 z^{3} + 3, z^{2} + 2, z^{3} + 2 z, z^{2} + 3 z + 3, z^{3} + 3 z^{2} + 3 z, 3 z^{3} + 2 z^{2} + 3 z + 3, 2 z^{3} + 2 z + 4, 1\right]\)
In [50]:
len(fieldElements)
Out[50]:
624
In [51]:
p^n-1
Out[51]:
624

A non-primitive polynomial won't generate all the nonzero field elements. Note the repetitions in the polynomal list below.¶

In [52]:
f = x^4 + x^2 + 2 ; pretty_print( f )
\(\displaystyle x^{4} + x^{2} + 2\)
In [53]:
isPrimitivePolynomial( f, n, p )
Passed step 1:  p=5 >=2 and n = 4 >= 2
Passed step 2:  a0 = 2 is a primitive root
Passed step 3:  f(x) = x^4 + x^2 + 2 has no linear factors
Passed step 4:  f(x) = x^4 + x^2 + 2 is either irreducible or irreducible ^ power
Passed step 5:  a = 2 is constant
Passed step 6:  a = a0 (-1)^n mod p where a0 = 2
Begin step 7:  Testing on prime factors p0 ... p2
  Skip step 7 test since prime p0 = 2 divides p-1 = 4
  Passed step 7 since x^m is not an integer for prime p1 =                                     3
  Failed step 7 since x^m is an integer for prime p2 = 13
Out[53]:
False
In [54]:
fieldElements = generateAllNonzeroFieldElements( f, n, p ); pretty_print( fieldElements )
\(\displaystyle \left[z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1, z, z^{2}, z^{3}, 4 z^{2} + 3, 4 z^{3} + 3 z, 4 z^{2} + 2, 4 z^{3} + 2 z, 3 z^{2} + 2, 3 z^{3} + 2 z, 4 z^{2} + 4, 4 z^{3} + 4 z, 2, 2 z, 2 z^{2}, 2 z^{3}, 3 z^{2} + 1, 3 z^{3} + z, 3 z^{2} + 4, 3 z^{3} + 4 z, z^{2} + 4, z^{3} + 4 z, 3 z^{2} + 3, 3 z^{3} + 3 z, 4, 4 z, 4 z^{2}, 4 z^{3}, z^{2} + 2, z^{3} + 2 z, z^{2} + 3, z^{3} + 3 z, 2 z^{2} + 3, 2 z^{3} + 3 z, z^{2} + 1, z^{3} + z, 3, 3 z, 3 z^{2}, 3 z^{3}, 2 z^{2} + 4, 2 z^{3} + 4 z, 2 z^{2} + 1, 2 z^{3} + z, 4 z^{2} + 1, 4 z^{3} + z, 2 z^{2} + 2, 2 z^{3} + 2 z, 1\right]\)