示例#1
0
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)
示例#2
0
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)))
示例#3
0
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)
示例#4
0
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)
示例#5
0
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