DragonWins Home Page
   Crypto Home
  
Working with GF(pn)
  (Last Mod: 
  27 November 2010 21:56:33
  )
This page is devoted to providing an introduction  to working with finite 
fields of the type used in cryptography. While the goal is to provide enough 
depth so that the reader can gain a decent feel for the underpinnings of the 
material, no real attempt is made to be absolutely rigorous or complete in the 
construction and description of the concepts presented here. Instead the focus 
is to foster a more intuitive feeling for the material based primarily on 
establishing that the various concepts and choices made are reasonable and 
well-grounded. As a 
result, it is believed that the reader will discover that the material is 
developed in such a way that a much better understanding of the concepts is 
possible than is likely to be gained with many of the cryptography books on the 
market which tend to either present a bunch of algorithms in cookbook fashion or 
present the number theory topics at a level of depth that requires a stronger 
abstract algebra background than most readers possess.
Recall from the discussion of finite fields, 
that a finite field is an algebra consisting of a set of elements and two 
operators that act on those elements. We are free to define the elements and the 
operators in any way we choose provided the properties required of a finite 
field are satisfied. Those requirements are:
	- The set must be an abelian group with respect to the first operator.
- The set, less the identity element for the first operator, must be an 
	abelian group with respect to the second operator.
- The second operator must be distributive over the first operator.
Further recall that to be an abelian group, the following properties must 
hold with respect to the operator:
	- The set must be closed.
- The set must be commutative.
- The set must be associative.
- The set must possess an identity element.
- The set must possess an inverse for every element in the set.
If n=1, then we have the finite field GF(p) where p is a 
prime number. The specific finite fields of this form that we have been working 
with are merely our old friends the "mod-p" worlds where our first 
operator is everyday normal addition except that the result is always reduced 
modulo-p and where our second operator is everyday normal multiplication 
except that the result is, once again, always reduced module-p. Before 
you proceed any further, be sure that you understand the following things:
	- That GF(p), or a mod-p world, satisfies all of the 
	requirements of a finite field.
- That a mod-n world where n is not a prime number does not 
	satisfy these requirements.
