def is_prime_power(n): """ Prime power is a positive integer power of a single prime number """ if len(factor(n)) == 1: return True return False
def GF(n, poly=[], var='x', fmtspec="p"): """A shorthand for generating finite fields. If poly is not specified then one will be chosen from a list of Conway polynomials.""" if numbthy.is_prime(n): if len(poly) < 2: return FiniteField(n, [1], var=var, fmtspec=fmtspec) else: return FiniteField( n, poly, var=var, fmtspec=fmtspec ) # Explicit characteristic and polynomial modulus else: # n is not prime - hope it's a prime power nfactors = numbthy.factor(n) if (len(nfactors) != 1): raise ValueError( 'GF({0}) only makes sense for {0} a prime power'.format(n)) p = nfactors[0][0] e = nfactors[0][1] # Prime p, exponent e if (len(poly) == 0): try: poly = readconway('CPimport.txt', p, e)[:-1] # Assume monic except (IOError, ValueError): print(" Look for non-Conway primitive polynomial") poly = findprimpoly(p, e) else: if nfactors[0][1] != len(poly): raise ValueError( 'Polynomial {0} does not have degree {1}'.format( poly + [1], nfactors[0][1])) return FiniteField(p, poly, var=var, fmtspec=fmtspec)
def findprimpoly(p, e): import sys if sys.version_info[0] > 2: iterrange = range # Version 3 patch else: iterrange = xrange # Version 2 patch ordfacts = numbthy.factor((p**e) - 1) print(p**e) - 1, " = ", ordfacts for thepolynum in iterrange(p + 1, p**e): # Note: Skip [0,d1,d2,...] as not irred # Note: Skip [d0,0,0,...,0,1] as not primitive and probably not irred thepoly = [(thepolynum // (p**i)) % p for i in range(e)] # length e list of p digits a = FiniteField( p, thepoly).gen() # create poly 'x' mod thepoly, check its order print thepoly, str(a) if ((a**((p**e) - 1)) == 1): # check for irreducibility, else try next poly isprim = True for (thefact, thepow) in ordfacts: print thefact if ((a**(((p**e) - 1) / thefact)) == 1): # thepoly not prim isprim = False break # Don't need to check any more cofactors if isprim: return thepoly print "Oops" # Should throw exception - should never reach this point, all prime/exp have primitive polys
def __init__(self, prime, poly, var='x', orderfacts=None, fmtspec="p"): """FiniteField(prime, poly, var='x', orderfacts=None, fmtspec="p") Create a finite field of order p**d, where d is the degree of the polynomial. Driving polynomial must be monic and top coeff (i.e. 1) is implicit. Example: >>> from finitefield import * >>> GF9 = FiniteField(3,[2,1]) # Define GF(3^2), polys w/ GF3 coeffs, mod x^2+x+2 >>> a = FiniteFieldElt(GF9,[1,2]) # Define 2x+1 in GF(9) Define GF(5^8), defined mod z^8+3z^5+z^4+z^2+3z+4 Providing the factored order as (5^8-1) = (2^5)(3)(13)(313) Default output is coefficients only ('c'), not full polynomials ('z') >>> GF5e8 = FiniteField(5,[4,3,1,0,1,3,0,0],'z',((2,5),(3,1),(13,1),(313,1)),'c') >>> '{0}'.format(c**20) # Default format '20340110' >>> '{0:p}'.format(c**20) # Force polynomial format '(2 + 3z^2 + 4z^3 + z^5 + z^6)'""" self.char = prime self.degree = len(poly) self.order = self.char**self.degree self.modpoly = poly self.var = var self.fmtspec = fmtspec # p=polynomial; c=coeffsonly if(orderfacts == None): self.facts_order_gpunits = numbthy.factor(self.order - 1) else: self.facts_order_gpunits = orderfacts if((self.char**self.degree-1) != reduce(lambda theprod,primepow:theprod*primepow, [prime**thepow for [prime,thepow] in orderfacts])): raise ValueError('{0} is not a factorization of ({1}^{2}-1)'.format(orderfacts,self.char,self.degree)) self.reduc_table = [[0 for j in range(self.degree)] for i in range(2*self.degree-1)] for i in range(self.degree): self.reduc_table[i][i] = 1 self.reduc_table[self.degree] = [(-self.modpoly[j])%self.char for j in range(self.degree)] for i in range(self.degree+1,2*self.degree-1): for j in range(self.degree): self.reduc_table[i][j] = sum(map(lambda k: (-self.modpoly[k]*self.reduc_table[i-self.degree+k][j]), range(self.degree))) % self.char
def isMaximallyIdempotent(n): factor_list = numbthy.factor(n) ipList = idempotentPartitions(n, factor_list) numFactors = len(factor_list) if len(ipList) == 2**(numFactors - 1) - 1: return True return False
def is_square_free(n): for p in [2, 3, 5, 7, 11, 13]: if n % p**2 == 0: return False factor_list = numbthy.factor(n) for (p, e) in factor_list: if (e > 1): return False return True
def is_composite_and_square_free(n): for p in [2, 3, 5, 7, 11, 13]: if n % p**2 == 0: return False factor_list = numbthy.factor(n) if len(factor_list) == 1: return False for (p, e) in factor_list: if (e > 1): return False return True
def __init__(self, prime, poly, var='x', orderfacts=None, fmtspec="p"): """FiniteField(prime, poly, var='x', orderfacts=None, fmtspec="p") Create a finite field of order p**d, where d is the degree of the polynomial. Driving polynomial must be monic and top coeff (i.e. 1) is implicit. Example: >>> from finitefield import * >>> GF9 = FiniteField(3,[2,1]) # Define GF(3^2), polys w/ GF3 coeffs, mod x^2+x+2 >>> a = FiniteFieldElt(GF9,[1,2]) # Define 2x+1 in GF(9) Define GF(5^8), defined mod z^8+3z^5+z^4+z^2+3z+4 Providing the factored order as (5^8-1) = (2^5)(3)(13)(313) Default output is coefficients only ('c'), not full polynomials ('z') >>> GF5e8 = FiniteField(5,[4,3,1,0,1,3,0,0],'z',((2,5),(3,1),(13,1),(313,1)),'c') >>> '{0}'.format(c**20) # Default format '20340110' >>> '{0:p}'.format(c**20) # Force polynomial format '(2 + 3*z**2 + 4*z**3 + z**5 + z**6)'""" self.char = prime self.degree = len(poly) self.order = self.char**self.degree self.modpoly = poly self.var = var self.fmtspec = fmtspec if (orderfacts == None): self.facts_order_gpunits = numbthy.factor(self.order - 1) else: self.facts_order_gpunits = orderfacts if ((self.char**self.degree - 1) != reduce( lambda theprod, primepow: theprod * primepow, [prime**thepow for [prime, thepow] in orderfacts])): raise ValueError( '{0} is not a factorization of ({1}^{2}-1)'.format( orderfacts, self.char, self.degree)) self.reduc_table = [[0 for j in range(self.degree)] for i in range(2 * self.degree - 1)] for i in range(self.degree): self.reduc_table[i][i] = 1 if (self.degree > 1): self.reduc_table[self.degree] = [(-self.modpoly[j]) % self.char for j in range(self.degree)] for i in range(self.degree + 1, 2 * self.degree - 1): for j in range(self.degree): self.reduc_table[i][j] = sum( map( lambda k: (-self.modpoly[k] * self. reduc_table[i - self.degree + k][j]), range(self.degree))) % self.char
def GF(n,name='x',modulus=[]): if numbthy.is_prime(n): if len(modulus)<2: print "Haven't coded prime field GF({0}) yet - sorry".format(n) raise ValueError("Haven't coded prime field GF({0}) yet - sorry".format(n)) else: return FiniteField(n,modulus,name) # Explicit characteristic and polynomial modulus else: # n is not prime - hope it's a prime power nfactors = numbthy.factor(n) if (len(nfactors) != 1): raise ValueError('GF({0}) only makes sense for {0} a prime power'.format(n)) p = nfactors[0][0]; e = nfactors[0][1] # Prime p, exponent e if (len(modulus) == 0): try: modulus = readconway('CPimport.txt',p,e)[:-1] # Assume monic except(IOError,ValueError): print(" Look for non-Conway primitive polynomial") modulus = findprimpoly(p,e) return FiniteField(p,modulus,name)
def GF(n, poly=[], var='x', fmtspec="p"): """A shorthand for generating finite fields. If poly is not specified then one will be chosen from a list of Conway polynomials.""" if numbthy.is_prime(n): if len(poly)<2: return FiniteField(n,[1],var=var,fmtspec=fmtspec) else: return FiniteField(n,poly,var=var,fmtspec=fmtspec) # Explicit characteristic and polynomial modulus else: # n is not prime - hope it's a prime power nfactors = numbthy.factor(n) if (len(nfactors) != 1): raise ValueError('GF({0}) only makes sense for {0} a prime power'.format(n)) p = nfactors[0][0]; e = nfactors[0][1] # Prime p, exponent e if (len(poly) == 0): try: poly = readconway('CPimport.txt',p,e)[:-1] # Assume monic except(IOError,ValueError): print(" Look for non-Conway primitive polynomial") poly = findprimpoly(p,e) else: if nfactors[0][1] != len(poly): raise ValueError('Polynomial {0} does not have degree {1}'.format(poly+[1],nfactors[0][1])) return FiniteField(p,poly,var=var,fmtspec=fmtspec)
def GF(n, name='x', modulus=[]): if numbthy.is_prime(n): if len(modulus) < 2: return FiniteField(n, [1], name) else: return FiniteField( n, modulus, name) # Explicit characteristic and polynomial modulus else: # n is not prime - hope it's a prime power nfactors = numbthy.factor(n) if (len(nfactors) != 1): raise ValueError( 'GF({0}) only makes sense for {0} a prime power'.format(n)) p = nfactors[0][0] e = nfactors[0][1] # Prime p, exponent e if (len(modulus) == 0): try: modulus = readconway('CPimport.txt', p, e)[:-1] # Assume monic except (IOError, ValueError): print(" Look for non-Conway primitive polynomial") modulus = findprimpoly(p, e) return FiniteField(p, modulus, name)
def findprimpoly(p,e): import sys if sys.version_info[0] > 2: iterrange = range # Version 3 patch else: iterrange = xrange # Version 2 patch ordfacts = numbthy.factor((p**e)-1) print (p**e)-1, " = ", ordfacts for thepolynum in iterrange(p+1,p**e): # Note: Skip [0,d1,d2,...] as not irred # Note: Skip [d0,0,0,...,0,1] as not primitive and probably not irred thepoly = [(thepolynum//(p**i))%p for i in range(e)] # length e list of p digits a = FiniteField(p,thepoly).gen() # create poly 'x' mod thepoly, check its order print thepoly, str(a) if ((a**((p**e)-1)) == 1): # check for irreducibility, else try next poly isprim = True for (thefact,thepow) in ordfacts: print thefact if ((a**(((p**e)-1)/thefact)) == 1): # thepoly not prim isprim = False break # Don't need to check any more cofactors if isprim: return thepoly print "Oops" # Should throw exception - should never reach this point, all prime/exp have primitive polys
def test_factor(self): for testcase in ((-15, ((3, 1), (5, 1))), (1234561000, ((2, 3), (5, 3), (211, 1), (5851, 1)))): self.assertEqual(numbthy.factor(testcase[0]), testcase[1])
def distinct_factors(n): factors = numbthy.factor(n) # print factors return len(factors)