def _check_H(p, H, field, gamma_mul): """ If H express the prime ideal, return (H, f), where f: residual degree. Else return some column of M_1 (not (1,0,..,0)^t). """ F_p = finitefield.FinitePrimeField(p) if H == None: f = field.degree else: f = H.row - H.column # rank(A), A.column # CCANT Algo 6.2.9 step 10-11 # step 10 B = matrix.unitMatrix(f, F_p) M_basis = [] for j in range(1, f + 1): alpha_pow = _pow_by_base_mul(B[j], p, gamma_mul, f) alpha_pow -= B[j] M_basis.append(alpha_pow) M_1 = matrix.FieldMatrix(f, f, M_basis).kernel() # step 11 if M_1.column > 1: # dim(M_1) > 1 return M_1[M_1.column] else: H_simple = _two_element_repr_prime_ideal( p, H.map(lambda x: x.getResidue()), field, f) p_alg = algfield.BasicAlgNumber([[p] + [0] * (field.degree - 1), 1], field.polynomial) sol = module.Ideal_with_generator([p_alg, H_simple]) return (sol, f)
def _div_mod_pO(self, other, base_multiply, p): """ ideal division modulo pO by using base_multiply """ n = other.row m = other.column F_p = finitefield.FinitePrimeField(p) #Algo 2.3.7 if self == None: self_new = matrix.zeroMatrix(n, F_p) r = 0 else: self_new = self r = self.column if r == m: return matrix.unitMatrix(n, F_p) # if r > m, raise NoInverseImage error X = matrix.Subspace.fromMatrix(other.inverseImage(self_new)) B = X.supplementBasis() other_self = other * B # first r columns are self, others are supplement other_self.toFieldMatrix() gamma_part = other_self.subMatrix( range(1, n + 1), range(r + 1, m + 1)) omega_gamma = other_self.inverseImage(_matrix_mul_by_base_mul( matrix.unitMatrix(n, F_p), gamma_part, base_multiply)) vect_list = [] for k in range(1, n + 1): vect = vector.Vector([F_p.zero] * ((m - r) ** 2)) for i in range(1, m - r + 1): for j in range(1, m - r + 1): vect[(m - r) * (i - 1) + j] = _mul_place( k, i, omega_gamma, m - r)[j + r] vect_list.append(vect) return matrix.FieldMatrix( (m - r) ** 2, n, vect_list).kernel()
def _separable_algebra(p, H, base_multiply): """ return A=O/H (as matrix representation) """ # CCANT Algo 6.2.9 step 8-9 F_p = finitefield.FinitePrimeField(p) n = base_multiply.row if H == None: H_new = matrix.zeroMatrix(n, 1, F_p) r = 0 else: H_new = H r = H.column # step 8 H_add_one = H_new.copy() if H_add_one.column == n: raise ValueError H_add_one.extendColumn(vector.Vector([F_p.one] + [F_p.zero] * (n - 1))) H_add_one.toSubspace(True) full_base = H_add_one.supplementBasis() full_base.toFieldMatrix() # step 9 A = full_base.subMatrix( range(1, n + 1), range(r + 1, n + 1)) gamma_mul = full_base.inverseImage( _matrix_mul_by_base_mul(A, A, base_multiply)) gamma_mul = gamma_mul.subMatrix( range(r + 1, n + 1), range(1, gamma_mul.column + 1)) return A, gamma_mul
def testBSGS(self): F_65537 = finitefield.FinitePrimeField(65537) e2 = elliptic.EC([-1, 0], F_65537) P1 = list(map(F_65537.createElement, [30840, 53250])) self.assertFalse(256 % e2.BSGS(P1)) P2 = list(map(F_65537.createElement, [10657, 46245])) self.assertFalse(256 % e2.BSGS(P2))
def testWeilPairing(self): # this example was refered to Washington. e = elliptic.EC([0, 2], 7) P = [5, 1] Q = [0, 3] R = e.WeilPairing(3, P, Q) self.assertEqual(finitefield.FinitePrimeFieldElement(2, 7), R) # test case of extension field, characteristic 7 p = 7 r = 11 F = finitefield.FinitePrimeField(p) PX = uniutil.polynomial({0:3,1:3,2:2,3:1,4:4,5:1,6:1,10:1},F) Fx = finitefield.FiniteExtendedField(p,PX) E = elliptic.EC([F.one,-F.one],F) Ex = elliptic.EC([Fx.one,-Fx.one],Fx) P = [3,6] assert E.whetherOn(P) assert Ex.whetherOn(P) assert E.mul(11,P) == E.infpoint Qxcoord = Fx.createElement(6*7**9+7**8+7**6+6*7**3+6*7**2+7+6) Qycoord = Fx.createElement(3*7**9+6*7**8+4*7**7+2*7**6+5*7**4+5*7**3+7**2+7+3) Q = [Qxcoord,Qycoord] assert Ex.whetherOn(Q) assert Ex.mul(11,Q) == Ex.infpoint w = Ex.WeilPairing(11, P, Q) Wp = Fx.createElement(7**9 + 5*7**8 + 4*7**7 + 2*7**5 + 7**4 + 6*7**2) assert w == Wp
def fppoly(coeffs, p): """ Return a Z_p coefficient polynomial constructed from given coeffs. The coeffs is a list of coefficients in ascending order. """ return uniutil.polynomial(enumerate(coeffs), finitefield.FinitePrimeField(p))
def testWeilPairingIsFunction(self): # e2 is isomorphic to Z/256 x Z/256 F_65537 = finitefield.FinitePrimeField(65537) e2 = elliptic.EC([-1, 0], F_65537) P1 = list(map(F_65537.createElement, [30840, 53250])) self.assertFalse(256 % e2.pointorder(P1)) P2 = list(map(F_65537.createElement, [10657, 46245])) self.assertFalse(256 % e2.pointorder(P2)) weil10 = set(e2.WeilPairing(256, P1, P2) for i in range(10)) # since Weil pairing is a function, the result is always same self.assertEqual(1, len(weil10)) # Weil pairing is a function E[m]xE[m] -> mu_m self.assertEqual(e2.basefield.one, weil10.pop()**256)
def PolynomialoverGF(fieldrepr, coeffs, symbol="#1"): """ Create OneVariablePolynomial from coeffs with mapping FinitePrimeField(char).createElement. """ if isinstance(fieldrepr, int): field = finitefield.FinitePrimeField(fieldrepr) elif isinstance( fieldrepr, (finitefield.FinitePrimeField, finitefield.FiniteExtendedField)): field = fieldrepr if type(coeffs) is dict: return polynomial.OneVariableSparsePolynomial(coeffs, symbol, field) elif type(coeffs) is list: coefficients = list(map(field.createElement, coeffs)) return polynomial.OneVariableDensePolynomial(coefficients, symbol)
def root_Fp(g, p, flag=True): """ Return a root over F_p of nonzero polynomial g. p must be prime. If flag = False, return a root randomly """ if isinstance(g, list): if not isinstance(g[0], tuple): g = zip(range(len(g)), g) Fp = finitefield.FinitePrimeField(p) g = uniutil.FinitePrimeFieldPolynomial(g, Fp) h = uniutil.FinitePrimeFieldPolynomial({1: -1, p: 1}, Fp) g = g.gcd(h) deg_g = g.degree() if g[0] == 0: deg_g = deg_g - 1 g = g.shift_degree_to(deg_g) while True: if deg_g == 0: return None if deg_g == 1: return (-g[0] / g[1]).toInteger() elif deg_g == 2: d = g[1] * g[1] - 4 * g[0] e = arith1.modsqrt(d.toInteger(), p) return ((-g[1] - e) / (2 * g[2])).toInteger() deg_h = 0 x = uniutil.FinitePrimeFieldPolynomial({0: -1, (p - 1) >> 1: 1}, Fp) if flag: a = 0 while deg_h == 0 or deg_h == deg_g: b = uniutil.FinitePrimeFieldPolynomial({0: -a, 1: 1}, Fp) v = g(b) h = x.gcd(v) a = a + 1 deg_h = h.degree() b = uniutil.FinitePrimeFieldPolynomial({0: a - 1, 1: 1}, Fp) else: while deg_h == 0 or deg_h == deg_g: a = bigrandom.randrange(p) b = uniutil.FinitePrimeFieldPolynomial({0: -a, 1: 1}, Fp) v = g(b) h = x.gcd(v) deg_h = h.degree() b = uniutil.FinitePrimeFieldPolynomial({0: a, 1: 1}, Fp) g = h(b) deg_g = deg_h
def GaloisField(char, modulus=None): """ Create FiniteField from modulus. modulus must be a form of PolynomialoverGF or PolynomialoverGF. GaloisField is aliased as GF or FiniteField . """ if isinstance(modulus, list): polyGF = PolynomialoverGF(char, modulus) return finitefield.FiniteExtendedField(char, polyGF) if type(modulus) is polynomial.OneVariablePolynomialCharNonZero: return finitefield.FiniteExtendedField(char, modulus) if type(char) is polynomial.OneVariablePolynomialCharNonZero: character = char.getCoefficientRing().getCharacteristic() return finitefield.FiniteExtendedField(character, char) elif not modulus: return finitefield.FinitePrimeField(char) raise ValueError( "modulus must be sequence or OneVariablePolynomialCharNonZero")
def allroots_Fp(g, p): """ Return roots over F_p of nonzero polynomial g. p must be prime. """ if isinstance(g, list): if not isinstance(g[0], tuple): g = zip(range(len(g)), g) Fp = finitefield.FinitePrimeField(p) g = uniutil.FinitePrimeFieldPolynomial(g, Fp) h = uniutil.FinitePrimeFieldPolynomial({1: -1, p: 1}, Fp) g = g.gcd(h) deg_g = g.degree() roots = [] if g[0] == 0: roots.append(0) deg_g = deg_g - 1 g = g.shift_degree_to(deg_g) return roots + roots_loop(g, deg_g, p, Fp)
def _splitting_squarefree(p, H, base_multiply, A, gamma_mul, alpha): """ split squarefree part """ F_p = finitefield.FinitePrimeField(p) if H == None: n = base_multiply.row f = n H_new = matrix.zeroMatrix(n, 1, F_p) else: n = H.row f = n - H.column H_new = H.copy() # step 12 one_gamma = vector.Vector([F_p.one] + [F_p.zero] * (f - 1)) # w.r.t. gamma_1 minpoly_matrix_alpha = matrix.FieldMatrix(f, 2, [one_gamma, alpha]) ker = minpoly_matrix_alpha.kernel() alpha_pow = alpha while ker == None: alpha_pow = _vect_mul_by_base_mul(alpha_pow, alpha, gamma_mul, f) minpoly_matrix_alpha.extendColumn(alpha_pow) ker = minpoly_matrix_alpha.kernel() minpoly_alpha = uniutil.FinitePrimeFieldPolynomial(enumerate(ker[1].compo), F_p) # step 13 m_list = minpoly_alpha.factor() # step 14 L = [] for (m_s, i) in m_list: M_s = H_new.copy() beta_s_gamma = _substitution_by_base_mul(m_s, alpha, gamma_mul, one_gamma, f) # beta_s_gamma (w.r.t. gamma) -> beta_s (w.r.t. omega) beta_s = A * beta_s_gamma omega_beta_s = _matrix_mul_by_base_mul(matrix.unitMatrix(n, F_p), beta_s.toMatrix(True), base_multiply) M_s.extendColumn(omega_beta_s) L.append(M_s.image()) return L