The key to the second point is that if n is not prime, then there will 
exist some elements within the residue set (namely those that are not relatively 
prime to n) for which no multiplicative inverse exists. 
At the risk of belaboring a point, keep in mind that GF(p) and a "mod-p 
world" are not the same. We are free to construct the elements and functions in 
GF(p) however we like provided the requirements for a finite field are 
met. A "mod-p world" is simply one example of a construction of a GF(p) 
finite field. Having said that, in the remainder of this document, references to 
GF(p) can be taken to mean "mod-p" unless stated otherwise without 
loss of generality.
Before proceeding, it is important to understand that we can't simply use a 
"mod-pn world" to construct a GF(pn) finite 
field if n is greater than one. The reason should be obvious; pn 
is not a prime number under these conditions and therefore there will be 
elements that lack multiplicative inverses. So we can't just use a set of 
integers and use normal addition and multiplication, even reduced modulo-pn.
Once again, we are free to choose our elements and define our operators in 
any way that works, but it only makes sense to start with something with which 
we are already familiar and which almost works and then make as few 
modifications as necessary to get it to work. It turns out that one way (not the 
only way) to do this is to define our set of symbols to be a set of polynomials. 
Then we can use normal polynomial arithmetic (addition and multiplication) as 
the starting point for our two operators since they already satisfy most of the 
properties we need.
So let's get started. The finite field GF(pn) requires pn 
elements and two operators that act on those elements, so the first step is to 
define the set of elements.
As a first step, let's devise a set of symbols that let's us easily represent 
pn things. The obvious answer is to represent them as an n-digit 
"number" in base-p. What we need to keep in mind, however, is that these 
are not numbers, they are just pn symbols that, at this point, 
have absolutely no order and no relation to each other - we could just as easily 
and validly used {Fred, Bob, Sue, Jane, ..., Dick, Harry} as our set of symbols. 
There is a very strong tendency to subconsciously perceive something that looks 
like a number as a number and treat is as a number even when it isn't. This can 
cause problems if we aren't on guard for it, which is why it is mentioned 
repeatedly in this discussion.
Having said that, let's 
for a moment treat our symbols as numbers and use that to make the step from 
representing numbers to representing polynomials a bit easier to see. For this example, let's use the symbols from GF(75). 
The symbols in such a field would (okay, could) look just like a 5-digit base-7 number such as 
36524. We can write this number as follows:
36524 = (3)(74) + (6)(73) + (5)(72) 
+ (2)(71) + (4)(70)
If we replace the number base with the variable D we have the 
following polynomial expression:
36524 = 3D4 + 6D3 + 5D2 + 2D1 
+ 4D0
We know that polynomials obey the normal rules of addition and 
multiplication, so let's see if we can leverage that.
It is very tempting to think that, in this case, D is equal to 7. That is not 
the case. We have now made the transition from 36524 being a base-7 integer to 
36524 being nothing more than a symbol in an arithmetic system that represents a 
polynomial in the variable D. Even after accepting that, there is a natural 
tendency to want to solve for D or think that the value of D has some meaning 
since that is what we are used to when working with most polynomial expressions. 
But that simply isn't the case here; D is just a dummy variable used to construct a polynomial 
expression and that 
polynomial expression itself is an element in the finite field we are 
constructing. Our operators will act on this, and other, polynomials and the 
results of those operations will be polynomials that are also in the set of 
elements for this finite field. 
Keep in mind that the reason we are using polynomials is for convenience; it 
simply makes it easier to define how our two operators map combinations of 
symbols to other symbols. For instance, our familiar rules make it easy for us 
to remember that (D+2) + (3D+1) maps to (4D+3). We could 
just have easily have defined addition such that (Bob) + (Sue) 
maps to (Harry), but that would be very hard for us to use and get 
comfortable with. Both are equally valid, just not equally as handy. Be careful 
not to put more meaning into these polynomials than is there. 
At this point what we have accomplished (an all the we have accomplished) is a systematic way of representing
pn symbols as unique polynomial expressions. We still have to 
define two operators, which we will call additional and multiplication, such 
that all of the required properties of an algebraic field are satisfied. Let's 
first deal with addition and see how we can define it to obtain an abelian 
group. Once we have this we can examine multiplication and see how we can define 
it to be an abelian group on the set consisting of all of our polynomials except 
the additive identity polynomial. Finally, we just need to ensure that 
multiplication is distributive over addition.
As stated above, we need to define our addition operator such that when it 
acts on the set of polynomials we've defined for GF(pn) that 
we have an abelian group, namely one that is closed, commutative, associative, 
has an identity element, and contains an additive inverse for each element in 
the set. We know that normal polynomial addition is commutative and associative, 
so we just need to avoid doing anything that would invalidate these properties. 
Likewise, we know that polynomial addition has an identity element, namely 0, 
and that this element is a member of our set. Thus three of our five properties 
are satisfied without any modification of the addition rules for everyday 
polynomials. 
However, the remaining two properties, closure and additive inverse, are not 
satisfied by normal polynomial addition. For example, let's consider adding the 
two polynomials 36524 and 50452 from the GF(75) world we started 
constructing previously. Using normal polynomial addition, this gives us:
   36524 = 3D4 + 6D3 + 5D2 + 2D1 
+ 4D0
+ 50452 = 5D4 + 0D3 + 4D2 + 5D1 
+ 2D0
-----------------------------------------------
     ?6??6 = 8D4 + 6D3 + 
9D2 + 7D1 
+ 6D0
As you can see, there are at least some elements of the set that we cannot 
add together and represent using one of the defined polynomials in our set. 
Similarly, the additive inverses are not present in the set:
   36524 =  3D4 +  6D3 +   5D2 +  2D1 
+  4D0
+  ????? = -3D4 + -6D3 + -5D2 + 
-2D1 
+ -4D0
-----------------------------------------------
     00000 =   0D4 +  
0D3 +  0D2 +  0D1 
+  0D0
However, neither of these should  cause too much 
concern because these two properties weren't initially satisfied for working in 
a mod-p world either until we 
made a minor tweak to the definition of addition - namely the concept of 
reducing the result modulo-p. If we add two polynomials of degree d 
then we get a polynomial of, at most, degree d. Since all of the symbols 
in our set are polynomials of degree (p-1) or less, this means that we 
have a good start at obtaining closure under addition since it's only the 
coefficients that are an issue. So what if we perform the addition of the 
coefficients in GF(p)? 
In making this minor modification to the normal polynomial addition operation 
we have obtained closure. For example:
   36524 = 3D4 + 6D3 + 5D2 + 2D1 
+ 4D0
+ 50452 = 5D4 + 0D3 + 4D2 + 5D1 
+ 2D0
-----------------------------------------------
     16206 = 1D4 + 6D3 + 
2D2 + 0D1 
+ 6D0
We have also obtained a complete set of inverse elements. For example:
   36524 = 3D4 + 6D3 + 5D2 + 2D1 
+ 4D0
+ 41253 = 4D4 + 1D3 + 2D2 + 5D1 
+ 3D0
-----------------------------------------------
     00000 =   0D4 +  
0D3 +  0D2 +  0D1 
+  0D0
Note how, in neither case, could we have simply treated the five digit 
symbols as integers  and 
added them together to get the correct result, once again emphasizing the point 
that even though they may look like numbers, they are not numbers and can't be 
treated as such.
Finally, we have done this without upsetting any of the other three 
properties that were already satisfied.
To summarize, addition in GF(pn) is defined to be the normal 
polynomial addition except that the coefficients of each term are added in GF(p). 
Another way of saying this is that normal polynomial addition is used except 
that the coefficients are reduced modulo-p.
As with the addition operator, we want to leverage normal polynomial 
multiplication as much as possible. We once again get three of the five 
properties right away since normal polynomial multiplication is both commutative 
and associative and the normal multiplicative identity element, namely 1, is 
included in the set. So once again we just need to tweak our definition of 
multiplication so as to obtain closure and to ensure that each element (with the 
exception of the additive identity element, namely 0) has a multiplicative 
inverse polynomial that is in the set. 
Using the same two polynomials from our GF(75) example above, the 
normal polynomial product of 36524 and 50452 would be:
   36524 = 3D4 + 6D3 + 5D2 + 2D1 
+ 4D0
* 50452 = 5D4 + 0D3 + 4D2 + 5D1 
+ 2D0
-----------------------------------------------
????? = 15D8 + 30D7 + 27D6 + 
49D5 
+ 76D4 + 45D3 + 36D2 + 24D1 
+ 8D0
However, we already know that one 
modification we need to make to our multiplication operator is to require that the polynomial coefficients 
be operated on in GF(p) in 
order to be consistent with how addition is performed on the coefficients. 
Without this, life would become very messy very fast and, almost certainly, we 
would not be able to satisfy the distributive property if nothing else. Even if 
this weren't the case, we would need to do so for the same reason as before - so 
that the coefficients always map back to those allowed by the set of polynomial 
symbols that has been defined. Doing this reduction on the previous result 
yields the following polynomial product:
????? = 1D8 + 2D7 + 6D6 + 0D5 
+ 6D4 + 3D3 + 1D2 + 3D1 
+ 1D0
We now need to map this back to our defined set of symbols by reducing it, 
somehow, to a polynomial of degree four or less. We will use the 
same basic concept, that of working in a modular world, to perform this 
reduction but we will need to work at the level of the polynomial as a whole and not 
at the level of the individual coefficients. There are two reasons for this. 
First, we have already imposed modular behavior on the individual coefficients 
and so we can't play that card a second time. Second, even if we could, it 
wouldn't change the fact that multiplication of two polynomials can result in a 
polynomial that is of a degree greater than allowed by our symbol set 
definition.  
The first thought that probably comes to mind is to use a parallel of the 
modulus that is used in a normal mod-p world. If the result from a 
multiplication operation results in a polynomial of degree n or higher 
then we can divide it by a "modulus polynomial" and define the 
remainder polynomial to be the result of our multiplication operation. 
Setting aside the fact that 
the polynomials are not intrinsically ordered, the obvious candidate for such a 
modulus polynomial would be D n since, in some very weak 
sense, it is "one greater" than the largest symbol in our set. At this 
point you should be thinking something along the lines that it only appears to 
be "one greater" when we view our symbols as integers and therefore this claim 
should be highly suspect right from the beginning since we know bad things 
generally happen when we let ourselves fall into that trap. We will have the 
same problem here, but let's pursue 
this path and see what lessons we learn.
If we divide the above polynomial by D5, we get a remainder 
of
  63131 = 6D4 + 3D3 + 1D2 + 
