create a finite field of order 8 in python

One way to create a finite field of order 8 in Python is to implement the field using polynomials modulo an irreducible polynomial of degree 3. We can represent elements of the field as polynomials of degree at most 2 with coefficients in the binary field GF(2) using the following mapping:

0 --> 0 1 --> 1 α --> x α^2 --> x + 1 α^3 --> x^2 + x + 1 α^4 --> x^2 + 1 α^5 --> x^2 + x α^6 --> x^2 α^7 --> 1

Here, α is a primitive element of the field.

Using this mapping, we can define addition and multiplication of elements in the field as polynomial addition and multiplication modulo the irreducible polynomial x^3 + x + 1.

Here's an implementation of a class for the finite field of order 8 in Python:

main.py
class GF8:
    def __init__(self, value):
        if isinstance(value, int):
            self.value = value
        elif isinstance(value, str):
            self.value = self.str_to_int(value)
    
    def str_to_int(self, s):
        mapping = {'0': 0, '1': 1, 'x': 2, 'y': 3, 'z': 4, 't': 5, 'u': 6, 'v': 7}
        return sum([mapping[c] * 8 ** i for i, c in enumerate(s[::-1])])
    
    def int_to_str(self, n):
        mapping = {0: '0', 1: '1', 2: 'x', 3: 'y', 4: 'z', 5: 't', 6: 'u', 7: 'v'}
        s = ''
        while n != 0:
            s += mapping[n % 8]
            n //= 8
        return s[::-1] if s else '0'
    
    def __repr__(self):
        return self.int_to_str(self.value)
    
    def __add__(self, other):
        return GF8(self.value ^ other.value)
    
    def __mul__(self, other):
        p = self.value
        q = other.value
        r = 0
        for i in range(8):
            if q & 1:
                r ^= p
            p <<= 1
            if p & 0x100:
                p ^= 0x11b
            q >>= 1
        return GF8(r)
    
    def __invert__(self):
        if self.value == 0:
            raise ZeroDivisionError('division by zero')
        b = 0x100
        a = self.value
        t0 = 1
        t1 = 0
        while a != 0:
            q = b // a
            b, a = a, b % a
            t0, t1 = t1, t0 ^ (q * t1)
        return GF8(t0)
    
    def __truediv__(self, other):
        return self * ~other
1450 chars
54 lines

In this implementation, we represent elements of the field as integers in base 8, with the binary digits of the base 8 representation mapping to the elements of GF(2^3).

We define addition and multiplication of elements in the field using the __add__ and __mul__ methods, respectively, and implement division using the extended Euclidean algorithm in the __invert__ and __truediv__ methods.

Here's an example of how to use the GF8 class:

main.py
a = GF8('x^2 + 1')
b = GF8('x^2 + x')
c = a * b
d = c / b
print(a, b, c, d)  # prints x^2 + 1, x^2 + x, x^2 + x + 1, x^2 + 1
125 chars
6 lines

related categories

gistlibby LogSnag