コード例 #1
0
def find_elliptic_curve(k, K, m_t):
    '''
    INPUT: 

    - ``k`` -- a base field

    - ``K`` -- an extension of K of degree n.

    - ``m_t`` -- a list of tuple containing a integer and a set of candidates 
      for the trace.

    OUTPUT: 
    
    - An elliptic curve defined over k with the required properties.

    - An integer case, depending on the value of the j-invariant of said 
      elliptic curve.

    - An integer m statisfying the properties described in isom_elliptic which 
      we will be using to compute Gaussian periods.

    ..NOTE::

        The case j = 0 or 1728 are not implemented yet. They shall raise 
        NotImplementedError.

    EXAMPLES:
    
    sage: R.<X> = PolynomialRing(GF(5))

    sage: f = R.irreducible_element(19, algorithm = 'random')

    sage: K = GF(5**19, names = 'x', modulus = f)

    sage: m_t = [(229,{0, 1, 3})]

    sage: find_elliptic(GF(5), K, m_t)

    (Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5,
    0,
    229)

    ALGORITHM:

    TODO : Doc is deprecated, to be redone.

    Function that finds an elliptic curve with the required charateristics, 
    those given in the function isom_elliptic.

    First, we have to determine if m is composite, a prime power or a power of 
    p, the characteristic of the base field. The first case is not implemented 
    yet. 
    We also note that the m given should satisfies several conditions based
    on the characteristic and the degree of K. See the docstrings of 
    isom_elliptic for more information.

    - If m is a power of p, the charateristic of the base field k, then we shall
      proceed as follow :

        We pick a random curve E/k and we set down t = Tr_k(Fr_E), for the
        curve to be what we want, we need :

          - t not zero,
          - (Z/m)* = <t> x S or #<t> = n 
          - m divides #E/K but not #E/L, for any intermediate extension L 
            of K/k; so we can construct points of order m such that their 
            abscissas or ordinates span exactly K. Or that we haven't any point
            of order m in any sub-extension.

        Then we test those conditions for both E and its quadratic twist, if one
        of them meet the requirements, we return it and its trace. If no 
        elliptic curves are found an error is returned.

    - If m is primer power, then we shall proceed as follow :

        We have m = l^r, for l a prime. For this method to work, we need l to 
        be an Elkies prime. A prime l is an Elkies prime for an elliptic curve 
        if the charateristic polynomial of the aforesaid elliptic curve splits 
        in GF(l).

        For now, we pick a random curve E/k and for it to work, if we set down 
        t = Tr_k(Fr_E), we need the following :

          - We have x**2 - tx + q = (x - a)(x - b) mod m, meaning the polynomial
            splits in Z/m,
          - (Z/m)* = <a> x S, with #<a> = n, 
          - ord_m(a) < ord_m(b),
          - m divides #E/K but not #E/L, for any intermediate extension L 
            of K/k; so we can construct points of order m such that their 
            abscissas or ordinates span exactly K.

        Once again, we test all that for both E and its quadratic twist; if one 
        them meet the requirements, we return it, its trace and a tuple
        containing the root a and t mod m. If none are found, there is 
        something wrong.


    - If m is composite, TODO.
    '''
    p = k.characteristic()
    q = k.cardinality()
    n = K.degree()
    m = m_t[0]
    S_t = m_t[1]
    compteur = 0

    #We start by the special cases j = 1728, 0
    E_j1728 = EllipticCurve(j = k(1728))

    if q%4 != 1:
        # If q != 1 mod 4, then there's no 4th root of unity, then magically
        # all the quartic twist are already in k and the trace is 0. We just
        # have to test the only curve y² = x³ + x.
        compteur += 1
        if 0 in S_t:
            return E_j1728, 0, compteur
    else:
        # If q = 1 mod 4, then the trace is not 0, and we have to try four
        # trace to see which is the best candidate.
        g = k.unit_gens()[0]
        c = g**((q-1)/4)
        t = E_j1728.trace_of_frobenius()
        L = [(t*(c**i).lift(), g**i) for i in range(4)]

        for i in range(4):
            compteur += 1
            if Integers(m)(L[i][0]) in S_t:
                # E, case, t
                return E_j1728.quartic_twist(L[i][1]), 1, compteur

    E_j0 = EllipticCurve(j = k(0))

    if q%6 != 1:
        # Same as before, if q != 1 mod 6, there's no 6th root of unity in
        # GF(q) and the trace is 0 (that's pretty quick reasoning.. :D).
        # Justification will come later.
        compteur += 1
        if 0 in S_t:
            return E_j0, 0, compteur
    else:
        g = k.unit_gens()[0]
        c = g**((q-1)/6)
        t = E_j0.trace_of_frobenius()
        L = [(t*(c**i).lift(), g**i) for i in range(6)]

        for l in L:
            if Integers(m)(l[0]) in S_t:
                return E_j0.sextic_twist(l[1]), 2, compteur

    # General case
    for j in k:
        if j == 0 or j == k(1728):
            continue

        E = EllipticCurve(j = j)
        t = E.trace_of_frobenius()
        L = [(t, E), (-t, E.quadratic_twist())]

        for l in L:
            compteur +=1
            if Integers(m)(l[0]) in S_t:
                return l[1], 0, compteur

    # If no elliptic curve has been found.
    return None, -1