3D1 
+ 1D0
Life appears to be good and this is clearly a simple modulus to use, but does 
it really satisfy our needs as we try to construct a finite field? 
As we 
found with a normal mod-p world, the modulus must be relatively prime to 
all the members in the set since those that aren't will not have a multiplicative inverse. 
If we use D5 as our modulus, we can clearly see that it is not 
relatively prime to all of the elements of the symbols set. For example:
D5 = D4 * D1
As a result, we might reasonably suspect that neither D1 
nor D4 would have a multiplicative inverse, and our suspicion 
would be correct. The
reasoning is directly analogous to the situation in a normal mod-p 
world.
Hence we need to 
choose a "primitive polynomial." But what is a primitive polynomial? We can't really use 
the name "primitive polynomial" to tell us much since we coined the name and could 
have called it anything. Instead, we need to define a primitive polynomial in terms 
of the properties we need it to possess. 
Since we want a primitive polynomial to be 
suitable for use as a modulus, let's once again examine what properties we need 
the modulus in a mod-p world to possess. There are two obvious properties 
at this point: (1) the modulus must be relatively prime to all elements of the 
set and (2) whenever any possible element not in the set is divided by the 
modulus the result must be a remainder that is in the set. The first property 
requires that the modulus polynomial be "irreducible" meaning only that it is 
not divisible by any polynomial in the set. The second property requires that 
the polynomial be of no more than degree n since any higher degree could 
result in remainder polynomials that are of degree n or higher thus 
violating our requirements. 
A third not-so-obvious property is that it must be possible to actually 
obtain all of the possible polynomials in the set as remainder polynomials. If 
this isn't the case, then we will almost certainly lose associativity and will 
almost certainly not be able to satisfy the distributability requirement. Don't 
be too concerned if the reason for this isn't obvious - it was stated as being a 
not-so-obvious property for a reason. Accepting that this is the case, however, 
the 
implication is that the modulus polynomial must be of no 
less than degree n since any lower degree will result in subsets of the 
set of polynomials that can't be produced by taking the remainder after dividing 
by the modulus polynomial. So we thus have the tighter requirement that our 
modulus polynomial must be an irreducible polynomial of degree n.
There is a fourth, even more subtle, property that a primitive polynomial must possess; namely it must be a "generator 
polynomial" for the entire set of polynomials. This means that, if M is 
the modulus polynomial, that (Dk mod M) must produce all polynomials 
in the set, except for the additive identity element, 0, as k varies from 
0 to (pn-2). The reason for this requirement is subtle and 
will not be explained in any depth here. The basic issue is that if the modulus 
polynomial is not a generator of the entire set, then the multiplicative group, 
even if it is abelian, will not be cyclic and it turns out that only a cyclic 
multiplicative abelian group will 
satisfy the distributivity property that we need to complete our finite field. 
Do not be concerned if this makes little sense (meaning that this document needs 
to be expanded in the future in an effort to make it make sense, or at least 
seem like a reasonable requirement). For now take this one on faith.
To summarize, multiplication in GF(pn) is defined to be the normal 
polynomial multiplication except that the coefficients of each term are 
multiplied in GF(p) and the polynomial is reduced modulo a primitive 
polynomial. 
Another way of saying this is that normal polynomial multiplication is used except 
that the coefficients are reduced modulo-p and the final result is the 
remainder after normal polynomial division by a primitive polynomial.
There is no efficient algorithmic approach to finding primitive polynomials 
in GF(pn). For the special case of p=2, there are methods for constructing and/or testing 
primitive polynomials in GF(2n), but not for finding all of 
them in an efficient manner. This section will not make any attempt to delve 
into the efficient construction of primitive polynomials. Instead it will assume 
that a brute force search over all of the possibilities is required. In 
practice, tables of primitive polynomials can be referenced (though finding them 
for anything other than GF(2n) is difficult), software designed 
specifically to find primitive polynomials can be used, or you can delve deeper 
into the theory to learn how to do it yourself.
In a brute force search, a reasonable first step is to identify all of the 
irreducible polynomials of degree n. The second step is then determining which 
of those are primitive. 
Two methods of identifying the irreducible polynomials come to mind. The 
first is to work through each possible irreducible polynomial of degree n 
and attempt to divide it by every possible polynomial of degree less than n. 
The second is to proceed in the opposite direction by producing polynomials of 
degree n by multiplying polynomials of degree less than n and 
eliminating the results from the list of possible irreducible polynomials. In 
the first approach, if done blindly, there are p(n+1) 
candidate polynomials and pn polynomials that need to be 
checked to see if they divide each candidate. Hence the order of complexity of 
identifying the irreducible polynomials using this method blindly is O(p(2n+1)). 
The second approach, if done blindly, requires each of the pn 
polynomials in the set to be multiplied pair-wise, including with themselves, 
resulting in a complexity of O(p2n). Although the 
second method only appears better than the first by a factor of p, there is also 
the fact that the first method involves polynomial division while the second 
involved only polynomial multiplication, which is a much faster process. On the 
other hand, the first method has no significant memory requirements while the 
second method requires sufficient memory to store the results for p(n+1) 
candidate polynomials. Clearly, neither method is tractable for GF(pn) 
fields of any significant size; in the case of our GF(75) field, we 
are talking about either 711 (2 billion) or 710 (~280 
million) operations with the latter also needing to store 76 (~120 
thousand) results. Although this is reasonably doable on modern PC's, if we 
increase the size of the field just a bit it would become infeasible even for 
all of the computing power likely to exist in the world for the foreseeable 
future.
Before we raise the white flag, let's explore what a bit of consideration can 
buy us. It's unlikely that we will reduce the complexity significantly, but we 
are very likely to gain a better appreciation for some of the basic properties 
of working with modular polynomials that we haven't seen to this point and that 
might come in handy later.
First, let's consider whether all of the possible p(n+1) 
candidate polynomials are really candidates at all. The first thing to note is 
that the coefficient of the Dn term can't be zero, otherwise 
we don't have a polynomial of degree n. The second thing to notice is 
that the constant term (coefficient of the D0 term) also can't 
be zero otherwise the polynomial would be divisible by D. In our GF(75) 
example, these two considerations alone eliminate more than one quarter of the 
candidates. 
Next, let's examine the case when the coefficient of the Dn 
term is greater than one. Clearly this term is divisible by a constant term, but 
is the entire polynomial also divisible by this same constant term? The answer 
is yes, since dividing a polynomial by a constant term reduces to multiplying 
each term in the polynomial by the multiplicative inverse of that constant and 
since this operation is carried out in GF(p), the result will be a 
polynomial in the set. For example, consider the polynomial
5D5 + 3D4 + 6D2 + 4
This should be evenly divisible by 5. Performing the division by multiplying 
the polynomial by the multiplicative inverse of 5 in GF(7), which is 3, we 
obtain
D5 + 2D4 + 4D2 + 5
This result means that we only have to consider as candidates those 
polynomials that are of order n and that have a high order coefficient of 
exactly one and a non-zero constant term coefficient. There are O(pn) 
such polynomials. But the news is even better than that; we can greatly reduce 
the set of test divisor polynomials. As when attempting to factor an integer, we 
do not need to test every integer that is smaller, we only need to test those 
integers that are prime and that are smaller than the square root of the integer 
we are trying to factor. A similar rule applies here, we only need to test those 
polynomials that are irreducible and of order less than or equal to n/2. 
If we assume that all polynomials with a high order coefficient of one and a 
non-zero constant coefficient are irreducible and must be used as test divisors, 
this results in a complexity of O(p(3n/2)). This is 
still exponential, but it extends the range of fields for which the computations 
are feasible. For our GF(75) example, this reduces the number of 
polynomial division operations needed from two billion to less than one million. 
This can be reduced significantly further by adopting a recursive approach and 
building up a table of irreducible polynomials of lower degrees and then using 
only the irreducible polynomials as test divisors.
Turning our attention to the second approach, we can use many of the same 
lessons. First, we only have to store pn results, which 
reduces the memory requirements in our GF(75) example from 120 
thousand results to only 17 thousand. Furthermore, we can work through the pairs 
of polynomials to be multiplied in a much more systematic fashion. We only need 
to consider pairs of polynomials where the products of the high order terms are
Dn and, as a consequence of what we know about divisibility by 
constant polynomials, we can restrict both polynomials to those whose high-order 
coefficients are one. The number of multiplications that must therefore be 
performed is O(npn). In the case of our GF(75) example, this 
is on the order of eighty-five thousand and a more careful accounting actually 
places it at slightly less than twenty-five thousand polynomial multiplications. 
As with the first approach, this can be further trimmed by identifying the lower 
order irreducible polynomials and only considering them in the multiplications, 
although we must take care to include integer powers of them as well.
Assuming that we have obtained or generated a list of all irreducible 
polynomials of degree n, how do we determine which ones are primitive?
The only guaranteed way of doing this is to test it by seeing if all of the 
polynomials in the set, with the exception of the additive identity polynomial, 
can be generated from it. 
Here are a couple of properties regarding primitive polynomials that we will 
use, but make no attempt to prove or even justify.
	
		
			
				
					- In GF(pn) there are exactly phi(pn 
					− 1)/n primitive polynomials of degree n, 
					where phi() is
					
					Euler's totient function.
