Creating an extension of a Prime Field

In this section we define the functions used to create a finite field with p^d elements. We will use the Maple function GF which creates an array of functions and constants relevant to the field.

I will illustrate them below. GF(p,d) chooses an irreducile polynomial, but I had trouble making

the arithmetic work. So I use the version GF(p,d,f) where I choose f to be irreducible and

primitive.

So we need to find a polynomial, f(T), which is irreducible and of degree d over F_p.

We will also insist that the polynomial be primitive. That is, in the multiplicative group of F_p[T]/f(T), the order of T is p^d - 1.

You'll notice I check that degree(f)=d. Randpoly(d,t) should produce a polynomial of degree d, but for some reason when d>40 it sometimes returns a polynomial of lower degree. So I inserted the check to be sure.

> GetIrrPoly := proc(p,d)
local bool, f;

bool:=false;
while bool = false do
f:= Randpoly(d,T) mod p;
if Irreduc(f) mod p and Primitive(f) mod p
and (degree(f)= d) then bool :=true fi;
od;
RETURN(f);
end proc;

GetIrrPoly := proc (p, d) local bool, f; bool := fa...
GetIrrPoly := proc (p, d) local bool, f; bool := fa...
GetIrrPoly := proc (p, d) local bool, f; bool := fa...
GetIrrPoly := proc (p, d) local bool, f; bool := fa...
GetIrrPoly := proc (p, d) local bool, f; bool := fa...
GetIrrPoly := proc (p, d) local bool, f; bool := fa...
GetIrrPoly := proc (p, d) local bool, f; bool := fa...
GetIrrPoly := proc (p, d) local bool, f; bool := fa...
GetIrrPoly := proc (p, d) local bool, f; bool := fa...

The field GF(2^50)

> p:=2; d:= 50;p := 2;

>

p := 2

d := 50

p := 2

> f := GetIrrPoly(p,d);

f := 1+T^3+T^2+T^7+T^13+T^14+T^17+T^19+T^18+T^21+T^...
f := 1+T^3+T^2+T^7+T^13+T^14+T^17+T^19+T^18+T^21+T^...

Next we use the Maple function GF to create the field. GF returns an array of constants and functions that do most of what we want with the finite field.

> FF:= GF(p,d,f);

>

FF := module () export `+`, `-`, `*`, `/`, `^`, inp...
FF := module () export `+`, `-`, `*`, `/`, `^`, inp...
FF := module () export `+`, `-`, `*`, `/`, `^`, inp...
FF := module () export `+`, `-`, `*`, `/`, `^`, inp...
FF := module () export `+`, `-`, `*`, `/`, `^`, inp...

Now we define our primitive element of the finite field. It is the image of T in the quotient space F_p[T]/f(T).
Maple won't let you use T itself, but it will always express things in terms of T not al. I don't get it.

> al := FF[ConvertIn](T);

al := modp1(ConvertIn(T,T),2)

I find the Maple syntax for the field operations tedious to type, so I made pseudonyms for them.

I chose to set Fzero := FF[zero] instead of using an alias. If you use an alias Fmul(Fzero,al) will return Fzero not 0.

> alias( Fadd=FF[`+`], Fmul=FF[`*`], Fexp = FF[`^`] );
Fzero := FF[zero]; Fone := FF[one];

Fadd, Fmul, Fexp

Fzero := modp1(ConvertIn(0,T),2)

Fone := modp1(ConvertIn(1,T),2)

> Fadd(Fzero,al);

modp1(ConvertIn(T,T),2)

> Fadd(Fone,al);

modp1(ConvertIn(T+1,T),2)

> Fmul(Fzero, al);

modp1(ConvertIn(0,T),2)

Wow, it really works! And it does the following computation quickly, so it thinks before it acts.

> Fexp(al,2^50-1);

modp1(ConvertIn(1,T),2)

> Fexp(al,111342347);

modp1(ConvertIn(T^48+T^43+T^42+T^41+T^38+T^37+T^34+...
modp1(ConvertIn(T^48+T^43+T^42+T^41+T^38+T^37+T^34+...

Amazing

The next two concern primitive elements. The first produces a primitive element randomly.

The second checks whether a given field element is primitive.

> FF[PrimitiveElement]();

modp1(ConvertIn(T^45+T^44+T^42+T^37+T^36+T^32+T^30+...
modp1(ConvertIn(T^45+T^44+T^42+T^37+T^36+T^32+T^30+...

> h:= Fadd(Fone,al);

h := modp1(ConvertIn(T+1,T),2)

> FF[isPrimitiveElement](h);

false

>

The finite field GF(5^2)

> H:= GF(5,2,T^2+T+1);

H := module () export `+`, `-`, `*`, `/`, `^`, inpu...
H := module () export `+`, `-`, `*`, `/`, `^`, inpu...
H := module () export `+`, `-`, `*`, `/`, `^`, inpu...
H := module () export `+`, `-`, `*`, `/`, `^`, inpu...
H := module () export `+`, `-`, `*`, `/`, `^`, inpu...

> gam:= H[ConvertIn](T);

gam := modp1(ConvertIn(T,T),5)

> alias (Hadd=H[`+`], Hmul=H[`*`], Hexp = H[`^`] );

Fadd, Fmul, Fexp, Hadd, Hmul, Hexp

Unfortunately, it is a bit clumsy to write elements of our field H. For example this is how we

have to write the elements 3 and 3 +4T.

> H[input](3);H[input](23);

modp1(ConvertIn(3,T),5)

modp1(ConvertIn(4*T+3,T),5)

In general, the integer a+b5 for a, b =0,1,2,3,or 4

corresponds to the field element a+bT.

Here is (4+ gam)*gam.

> Hmul(Hadd(gam,H[input](4)),gam);

modp1(ConvertIn(3*T+4,T),5)

We could alias H[input] and it's inverse H[output] and, while we're at it....

> alias( Hin = H[input], Hout = H[output], HPrim=H[PrimitiveElement], HisPrim=H[isPrimitiveElement]);

Fadd, Fmul, Fexp, Hadd, Hmul, Hexp, Hin, Hout, HPri...

> HisPrim(Hin(23));

>

true

>