コード例 #2
0
ファイル: Rainselliptic.py プロジェクト: brieulle/Rains-pinch
def find_elliptic_curve(k, K, m_t):
    '''
    INPUT: 

    - ``k`` -- a base field,

    - ``K`` -- an extension of K of degree n,

    - ``m_t`` -- a list of tuple containing an integer and a set of candidates 
      for the trace.

    OUTPUT: 
    
    - An elliptic curve defined over k with the required properties.

    - An integer case, depending on the value of the j-invariant or the 
      the supersingularity of said elliptic curve.

    EXAMPLES:
    
    sage: R.<X> = PolynomialRing(GF(5))

    sage: f = R.irreducible_element(19, algorithm = 'random')

    sage: K = GF(5**19, names = 'x', modulus = f)

    sage: m_t = (229,{2})

    sage: find_elliptic_curve(GF(5), K, m_t)

    (Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 5, 1)

    ALGORITHM:

    The goal is to pick an elliptic curve of which the trace of its Frobenius 
    t is among the right class modulo m, the ones in S_t. We do that in order to
    have point of order m only on E/GF(q^n) or above, since then the abscissas 
    of a point of order m will span GF(q^n) and we'll be able to compute the 
    elliptic periods as it was planned.

    We start by looking at the two special cases j = 1728 or 0. If q is not 1 
    modulo 4 and 3 respectively, then the curves are supersingular (t = 0) and 
    if 0 is among the good traces, they are to be treated like the other 
    curves.

    If for j = 0 we have q = 1 mod 3, then we have to tests E(j = 0) and all of
    its sextic twists. Once again if t is in S_t, then we return the right 
    curves and the case 2 to compute the periods accordingly.

    If for j = 1728 we have q = 1 mod 4, then we have to tests  E(j = 1728) and
    all of its quartic twists. If one the trace is in S_t, we return the right 
    curves and the case 1.

    If j != 0 and 1728, then we tests all the elements of GF(q) to find the 
    right curve. For each j we test if t or -t is in S_t and return the curve 
    accordingly plus the case 0.

    If no curves are found, we return None and the case -1, which will raise an
    runtimeError in the main function.
    '''
    p = k.characteristic()
    q = k.cardinality()
    m = m_t[0]
    S_t = m_t[1]

    #We start by the special cases j = 1728, 0
    E_j1728 = EllipticCurve(j = k(1728))

    if q%4 != 1:
        # If q != 1 mod 4, then there's no 4th root of unity, then magically
        # all the quartic twist are already in k and the trace is 0. We just
        # have to test the only curve y� = x� + x.
        if 0 in S_t:
            return E_j1728, 0
    else:
        # If q = 1 mod 4, then the trace is not 0, and we have to try four
        # trace to see which is the best candidate.
        g = k.unit_gens()[0]
        c = g**((q-1)/4)
        t = E_j1728.trace_of_frobenius()
        L = [(t*(c**i).centerlift(), g**i) for i in range(4)]

        for i in range(4):
            if Integers(m)(L[i][0]) in S_t:
                # E, case, t
                return E_j1728.quartic_twist(L[i][1]), 1

    E_j0 = EllipticCurve(j = k(0))

    if q%3 != 1:
        # Same as before, if q != 1 mod 6, there's no 6th root of unity in
        # GF(q) and the trace is 0 (that's pretty quick reasoning.. :D).
        # Justification will come later. Since q = 1 mod 2, if q = 1 mod 3
        # then q = 1 mod 6.
        if 0 in S_t:
            return E_j0, 0
    else:
        g = k.unit_gens()[0]
        c = g**((q-1)/6)
        t = E_j0.trace_of_frobenius()
        L = [(t*(c**i).centerlift(), g**i) for i in range(6)]

        for l in L:
            if Integers(m)(l[0]) in S_t:
                return E_j0.sextic_twist(l[1]), 2

    # General case
    for j in k:
        if j == 0 or j == k(1728):
            continue

        E = EllipticCurve(j = j)
        t = E.trace_of_frobenius()
        L = [(t, E), (-t, E.quadratic_twist())]

        for l in L:
            if Integers(m)(l[0]) in S_t:
                return l[1], 0

    # If no elliptic curve has been found.
    return None, -1