def encrypt(self, message, pubkey, seed=None, text=False): random.seed(seed) tmp = None if not text: tmp = Integer(message).digits(2) else: tmp = 0 for let in message: tmp = tmp*256 tmp = (tmp + ord(let)) tmp = Integer(tmp).digits(2) tmp.reverse() l = len(tmp) sigma = [0]*l for i in xrange(l): sigma[i] = random.choice([0,1]) r = self.H3("".join(map(str,sigma)) + message) if self.pairing == "tate": pair = self._ext(pubkey[0]).tate_pairing(self.distortion(pubkey[1]), self.order, self.k, self.ec2.base_ring().cardinality()) else: pair = self._ext(pubkey[0]).weil_pairing(self.distortion(pubkey[1]), self.order) print "Sin cifrar", tmp c1 = self._mask(list(sigma), pair**r, self.H2) c2 = self._mask(tmp, sigma, self.H4) return r*self.P, c1, c2
def B(self,x,y): r""" Bilinear form B(x,y) mod 1, givenby the quadratic form Q INPUT: -''x'' -- rational -''y'' -- rational OUTPUT: -''B(x,y)'' -- rational EXAMPLES:: sage: WR=WeilRepDiscriminantForm(3,dual=True) sage: WR.B(1/6,1/2) 1/2 sage: WR.B(1/6,1/6) 1/6 sage: WR.B(1/6,-1+1/6) 1/6 """ #print "N=",self._N,x,y r=Integer(2)*self._N*x*y p=r.numerator() q=r.denominator() res=QQ(p % q)/QQ(q) return res
def id_dirichlet(fun, N, n): N = Integer(N) if N == 1: return (1, 1) p2 = valuation(N, 2) N2 = 2**p2 Nodd = N // N2 Nfact = list(factor(Nodd)) #print "n = "+str(n) #for j in range(20): # print "chi(%d) = e(%d/%d)"%(j+2, fun(j+2,n), n) plist = [z[0] for z in Nfact] ppows = [z[0]**z[1] for z in Nfact] ppows2 = list(ppows) idems = [1 for z in Nfact] proots = [primitive_root(z) for z in ppows] # Get CRT idempotents if p2 > 0: ppows2.append(N2) for j in range(len(plist)): exps = [1 for z in idems] if p2 > 0: exps.append(1) exps[j] = proots[j] idems[j] = crt(exps, ppows2) idemvals = [fun(z, n) for z in idems] # now normalize to right root of unity base idemvals = [ idemvals[j] * euler_phi(ppows[j]) / n for j in range(len(idemvals)) ] ans = [ Integer(mod(proots[j], ppows[j])**idemvals[j]) for j in range(len(proots)) ] ans = crt(ans, ppows) # There are cases depending on 2-part of N if p2 == 0: return (N, ans) if p2 == 1: return (N, crt([1, ans], [2, Nodd])) if p2 == 2: my3 = crt([3, 1], [N2, Nodd]) if fun(my3, n) == 0: return (N, crt([1, ans], [4, Nodd])) else: return (N, crt([3, ans], [4, Nodd])) # Final case 2^3 | N my5 = crt([5, 1], [N2, Nodd]) test1 = fun(my5, n) * N2 / 4 / n test1 = Integer(mod(5, N2)**test1) minusone = crt([-1, 1], [N2, Nodd]) test2 = (fun(minusone, n) * N2 / 4 / n) % (N2 / 4) if test2 > 0: test1 = Integer(mod(-test1, N2)) return (N, crt([test1, ans], [N2, Nodd]))
def get_not_type_one_two_primes(K, aux_prime_count=3, loop_curves=False): """Not type 1-2 primes are the finitely many primes outside of which the isogeny character is necessarily of Momose Type 1 or 2 (or 3, which is not relevant for us).""" if K.is_totally_real(): aux_primes = K.primes_of_degree_one_list(aux_prime_count) else: it = K.primes_of_degree_one_iter() aux_primes = [] while len(aux_primes) < aux_prime_count: aux_prime_candidate = next(it) if not aux_prime_candidate.is_principal(): aux_primes.append(aux_prime_candidate) tracking_dict = {} epsilons = EPSILONS_NOT_TYPE_1_2 C_K = K.class_group() for q in aux_primes: q_class_group_order = C_K(q).multiplicative_order() # these will be dicts with keys the epsilons, values sets of primes AB_primes_dict = get_AB_primes(q, epsilons, q_class_group_order) C_primes_dict = get_C_primes(K, q, epsilons, q_class_group_order, loop_curves) unified_dict = {} q_rat = Integer(q.norm()) assert q_rat.is_prime() for eps in epsilons: unified_dict[eps] = lcm([q_rat, AB_primes_dict[eps], C_primes_dict[eps]]) tracking_dict[q] = unified_dict tracking_dict_inv_collapsed = {} for eps in epsilons: q_dict = {} for q in aux_primes: q_dict[q] = tracking_dict[q][eps] q_dict_collapsed = gcd(list(q_dict.values())) tracking_dict_inv_collapsed[eps] = q_dict_collapsed final_split_dict = {} for eps_type in set(epsilons.values()): eps_type_tracking_dict_inv = { eps: ZZ(tracking_dict_inv_collapsed[eps]) for eps in epsilons if epsilons[eps] == eps_type } eps_type_output = lcm(list(eps_type_tracking_dict_inv.values())) eps_type_output = eps_type_output.prime_divisors() eps_type_output = filter_ABC_primes(K, eps_type_output, eps_type) final_split_dict[eps_type] = set(eps_type_output) output = set.union(*(val for val in final_split_dict.values())) output = list(output) output.sort() return output
def wiener(e, n): m = 12345 c = pow(m, e, n) list1 = continued_fraction(Integer(e) / Integer(n)) conv = list1.convergents() for i in conv: d = int(i.denominator()) m1 = pow(c, d, n) if m1 == m: return d
def test_dimension_jacobi(N, k): from nils.jacobiforms.dimension_jac_forms import dimension_jac_cusp_forms N = Integer(N) dj = dimension_jac_cusp_forms(k + Integer(1) / Integer(2), N) M = FiniteQuadraticModule([2 * N], [1 / (4 * N)]) s = GenusSymbol(M.jordan_decomposition().genus_symbol()) dv = s.dimension_cusp_forms(k, reduction=True) if not dj == dv: print "Error: ", N, dj, dv return False return True
def weight_one_half_dim(FQM, use_reduction = True, proof = False, debug = 0, local=True): N = Integer(FQM.level()) if not N % 4 == 0: return 0 m = Integer(N/Integer(4)) d = 0 for l in m.divisors(): if is_squarefree(m/l): if debug > 1: print "l = {0}".format(l) TM = FiniteQuadraticModule([2*l],[-1/Integer(4*l)]) if local: dd = [0,0] # eigenvalue 1, -1 multiplicity for p,n in lcm(FQM.level(),4*l).factor(): N = None TN = None J = FQM.jordan_decomposition() L = TM.jordan_decomposition() for j in xrange(1,n+1): C = J.constituent(p**j)[0] D = L.constituent(p**j)[0] if debug > 1: print "C = {0}, D = {1}".format(C,D) if N == None and C.level() != 1: N = C elif C.level() != 1: N = N + C if TN == None and D.level() != 1: TN = D elif D.level() != 1: TN = TN + D dd1 = invariants_eps(N, TN, use_reduction, proof, debug) if debug > 1: print "dd1 = {}".format(dd1) if dd1 == [0,0]: # the result is multiplicative # a single [0,0] as a local result # yields [0,0] in the end # and we're done here dd = [0,0] break if dd == [0,0]: # this is the first prime dd = dd1 else: # some basic arithmetic ;-) # 1 = 1*1 = (-1)(-1) # -1 = 1*(-1) = (-1)*1 ddtmp = copy(dd) ddtmp[0] = dd[0]*dd1[0] + dd[1]*dd1[1] ddtmp[1] = dd[0]*dd1[1] + dd[1]*dd1[0] dd = ddtmp if debug > 1: print "dd = {0}".format(dd) d += dd[0] else: d += invariants_eps(FQM, TM, use_reduction, proof, debug)[0] return d
def _kappaSR_monom_to_X(expr): X = StrataGraph.Xvar if expr in ZZ: return expr elif expr.operator() == None: ka_subscript = Integer(str(expr)[2:]) return X**ka_subscript elif expr.operator() == operator.pow: ops = expr.operands() expon = ops[1] ka = ops[0] ka_subscript = Integer(str(ka)[2:]) return expon * X**ka_subscript
def __calculate_rank(self): # this will work once the lattice class is used and Nils's # implementation of the module class if self._L != None: L = self._L o_inv = L.o_invariant() V2 = L.bullet_vectors_of_order_2() return L.det() + Integer( len(V2) * (-1)**(self.__par + o_inv)).divide_knowing_divisible_by(2) else: # stupid... just for testing purposes return Integer(1)
def simple_gamma0_genus_symbols(r=range(1, 500), precomputed=None): if isinstance(precomputed, list): l = precomputed comp = False res = [] for s in l: if Integer(4).divides(s.level()): if s.defines_isomorphic_module( gamma0_N_genus_symbol(s.level() / Integer(4))): res.append(s) print s return res, filter(lambda x: x not in res, l)
def __init__(self, A, use_genus_symbols=False, aniso_formula=False, use_reduction=False): try: from sfqm.fqm.genus_symbol import GenusSymbol except ImportError as e: print(e) use_genus_symbols = False print("Not using genus symbols.") self._use_reduction = use_reduction if use_genus_symbols: if isinstance(A, str): g = GenusSymbol(A) else: try: g = GenusSymbol(A.jordan_decomposition().genus_symbol()) except: raise ValueError self._g = g n2 = self._n2 = g.torsion(2) self._v2 = g.two_torsion_values() self._M = None self._aniso_formula = aniso_formula else: self._M = FiniteQuadraticModule(A) self._g = None self._level = self._M.level() self._aniso_formula = False if is_odd(self._M.order()): self._n2 = n2 = 1 self._v2 = {0: 1} else: self._M2 = M2 = self._M.kernel_subgroup(2).as_ambient()[0] self._n2 = n2 = self._M2.order() self._v2 = list(self._M2.values()) if use_genus_symbols: self._signature = g.signature() m = g.order() else: self._signature = self._M.signature() m = self._M.order() self._m = m d = Integer(1) / Integer(2) * (m + n2) # |discriminant group/{+/-1}| self._d = d self._alpha3 = None self._alpha4 = None
def make_curve(num_bits, num_curves=1): """ Description: Finds num_curves Barreto-Naehrig curves with a prime order that is at least 2^num_bits. Input: num_bits - number of bits for the prime order of the curve num_curves - number of curves to find Output: curves - list of the first num_curves BN curves each of prime order at least 2^num_bits; each curve is represented as a tuple (q,t,r,k,D) """ def P(y): x = Integer(y) return 36*pow(x,4) + 36*pow(x,3) + 24*pow(x,2) + 6*x + 1 x = Integer(floor(pow(2, (num_bits)/4.0)/(sqrt(6)))) q = 0 r = 0 t = 0 curve_num = 0 curves = [] while curve_num < num_curves or (log(q).n()/log(2).n() < 2*num_bits and not (utils.is_suitable_q(q) and utils.is_suitable_r(r) and utils.is_suitable_curve(q,t,r,12,-3,num_bits))): t = Integer(6*pow(x,2) + 1) q = P(-x) r = q + 1 - t b = utils.is_suitable_q(q) and utils.is_suitable_r(r) and utils.is_suitable_curve(q,t,r,12,-3,num_bits) if b: try: assert floor(log(r)/log(2)) + 1 >= num_bits, 'Subgroup not large enough' curves.append((q,t,r,12,-3)) curve_num += 1 except AssertionError as e: pass if curve_num < num_curves or not b: q = P(x) r = q+1-t if (utils.is_suitable_q(q) and utils.is_suitable_r(r) and utils.is_suitable_curve(q,t,r,12,-3,num_bits)): try: assert floor(log(r)/log(2)) + 1 >= num_bits, 'Subgroup not large enough' curves.append((q,t,r,12,-3)) curve_num += 1 except AssertionError as e: pass x += 1 return curves
def compute(self, p=None, cut_nonsimple_aniso=True, fast=1): args = list() for N in range(1, self._level_limit): v2 = Integer(N).valuation(2) N2 = 2**v2 if v2 in [0, 1, 2, 3] and is_squarefree(Integer(N) / N2): s = anisotropic_symbols(N, self._signature) if len(s) == 0: continue args = args + s logger.debug('args = {0}'.format(args)) logger.info('starting with {} anisotropic modules'.format(len(args))) self.compute_from_startpoints(args, p, cut_nonsimple_aniso, fast) return self._simple
def _method_pt1(num_bits, k, D, y): a = Integer(-D * y**2) R = PolynomialRing(ZZ, 'x') f = R.cyclotomic_polynomial(k)(x - 1).polynomial(base_ring=R) g = (a + (x - 2)**2).polynomial(base_ring=R) r = Integer(f.resultant(g)) if (Mod(r, k) == 1) and r > 2**(num_bits - 1) and utils.is_suitable_r( r): # found a valid r, so use it F = GF(r) f = f.change_ring(F) g = g.change_ring(F) t = Integer(f.gcd(g).any_root()) return t, r else: return 0, 0
def test_list_freitag(m=-1): all = True if m == -1 else False for n, symbols in list_freitag.items(): if all or n == m: for symbol in symbols: M = FiniteQuadraticModule(symbol) V = VectorValuedModularForms(M) k = Integer(2 + n) / Integer(2) glob = is_global(M, 2, n) if glob: d = V.dimension_cusp_forms(k) else: d = "?" print("n = {0} {1}: Dimension({2}) = {3}, {4}, |M|={5}".format( n, symbol, str(k), d, glob, M.order()))
def small_A_twist(E): """ Description: Finds a curve isogenous to E that has small A in the curve equation y^2 = x^3 + A*x + B Input: E - elliptic curve Output: E' - elliptic curve isogenous to E that has small A in the curve equation y^2 = x^3 + A*x + B """ a = E.ainvs()[3] q = E.base_field().order() a = power_mod(Integer(a), -1, q) if kronecker(a, q) == -1: b = 2 while kronecker(b, q) == 1: b += 1 a = a * b assert kronecker(a, q) == 1 d = Mod(a, q).sqrt() ainvs = [i for i in E.ainvs()] ainvs[3] *= d**2 ainvs[4] *= d**3 return EllipticCurve(E.base_field(), ainvs)
def test_curve(q, t, r, k, D, E): """ Description: Tests that E is an elliptic curve over F_q with trace t, a subgroup of order r with embedding degree k, and fundamental discriminant D Input: q - size of prime field t - trace of Frobenius r - size of prime order subgroup k - embedding degree D - (negative) fundamental discriminant Output: bool - true iff E is an elliptic curve over F_q with trace t, a subgroup of order r with embedding degree k, and fundamental discriminant D """ bool = True bool = bool and (power_mod(q, k, r) == 1) #q^k -1 ==0 mod r bool = bool and (E.trace_of_frobenius() == t) bool = bool and (kronecker( (t * t - 4 * q) * Integer(D).inverse_mod(q), q) == 1) bool = bool and (E.cardinality() == q + 1 - t) bool = bool and (E.cardinality() % r == 0) return bool
def test_download_sage(self): # A dimension 1 example L1_sage_code = self.tc.get('/ModularForm/GL2/ImaginaryQuadratic/2.0.3.1/18333.3/a/download/sage').get_data(as_text=True) L1_variables = self.check_sage_compiles_and_extract_variables(L1_sage_code) assert L1_variables['NN'].norm() == Integer(18333) a = L1_variables['a'] ZF = L1_variables['ZF'] assert L1_variables['NN'] == ZF.ideal((6111, 3*a + 5052)) for gens in [(27*a-22,),(-29*a+15,),(-29*a+14,),(29*a-11,),(-29*a+18,),(-29*a+9,)]: assert ZF.ideal(gens) in L1_variables['hecke_eigenvalues'] hecke_av_start = [0, -1, 2, -1, 1, -3, 4, 0, -2, -8, 7, -9, -8, -4, -9, 8, 10, -11] assert L1_variables['hecke_eigenvalues_array'][:len(hecke_av_start)] == hecke_av_start # A dimension 2 example L2_sage_code = self.tc.get('/ModularForm/GL2/ImaginaryQuadratic/2.0.4.1/377.1/a2/download/sage').get_data(as_text=True) L2_variables = self.check_sage_compiles_and_extract_variables(L2_sage_code) i = L2_variables['F'].gen() z = L2_variables['z'] ZF = L2_variables['ZF'] assert L2_variables['NN'] == ZF.ideal((16*i - 11)), "level doesn't match" # the level displayed on BMF homepage for gens in [(2*i+3,),(i+4,),(i-4,),(-2*i+5,),(2*i+5,),(i+6,)]: assert ZF.ideal(gens) in L2_variables['hecke_eigenvalues'] hecke_av_start = [-z, 2*z, -1, 2*z+2, "not known", 2*z-1, 4, 2*z+3, "not known", 2*z+1, -2*z-5, -4*z+5, -4*z+5, 2*z+1, 2*z] assert L2_variables['hecke_eigenvalues_array'][:len(hecke_av_start)] == hecke_av_start
def lpp_table(self): """generate the large putative primes table""" output_str = r"${Delta_K}$ & $\Q(\sqrt{{{D}}})$ & {large_putative_primes}\\" latex_output = [] for D in range(-self.range, self.range + 1): if Integer(D).is_squarefree(): if not D in CLASS_NUMBER_ONE_DISCS: if D != 1: K = QuadraticField(D) Delta_K = K.discriminant() candidates = get_isogeny_primes(K, aux_prime_count=25, bound=2000, loop_curves=False) candidates = [ c for c in candidates if c not in EC_Q_ISOGENY_PRIMES ] candidates = [c for c in candidates if c > 71] candidates.sort() large_putative_primes = ", ".join(map(str, candidates)) output_here = output_str.format( Delta_K=Delta_K, D=D, large_putative_primes=large_putative_primes, ) latex_output.append(output_here) for one_line in latex_output: print(one_line)
def dict_to_latex_table(d, n=None, max_per_table=10, midrules=False): beginstr = r"\begin{table}" + "\n" + r"\centering" if not n == None: beginstr += r"\caption{$" + str(Integer(n + 2) / 2) + \ r"$-simple discriminant forms of signature $" + \ str(str((2 - n) % 8)) + r"$}" beginstr += r"\begin{tabularx}{lX} \toprule level & $k$-simple modules\\\midrule" + \ "\n" endstr = r"\bottomrule\end{tabularx}\end{table}" + "\n" s = beginstr dk = sorted(d.keys()) for i in range(len(d.keys())): N = dk[i] if len(d[N]) == 0: continue s += "$" + str(N) + "$" + " & " l = sorted(d[N], lambda x, y: int(-1) if x.order() <= y.order() else int(1)) for m in l: s += str(FQM_vertex(m)).strip() + ", " s = s[:-2] if midrules: s += r"\\\midrule" + "\n" else: s += r"\\" + "\n" if (i + 1) % max_per_table == 0: s += endstr + beginstr s += endstr return s
def all_symbols(sign, rank, D): symbols = list() # print D fac = Integer(D).factor() symbols = list() for p, v in fac: psymbols = list() parts = Partitions(v) exp_mult = list() for vs in parts: exponents = Set(list(vs)) if len(vs) <= rank: mult = dict() for vv in exponents: mult[vv] = list(vs).count(vv) exp_mult.append(mult) Dp = D // (p**v) for vs in exp_mult: # print "partition:", vs ell = list() if p == 2: for vv, mult in vs.iteritems(): ll = list() for t in [0, 1]: # even(0) or odd(1) type for det in [1, 3, 5, 7]: # the possible determinants if mult % 2 == 0 and t == 0: ll.append([vv, mult, det, 0, 0]) if mult == 1: odds = [det] elif mult == 2: if det in [1, 7]: odds = [0, 2, 6] else: odds = [2, 4, 6] else: odds = [ o for o in range(8) if o % 2 == mult % 2 ] for oddity in odds: if t == 1: ll.append([vv, mult, det, 1, oddity]) ell.append(ll) else: for vv, mult in vs.iteritems(): ll = [[vv, mult, 1], [vv, mult, -1]] ell.append(ll) l = list(itertools.product(*ell)) l = map(lambda x: {p: list(x)}, l) psymbols = psymbols + l if len(symbols) == 0: symbols = psymbols else: symbols_new = list() for sym in symbols: for psym in psymbols: newsym = deepcopy(sym) newsym.update(psym) symbols_new.append(newsym) symbols = symbols_new return symbols
def get_type_2_primes(K, aux_prime_count=5, bound=None): """Compute a list containing the type 2 primes""" # First compute the superset of type 2 primes which are not of Momose Type 2 output = get_type_2_not_momose(K, aux_prime_count) # Now deal with Momose Type 2 # First get the bound if bound is None: bound = get_type_2_bound(K) print("type_2_bound = {}".format(bound)) # We need to include all primes up to 25 # see Larson/Vaintrob's proof of Theorem 6.4 output = output.union(set(prime_range(25))) for p in pari.primes(25, bound): p_int = Integer(p) if p_int % 4 == 3: # Momose Type 2 primes are necessarily congruent to 3 mod 4 if satisfies_condition_CC(K, p_int): output.add(p_int) # Sort and return output = list(output) output.sort() return output
def galois_action(self, t, N): from sage.modular.modsym.p1list import lift_to_sl2z if self.is_infinity(): return self if not isinstance(t, Integer): t = Integer(t) a = self._Cusp__a b = self._Cusp__b * t.inverse_mod(N) if b.gcd(a) != ZZ(1): _,_,a,b = lift_to_sl2z(a,b,N) a = Integer(a); b = Integer(b) # Now that we've computed the Galois action, we efficiently # construct the corresponding cusp as a Cusp object. return Cusp(a,b,check=False)
def __init__(self, curve=None, nbits=256): curves = self.supported_curves() if curve is None: if nbits == 160: curve = "brainpoolp160r1" elif nbits == 192: curve = "nist192p" elif nbits == 224: curve = "nist224p" elif nbits == 256: curve = "secp256k1" elif nbits == 320: curve = "brainpoolp320r1" elif nbits == 384: curve = "nist384p" elif nbits == 521: curve = "nist521p" else: raise NotImplementedError("nlen={nlen} is not implemented".format(nlen=nbits)) if str.lower(curve) in curves.keys(): self.curve = curves[curve] self.baselen = self.curve.baselen self.nbits = self.curve.order.bit_length() self.G = self.curve.generator self.n = Integer(self.G.order()) self.F = FiniteField(self.curve.curve.p()) self.C = EllipticCurve([self.F(self.curve.curve.a()), self.F(self.curve.curve.b())]) self.GG = self.C([self.G.x(), self.G.y()]) else: raise NotImplementedError("curve={curve} is not implemented".format(curve=curve))
def predicate(v, standard_basis=True): G_powers, A0, A1 = self._data_for_test() w = 2 ** (self.klen_list[0] - 1) f = Integer((2 ** (max(self.klen_list) - 1)) / w) if standard_basis: nz = v[-1] else: nz = sum(round(v[i]) * A1[i] for i in range(len(A1))) # the last coefficient must be non-zero if abs(nz) != tau: return False if standard_basis: kG = G_powers[v[0] // f] else: kG = sum(round(v[i]) * G_powers[A0[i]] for i in range(len(A0))) r = self.r_list[0] if (kG + G_powers[w]).xy()[0] == r: return True elif (-kG + G_powers[w]).xy()[0] == r: return True else: return False
def compute_rw(k_s): """ Cette méthode va calculer rw en fonction du password :return: rw en format digest """ # On hash le password blk2 = BLAKE2b.new(digest_bits=256) blk2.update(PWD.encode()) # On calcule H' (ks * H(pwd) * g) H_prime = (k_s * Integer("0x" + blk2.hexdigest())).lift() * g # On fait en sorte que x et y de H' soient de la même taille en les paddant x, y = pad(H_prime) bytearray_x = bytearray(bitstring_to_bytes(x)) bytearray_y = bytearray(bitstring_to_bytes(y)) # On passe le password en byrearray pour le concatener avec x et y de H' bytearray_password = bytearray(PWD.encode()) data = bytearray_password + bytearray_x + bytearray_y blk2 = BLAKE2b.new(digest_bits=256) blk2.update(data) rw = blk2.digest() return rw
def type_2_primes(K, embeddings, bound=None): """Compute a list containing the type 2 primes""" logger.debug("Starting Type 2 computation ...") # First compute the superset of type 2 primes which are not of Momose Type 2 output = get_type_2_not_momose(K, embeddings) logger.debug("Type 2 not Momose = {}".format(sorted(output))) # Now deal with Momose Type 2 # First get the bound if bound is None: bound = get_type_2_bound(K) logger.info("type_2_bound = {}".format(bound)) # We need to include all primes up to 25 # see Larson/Vaintrob's proof of Theorem 6.4 output = output.union(set(prime_range(25))) for p in pari.primes(25, bound): p_int = Integer(p) if p_int % 4 == 3: # Type 2 primes necessarily congruent to 3 mod 4 if satisfies_condition_CC(K, p_int): output.add(p_int) output = list(output) output.sort() return output
def __init__(self, data, weight=None, prec=3, dual=False): if isinstance(data, dict): #print "dict" self._coeff_dict = data elif isinstance(data, str): #print "str" try: if data == '': F = FiniteQuadraticModule(matrix(2, 2, [0, 1, 1, 0])) else: F = FiniteQuadraticModule(data) if dual: F = F.twist(Integer(-1)) J = F.jordan_decomposition() L = LocalSpaceByJordanData(J._jordan_decomposition_data()) except: jd = genus_symbol_dict_to_jd(GenusSymbol(data)._symbol_dict) L = LocalSpaceByJordanData(jd) self._coeff_dict = L.eisenstein_series(weight, prec=prec) else: #print "else" L = Lattice(data) if dual: L = L(-1) self._coeff_dict = L.eisenstein_series(weight, prec=prec)
def string2number(s): # a start to replace p2sage (used for the paramters in the FE) strs = str(s).replace(' ','') try: if 'e' in strs: # check for e(m/n) := exp(2*pi*i*m/n), used by Dirichlet characters, for example r = re.match(r'^\$?e\\left\(\\frac\{(?P<num>\d+)\}\{(?P<den>\d+)\}\\right\)\$?$',strs) if not r: r = re.match(r'^e\((?P<num>\d+)/(?P<den>\d+)\)$',strs) if r: q = Rational(r.groupdict()['num'])/Rational(r.groupdict()['den']) return CDF(exp(2*pi*I*q)) if 'I' in strs: return CDF(strs) elif (type(s) is list or type(s) is tuple) and len(s) == 2: return CDF(tuple(s)) elif '/' in strs: return Rational(strs) elif strs=='0.5': # Temporary fix because 0.5 in db for EC return Rational('1/2') elif '.' in strs: return float(strs) else: return Integer(strs) except: return s
def test_nonsurj(v=range(1,50)): """ For each non CM curve of conductor in the list v, compute the primes where the representation isn't surjective using both galrep and Sage, and make sure the answers agree. """ from sage.all import cremona_curves, Integer from wrapper import GalRep G = GalRep() for E in cremona_curves(v): if E.has_cm(): continue a = E.galois_representation().non_surjective() F = E.short_weierstrass_model() b = G.non_surjective_primes(Integer(F.a4()), Integer(F.a6())) if a != b: raise RuntimeError, "Test failed for %s!"%E.cremona_label()
def polynomial_conjugacy_class_matcher_fn(input): """ Given an input of the form [{"RootOf":["0","1"], "ConjugacyClass":3}, {"RootOf":["-7","1"], "ConjugacyClass":4}] returns a function that - takes an argument alpha - matches alpha as a root to one of the 'RootsOf' - returns the value in the corresponding 'ConjugacyClass' """ P = PolynomialRing(Integers(), "x") fn_cc_pairs = [] for d in input: pol = P([Integer(int_val) for int_val in d["RootOf"]]) fn_cc_pairs.append((pol, d["ConjugacyClass"])) def polynomial_conjugacy_class_matcher(alpha): """ A function that has an internal list of pairs (pol, return_val). Given alpha, finds the pol that it is a root of and returns the associated return_val """ for pol_fn, conjugacy_class_index in fn_cc_pairs: if pol_fn(alpha) == 0: return conjugacy_class_index raise AssertionError("alpha = %s is supposed to be root of one of %s" % (alpha, input)) return polynomial_conjugacy_class_matcher
def get_factor_over_nf(curve, prime_ideal, prime_number, conductor, accuracy): """ Returns the inverse of the factor corresponding to the given prime ideal in the Euler product expansion of the L-function at prime_ideal. Unless the accuracy doesn't need this expansion, and then returns 1 in power series ring. """ P = PowerSeriesRing(ZZ, 'T') T = P.gen() q = prime_ideal.norm() inertial_deg = Integer(q).ord(prime_number) if inertial_deg > accuracy: return P(1) if prime_ideal.divides(conductor): a = curve.local_data(prime_ideal).bad_reduction_type() L = 1 - a * (T**inertial_deg) else: discriminant = curve.discriminant() if prime_ideal.divides(discriminant): a = q + 1 - curve.local_minimal_model(prime_ideal).reduction( prime_ideal).count_points() else: a = q + 1 - curve.reduction(prime_ideal).count_points() L = 1 - a * (T**inertial_deg) + q * (T**(2 * inertial_deg)) return L
def bad_primes(self): try: return self._bad_primes except AttributeError: from sage.rings.all import Integer self._bad_primes = [Integer(str(x)) for x in self._data["BadPrimes"]] return self._bad_primes
def method(r,k,D,max_trials=10000, g=0): """ Description: Run the Cocks-Pinch method to find an elliptic curve Input: r - prime k - embedding degree, r % k == 1 D - (negative) fundamental discriminant where D is a square mod r max_trials - the number of integers q to test for primality in the CP method g - an element of order k in Z_r^* Output: (q,t) - tuple where q is a prime and t is chosen such that there exists an elliptic curve E over F_q with trace t, and r | q+1-t; if the algorithm fails to find (q,t), it will return (0,0) """ assert test_promise(r,k,D), 'Invalid inputs' if g != 0: assert power_mod(g,k,r) == 1, 'Invalid inputs' else: g = find_element_of_order(k,r) D = Integer(D) t = Integer(g) + 1 root_d = Integer(Mod(D, r).sqrt()) u = Integer(Mod((t-2)*root_d.inverse_mod(r) ,r)) q = 1 j = Integer(0) i = Integer(0) count = 0 while (count < max_trials): q = Integer( (t+i*r)**2 - D*(u + j*r)**2) if q % 4 ==0: q = q//4 if utils.is_suitable_q(q): return (q, t+i*r) q = 1 if random() < 0.5: j+=1 else: i+=1 count+=1 return (0, 0) # no prime found, so end
def check_character_values(self, rec, verbose=False): """ The x's listed in values and values_gens should be coprime to the modulus N in the label. For x's that appear in both values and values_gens, the value should be the same. """ # TIME about 3000s for full table N = Integer(rec['modulus']) v2, u2 = N.val_unit(2) if v2 == 1: # Z/2 doesn't contribute generators, but 2 divides N adjust2 = -1 elif v2 >= 3: # Z/8 and above requires two generators adjust2 = 1 else: adjust2 = 0 if N == 1: # The character stores a value in the case N=1 ngens = 1 else: ngens = len(N.factor()) + adjust2 vals = rec['values'] val_gens = rec['values_gens'] val_gens_dict = dict(val_gens) if len(vals) != min(12, euler_phi(N)) or len(val_gens) != ngens: if verbose: print "Length failure", len(vals), euler_phi(N), len(val_gens), ngens return False if N > 2 and (vals[0][0] != N-1 or vals[1][0] != 1 or vals[1][1] != 0 or vals[0][1] not in [0, rec['order']//2]): if verbose: print "Initial value failure", N, rec['order'], vals[:2] return False if any(N.gcd(g) > 1 for g, gval in val_gens+vals): if verbose: print "gcd failure", [g for g, gval in val_gens+vals if N.gcd(g) > 1] return False for g, val in vals: if g in val_gens_dict and val != val_gens_dict[g]: if verbose: print "Mismatch failure", g, val, val_gens_dict[g] return False return True
def encrypt(self, message, pubkey, seed=None, text=False): random.seed(seed) tmp = None if not text: tmp = Integer(message).digits(2) else: tmp = 0 for let in message: tmp = tmp*256 tmp = (tmp + ord(let)) tmp = Integer(tmp).digits(2) tmp.reverse() r = random.randint(2, self.order-1) if self.pairing == "tate": pair = self._ext(pubkey[0]).tate_pairing(self.distortion(pubkey[1]), self.order, self.k, self.ec2.base_ring().cardinality()) else: pair = self._ext(pubkey[0]).weil_pairing(self.distortion(pubkey[1]), self.order) return r*self.P, self._mask(tmp, pair**r)
def genus_symbol_string_to_dict(s): sl = s.split('.') d = dict() for s in sl: L1 = s.split('^') if len(L1)>2: raise ValueError() elif len(L1) == 1: nn = 1 else: nn = L1[1] n = Integer(nn) L1= L1[0].split("_") q = Integer(L1[0]) if len(L1) > 2: # more than one _ in item raise ValueError elif len(L1) == 2: if Integer(L1[1]) in range(8): t = Integer(L1[1]) else: raise ValueError, "Type given, which ist not in 0..7: %s"%(L1[1]) else: t = None if not (n != 0 and q != 1 and q.is_prime_power() and ( None == t or (is_even(q) and t%2 == n%2)) and ( not (None == t and is_even(q)) or 0 == n%2) ): raise ValueError,"{0} is not a valid signature!".format(s) p = q.prime_factors()[0] r = q.factor()[0][1] eps = sign(n) n = abs(n) if not d.has_key(p): d[p]=list() if p==2: if t == None: print "eps = ", eps if not is_even(n): raise ValueError() d[p].append([r, n, 3*(-1)**(Integer(n-2)/2) % 8 if eps == -1 else (-1)**(Integer(n)),t,4 if eps == -1 else 0]) print d else: if t.kronecker(2) == eps: det = t % 8 else: if eps == -1: det = 3 else: det = 1 d[p].append([r,n,det,1,t % 8]) else: d[p].append([r,n,eps]) return d
def __init__(self, modulus, number): assert gcd(modulus, number)==1 self.modulus = Integer(modulus) self.number = Integer(number)
class ConreyCharacter: """ tiny implementation on Conrey index only """ def __init__(self, modulus, number): assert gcd(modulus, number)==1 self.modulus = Integer(modulus) self.number = Integer(number) @property def texname(self): return WebDirichlet.char2tex(self.modulus, self.number) @cached_method def modfactor(self): return self.modulus.factor() @cached_method def conductor(self): cond = Integer(1); number = self.number for p,e in self.modfactor(): mp = Mod(number, p**e); if mp == 1: continue if p == 2: cond = 4 if number % 4 == 3: mp = -mp else: cond *= p mp = mp**(p-1) while mp != 1: cond *= p mp = mp**p return cond def is_primitive(self): return self.conductor() == self.modulus @cached_method def parity(self): number = self.number par = 0; for p,e in self.modfactor(): if p == 2: if number % 4 == 3: par = 1 - par else: phi2 = (p-1)/Integer(2) * p **(e-1) if Mod(number, p ** e)**phi2 != 1: par = 1 - par return par def is_odd(self): return self.parity() == 1 def is_even(self): return self.parity() == 0 @cached_method def multiplicative_order(self): return Mod(self.number, self.modulus).multiplicative_order() @property def order(self): return self.multiplicative_order() @cached_method def kronecker_symbol(self): c = self.conductor() p = self.parity() return kronecker_symbol(symbol_numerator(c, p))
def legendre(n, x): e = Integer(1)/(Integer(2)**n * fact(Integer(n))) * diff((x**2-1)**n, x, n) return e.expand()
def _compute_simple_modules_graph_from_startpoint(self, s, p=None, cut_nonsimple_aniso=True, fast=1): # for forking this is necessary logger = get_logger(s) # print logger k = self._weight ########################################################### # Determine which primes need to be checked # According to the proof of Proposition XX in [BEF], we # only need to check primesnot dividing the 6*level(s), # for which prime_pol(s,p,k) <= 0. # For those primes, we check if there is any # k-simple fqm in s.C(p) and if not, we do not have to # consider p anymore. ########################################################### if p == None: p = 2 N = Integer(6) * s.level() slp = N.prime_factors() for q in prime_range(next_prime(N) + 1): if not q in slp: logger.info( "Smallest prime not dividing 6*level({0}) = {1} is p = {2}".format(s, Integer(6) * s.level(), q)) p = q break while prime_pol(s, p, k) <= 0 or p in slp: p = next_prime(p) p = uniq(prime_range(p) + slp) logger.info("Starting with s = {0} and primes = {1}".format(s, p)) if isinstance(p, list): primes = p else: primes = [p] simple = s.is_simple(k, reduction = self._reduction, bound = self._bound) if not simple: logger.info("{0} is not simple.".format(s)) # print simple s = FQM_vertex(s) # print s self.add_vertex(s) # print "added vertex ", s ############################################################ # Starting from the list of primes we generated, # we now compute which primes we actually need to consider. # That is, the primes such that there is a fqm in s.C(p) # which is k-simple. ############################################################ np = list() if cut_nonsimple_aniso and simple: for i in range(len(primes)): p = primes[i] fs = False for t in s.genus_symbol().C(p, False): if t.is_simple(k, bound = self._bound): fs = True logger.debug("Setting fs = True") break if fs: np.append(p) primes = np # print "here", primes logger.info("primes for graph for {0}: {1}".format(s, primes)) # if len(primes) == 0: # return heights = self._heights h = 0 if not heights.has_key(h): heights[h] = [s] else: if heights[h].count(s) == 0: heights[h].append(s) vertex_colors = self._vertex_colors nonsimple_color = self._nonsimple_color simple_color = self._simple_color # Bs contains the modules of the current level (= height = h) Bs = [s] # set the correct color for the vertex s if simple: if vertex_colors[simple_color].count(s) == 0: vertex_colors[simple_color].append(s) elif vertex_colors[nonsimple_color].count(s) == 0: vertex_colors[nonsimple_color].append(s) ################################################### # MAIN LOOP # we loop until we haven't found any simple fqm's ################################################### while simple: h = h + 1 if not heights.has_key(h): heights[h] = list() # the list Bss will contain the k-simple modules of the next height level # recall that Bs contains the modules of the current height level Bss = list() simple = False # checklist = modules that we need to check for with .is_simple(k) # we assemble this list because afterwards # we check them in parallel checklist = [] for s1 in Bs: Bs2 = list() for p in primes: # check if we really need to check p for s1 # otherwise none of the fqm's in s1.C(p) are simple # and we will not consider them. if prime_pol(s1.genus_symbol(), p, k) <= 0: Bs2 = Bs2 + s1.genus_symbol().C(p, False) else: logger.info( "Skipping p = {0} for s1 = {1}".format(p, s1)) # print "Skipping p = {0} for s1 = {1}".format(p, s1) # print "Bs2 = ", Bs2 # now we actually check the symbols in Bs2 for s2 in Bs2: if s2.max_rank() > self._rank_limit: # we skip s2 if its minimal number of generators # is > than the given rank_limit. continue s2 = FQM_vertex(s2) skip = False for v in self._heights[h]: # we skip symbols that correspond to isomorphic modules if v.genus_symbol().defines_isomorphic_module(s2.genus_symbol()): skip = True logger.debug( "skipping {0} b/c isomorphic to {1}".format(s2.genus_symbol(), v.genus_symbol())) s2 = v break if skip: continue if not skip: self.add_vertex(s2) heights[h].append(s2) self.update_edges(s2, h, fast=fast) # before using the actual dimension formula # we check if there is already a non-k-simple neighbor # (an incoming edge from a non-k-simple module) # which would imply that s2 is not k-simple. has_nonsimple_neighbor = False for e in self.incoming_edges(s2): if vertex_colors[nonsimple_color].count(e[0]) > 0: has_nonsimple_neighbor = True logger.debug( "Has nonsimple neighbor: {0}".format(s2.genus_symbol())) break if has_nonsimple_neighbor: #not simple if not vertex_colors[nonsimple_color].count(s2) > 0: vertex_colors[nonsimple_color].append(s2) else: checklist.append((s2, k, self._reduction, self._bound)) logger.debug("checklist = {0}".format(checklist)) # check the modules in checklist # for being k-simple # this is done in parallel # when a process returns # we add the vertex and give it its appropriate color if NCPUS1 == 1: checks = [([[s[0]]],check_simple(*s)) for s in checklist] else: checks = list(check_simple(checklist)) logger.info("checks = {0}".format(checks)) for check in checks: s2 = check[0][0][0] if check[1]: simple = True logger.info( "Found simple module: {0}".format(s2.genus_symbol())) Bss.append(s2) if not vertex_colors[simple_color].count(s2) > 0: vertex_colors[simple_color].append(s2) else: if not vertex_colors[nonsimple_color].count(s2) > 0: vertex_colors[nonsimple_color].append(s2) Bs = Bss simple = [v.genus_symbol() for v in vertex_colors[simple_color]] self._simple = uniq(simple)