- A primitive polynomial is an irreducible polynomial such 
					that the smallest positive integer m for which the 
					polynomial divides Dm - 1 is m = 
					pn − 1.
 
		 
	 
 
Let's see what this says about our GF(75) example. First, let's 
determine how many primitive polynomials there are.
Number of primitive polynomials = phi(pn 
− 1)/n 
Number of primitive polynomials = phi(75 - 1)/5
Number of primitive polynomials = phi(16806)/5 
Number of primitive polynomials = phi( (2)(3)(2801) )/5
Number of primitive polynomials = phi(2)phi(3)phi(2801)/5
Number of primitive polynomials = (1)(2)(2800)/5
Number of primitive polynomials = 1120
While there's no way (that I am aware of) to determine how many irreducible 
polynomials (of degree n) there are, we have previously determined that an upper 
limit on the number is 2058 )(1*7*7*7*6), so more than half of them are 
primitive. Keep in mind that this is merely an anecdotal result and is in no way 
meant to imply anything general.
The second property may not look useful, but in fact is quite handy for a 
couple of things. First consider the fact that, put another way, it says that
M*K = (Dm - 1)
Where M is our modulus polynomial and K is just some polynomial. This is 
directly analogous to the statement 
p*k = (xm - 1)
when working in the mod-p world. Note that neither k nor K 
have to be elements in the fields. As in the mod-p world, we can reduce 
both sides to obtain
M*K 
 (Dm 
- 1)
 (Dm 
- 1) 
 0 
