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;
The field GF(2^50)
> p:=2; d:= 50;p := 2;
>
>
f := GetIrrPoly(p,d);
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);
>
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);
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(Fzero,al);
> Fadd(Fone,al);
> Fmul(Fzero, al);
Wow, it really works! And it does the following computation quickly, so it thinks before it acts.
> Fexp(al,2^50-1);
> Fexp(al,111342347);
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]();
> h:= Fadd(Fone,al);
> FF[isPrimitiveElement](h);
>
The finite field GF(5^2)
> H:= GF(5,2,T^2+T+1);
> gam:= H[ConvertIn](T);
>
alias (Hadd=H[`+`], Hmul=H[`*`], Hexp = H[`^`] );
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);
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);
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]);
> HisPrim(Hin(23));
>
>