""" FiniteField class that acts like an integer class This makes use of the SmallField Class but creates an object that looks just like an integer object but acts like a finite field. Written by: Bryan Mills """ import math from SmallField import Field # overload the integer object class FiniteField(int): """Finite Field object Looks like an int, tastes like a finite field defaults to GF(7); use setBitVector('1011') to set otherwise """ def bitvector(self): return "1011" def __init__(self, v): super(FiniteField, self).__init__(v) self.F = Field(self.bitvector()) self.v = int(v) def setBitVector(self, bitvector): self.F = Field(bitvector) def __zero__(self): return self.__class__(0) def __add__(self, other): ov = self._getValue(other) return self.F.plus(self.v,ov) def __sub__(self, other): return self.__add__(other) def __mul__(self, other): ov = self._getValue(other) if(self.v == 0 or ov == 0): return self.__zero__() return self.__class__(self.F.prod(self.v,ov)) def __inv__(self): if(self.v == 0): return self.__zero__() return self.__class__(self.F.inv(self.v)) def __div__(self, other): if other == 0: return self.__zero__() if(isinstance(other, FiniteField)): ov = other else: ov = self.__class__(other) return self.__class__(self.F.prod(self.v,self.F.inv(ov.v))) def __rdiv__(self, other): if(isinstance(other, FiniteField)): ov = other else: ov = self.__class__(other) return self.__class__(ov.__div__(self)) def __pow__(self, e): retval = FiniteField(self.v) for i in range(0,e): retval = retval.__mul__(self) return retval def __neg__(self): return self.__inv__() def __rpow__(self, e): return self.__pow__(e) def __abx__(self): return self def __rmul__(self, other): return self.__mul__(other) def __radd__(self, other): return self.__add__(other) def __rsub__(self, other): return self.__add__(other) def __str__(self): return self.v.__str__() def __repr__(self): return self.v.__str__() def _getValue(self, o): if(isinstance(o, FiniteField)): ov = o.v else: ov = o return ov class FiniteFieldGF7(FiniteField): """Finite Field Object in GF(7) """ def bitvector(self): return "1011" class FiniteFieldGF257(FiniteField): """Finite Field Object in GF(257) """ def bitvector(self): return "100011101" import unittest class TestFiniteFieldFunctions(unittest.TestCase): def setUp(self): self.prime_num = 7 self.bitvector = "1011" self.gf7_table_mul = [ [0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 4, 6, 3, 1, 7, 5], [0, 3, 6, 5, 7, 4, 1, 2], [0, 4, 3, 7, 6, 2, 5, 1], [0, 5, 1, 4, 2, 7, 3, 6], [0, 6, 7, 1, 5, 3, 2, 4], [0, 7, 5, 2, 1, 6, 4, 3],] self.gf7_table_add = [ [0, 1, 2, 3, 4, 5, 6, 7], [1, 0, 3, 2, 5, 4, 7, 6], [2, 3, 0, 1, 6, 7, 4, 5], [3, 2, 1, 0, 7, 6, 5, 4], [4, 5, 6, 7, 0, 1, 2, 3], [5, 4, 7, 6, 1, 0, 3, 2], [6, 7, 4, 5, 2, 3, 0, 1], [7, 6, 5, 4, 3, 2, 1, 0],] def testMultiply(self): for i in range(0,self.prime_num+1): for j in range(0,self.prime_num+1): f1 = FiniteFieldGF7(i) fv = f1 * j sv = self.gf7_table_mul[i][j] self.assertEqual(fv, sv, "Multiplication table at location %dx%d is invalid. Found:%d; Should be:%d" % (i,j,fv,sv)) ## test the other direction fv = j * f1 sv = self.gf7_table_mul[i][j] self.assertEqual(fv, sv, "Multiplication table at location %dx%d is invalid. Found:%d; Should be:%d" % (i,j,fv,sv)) def testAddition(self): for i in range(0,self.prime_num+1): for j in range(0,self.prime_num+1): f1 = FiniteFieldGF7(i) fv = f1 + j sv = self.gf7_table_add[i][j] self.assertEqual(fv, sv, "Addition table at location %dx%d is invalid. Found:%d; Should be:%d" % (i,j,fv,sv)) ## test the other direction fv = j + f1 self.assertEqual(fv, sv, "Addition table at location %dx%d is invalid. Found:%d; Should be:%d" % (i,j,fv,sv)) class TestOtherFiniteFieldFunctions(unittest.TestCase): def testDivideMultiply(self): for i in range(0,256): # I was testing all combos but it was too slow to keep for j in range(50,51): f1 = FiniteFieldGF257(i)*j div = f1/j self.assertEqual(div, i, "%d * %d / %d doesn't equal %d" % (i,j,j,i)) def testInverse(self): for i in range(1,256): f1 = FiniteFieldGF257(i).__inv__()*i self.assertEqual(f1, 1, "%d.__inv__() * %d doesn't equal 1" % (i,i)) if __name__ == "__main__": unittest.main()