(mod M)
 0 
(mod M)
Dm 
 1 
(mod M)
 1 
(mod M)
But we also know that anything raised to the zero power is also congruent to 
the multiplicative identity, and hence 
Dm 
 D0 
(mod M)
 D0 
(mod M)
The requirement that this is true for no smaller value of m than (pn 
- 1) requires that every Dk for 0<k<m produce a 
different element of the set. We also know that, unless D is identically 
equal to 0, that Dk can never produce 0. Since there are pn 
elements of the set there are (pn - 1) elements that are 
different from 0 and since we have (pn - 1) different values 
of k to choose from, D must be a generator of the entire set. 
So one way to determine if a particular M (irreducible polynomial of 
degree n) is primitive is to determine if D is, in fact, a 
generator of the entire set using that M. However, it is not enough to 
simply test if Dm is congruent to 1 (mod M), since it will be. 
But checks against the powers corresponding to the factors of m will give 
a good indication.
Instead of finding a primitive polynomial by brute for in our GF(75) 
world, we will use the 
Combinatorial Object Server from the University of Victoria. This tool 
indicates the following as being a primitive polynomial in GF(75)
105004 = D5 + 5D3 + 4
The bottom line, unfortunately, is that while we can make significant strides in 
reducing the number of operations required, the complexity of finding the 
primitive polynomials in a particular finite field is 
still exponential and therefore limited to relatively small finite fields. As 
stated before, for specific fields, most notably GF(2n), shortcuts 
have been developed to at least generate primitive polynomials of a particular 
degree.
We've already established that expressing the elements in GF(pn) 
is a viable and useful approach. What the previous discussion has shown is that 
each element, other than 0, can also be expressed as an integer power of D. 
This means that there is a one-to-one mapping between in first (pn 
- 1) powers of D and the non-zero polynomials in GF(pn). 
This, in turn, means that we can use either representation at will and switch 
back and forth between them as the situation warrants.
However, there is a catch. While determining which polynomial a 
particular power of D maps to is straight forward, the reverse is not the 
case. Given a polynomial in D, it is very difficult to determine which 
power of D it maps to by any means other than brute force enumeration. 
The reason for this is that we are looking for the solution to the following 
problem:
P = Da mod M
Where we have a polynomial P and want to find the 
exponent a. However, this is the discrete logarithm problem upon which 
the security of cryptographic protocols and systems such as Diffie-Hellman and 
RSA are based.
The fact that Dm 
 1 
