Beispiel #1
0
def isogenous_curves(j, l=None, Phi=None, multiplicities=True, E=None):
    field = j.parent()
    x = PolynomialRing(field, 'x').gen()
    if Phi == None:
        Phi = ClassicalModularPolynomialDatabase()[l]
    f = Phi(x, j)
    if not multiplicities:
        if E == None:
            return [i[0] for i in f.roots() for _ in range(i[1])]
        return [(i[0], elkies_mod_poly(E, i[0],
                                       Phi.degree() // 2)) for i in f.roots()
                for _ in range(i[1])]
    return f.roots()
Beispiel #2
0
def is_supersingular(E):
    p = E.base_field().characteristic()
    j = E.j_invariant()
    if not j in GF(p**2):
        return False
    if p <= 3:
        return j == 0
    F = ClassicalModularPolynomialDatabase()[2]
    x = PolynomialRing(GF(p**2), 'x').gen()
    f = F(x, j)
    roots = [i[0] for i in f.roots() for _ in range(i[1])]
    if len(roots) < 3:
        return False
    vertices = [j, j, j]
    m = floor(log(p, 2)) + 1
    for k in range(1, m + 1):
        for i in range(3):
            f = F(x, roots[i])
            g = x - vertices[i]
            a = f.quo_rem(g)[0]
            vertices[i] = roots[i]
            attempt = a.roots()
            if len(attempt) == 0:
                return False
            roots[i] = attempt[0][0]
    return True
Beispiel #3
0
def is_torsion_bicyclic(E, l):
    order = E.order()
    v = ZZ.valuation(l)
    n = v(order)
    if n < 2:
        return False
    D = E.trace_of_frobenius()**2 - 4 * E.base_field().order()
    if not (l**2).divides(D):
        return False
    Phi = ClassicalModularPolynomialDatabase()[l]
    x = PolynomialRing(E.base_field(), 'x').gen()
    return len(Phi(E.j_invariant(), x).roots()) > 2
Beispiel #4
0
def elkies_mod_poly(E, j2, l):
    j = E.j_invariant()
    Phi = ClassicalModularPolynomialDatabase()[l]
    x = PolynomialRing(E.base_field(), 'x').gen()
    f = Phi(j2, x)
    F1 = f.derivative()(j)
    g = Phi(j, x)
    F2 = g.derivative()(j2)
    try:
        lam = E.a6() / E.a4() * F1 / F2 * j * (-18) / l
        aa = -lam**2 / (j2 * (j2 - 1728) * l**4 * 48)
        bb = -lam**3 / (j2**2 * (j2 - 1728) * l**6 * 864)
        return EllipticCurve(E.base_field(), [aa, bb])
    except:
        return None
 def endomorphism_index(self):
     j = self._j_invariant
     field = j.parent()
     t = self._domain.trace_of_frobenius()
     self._trace = t
     Dv = t**2 - 4 * self._domain.base_field().order()
     D = Dv.squarefree_part()
     v = Dv // D
     if D % 4 != 1:
         v = v // 4
     ls = [(i[0], i[1] // 2) for i in list(factor(v)) if i[1] >= 2]
     u = 1
     for a in ls:
         l = a[0]
         Phi = ClassicalModularPolynomialDatabase()[l]
         dist = len(find_descending_path(j, Phi, l, special=False)) - 1
         ex = a[1] - dist
         u *= l**ex
     self._index = u
Beispiel #6
0
def elkies_first_step(E, l, lam):
    q = E.base_field().order()
    lam = GF(l)(lam)
    Phi = ClassicalModularPolynomialDatabase()[l]
    x = PolynomialRing(E.base_field(), 'x').gen()
    f = Phi(x, E.j_invariant())
    j_1, j_2 = f.roots()[0][0], f.roots()[1][0]
    E1 = elkies_mod_poly(E, j_1, l)
    try:
        I = EllipticCurveIsogeny(E, None, E1, l)
    except:
        I = l_isogeny(E, E1, l)
    r = lam.multiplicative_order()
    k = GF(q ** r)
    ext = extend_field(E, r)
    try:
        P = ext.lift_x(I.kernel_polynomial().any_root(k))
    except:
        return j_2
    if ext(P[0] ** q, P[1] ** q) == Integer(lam) * P:
        return j_1
    else:
        return j_2
Beispiel #7
0
    def hecke_matrix(self, L):
        r"""
        This function returns the `L^{\text{th}}` Hecke matrix.

        INPUT:

        - ``self`` -- SupersingularModule object

        - ``L`` -- integer, positive

        OUTPUT:
            matrix -- sparse integer matrix

        EXAMPLES:
        This example computes the action of the Hecke operator `T_2`
        on the module of supersingular points on `X_0(1)/F_{37}`::

            sage: S = SupersingularModule(37)
            sage: M = S.hecke_matrix(2)
            sage: M
            [1 1 1]
            [1 0 2]
            [1 2 0]

        This example computes the action of the Hecke operator `T_3`
        on the module of supersingular points on `X_0(1)/F_{67}`::

            sage: S = SupersingularModule(67)
            sage: M = S.hecke_matrix(3)
            sage: M
            [0 0 0 0 2 2]
            [0 0 1 1 1 1]
            [0 1 0 2 0 1]
            [0 1 2 0 1 0]
            [1 1 0 1 0 1]
            [1 1 1 0 1 0]

        .. note::

            The first list --- list_j --- returned by the supersingular_points
            function are the rows *and* column indexes of the above hecke
            matrices and its ordering should be kept in mind when interpreting
            these matrices.

        AUTHORS:

        - David Kohel -- [email protected]

        - Iftikhar Burhanuddin -- [email protected]
        """
        if L in self.__hecke_matrices:
            return self.__hecke_matrices[L]
        SS, II = self.supersingular_points()
        if L == 2:
            # since T_2 gets computed as a side effect of computing the supersingular points
            return self.__hecke_matrices[2]
        Fp2 = self.__finite_field
        h = len(SS)
        R = self.base_ring()
        T_L = MatrixSpace(R, h)(0)
        S, X = Fp2['x'].objgen()

        if L in [3, 5, 7, 11]:
            for i in range(len(SS)):
                ss_i = SS[i]
                phi_L_in_x = Phi_polys(L, X, ss_i)
                rts = phi_L_in_x.roots()
                for r in rts:
                    T_L[i, int(II[r[0]])] = r[1]
        else:
            DBMP = ClassicalModularPolynomialDatabase()
            phi_L = DBMP[L]
            M, (x, y) = Fp2['x,y'].objgens()
            phi_L = phi_L(x, y)

            # As an optimization, we compute the coefficients of y and evaluate
            # them, since univariate polynomial evaluation is much faster than
            # multivariate evaluation (in Sage :-( ).
            uni_coeff = [phi_L(x,0).univariate_polynomial()] + \
                              [phi_L.coefficient(y**i).univariate_polynomial() for
                                          i in range(1,phi_L.degree(y)+1)]
            for i in range(len(SS)):
                ss_i = SS[i]
                ## We would do the eval below, but it is too slow (right now).
                #phi_L_in_x = phi_L(X, ss_i)

                phi_L_in_x = S([f(ss_i) for f in uni_coeff])
                rts = phi_L_in_x.roots()
                for r in rts:
                    T_L[i, int(II[r[0]])] = r[1]

        self.__hecke_matrices[L] = T_L
        return T_L
Beispiel #8
0
def elkies_next_step(j_0, j_1, l, lam):
    Phi = ClassicalModularPolynomialDatabase()[l]
    R = PolynomialRing(j_0.parent(), 'x')
    x = R.gen()
    f = R(Phi(x, j_1) / (x - j_0))
    return f.roots()[0][0]