def shortCut(p, d, poly): #where p is prime and is p in Fp ZmodP = IntegersModP(p) if poly.field is not ZmodP: raise TypeError( "Given a polynomial that's not over %s, but instead %r" % (ZmodP.__name__, poly.field.__name__)) #coefs = [0]*(p+1) #coefs[-1] = 1 #r = polynomialsOver(ZmodP)(coefs).factory r = polynomialsOver(ZmodP).factory r = r([0, 1]) #loop through finding remainder (in mod f(x)) d times for i in range(d): #take r to the pth power #find the remainder in mod f r = r.powmod(p, poly) #q, r = divmod(r,poly) #r = toPowP(p,d,r) #q, r = divmod(r,poly) gc = gcd(r - polynomialsOver(poly.field)([0, 1]), poly) return gc
def FiniteField(p, m=1, polynomialModulus=None): Zp = IntegersModP(p) if m == 1: return Zp Polynomial = polynomialsOver(Zp) if polynomialModulus is None: polynomialModulus = generateIrreduciblePolynomial(modulus=p, degree=m) class Fq(FieldElement): fieldSize = int(p ** m) primeSubfield = Zp idealGenerator = polynomialModulus operatorPrecedence = 3 def __init__(self, poly): if type(poly) is Fq: self.poly = poly.poly elif type(poly) is int or type(poly) is Zp: self.poly = Polynomial([Zp(poly)]) elif isinstance(poly, Polynomial): self.poly = poly % polynomialModulus else: self.poly = Polynomial([Zp(x) for x in poly]) % polynomialModulus self.field = Fq @typecheck def __add__(self, other): return Fq(self.poly + other.poly) @typecheck def __sub__(self, other): return Fq(self.poly - other.poly) @typecheck def __mul__(self, other): return Fq(self.poly * other.poly) @typecheck def __eq__(self, other): return isinstance(other, Fq) and self.poly == other.poly def __pow__(self, n): return Fq(pow(self.poly, n)) def __neg__(self): return Fq(-self.poly) def __abs__(self): return abs(self.poly) def __repr__(self): return repr(self.poly) + ' \u2208 ' + self.__class__.__name__ @typecheck def __divmod__(self, divisor): q,r = divmod(self.poly, divisor.poly) return (Fq(q), Fq(r)) def inverse(self): if self == Fq(0): raise ZeroDivisionError x,y,d = extendedEuclideanAlgorithm(self.poly, self.idealGenerator) if d.degree() != 0: raise Exception('Somehow, this element has no inverse! Maybe intialized with a non-prime?') return Fq(x) * Fq(d.coefficients[0].inverse()) Fq.__name__ = 'F_{%d^%d}' % (p,m) return Fq
def generatePolynomial(modulus, degree): Zp = IntegersModP(modulus) Polynomial = polynomialsOver(Zp) coefficients = [Zp(random.randint(0, modulus-1)) for _ in range(degree)] randomMonicPolynomial = Polynomial(coefficients + [Zp(1)]) return randomMonicPolynomial
def toPowP(p, d, r): oldCoefs = r.getCoefs() newCoefs = [0] * p * len(oldCoefs) #create list of size p*m where m is the deg(r) #create coefs for r^p = a0 + a1x^p +a2x^2p + ... + am-1x^(p(m-1)) + amx^pm for i in range(len(oldCoefs)): newCoefs[p * i] = oldCoefs[i] return polynomialsOver(r.field)(newCoefs)
def generateIrreduciblePolynomial(modulus, degree): Zp = IntegersModP(modulus) Polynomial = polynomialsOver(Zp) while True: coefficients = [Zp(random.randint(0, modulus-1)) for _ in range(degree)] randomMonicPolynomial = Polynomial(coefficients + [Zp(1)]) print(randomMonicPolynomial) if isIrreducible(randomMonicPolynomial, modulus): return randomMonicPolynomial
def generateIrreduciblePolynomialV2(modulus, degree): Zp = IntegersModP(modulus) Polynomial = polynomialsOver(Zp) while True: coefficients = [Zp(random.randint(0, modulus-1)) for _ in range(degree)] randomMonicPolynomial = Polynomial(coefficients + [Zp(1)]) print(randomMonicPolynomial) if isIrreducibleV2(randomMonicPolynomial, modulus): return randomMonicPolynomial
def generateRandomDegreePolynomial(modulus): Zp = IntegersModP(modulus) Polynomial = polynomialsOver(Zp) coefficients = [Zp(random.randint(0, modulus-1)) for _ in range(modulus+1)] nonzero = [i for i, e in enumerate(coefficients) if e != 0] if(len(nonzero)>0): lastNonzero = nonzero[len(nonzero)-1] coefficients[lastNonzero] = Zp(1) randomMonicPolynomial = Polynomial(coefficients) return randomMonicPolynomial
def isIrreducible(polynomial, p): ZmodP = IntegersModP(p) if polynomial.field is not ZmodP: raise TypeError("Given a polynomial that's not over %s, but instead %r" % (ZmodP.__name__, polynomial.field.__name__)) poly = polynomialsOver(ZmodP).factory x = poly([0,1]) powerTerm = x isUnit = lambda p: p.degree() == 0 for _ in range(int(polynomial.degree() / 2)): powerTerm = powerTerm.powmod(p, polynomial) gcdOverZmodp = gcd(polynomial, powerTerm - x) if not isUnit(gcdOverZmodp): return False return True
def isIrreducibleV2(polynomial, p): ZmodP = IntegersModP(p) if polynomial.field is not ZmodP: raise TypeError("Given a polynomial that's not over %s, but instead %r" % (ZmodP.__name__, polynomial.field.__name__)) poly = polynomialsOver(ZmodP).factory x = poly([0,1]) isUnit = lambda p: p.degree() == 0 n = polynomial.degree() for i in range(int(n / 2)): d = i+1 r = (n+1) % d if r == 0: gcdOverZmodp = shortCut(p,d,polynomial) if not isUnit(gcdOverZmodp): return False return True
tasks = [] bgtasks = [] for i in range(N): context = PassiveMpc('sid', N, t, i, sends[i], recvs[i], program) tasks.append(loop.create_task(context._run())) await asyncio.gather(*tasks) ####################### # Generating test files ####################### # Fix the field for now Field = GF(0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001) Poly = polynomialsOver(Field) def write_polys(prefix, modulus, N, t, polys): for i in range(N): shares = [f(i + 1) for f in polys] with open('%s-%d.share' % (prefix, i), 'w') as f: write_shares(f, modulus, t, i, shares) def generate_test_triples(prefix, k, N, t): # Generate k triples, store in files of form "prefix-%d.share" polys = [] for j in range(k): a = Field(random.randint(0, Field.modulus - 1)) b = Field(random.randint(0, Field.modulus - 1))
def FiniteField(p, m, polynomialModulus=None): Zp = IntegersModP(p) if m == 1: return Zp Polynomial = polynomialsOver(Zp) if polynomialModulus is None: polynomialModulus = generateIrreduciblePolynomial(modulus=p, degree=m) class Fq(FieldElement): fieldSize = int(p**m) primeSubfield = Zp idealGenerator = polynomialModulus operatorPrecedence = 3 modulus = p degree = m def __init__(self, poly): if type(poly) is Fq: self.poly = poly.poly elif type(poly) is int or type(poly) is Zp: self.poly = Polynomial([Zp(poly)]) elif isinstance(poly, Polynomial): self.poly = poly % polynomialModulus else: self.poly = Polynomial([Zp(x) for x in poly]) % polynomialModulus self.field = Fq @typecheck def __add__(self, other): return Fq(self.poly + other.poly) @typecheck def __sub__(self, other): return Fq(self.poly - other.poly) @typecheck def __mul__(self, other): return Fq(self.poly * other.poly) @typecheck def __eq__(self, other): return isinstance(other, Fq) and self.poly == other.poly def __pow__(self, n): return Fq(pow(self.poly, n)) def __neg__(self): return Fq(-self.poly) def __abs__(self): return abs(self.poly) def __repr__(self): return repr(self.poly) + ' \u2208 ' + self.__class__.__name__ @typecheck def __divmod__(self, divisor): q, r = divmod(self.poly, divisor.poly) return (Fq(q), Fq(r)) def trace(self): a = self.poly for i in range( 1, self.degree ): # remembering range doesn't include the last one. a = Fq(a + self.poly**(self.modulus**i)) return Fq(a) def inverse(self): if self == Fq(0): raise ZeroDivisionError x, y, d = extendedEuclideanAlgorithm(self.poly, self.idealGenerator) if d.degree() != 0: raise Exception( 'Somehow, this element has no inverse! Maybe intialized with a non-prime?' ) return Fq(x) * Fq(d.coefficients[0].inverse()) Fq.__name__ = 'F_{%d^%d}' % (p, m) return Fq
p = 16798108731015832284940804142231733909759579603404752749028378864165570215949L u = 8 q = (p**u - 1)/(p-1)/37 from modp import IntegersModP from finitefield import FiniteField, generateIrreduciblePolynomial from polynomial import polynomialsOver Zpu = IntegersModP(p**u) Poly = polynomialsOver(Zpu).factory #f = Poly([3,0,0,0, 0,0,0,1]) #Fpu = FiniteField(p,u, polynomialModulus=f)