(mod M) in our GF(pn) finite field gives us a very 
powerful and efficient means of computing multiplicative inverses. If we want to 
find the multiplicative inverse of D s then all we must do is 
find D t such that
 1 
(mod M) in our GF(pn) finite field gives us a very 
powerful and efficient means of computing multiplicative inverses. If we want to 
find the multiplicative inverse of D s then all we must do is 
find D t such that 
(Ds)(Dt) = Dm
Which means that 
Dt = (Ds)-1 = D(m-s)
This is not to say that this has become easy, except in 
comparison to the alternatives. For instance, if we wanted to find the 
multiplicative inverse of D17, we could easily determine that the 
power we need to raise D to is 16779 since m is (pn-1) 
which is 16806. This may look completely daunting at first, but remember that we 
have the very powerful square-and-multiply technique for performing fast modular 
exponentiation.
There is one catch in this approach. While determining which 
polynomial a particular power of D maps to is straight forward, the 
reverse is not the case. Given a polynomial in D, it is very difficult to 
determine which power of D it maps to. The reason is that we are looking 
for the solution to the following problem:
P = Da mod M
Where we have a polynomial P and want to find the exponent a. 
However, this is the discrete logarithm problem upon which the security of 
cryptographic protocols and systems such as Diffie-Hellman and RSA are based.
http://en.wikipedia.org/wiki/Primitive_polynomial (Accessed 27 JUL 07)
http://www.theory.cs.uvic.ca/~cos/gen/poly.html (Accessed 27 JUL 07).