How to evaluate GF(256) element

6k Views Asked by At

I wonder is there any easy way to evaluate elements of GF$(256)$: meaning that I would like to know what $\alpha^{32}$ or $\alpha^{200}$ is in polynomial form? I am assuming that the primitive polynomial is $D^8+D^4+D^3+D^2+1$. For example for GF$(8)$ what we do is as follow to calculate $\alpha^3$ is divide it by $\alpha^3+\alpha+1$ and we get $\alpha+1$ but here in GF$(256)$ this will be really tedious so I would like to know is there any way to calculate above expressions or similar expressions like $\alpha^{100}$ in GF$(256)$.

Thanks.

3

There are 3 best solutions below

0
On

NOTE: None of the following Python code has been tested. Furthermore, it's not real code but rather pseudo-code adapted to Python in order to explain a rigorous algorithm while making it readable as possible to people who don't know code or don't know Python.

Wikipedia has a very helpful algorithm for this and it is about the exact field you are dealing with. Let $\mathbf a$ be the first multiplicand and $\mathbf b$ be the second multiplicand. Now, initialize $\mathbf p=0$. At the end, the variable $\mathbf p$ will have the product. Wikipedia describes with more detail into the binary bit manipulations with this algorithm than I do, but here's the pseudo-Python code:

function multiply(a, b):
    p = 0
    # Loop through this eight times, once for each term in b:
    repeat 8 times:
        # If b's constant term is 1, then add p by a:
        if coefficient(b, 1) == 1: p += a
        # Now, we've taken care of this term by a.
        # Therefore, get rid of the constant term of b and divide b by x:
        b -= coefficient(b, 1)
        b //= x

        # carry stores the leading coefficient of a.
        carry = coefficient(a, x^7)
        # Now, get rid of the x^7 term and multiply a by x:
        a -= coefficient(a, x^7)*x^7
        a *= x
        # Now, in order to deal with the loss of the x^7 term,
        # which would now be an x^8 term since we multiplied by x,
        # if carry had a value of 1, then we need to add x^4+x^3+x^2+1.
        # We do this because x^8=x^4+x^3+x^2+1 in this field.
        if carry == 1: a += x^4+x^3+x^2+1

    # Finally, return the product:
    return p

Now, we need to combine this with @stewbasic's idea of exponentiation by squaring:

function exponentiation(alpha, power):
    answer = 1
    # This represents alpha to the current power of 2.
    # At the beginning, the first power of 2 is 2^0=1, so alpha^1=alpha.
    alpha_to_power = alpha
    # Loop through this eight times, once for each bit in power.
    # We assume power is an eight bit number since alpha^256=1.
    repeat 8 times:
        # If the last bit of power is 1, then multiply alpha_to_power to answer:
        if last_bit(power) == 1: answer = multiply(answer, alpha_to_power)
        # Right shift power in order to get rid of the last bit:
        power >>= 1

        # Then, square alpha_to_power
        # in order to advance to the next power of 2:
        alpha_to_power = multiply(alpha_to_power, alpha_to_power)

    # Finally, return the answer:
    return answer

For some $GF(2^m)$, the multiply function has a for loop of m and the exponentiation function has a for loop of m in which the multiply function is called 1-2 times each loop around. Therefore, this is a $O(m^2)$ algorithm, which is quite reasonable for your case of $m=8$.

0
On

Arithmetic with polynomials — including things like divisibility and modular arithmitic — is closely analogous to arithmetic with integers, and many of the same methods apply.

In particular, consider the standard techniques for doing similar computations in the integers, e.g. as described at How do I compute $a^b\,\bmod c$ by hand?.

1
On

GF$(256)$ is small enough that you should construct an antilog table for it and save it for later reference rather than compute the polynomial form of $\alpha^{32}$ or $\alpha^{100}$ on the fly each time you need it. The computer version of the antilog table is an array that stores the polynomial forms for $1 (= \alpha^0), \alpha, \alpha^2, \cdots, \alpha^{254}$ in locations $0, 1, 2, \cdots, 254$. For human use, the table is constructed with two columns and looks something like this $$\begin{array}{r|l} \hline\\ i & \alpha^i \text{ equals}\\ \hline\\ 0 & 00000001\\ 1 & 00000010\\ 2 & 00000100\\ 3 & 00001000\\ 4 & 00010000\\ 5 & 00100000\\ 6 & 01000000\\ 7 & 10000000\\ 8 & 00011101\\ 9 & 00111010\\ 10 & 01110100\\ 11 & 11101000\\ 12 & 11001101\\ \vdots & \vdots\quad \vdots \quad \vdots\\ 254 & 10001110\\ \hline \end{array}$$ The $i$-th entry in the second column is the polynomial representation of $\alpha^i$ in abbreviated format. For example, $\alpha^8$ is stated to be equal to $00011101$ which is shorthand for $\alpha^4+\alpha^3+\alpha^2+1$. The entry for $\alpha^i$ is obtained by shifting the entry immediately above by one place to the left (inserting a $0$ on the right) and if there is an $\alpha^8$ term thus formed, removing it and adding $\alpha^4+\alpha^3+\alpha^2+1$ (i.e. XORing $00011101$) into the rightmost $8$ bits. This process is easy to mechanize to produce the antilog table by computer rather than by hand (which can be tedious and mistake-prone).