def padic_field(): """ Return a random p-adic field modulo n with p at most 10000 and precision between 10 and 100. EXAMPLES:: sage: import sage.rings.tests sage: sage.rings.tests.padic_field() ...-adic Field with capped relative precision ... """ from sage.all import ZZ, Qp prec = ZZ.random_element(x=10, y=100) p = ZZ.random_element(x=2, y=10**4 - 30).next_prime() return Qp(p, prec)
def attack(base, multiplication_result): """ Solves the discrete logarithm problem using Smart's attack. More information: Smart N. P., "The discrete logarithm problem on elliptic curves of trace one" :param base: the base point :param multiplication_result: the point multiplication result :return: l such that l * base == multiplication_result """ curve = base.curve() gf = curve.base_ring() p = gf.order() assert curve.trace_of_frobenius() == 1, f"Curve should have trace of Frobenius = 1." lift_curve = EllipticCurve(Qp(p), list(map(lambda a: int(a) + p * ZZ.random_element(1, p), curve.a_invariants()))) lifted_base = p * _lift(lift_curve, base, gf) lifted_multiplication_result = p * _lift(lift_curve, multiplication_result, gf) lb_x, lb_y = lifted_base.xy() lmr_x, lmr_y = lifted_multiplication_result.xy() return int(gf((lmr_x / lmr_y) / (lb_x / lb_y)))
def padic_data(label, p): try: N, iso, number = split_lmfdb_label(label) except AttributeError: return abort(404) info = {'p': p} if db.ec_curvedata.lookup(label, label_col='lmfdb_label', projection="rank") == 0: info['reg'] = 1 elif number == '1': data = db.ec_padic.lucky({'lmfdb_iso': N + '.' + iso, 'p': p}) if data is None: info['reg'] = 'no data' else: val = int(data['val']) aprec = data['prec'] reg = Qp(p, aprec)(int(data['unit']), aprec - val) << val info['reg'] = web_latex(reg) else: info['reg'] = "no data" return render_template("ec-padic-data.html", info=info)
def padic_data(): info = {} label = request.args['label'] p = int(request.args['p']) info['p'] = p N, iso, number = split_lmfdb_label(label) if request.args['rank'] == '0': info['reg'] = 1 elif number == '1': data = db.ec_padic.lucky({'lmfdb_iso': N + '.' + iso, 'p': p}) if data is None: info['reg'] = 'no data' else: val = int(data['val']) aprec = data['prec'] reg = Qp(p, aprec)(int(data['unit']), aprec - val) << val info['reg'] = web_latex(reg) else: info['reg'] = "no data" return render_template("ec-padic-data.html", info=info)
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 compute_frob_matrix_and_cp_H2(f, p, prec, **kwargs): """ Return a p-adic matrix approximating the action of Frob on H^2 of a surface or abelian variety, and its characteristic polynomial over ZZ Input: - f defining the curve or surface - p, prime - prec, a lower bound for the desired precision to run the computations, this increases the time exponentially - kwargs, keyword arguments to be passed to controlledreduction Output: - `prec`, the minimum digits absolute precision for approximation of the Frobenius - a matrix representing an approximation of Frob matrix with at least `prec` digits of absolute precision - characteristic polynomial of Frob on H^2 - the number of classes omitted by working with primitive cohomology Note: if given two or one univariate polynomial, we will try to change the model over Qpbar, in order to work with an odd and monic model """ K = Qp(p, prec=prec + 10) OK = ZpCA(p, prec=prec) Rf = f.parent() R = f.base_ring() if len(Rf.gens()) == 2: if min(f.degrees()) != 2: raise NotImplementedError("Affine curves must be hyperelliptic") x, y = f.variables() if f.degree(x) == 2: f = f.substitute(x=y, y=x) # Get Weierstrass equation # y^2 + a*y + b == 0 b, a, _ = map(R['x'], R['x']['y'](f).monic()) # y^2 + a*y + b == 0 --> (2y + a)^2 = a^2 - 4 b f = a**2 - 4 * b f = find_monic_and_odd_model(f.change_ring(K), p) cp1 = HyperellipticCurve(f.change_ring( GF(p))).frobenius_polynomial().reverse() F1 = hypellfrob(p, max(3, prec), f.lift()) F1 = F1.change_ring(OK) cp, frob_matrix = from_H1_to_H2(cp1, F1, tensor=kwargs.get('tensor', False)) frob_matrix = frob_matrix.change_ring(K) shift = 0 elif len(Rf.gens()) == 3 and f.total_degree() == 4 and f.is_homogeneous(): # Quartic plane curve if p < 17: prec = max(4, prec) else: prec = max(3, prec) if 'find_better_model' in kwargs: model = kwargs['find_better_model'] else: # there is a speed up, but we may also lose some nice numerical stability from the original sparseness model = binomial(2 + (prec - 1) * f.total_degree(), 2) < 2 * len(list(f**(prec - 1))) cp1, F1 = controlledreduction( f, p, min_abs_precision=prec, frob_matrix=True, threads=1, find_better_model=model, ) # change ring to OK truncates precision accordingly F1 = F1.change_ring(OK) cp, frob_matrix = from_H1_to_H2(cp1, F1, tensor=kwargs.get('tensor', False)) shift = 0 elif len(Rf.gens()) == 4 and f.total_degree() in [4, 5 ] and f.is_homogeneous(): shift = 1 # we will not see the polarization # Quartic surface if f.total_degree() == 4: if p == 3: prec = max(5, prec) elif p == 5: prec = max(4, prec) elif p < 43: prec = max(3, prec) else: prec = max(2, prec) elif f.total_degree() == 5: if p in [3, 5]: prec = max(7, prec) elif p <= 23: prec = max(6, prec) else: prec = max(5, prec) OK = ZpCA(p, prec=prec) # a rough estimate if it is worth to find a non degenerate mode for f if 'find_better_model' in kwargs: model = kwargs['find_better_model'] else: # there is a speed up, but we may also lose some nice numerical stability from the original sparseness model = binomial(3 + (prec - 1) * f.total_degree(), 3) < 4 * len(list(f**(prec - 1))) threads = kwargs.get('threads', ncpus) cp, frob_matrix = controlledreduction(f, p, min_abs_precision=prec, frob_matrix=True, find_better_model=model, threads=threads) frob_matrix = frob_matrix.change_ring(OK).change_ring(K) else: raise NotImplementedError("At the moment we only support:\n" " - Quartic or quintic surfaces\n" " - Jacobians of quartic curves\n" " - Jacobians of hyperelliptic curves\n") return prec, cp, frob_matrix, shift