def insert_EC_L_functions(start=1, end=100): curves = C.ellcurves.curves for N in range(start, end): print "Processing conductor", N sys.stdout.flush() query = curves.find({'conductor': N, 'number': 1}) for curve in query: E = EllipticCurve([int(x) for x in curve['ainvs']]) L = lc.Lfunction_from_elliptic_curve(E) first_zeros = L.find_zeros_via_N(curve['rank'] + 1) if len(first_zeros) > 1: if not first_zeros[-2] == 0: print "problem" z = float(first_zeros[-1]) Lfunction_data = {} Lfunction_data['first_zero'] = z Lfunction_data['description'] = 'Elliptic curve L-function for curve ' + str(curve['label'][:-1]) Lfunction_data['degree'] = 2 Lfunction_data['signature'] = [0, 1] Lfunction_data['eta'] = [(1.0, 0), ] Lfunction_data['level'] = N Lfunction_data['special'] = {'type': 'elliptic', 'label': curve['label'][:-1]} coeffs = [] for k in range(1, 11): coeffs.append(CC(E.an(k) / sqrt(k))) Lfunction_data['coeffs'] = [(float(x.real()), float(x.imag())) for x in coeffs] Lfunctions.insert(Lfunction_data)
def modular_form_display(label, number): try: number = int(number) except: number = 10 if number < 10: number = 10 # if number > 100000: # number = 20 # if number > 50000: # return "OK, I give up." # if number > 20000: # return "This incident will be reported to the appropriate authorities." # if number > 9600: # return "You have been banned from this website." # if number > 4800: # return "Seriously." # if number > 2400: # return "I mean it." # if number > 1200: # return "Please stop poking me." if number > 1000: number = 1000 data = db_ec().find_one({'lmfdb_label': label}) if data is None: return elliptic_curve_jump_error(label, {}) ainvs = [int(a) for a in data['ainvs']] E = EllipticCurve(ainvs) modform = E.q_eigenform(number) modform_string = web_latex_split_on_pm(modform) return modform_string
def add_heights(data, verbose = False): r""" If data holds the data fields for a curve this returns the same with the heights of the points included as a new field with key 'heights'. It is more convenient to do this separately than while parsing the input files since curves() knows tha a-invariants but not the gens and curve_data() vice versa. """ if 'heights' in data and 'reg' in data: return data ngens = data.get('ngens', 0) if ngens == 0: data['heights'] = [] data['reg'] = float(1) return data # Now there is work to do K = nf_lookup(data['field_label']) if 'ainvs' in data: ainvs = data['ainvs'] else: ainvs = nfcurves.find_one({'label':data['label']})['ainvs'] ainvsK = parse_ainvs(K, ainvs) # list of K-elements E = EllipticCurve(ainvsK) gens = [E(parse_point(K,x)) for x in data['gens']] data['heights'] = [float(P.height()) for P in gens] data['reg'] = float(E.regulator_of_points(gens)) if verbose: print("added heights %s and regulator %s to %s" % (data['heights'],data['reg'], data['label'])) return data
def add_isogeny_matrices(N1,N2): """ Add the 'isogeny_matrix' field to every curve in the database whose conductor is between N1 and N2 inclusive. The matrix is stored as a list of n lists of n ints, where n is the size of the class and the (i,j) entry is the degree of a cyclic isogeny from curve i to curve j in the class, using the lmfdb numbering within each class. Hence this matrix is exactly the same for all curves in the class. This was added in July 2014 to save recomputing the complete isogeny class every time despite the fact that the curves in the class were already in the database. """ query = {} query['conductor'] = { '$gt': int(N1)-1, '$lt': int(N2)+1 } query['number'] = int(1) res = curves.find(query) res = res.sort([('conductor', pymongo.ASCENDING), ('lmfdb_iso', pymongo.ASCENDING)]) for C in res: if 'isogeny_matrix' in C: print("class {} has isogeny matrix already, skipping".format(C['label'])) continue lmfdb_iso = C['lmfdb_iso'] E = EllipticCurve([int(a) for a in C['ainvs']]) M = E.isogeny_class(order="lmfdb").matrix() mat = [list([int(c) for c in r]) for r in M.rows()] n = len(mat) print("{} curves in class {}".format(n,lmfdb_iso)) for label_i in [lmfdb_iso+str(i+1) for i in range(n)]: data = {} data['lmfdb_label'] = label_i data['isogeny_matrix'] = mat curves.update({'lmfdb_label': label_i}, {"$set": data}, upsert=True)
def download_EC_qexp(label, limit): N, iso, number = split_lmfdb_label(label) if number: ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label') else: ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_iso') E = EllipticCurve(ainvs) response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True))) response.headers['Content-type'] = 'text/plain' return response
def test_ap_via_enumeration(B=1000): a4 = 6912*a - 5643 a6 = -131328*a + 298566 E = EllipticCurve([a4, a6]) D = E.discriminant() for P in primes_of_bounded_norm(B): if D.valuation(P) == 0: R = sqrt5_fast.ResidueRing(P, 1) ap0 = sqrt5.ap_via_enumeration(R(a4), R(a6)) k = P.residue_field(); E0 = E.change_ring(k); ap1 = k.cardinality() + 1 - E0.cardinality() assert ap0 == ap1
def test1(B=10 ** 4): from sage.all import polygen, primes, QQ, EllipticCurve import psage.libs.smalljac.wrapper x = polygen(QQ, "x") J = psage.libs.smalljac.wrapper.SmallJac(x ** 3 + 17 * x + 3) E = EllipticCurve([17, 3]) N = E.conductor() for p in primes(B): if N % p: assert E.ap(p) == J.ap(p)
def download_EC_qexp(label, limit): CDB = db_ec() N, iso, number = split_lmfdb_label(label) if number: data = CDB.find_one({'lmfdb_label': label}) else: data = CDB.find_one({'lmfdb_iso': label}) E = EllipticCurve(parse_ainvs(data['ainvs'])) response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True))) response.headers['Content-type'] = 'text/plain' return response
def plot_ec(label): ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label') if ainvs is None: return elliptic_curve_jump_error(label, {}) E = EllipticCurve(ainvs) P = E.plot() _, filename = tempfile.mkstemp('.png') P.save(filename) data = open(filename).read() os.unlink(filename) response = make_response(data) response.headers['Content-type'] = 'image/png' return response
def r_an(ainvs, eps=1e-4): E = EllipticCurve(F, ainvs) L = E.lseries() D = L.dokchitser(30) f = D.taylor_series(1) r = 0 while abs(f[r]) < eps: r += 1 if D.eps == 1: assert r%2 == 0 else: assert r%2 == 1 return r
def download_EC_qexp(label, limit): logger.debug(label) CDB = lmfdb.base.getDBConnection().elliptic_curves.curves N, iso, number = lmfdb_label_regex.match(label).groups() if number: data = CDB.find_one({"lmfdb_label": label}) else: data = CDB.find_one({"lmfdb_iso": label}) ainvs = data["ainvs"] logger.debug(ainvs) E = EllipticCurve([int(a) for a in ainvs]) response = make_response(",".join(str(an) for an in E.anlist(int(limit), python_ints=True))) response.headers["Content-type"] = "text/plain" return response
def download_EC_qexp(label, limit): ec_logger.debug(label) CDB = lmfdb.base.getDBConnection().elliptic_curves.curves N, iso, number = split_lmfdb_label(label) if number: data = CDB.find_one({'lmfdb_label': label}) else: data = CDB.find_one({'lmfdb_iso': label}) ainvs = data['ainvs'] ec_logger.debug(ainvs) E = EllipticCurve([int(a) for a in ainvs]) response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True))) response.headers['Content-type'] = 'text/plain' return response
def plot_ec(label): CDB = db_ec() data = CDB.find_one({'lmfdb_label': label}) if data is None: return elliptic_curve_jump_error(label, {}) E = EllipticCurve(parse_ainvs(data['xainvs'])) P = E.plot() _, filename = tempfile.mkstemp('.png') P.save(filename) data = open(filename).read() os.unlink(filename) response = make_response(data) response.headers['Content-type'] = 'image/png' return response
def plot_ec(label): C = lmfdb.base.getDBConnection() data = C.elliptic_curves.curves.find_one({'lmfdb_label': label}) if data is None: return elliptic_curve_jump_error(label, {}) ainvs = [int(a) for a in data['ainvs']] E = EllipticCurve(ainvs) P = E.plot() _, filename = tempfile.mkstemp('.png') P.save(filename) data = open(filename).read() os.unlink(filename) response = make_response(data) response.headers['Content-type'] = 'image/png' return response
def allgens(line): r""" Parses one line from an allgens file. Returns the label and a dict containing fields with keys 'conductor', 'iso', 'number', 'ainvs', 'jinv', 'cm', 'rank', 'gens', 'torsion_order', 'torsion_structure', 'torsion_generators', all values being strings or ints. Input line fields: conductor iso number ainvs rank torsion_structure gens torsion_gens Sample input line: 20202 i 2 [1,0,0,-298389,54947169] 1 [2,4] [-570:6603:1] [-622:311:1] [834:19239:1] """ data = split(line) label = data[0] + data[1] + data[2] rank = int(data[4]) t = data[5] if t=='[]': t = [] else: t = [int(c) for c in t[1:-1].split(",")] torsion = int(prod([ti for ti in t], 1)) ainvs = parse_ainvs(data[3]) E = EllipticCurve([ZZ(a) for a in ainvs]) jinv = unicode(str(E.j_invariant())) if E.has_cm(): cm = int(E.cm_discriminant()) else: cm = int(0) content = { 'conductor': int(data[0]), 'iso': data[0] + data[1], 'number': int(data[2]), 'ainvs': ainvs, 'jinv': jinv, 'cm': cm, 'rank': int(data[4]), 'gens': ["(%s)" % gen[1:-1] for gen in data[6:6 + rank]], 'torsion': torsion, 'torsion_structure': ["%s" % tor for tor in t], 'torsion_generators': ["%s" % parse_tgens(tgens[1:-1]) for tgens in data[6 + rank:]], } extra_data = make_extra_data(label,content['number'],ainvs,content['gens']) content.update(extra_data) return label, content
def modular_form_display(label, number): try: number = int(number) except ValueError: number = 10 if number < 10: number = 10 if number > 1000: number = 1000 data = db_ec().find_one({'lmfdb_label': label}) if data is None: return elliptic_curve_jump_error(label, {}) E = EllipticCurve(parse_ainvs(data['xainvs'])) modform = E.q_eigenform(number) modform_string = web_latex_split_on_pm(modform) return modform_string
def by_weierstrass(eqn): w = weierstrass_eqn_regex.match(eqn) if not w: w = short_weierstrass_eqn_regex.match(eqn) if not w: return elliptic_curve_jump_error(eqn, {}) try: ainvs = [ZZ(ai) for ai in w.groups()] except TypeError: return elliptic_curve_jump_error(eqn, {}) E = EllipticCurve(ainvs).global_minimal_model() N = E.conductor() data = db_ec().find_one({'xainvs': EC_ainvs(E)}) if data is None: return elliptic_curve_jump_error(eqn, {'conductor':N}, missing_curve=True) return redirect(url_for(".by_ec_label", label=data['lmfdb_label']), 301)
def modular_form_display(label, number): try: number = int(number) except ValueError: number = 10 if number < 10: number = 10 if number > 1000: number = 1000 ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label') if ainvs is None: return elliptic_curve_jump_error(label, {}) E = EllipticCurve(ainvs) modform = E.q_eigenform(number) modform_string = web_latex_split_on_pm(modform) return modform_string
def by_weierstrass(eqn): w = weierstrass_eqn_regex.match(eqn) if not w: w = short_weierstrass_eqn_regex.match(eqn) if not w: return elliptic_curve_jump_error(eqn, {}) try: ainvs = [ZZ(ai) for ai in w.groups()] except TypeError: return elliptic_curve_jump_error(eqn, {}) E = EllipticCurve(ainvs).global_minimal_model() label = db.ec_curves.lucky({'ainvs': EC_ainvs(E)},'lmfdb_label') if label is None: N = E.conductor() return elliptic_curve_jump_error(eqn, {'conductor':N}, missing_curve=True) return redirect(url_for(".by_ec_label", label=label), 301)
def modular_form_display(label, number): try: number = int(number) except ValueError: number = 10 if number < 10: number = 10 if number > 1000: number = 1000 ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label') if ainvs is None: return elliptic_curve_jump_error(label, {}) E = EllipticCurve(ainvs) modform = E.q_eigenform(number) modform_string = web_latex(modform) return modform_string
def EllipticCurve_from_hoeij_data(line): """Given a line of the file "http://www.math.fsu.edu/~hoeij/files/X1N/LowDegreePlaces" that is actually corresponding to an elliptic curve, this function returns the elliptic curve corresponding to this """ Rx = PolynomialRing(QQ, 'x') x = Rx.gen(0) Rxy = PolynomialRing(Rx, 'y') y = Rxy.gen(0) N = ZZ(line.split(",")[0].split()[-1]) x_rel = Rx(line.split(',')[-2][2:-4]) assert x_rel.leading_coefficient() == 1 y_rel = line.split(',')[-1][1:-5] K = QQ.extension(x_rel, 'x') x = K.gen(0) y_rel = Rxy(y_rel).change_ring(K) y_rel = y_rel / y_rel.leading_coefficient() if y_rel.degree() == 1: y = -y_rel[0] else: #print "needing an extension!!!!" L = K.extension(y_rel, 'y') y = L.gen(0) K = L #B=L.absolute_field('s') #f1,f2 = B.structure() #x,y=f2(x),f2(y) r = (x**2 * y - x * y + y - 1) / x / (x * y - 1) s = (x * y - y + 1) / x / y b = r * s * (r - 1) c = s * (r - 1) E = EllipticCurve([1 - c, -b, -b, 0, 0]) return N, E, K
def _test_an_dict_over_Q(ainvs, B=100): """ Test that the an_dict function works and gives the correct answer for an elliptic curve defined over QQ, by computing using the generic code in this file, and comparing with the output of Sage's anlist function for rational elliptic curves. """ from sage.all import polygen, QQ, NumberField, EllipticCurve x = polygen(QQ,'x') F = NumberField(x - 1,'a'); a = F.gen() E = EllipticCurve(F, ainvs) EQ = EllipticCurve(QQ, ainvs) v = EQ.anlist(B) an = an_dict(E, B) for i, j in an.iteritems(): assert j == v[i[0]]
def __init__(self, ec, P = None, dmap = None, order = None, pairing="weil", k = None, seed=None): self.ec = ec self.P = P self.distortion = self._deco(dmap) if dmap == None: self.distortion = self._ext if order == None: self.order = P.order() else: self.order = order self.pairing = pairing ord = self.ec.base_ring().cardinality() if k == None: k = Zmod(self.order)(ord).multiplicative_order() self.k = k random.seed(seed) self.t = random.randint(2, self.order-1) base = FiniteField(ord**self.k, 'b') self.hom = Hom(self.ec.base_ring(), base)(base.gen()**((ord**self.k-1)/(ord-1))) self.ec2 = EllipticCurve(map(int,self.ec.a_invariants())).change_ring(base)
def make_extra_data(label, number, ainvs, gens): """ C is a database elliptic curve entry. Returns a dict with which to update the entry. Data fields needed in C already: 'ainvs', 'lmfdb_label', 'gens', 'number' """ E = EllipticCurve([int(a) for a in ainvs]) data = {} # convert from a list of strings to a single string, e.g. from ['0','0','0','1','1'] to '[0,0,0,1,1]' data['xainvs'] = ''.join(['[', ','.join(ainvs), ']']) data['equation'] = web_latex(E) data['signD'] = int(E.discriminant().sign()) data['local_data'] = [{ 'p': int(ld.prime().gen()), 'ord_cond': int(ld.conductor_valuation()), 'ord_disc': int(ld.discriminant_valuation()), 'ord_den_j': int(max(0, -(E.j_invariant().valuation(ld.prime().gen())))), 'red': int(ld.bad_reduction_type()), 'kod': web_latex(ld.kodaira_symbol()).replace('$', ''), 'cp': int(ld.tamagawa_number()) } for ld in E.local_data()] Etw, Dtw = E.minimal_quadratic_twist() if Etw.conductor() == E.conductor(): data['min_quad_twist'] = {'label': label, 'disc': int(1)} else: # Later this should be changed to look for xainvs but now all curves have ainvs minq_ainvs = [str(c) for c in Etw.ainvs()] r = curves.find_one({ 'jinv': str(E.j_invariant()), 'ainvs': minq_ainvs }) minq_label = "" if r is None else r['label'] data['min_quad_twist'] = {'label': minq_label, 'disc': int(Dtw)} from lmfdb.elliptic_curves.web_ec import parse_points gens = [E(g) for g in parse_points(gens)] data['heights'] = [float(P.height()) for P in gens] if number == 1: data['aplist'] = E.aplist(100, python_ints=True) data['anlist'] = E.anlist(20, python_ints=True) return data
def make_extra_data(label,number,ainvs,gens): """Given a curve label (and number, as some data is only stored wih curve number 1 in each class) and its ainvs and gens, returns a dict with which to update the entry. Extra items computed here: 'equation': latex string of curve's equation 'signD': sign of discriminant 'local_data': list of dicts, one item for each bad prime 'min_quad_twist': dict holding curve's min quadratic twist and the twisting discriminant 'heights': list of heights of gens and for curve #1 in a class only: 'aplist': list of a_p for p<100 'anlist': list of a_n for n<=20 """ E = EllipticCurve(parse_ainvs(ainvs)) data = {} # convert from a list of strings to a single string, e.g. from ['0','0','0','1','1'] to '[0,0,0,1,1]' data['equation'] = web_latex(E) data['signD'] = int(E.discriminant().sign()) data['local_data'] = [{'p': int(ld.prime().gen()), 'ord_cond':int(ld.conductor_valuation()), 'ord_disc':int(ld.discriminant_valuation()), 'ord_den_j':int(max(0,-(E.j_invariant().valuation(ld.prime().gen())))), 'red':int(ld.bad_reduction_type()), 'rootno':int(E.root_number(ld.prime().gen())), 'kod':web_latex(ld.kodaira_symbol()).replace('$',''), 'cp':int(ld.tamagawa_number())} for ld in E.local_data()] Etw, Dtw = E.minimal_quadratic_twist() if Etw.conductor()==E.conductor(): data['min_quad_twist'] = {'label':label, 'disc':int(1)} else: minq_ainvs = ''.join(['['] + [str(c) for c in Etw.ainvs()] + [']']) r = curves.find_one({'jinv':str(E.j_invariant()), 'ainvs':minq_ainvs}) minq_label = "" if r is None else r['label'] data['min_quad_twist'] = {'label':minq_label, 'disc':int(Dtw)} from lmfdb.elliptic_curves.web_ec import parse_points gens = [E(g) for g in parse_points(gens)] data['heights'] = [float(P.height()) for P in gens] if number==1: data['aplist'] = E.aplist(100,python_ints=True) data['anlist'] = E.anlist(20,python_ints=True) return data
def tidy_ecdb(C): """A rewrite function for tidying up the curves collection, Feb 2018. """ if C['conductor']<380000: return C # 1. delete the old redundant 'ainvs' field (we now use 'xainvs' #C.pop('ainvs') # # 2. add local root number if missing ld = C['local_data'] if not 'rootno' in ld[0]: E = EllipticCurve([int(ai) for ai in C['xainvs'][1:-1].split(",")]) for i, ldp in enumerate(ld): ldp['rootno'] = int(E.root_number(ZZ(ldp['p']))) ld[i] = ldp C['local_data'] = ld return C
def test7(lab1, lab2): E1 = EllipticCurve(lab1) E2 = EllipticCurve(lab2) res1 = test_isom(E1, E2, True) res2 = test_isom(E1, E2, False) if res1 and res2: print( "Problem: curves {} and {} are both symplectically and anti-sympectically isomorphic!" .format(lab1, lab2)) return 0 elif not (res1 or res2): print( "Problem: curves {} and {} are neither symplectically nor anti-sympectically isomorphic!" .format(lab1, lab2)) return 0 else: return +1 if res1 else -1
def _test_an_dict_over_Q(ainvs, B=100): """ Test that the an_dict function works and gives the correct answer for an elliptic curve defined over QQ, by computing using the generic code in this file, and comparing with the output of Sage's anlist function for rational elliptic curves. """ from sage.all import polygen, QQ, NumberField, EllipticCurve x = polygen(QQ, 'x') F = NumberField(x - 1, 'a') a = F.gen() E = EllipticCurve(F, ainvs) EQ = EllipticCurve(QQ, ainvs) v = EQ.anlist(B) an = an_dict(E, B) for i, j in an.items(): assert j == v[i[0]]
def plot_iso_graph(label): C = lmfdb.base.getDBConnection() data = C.elliptic_curves.curves.find_one({'lmfdb_iso': label}) if data is None: return elliptic_curve_jump_error(label, {}) ainvs = [int(a) for a in data['ainvs']] E = EllipticCurve(ainvs) G = E.isogeny_graph() n = G.num_verts() P = G.plot(edge_labels=True, layout='spring') _, filename = tempfile.mkstemp('.png') P.save(filename) data = open(filename).read() os.unlink(filename) response = make_response(data) response.headers['Content-type'] = 'image/png' return response
def test1(B=50): """ Tests that the functions all run without crashing over a specific number field. Does not test that the output is correct. That should be in another test. """ from sage.all import polygen, QQ, NumberField, EllipticCurve x = polygen(QQ,'x') F = NumberField(x**2 - x - 1,'a'); a = F.gen() E = EllipticCurve([1,a+1,a,a,0]) ap(E,F.ideal(3)) primes_of_bounded_norm(F,B) ap_list(E,B) assert len(ap_list(E,B,primes=True)) == 2 apd = ap_dict(E,B) reduced_rep(F.ideal(3)) assert an_dict(E,B) == an_dict_from_ap(apd, E.conductor(), B)
def elliptic_curve_jump(info): label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s', '', label) lab = re.sub(r'^\[', '', lab) lab = re.sub(r']$', '', lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec).minimal_model() # Now we do have a valid curve over Q, but it might # not be in the database. lmfdb_label = db.ec_curves.lucky({'ainvs': EC_ainvs(E)}, 'lmfdb_label') if lmfdb_label is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(lmfdb_label) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: return elliptic_curve_jump_error('', info)
def tidy_ecdb(C): """A rewrite function for tidying up the curves collection, Feb 2018. """ if C['conductor'] < 380000: return C # 1. delete the old redundant 'ainvs' field (we now use 'xainvs' #C.pop('ainvs') # # 2. add local root number if missing ld = C['local_data'] if not 'rootno' in ld[0]: E = EllipticCurve([int(ai) for ai in C['xainvs'][1:-1].split(",")]) for i, ldp in enumerate(ld): ldp['rootno'] = int(E.root_number(ZZ(ldp['p']))) ld[i] = ldp C['local_data'] = ld return C
def by_weierstrass(eqn): w = weierstrass_eqn_regex.match(eqn) if not w: w = short_weierstrass_eqn_regex.match(eqn) if not w: return elliptic_curve_jump_error(eqn, {}) try: ainvs = [ZZ(ai) for ai in w.groups()] except TypeError: return elliptic_curve_jump_error(eqn, {}) E = EllipticCurve(ainvs).global_minimal_model() N = E.conductor() ainvs = [str(ai) for ai in E.ainvs()] data = db_ec().find_one({'ainvs': ainvs}) if data is None: return elliptic_curve_jump_error(eqn, {'conductor':N}, missing_curve=True) return redirect(url_for(".by_ec_label", label=data['lmfdb_label']), 301)
def download_EC_qexp(label, limit): try: N, iso, number = split_lmfdb_label(label) except (ValueError,AttributeError): return elliptic_curve_jump_error(label, {}) if number: ainvs = db.ec_curvedata.lookup(label, 'ainvs', 'lmfdb_label') else: ainvs = db.ec_curvedata.lookup(label, 'ainvs', 'lmfdb_iso') if ainvs is None: return elliptic_curve_jump_error(label, {}) if limit > 100000: return redirect(url_for('.download_EC_qexp',label=label,limit=10000), 301) E = EllipticCurve(ainvs) response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True))) response.headers['Content-type'] = 'text/plain' return response
def decrypt(c, d, n): n = int(n) size = n.bit_length() // 2 c_high, c_low = c b = (c_low**2 - c_high**3) % n EC = EllipticCurve(Zmod(n), [0, b]) m_high, m_low = (EC((c_high, c_low)) * d).xy() m_high, m_low = int(m_high), int(m_low) return (m_high << size) | m_low
def plot_iso_graph(label): C = lmfdb.base.getDBConnection() data = C.elliptic_curves.curves.find_one({"lmfdb_iso": label}) if data is None: return elliptic_curve_jump_error(label, {}) ainvs = [int(a) for a in data["ainvs"]] E = EllipticCurve(ainvs) G = E.isogeny_graph() n = G.num_verts() G.relabel(range(1, n + 1)) # proper lmfdb labels... P = G.plot(edge_labels=True, layout="spring") _, filename = tempfile.mkstemp(".png") P.save(filename) data = open(filename).read() os.unlink(filename) response = make_response(data) response.headers["Content-type"] = "image/png" return response
def EllipticCurve_polredabs(E): """ Input: - E - an elliptic curve over a number field K Output: - E1 - the elliptic curve that is the base change of E along phi: K -> L where phi is the morphism from K to its polredabs field """ return EllipticCurve(EllipticCurve_polredabs_a_invariants(E, False))
def base_change(E, phi): """ INPUT: * "E" - an elliptic curve - phi - morphism whose domain is the base ring of E Output: - the elliptic curve obtained by applying phi to the coefficients of E """ return EllipticCurve(phi.codomain(), map(phi, E.a_invariants()))
def find_cong_db(Nmin, Nmax, p, ofile=None, verbose=False): if ofile: ofile = open(ofile, mode='a') nc = 0 for N in srange(Nmin, Nmax + 1): if N % 100 == 0: print(N) curves_N = get_curves(N) if curves_N: if verbose: print("N1 = {} ({} classes)".format(N, len(curves_N))) for M in srange(11, N + 1): #for M in srange(11,42000): curves_M = get_curves(M) if curves_M and verbose: pass print("...N2 = {} ({} classes)".format(M, len(curves_M))) for c1 in curves_N: ap1 = c1['aplist'] iso1 = c1['iso_nlabel'] lab1 = str(c1['label']) curves2 = [ c2 for c2 in curves_M if M < N or c2['iso_nlabel'] < iso1 ] curves2 = [ c2 for c2 in curves2 if test2(N, ap1, M, c2['aplist'], p) ] for c2 in curves2: lab2 = str(c2['label']) print("Candidate for congruence mod {}: {} {}".format( p, lab1, lab2)) E1 = EllipticCurve(lab1) E2 = EllipticCurve(lab2) res, reason = test_cong(p, E1, E2) report(res, reason, p, lab1, lab2) if res: nc += 1 if ofile: ofile.write("{} {} {}\n".format(p, lab1, lab2)) if ofile: ofile.close() print("{} pairs of congruent curves found".format(nc))
def associated_ec(self): """ Returns the elliptic curve that is birationally equivalent to this Edwards curve. That is, the elliptic curve given by E: y^2 = x^3 + 2(a + d)x^2 + (a - d)^2x """ a, d = self.ainvs() K = self.__base_ring return EllipticCurve(K, [0, 2 * (a + d), 0, (a - d)**2, 0])
def old_test_irred(s, p=7): Elist = [EllipticCurve(lab) for lab in s] rhos = [E.galois_representation() for E in Elist] r = [rho.is_irreducible(p) for rho in rhos] if all(r): return True if not any(r): return False print("Set {} is mixed: {}".format(s, r)) return None
def gen_random_curve(bits): """generates a random curve with prime of given bit length""" p = random_prime(2**bits, proof=True, lbound=2**(bits - 1)) while True: a = random.randint(1, p - 1) b = random.randint(1, p - 1) if ((4 * (a**3)) + (27 * (b**2))) % p != 0: F = GF(p) E = EllipticCurve(F, [a, b]) return (E, F)
def __init__(self, a, b, symplectic=True): self._base = a.parent() self._symplectic = symplectic self._a = a self._b = b self.Eab = EllipticCurve([0,0,0,a,b]) self._DeltaE = -16*(4*a**3+27*b**2) if symplectic: self._F = F_ab(a,b) else: self._F = G_ab(a,b) self._Del = Del(self._F) self._K = K_covariant(self._F) self._C = C_covariant(self._F) if symplectic: assert self.j([0,1,0])==self.Eab.j_invariant() # else there is no base-point since E is normally not # antisymplectically isomorphic to itself! self.P2C = {} # P2C is a dict with keys points on XE(7) and values the curve associated with that point
def insert_EC_L_functions(start=1, end=100): curves = C.ellcurves.curves for N in range(start, end): print("Processing conductor", N) sys.stdout.flush() query = curves.find({'conductor': N, 'number': 1}) for curve in query: E = EllipticCurve([int(x) for x in curve['ainvs']]) L = lc.Lfunction_from_elliptic_curve(E) first_zeros = L.find_zeros_via_N(curve['rank'] + 1) if len(first_zeros) > 1: if not first_zeros[-2] == 0: print("problem") z = float(first_zeros[-1]) Lfunction_data = {} Lfunction_data['first_zero'] = z Lfunction_data[ 'description'] = 'Elliptic curve L-function for curve ' + str( curve['label'][:-1]) Lfunction_data['degree'] = 2 Lfunction_data['signature'] = [0, 1] Lfunction_data['eta'] = [ (1.0, 0), ] Lfunction_data['level'] = N Lfunction_data['special'] = { 'type': 'elliptic', 'label': curve['label'][:-1] } coeffs = [] for k in range(1, 11): coeffs.append(CC(E.an(k) / sqrt(k))) Lfunction_data['coeffs'] = [(float(x.real()), float(x.imag())) for x in coeffs] Lfunctions.insert(Lfunction_data)
def curve(self, P=None, verbose=False): # Given a point on X_E(7), return the symplectically isomorphic curve. if P==None: return self.Eab tP = tuple(P) try: return self.P2C[tP] except KeyError: pass if verbose: print("mapping P={} to its curve".format(P)) if self._symplectic and P==[0,1,0]: E2 = self.Eab if self._base==QQ: E2 = E2.minimal_model() self.P2C[tP] = [E2] if verbose: print("P={} is the base point, returning {}".format(P,E2.ainvs())) return [E2] ds = (d for d in (self.d11(P), self.d22(P), self.d33(P), self.d44(P))) d = 0 while d==0: d = ds.next() if verbose: print("d={}".format(d)) if not self._symplectic: d *= self.DeltaE() c4 = self.C(P) * d**2 c6 = -self.K(P) * d**3 E2 = EllipticCurve([0,0,0,-c4/48,-c6/864]) assert E2.j_invariant()==self.j(P) if self._base==QQ: E2 = E2.minimal_model() self.P2C[tP] = [E2] if verbose: print("P={} is a general point, returning {}".format(P,E2.ainvs())) return [E2]
def factorize(n, D): """ Recovers the prime factors from a modulus using Cheng's elliptic curve complex multiplication method. More information: Sedlacek V. et al., "I want to break square-free: The 4p - 1 factorization method and its RSA backdoor viability" :param n: the modulus :param D: the discriminant to use to generate the Hilbert polynomial :return: a tuple containing the prime factors """ assert D % 8 == 3, "D should be square-free" zmodn = Zmod(n) pr = zmodn["x"] H = pr(hilbert_class_polynomial(-D)) Q = pr.quotient(H) j = Q.gen() try: k = j * _polynomial_inverse((1728 - j).lift(), H) except ArithmeticError as err: # If some polynomial was not invertible during XGCD calculation, we can factor n. p = gcd(int(err.args[1].lc()), n) return int(p), int(n // p) E = EllipticCurve(Q, [3 * k, 2 * k]) while True: x = zmodn.random_element() logging.debug(f"Calculating division polynomial of Q{x}...") z = E.division_polynomial(n, x=Q(x)) try: d, _, _ = _polynomial_xgcd(z.lift(), H) except ArithmeticError as err: # If some polynomial was not invertible during XGCD calculation, we can factor n. p = gcd(int(err.args[1].lc()), n) return int(p), int(n // p) p = gcd(int(d), n) if 1 < p < n: return int(p), int(n // p)
def test_ecdsa_nonce_reuse(self): p = 115792089210356248762697446949407573530086143415290314195533631308867097853951 a = 115792089210356248762697446949407573530086143415290314195533631308867097853948 b = 41058363725152142129326129780047268409114441015993725554835256314039467401291 p_256 = EllipticCurve(GF(p), [a, b]) gen = p_256.gen(0) n = int(gen.order()) d = randint(1, n - 1) l = randint(1, n - 1) r = int((l * gen).xy()[0]) m1 = getrandbits(n.bit_length()) s1 = pow(l, -1, n) * (m1 + r * d) % n m2 = getrandbits(n.bit_length()) s2 = pow(l, -1, n) * (m2 + r * d) % n for l_, d_ in self.ecdsa_nonce_reuse.attack(n, m1, r, s1, m2, r, s2): self.assertIsInstance(l_, int) self.assertIsInstance(d_, int) if l_ == l and d_ == d: break else: self.fail()
def fix1_qcurve_flag(ec, verbose=False): """ Update ec structure (from nfcurves collection) with the correct q_curves flag. For degree >2 at present we only do trivial tests here which do not require any computation. """ if ec['q_curve']: # keep old True values return ec # Easy sufficient tests in all degrees qc = False if ec['cm']: qc = True elif all(c == '0' for c in ec['jinv'].split(",")[1:]): qc = True if qc: # then we have just set it to True if ec['q_curve'] != qc: if verbose: print("{}: changing q_curve flag from {} to {}".format( ec['label'], ec['q_curve'], qc)) ec['q_curve'] = qc return ec # else if degree != 2 just replace possibly false negatives with '?' if ec['degree'] > 2: qc = '?' # if ec['q_curve'] != qc: # print("{}: changing q_curve flag from {} to {}".format(ec['label'],ec['q_curve'],qc)) ec['q_curve'] = qc return ec # else (degree 2 only for now) do the work (knowing that E does # not have CM and j(E) is not in Q) K = FIELD(ec['field_label']) sigma = K.K().galois_group()[1] # Compute the Q-curve flag from scratch N = ideal_from_string(K.K(), ec['conductor_ideal']) if sigma(N) != N: qc = False else: # construct and check the curve ainvsK = parse_ainvs(K.K(), ec['ainvs']) E = EllipticCurve(ainvsK) qc = is_Q_curve(E) if ec['q_curve'] != qc: if verbose: print("{}: changing q_curve flag from {} to {}".format( ec['label'], ec['q_curve'], qc)) ec['q_curve'] = qc return ec
def do_offline() -> None: print('{"command":"sign", "params":{"command":"info"}}') p = int(input('p: ')) a = int(input('a: ')) b = int(input('b: ')) Hxy = eval(input('H: ')) Gxy = eval(input('G: ')) E = EllipticCurve(GF(p), [a, b]) H = E(Hxy) G = E(Gxy) key = pohlig(E, H, G) print(f'solved: {key}') # now we forge a signed request with the 'flag' command print('forging request...') request = make_request('flag', name='fbctf') message = json.dumps(request, sort_keys=True) R, S = sign(message, key, E.order(), G) sig = base64.b64encode(bytes(str(R) + '|' + str(S), 'utf-')) request['sig'] = sig.decode('utf-8') print(json.dumps(request, sort_keys=True))
def smart_attack(tildeE, tildeG, tildeA, p, a, b, lift="x"): assert tildeE.order() == p # The curve is anomalous E = EllipticCurve(Qp(p), [a, b]) # Lift of curve to Qp if lift == "x": G = E.lift_x(ZZ(tildeG.xy()[0])) # Might have to take the other lift. A = E.lift_x(ZZ(tildeA.xy()[0])) # Might have to take the other lift. else: G = E.lift_y(ZZ(tildeG.xy()[1])) A = E.lift_y(ZZ(tildeA.xy()[1])) p_times_G = p * G p_times_A = p * A x_G, y_G = p_times_G.xy() x_A, y_A = p_times_A.xy() phi_G = -(x_G / y_G) # Map to Z/pZ phi_A = -(x_A / y_A) # Map to Z/pZ k = phi_A / phi_G # Solve the discrete log in Z/pZ (aka do a division) return k.expansion()[0]
def elliptic_curve_jump(info): label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec).minimal_model() # Now we do have a valid curve over Q, but it might # not be in the database. lmfdb_label = db.ec_curves.lucky({'ainvs': EC_ainvs(E)}, 'lmfdb_label') if lmfdb_label is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(lmfdb_label) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: return elliptic_curve_jump_error('', info)
def challenge(): # Define the curve p = 310717010502520989590157367261876774703 a = 2 b = 3 E = EllipticCurve(GF(p), [a, b]) # generator's public key G = E.point( ( 179210853392303317793440285562762725654, 105268671499942631758568591033409611165, ) ) # alice's public key A = E.point( ( 280810182131414898730378982766101210916, 291506490768054478159835604632710368904, ) ) # bob's public key B = E.point( ( 272640099140026426377756188075937988094, 51062462309521034358726608268084433317, ) ) # Ciphertext iv = "07e2628b590095a5e332d397b8a59aa7" encrypted_flag = "8220b7c47b36777a737f5ef9caa2814cf20c1c1ef496ec21\ a9b4833da24a008d0870d3ac3a6ad80065c138a2ed6136af" n = pohlig_hellman(G, A, E) secret = (n * B).xy()[0] print(decrypt_flag(secret, iv, encrypted_flag))
def render_isogeny_class(iso_class): info = {} credit = 'John Cremona' label=iso_class C = base.getDBConnection() data = C.ellcurves.isogeny.find_one({'label': label}) if data is None: return "No such isogeny class" ainvs = [int(a) for a in data['ainvs_for_optimal_curve']] E = EllipticCurve(ainvs) info = {'label': label} info['optimal_ainvs'] = ainvs if 'imag' in data: info['imag']=data['imag'] if 'real' in data: info['real']=data['real'] info['rank'] = data['rank'] info['isogeny_matrix']=latex(matrix(eval(data['isogeny_matrix']))) info['modular_degree']=data['degree'] #info['f'] = ajax_more(E.q_eigenform, 10, 20, 50, 100, 250) info['f'] = web_latex(E.q_eigenform(10)) G = E.isogeny_graph(); n = G.num_verts() G.relabel(range(1,n+1)) # proper cremona labels... info['graph_img'] = image_src(G.plot(edge_labels=True)) curves = data['label_of_curves_in_the_class'] info['curves'] = list(curves) info['download_qexp_url'] = url_for('download_qexp', limit=100, ainvs=','.join([str(a) for a in ainvs])) info['download_all_url'] = url_for('download_all', label=str(label)) friends=[('Elliptic Curve %s' % l , "/EllipticCurve/Q/%s" % l) for l in data['label_of_curves_in_the_class']] friends.append(('Quadratic Twist', "/quadratic_twists/%s" % (label))) friends.append(('Modular Form', url_for("emf.render_classical_modular_form_from_label",label="%s" %(label)))) info['friends'] = friends t= "Elliptic Curve Isogeny Class %s" % info['label'] bread = [('Elliptic Curves ', url_for("rational_elliptic_curves")),('isogeny class %s' %info['label'],' ')] return render_template("elliptic_curve/iso_class.html", info = info,bread=bread, credit=credit,title = t)
def make_extra_data(label,number,ainvs,gens): """ C is a database elliptic curve entry. Returns a dict with which to update the entry. Data fields needed in C already: 'ainvs', 'lmfdb_label', 'gens', 'number' """ E = EllipticCurve([int(a) for a in ainvs]) data = {} # convert from a list of strings to a single string, e.g. from ['0','0','0','1','1'] to '[0,0,0,1,1]' data['xainvs'] = ''.join(['[',','.join(ainvs),']']) data['equation'] = web_latex(E) data['signD'] = int(E.discriminant().sign()) data['local_data'] = [{'p': int(ld.prime().gen()), 'ord_cond':int(ld.conductor_valuation()), 'ord_disc':int(ld.discriminant_valuation()), 'ord_den_j':int(max(0,-(E.j_invariant().valuation(ld.prime().gen())))), 'red':int(ld.bad_reduction_type()), 'rootno':int(E.root_number(ld.prime().gen())), 'kod':web_latex(ld.kodaira_symbol()).replace('$',''), 'cp':int(ld.tamagawa_number())} for ld in E.local_data()] Etw, Dtw = E.minimal_quadratic_twist() if Etw.conductor()==E.conductor(): data['min_quad_twist'] = {'label':label, 'disc':int(1)} else: # Later this should be changed to look for xainvs but now all curves have ainvs minq_ainvs = [str(c) for c in Etw.ainvs()] r = curves.find_one({'jinv':str(E.j_invariant()), 'ainvs':minq_ainvs}) minq_label = "" if r is None else r['label'] data['min_quad_twist'] = {'label':minq_label, 'disc':int(Dtw)} from lmfdb.elliptic_curves.web_ec import parse_points gens = [E(g) for g in parse_points(gens)] data['heights'] = [float(P.height()) for P in gens] if number==1: data['aplist'] = E.aplist(100,python_ints=True) data['anlist'] = E.anlist(20,python_ints=True) return data
def modular_form_display(label, number): number = int(number) if number < 10: number = 10 if number > 100000: number = 20 if number > 50000: return "OK, I give up." if number > 20000: return "This incident will be reported to the appropriate authorities." if number > 9600: return "You have been banned from this website." if number > 4800: return "Seriously." if number > 2400: return "I mean it." if number > 1200: return "Please stop poking me." if number > 1000: number = 1000 E = EllipticCurve(str(label)) modform = E.q_eigenform(number) modform_string = web_latex_split_on_pm(modform) return modform_string