Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- ffield.py 2016-02-12 16:14:40.654378453 -0500
- +++ ffield3.py 2016-02-12 16:16:21.017352960 -0500
- @@ -23,10 +23,10 @@
- testing_doc Describes some tests to make sure the code is working
- as well as some of the built in testing routines.
- -
- +
- """
- -import string, random, os, os.path, cPickle
- +import string, random, os, os.path, pickle, functools
- # The following list of primitive polynomials are the Conway Polynomials
- @@ -81,14 +81,11 @@
- for n in gPrimitivePolysCondensed.keys():
- gPrimitivePolys[n] = [0]*(n+1)
- - if (n < 16):
- - unity = 1
- - else:
- - unity = long(1)
- + unity = 1
- for index in gPrimitivePolysCondensed[n]:
- gPrimitivePolys[n][index] = unity
- gPrimitivePolys[n].reverse()
- -
- +
- class FField:
- """
- @@ -112,15 +109,15 @@
- TestFullDivision
- TestInverse
- - Most of these methods take integers or longs representing field
- - elements as arguments and return integers representing the desired
- + Most of these methods take integers representing field elements
- + as arguments and return integers representing the desired
- field elements as output. See ffield.fields_doc for an explanation
- of the integer representation of field elements.
- Example of how to use the FField class:
- -
- +
- >>> import ffield
- ->>> F = ffield.FField(5) # create the field GF(2^5)
- +>>> F = ffield.FField(5) # create the field GF(2^5)
- >>> a = 7 # field elements are denoted as integers from 0 to 2^5-1
- >>> b = 15
- >>> F.ShowPolynomial(a) # show the polynomial representation of a
- @@ -142,7 +139,7 @@
- See documentation on the appropriate method for further details.
- """
- -
- +
- def __init__(self,n,gen=0,useLUT=-1):
- """
- This method constructs the field GF(2^p). It takes one
- @@ -162,8 +159,8 @@
- Note that you can look at the generator for the field object
- F by looking at F.generator.
- """
- -
- - self.n = n
- +
- + self.n = n
- if (gen):
- self.generator = gen
- else:
- @@ -172,31 +169,25 @@
- if (useLUT == 1 or (useLUT == -1 and self.n < 10)): # use lookup table
- self.unity = 1
- - self.Inverse = self.DoInverseForSmallField
- + self.Inverse = self.DoInverse
- self.PrepareLUT()
- self.Multiply = self.LUTMultiply
- self.Divide = self.LUTDivide
- - self.Inverse = lambda x: self.LUTDivide(1,x)
- - elif (self.n < 15):
- + self.Inverse = lambda x: self.LUTDivide(1,x)
- + else:
- self.unity = 1
- - self.Inverse = self.DoInverseForSmallField
- - self.Multiply = self.DoMultiply
- - self.Divide = self.DoDivide
- - else: # Need to use longs for larger fields
- - self.unity = long(1)
- - self.Inverse = self.DoInverseForBigField
- - self.Multiply = lambda a,b: self.DoMultiply(long(a),long(b))
- - self.Divide = lambda a,b: self.DoDivide(long(a),long(b))
- + self.Inverse = self.DoInverse
- + self.Multiply = lambda a,b: self.DoMultiply(a,b)
- + self.Divide = lambda a,b: self.DoDivide(a,b)
- def PrepareLUT(self):
- fieldSize = 1 << self.n
- - lutName = 'ffield.lut.' + `self.n`
- + lutName = 'ffield.lut.' + repr(self.n)
- if (os.path.exists(lutName)):
- - fd = open(lutName,'r')
- - self.lut = cPickle.load(fd)
- - fd.close()
- + with open(lutName,'rb') as fd:
- + self.lut = pickle.load(fd)
- else:
- self.lut = LUT()
- self.lut.mulLUT = range(fieldSize)
- @@ -204,26 +195,25 @@
- self.lut.mulLUT[0] = [0]*fieldSize
- self.lut.divLUT[0] = ['NaN']*fieldSize
- for i in range(1,fieldSize):
- - self.lut.mulLUT[i] = map(lambda x: self.DoMultiply(i,x),
- - range(fieldSize))
- - self.lut.divLUT[i] = map(lambda x: self.DoDivide(i,x),
- - range(fieldSize))
- - fd = open(lutName,'w')
- - cPickle.dump(self.lut,fd)
- - fd.close()
- + self.lut.mulLUT[i] = list(map(lambda x: self.DoMultiply(i,x),
- + range(fieldSize)))
- + self.lut.divLUT[i] = list(map(lambda x: self.DoDivide(i,x),
- + range(fieldSize)))
- + with open(lutName,'wb') as fd:
- + pickle.dump(self.lut,fd)
- +
- -
- def LUTMultiply(self,i,j):
- return self.lut.mulLUT[i][j]
- def LUTDivide(self,i,j):
- return self.lut.divLUT[i][j]
- -
- +
- def Add(self,x,y):
- """
- Adds two field elements and returns the result.
- """
- -
- +
- return x ^ y
- def Subtract(self,x,y):
- @@ -245,8 +235,8 @@
- m = self.MultiplyWithoutReducing(f,v)
- return self.FullDivision(m,self.generator,
- self.FindDegree(m),self.n)[1]
- -
- - def DoInverseForSmallField(self,f):
- +
- + def DoInverse(self,f):
- """
- Computes the multiplicative inverse of its argument and
- returns the result.
- @@ -254,14 +244,6 @@
- return self.ExtendedEuclid(1,f,self.generator,
- self.FindDegree(f),self.n)[1]
- - def DoInverseForBigField(self,f):
- - """
- - Computes the multiplicative inverse of its argument and
- - returns the result.
- - """
- - return self.ExtendedEuclid(self.unity,long(f),self.generator,
- - self.FindDegree(long(f)),self.n)[1]
- -
- def DoDivide(self,f,v):
- """
- Divide(f,v) returns f * v^-1.
- @@ -291,16 +273,13 @@
- Multiplies two field elements and does not take the result
- modulo self.generator. You probably should not use this
- unless you know what you are doing; look at Multiply instead.
- -
- - NOTE: If you are using fields larger than GF(2^15), you should
- - make sure that f and v are longs not integers.
- """
- -
- +
- result = 0
- mask = self.unity
- i = 0
- while (i <= self.n):
- - if (mask & v):
- + if (mask & v):
- result = result ^ f
- f = f << 1
- mask = mask << 1
- @@ -329,7 +308,7 @@
- f and v represented as a polynomials.
- This method returns the field elements a and b such that
- - f(x) = a(x) * v(x) + b(x).
- + f(x) = a(x) * v(x) + b(x).
- That is, a is the divisor and b is the remainder, or in
- other words a is like floor(f/v) and b is like f modulo v.
- @@ -361,7 +340,7 @@
- result.append(1)
- else:
- result.append(0)
- -
- +
- return result
- def ShowPolynomial(self,f):
- @@ -374,13 +353,13 @@
- if (f == 0):
- return '0'
- -
- +
- for i in range(fDegree,0,-1):
- if ((1 << i) & f):
- - result = result + (' x^' + `i`)
- + result = result + (' x^' + repr(i))
- if (1 & f):
- - result = result + ' ' + `1`
- - return string.replace(string.strip(result),' ',' + ')
- + result = result + ' ' + repr(1)
- + return result.strip().replace(' ',' + ')
- def GetRandomElement(self,nonZero=0,maxDegree=None):
- """
- @@ -398,14 +377,14 @@
- if (maxDegree < 31):
- return random.randint(nonZero != 0,(1<<maxDegree)-1)
- else:
- - result = 0L
- + result = 0
- for i in range(0,maxDegree):
- - result = result ^ (random.randint(0,1) << long(i))
- + result = result ^ (random.randint(0,1) << i)
- if (nonZero and result == 0):
- return self.GetRandomElement(1)
- else:
- return result
- -
- +
- def ConvertListToElement(self,l):
- @@ -419,9 +398,9 @@
- result modulo the generator to get a proper element in the
- field.
- """
- -
- +
- temp = map(lambda a, b: a << b, l, range(len(l)-1,-1,-1))
- - return reduce(lambda a, b: a | b, temp)
- + return functools.reduce(lambda a, b: a | b, temp)
- def TestFullDivision(self):
- """
- @@ -439,9 +418,9 @@
- (c,d) = self.FullDivision(a,b,aDegree,bDegree)
- recon = self.Add(d, self.Multiply(c,b))
- assert (recon == a), ('TestFullDivision failed: a='
- - + `a` + ', b=' + `b` + ', c='
- - + `c` + ', d=' + `d` + ', recon=', recon)
- -
- + + repr(a) + ', b=' + repr(b) + ', c='
- + + repr(c) + ', d=' + repr(d) + ', recon=', recon)
- +
- def TestInverse(self):
- """
- This function tests the Inverse function by generating
- @@ -452,9 +431,9 @@
- a = self.GetRandomElement(nonZero=1)
- aInv = self.Inverse(a)
- prod = self.Multiply(a,aInv)
- - assert 1 == prod, ('TestInverse failed:' + 'a=' + `a` + ', aInv='
- - + `aInv` + ', prod=' + `prod`,
- - 'gen=' + `self.generator`)
- + assert 1 == prod, ('TestInverse failed:' + 'a=' + repr(a) + ', aInv='
- + + repr(aInv) + ', prod=' + repr(prod),
- + 'gen=' + repr(self.generator))
- class LUT:
- """
- @@ -469,13 +448,13 @@
- +,-,*,%,//,/ operators to be the appropriate field operation.
- Note that before creating FElement objects you must first
- create an FField object. For example,
- -
- +
- >>> import ffield
- ->>> F = FField(5)
- ->>> e1 = FElement(F,7)
- +>>> F = ffield.FField(5)
- +>>> e1 = ffield.FElement(F,7)
- >>> e1
- x^2 + x^1 + 1
- ->>> e2 = FElement(F,19)
- +>>> e2 = ffield.FElement(F,19)
- >>> e2
- x^4 + x^1 + 1
- >>> e3 = e1 + e2
- @@ -486,9 +465,9 @@
- x^4 + x^3
- >>> e4 * e2 == (e3)
- 1
- -
- +
- """
- -
- +
- def __init__(self,field,e):
- """
- The constructor takes two arguments, field, and e where
- @@ -499,7 +478,7 @@
- """
- self.f = e
- self.field = field
- -
- +
- def __add__(self,other):
- assert self.field == other.field
- return FElement(self.field,self.field.Add(self.f,other.f))
- @@ -522,7 +501,7 @@
- self.field.FindDegree(self.f),
- self.field.FindDegree(o.f))[0])
- - def __div__(self,other):
- + def __truediv__(self,other):
- assert self.field == other.field
- return FElement(self.field,self.field.Divide(self.f,other.f))
- @@ -535,7 +514,7 @@
- def __eq__(self,other):
- assert self.field == other.field
- return self.f == other.f
- -
- +
- def FullTest(testsPerField=10,sizeList=None):
- """
- This function runs TestInverse and TestFullDivision for testsPerField
- @@ -544,7 +523,7 @@
- GF(2^7). If sizeList == None (which is the default), then every
- field is tested.
- """
- -
- +
- if (None == sizeList):
- sizeList = gPrimitivePolys.keys()
- for i in sizeList:
- @@ -601,7 +580,7 @@
- as telling us that we can replace every occurence of
- x^7 with x + 1. Thus f(x) becomes x * x^7 + x^3 + x which
- becomes x * (x + 1) + x^3 + x = x^3 + x^2 . Essentially, taking
- -polynomials mod x^7 by replacing all x^7 terms with x + 1 will
- +polynomials mod x^7 by replacing all x^7 terms with x + 1 will
- force down the degree of f(x) until it is below 7 (the leading power
- of g(x). See a book on abstract algebra for more details.
- """
- @@ -660,9 +639,8 @@
- GF(2^p) with p > 31 you have to write lots of ugly bit field
- code in most languages. Since Python has built in support for
- arbitrary precision integers, you can make this code work for
- - arbitrary field sizes provided you operate on longs instead of
- - ints. That is if you give as input numbers like
- - 0L, 1L, 1L << 55, etc., most of the code should work.
- + arbitrary field sizes. That is if you give as input numbers like
- + 0, 1, 1 << 55, etc., most of the code should work.
- --------------------------------------------------------------------
- BASIC DESIGN
- @@ -672,7 +650,7 @@
- using integers and design the class methods to work properly on this
- representation. Using integers is efficient since integers are easy
- to store and manipulate and allows us to handle arbitrary field sizes
- -without changing the code if we instead switch to using longs.
- +without changing the code.
- Specifically, an integer represents a bit string
- @@ -692,7 +670,7 @@
- such operations to make most of the computations efficient.
- """
- -
- +
- license_doc = """
- This code was originally written by Emin Martinian (emin@allegro.mit.edu).
- @@ -731,7 +709,7 @@
- testing_doc = """
- The FField class has a number of built in testing functions such as
- TestFullDivision, TestInverse. The simplest thing to
- -do is to call the FullTest method.
- +do is to call the FullTest method.
- >>> import ffield
- >>> ffield.FullTest(sizeList=None,testsPerField=100)
- @@ -760,7 +738,7 @@
- return doctest.testmod(ffield)
- if __name__ == "__main__":
- - print 'Starting automated tests (this may take a while)'
- + print('Starting automated tests (this may take a while)')
- _test()
- - print 'Tests passed.'
- + print('Tests passed.')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement