Try using the following gp script:
multable( p, P, g ) =
{
P = Mod(1,p) * P;
g = Mod( Mod(1,p) * g, P );
d = poldegree( P );
n = p^d;
/*
This version makes B[2] = Mod( 1, P ) which is wrong
B = concat( [0], vector( n-1, i, g^(i-1) ) );
The following line corrects the mistake
*/
B = concat( [0], vector( n-1, i, Mod( Mod(1,p), P ) * g^(i-1) ) );
R = vector( n );
for( i = 1, n,
R[ 1 + subst( lift(lift( B[i] )), x, p )] = i-1;
);
for( a = 1, p^d,
ae = B[a];
for ( b = 1, p^d,
be = B[b];
re = ae * be;
print1( R[ 1 + subst( lift(lift( re )), x, p )], "\t" );
);
print;
);
}
Save it in a file (say "ff.gp") and then invoke gp (it's an interactive environment for pari). A sample session might be
$ gp -q
? read ("/tmp/ff.gp")
? multable(2, x^3+x+1, x)
0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
0 2 3 4 5 6 7 1
0 3 4 5 6 7 1 2
0 4 5 6 7 1 2 3
0 5 6 7 1 2 3 4
0 6 7 1 2 3 4 5
0 7 1 2 3 4 5 6
?
The arguments to multable are the characteristic, the polynomial generating the field and a generator of the multiplicative group. To generate the addition table, substitute with
re = ae + be on the due line.
Cheers
Antonio
The stupider the astronaut, the easier it is to win the trip to Vega - A. Tucket
Update: The mistake for g^0 + g^0 should be corrected now