예제 #1
0
def gen_params_from_r(r, k):
    """
    Description:
    
        Finds a fundamental discriminant D to use as input to the Cocks-Pinch method
    
    Input:
    
        r - prime such that r % k == 1
        k - embedding degree  
    
    Output:
        
        r - prime such that r % k == 1
        k - embedding degree
        D - (negative) fundamental discriminant where D is a square mod r
    
    """
    D = -Integer(Mod(int(random() * (1000)), r))
    i = 0
    while not kronecker(
            D, r) == 1:  # expected number of iterations of the while loop is 2
        D = -Integer(Mod(int(random() * (1000)), r))
        i += 1
    D = fundamental_discriminant(D)
    if not (kronecker(D, r) == 1):
        return r, k, 0
    return r, k, D
def small_A_twist(E):
    """
    Description:
        
        Finds a curve isogenous to E that has small A in the curve equation y^2 = x^3 + A*x + B
    
    Input:
    
        E - elliptic curve
    
    Output:
    
        E' - elliptic curve isogenous to E that has small A in the curve equation y^2 = x^3 + A*x + B
    
    """
    a = E.ainvs()[3]
    q = E.base_field().order()
    a = power_mod(Integer(a), -1, q)
    if kronecker(a, q) == -1:
        b = 2
        while kronecker(b, q) == 1:
            b += 1
        a = a * b
    assert kronecker(a, q) == 1
    d = Mod(a, q).sqrt()
    ainvs = [i for i in E.ainvs()]
    ainvs[3] *= d**2
    ainvs[4] *= d**3
    return EllipticCurve(E.base_field(), ainvs)
def small_B_twist(E):
    """
    Description:
        
        Finds a curve isogenous to E that has small B in the curve equation y^2 = x^3 + A*x + B
    
    Input:
    
        E - elliptic curve
    
    Output:
    
        E' - elliptic curve isogenous to E that has small B in the curve equation y^2 = x^3 + A*x + B
    
    """
    b = E.ainvs()[4]
    q = E.base_field().order()
    b = power_mod(Integer(b), -1, q)
    d = 0
    s = Mod(1, q)
    bool = True
    while bool:
        try:
            d = (s * b)
            d = d.nth_root(3)
            d = Integer(d)
            bool = False
        except ValueError as e:
            s += 1
            pass
    ainvs = [i for i in E.ainvs()]
    ainvs[3] *= d**2
    ainvs[4] *= d**3
    return EllipticCurve(E.base_field(), ainvs)
예제 #4
0
def method(r, k, D, max_trials=10000, g=0):
    """
    Description:
        
        Run the Cocks-Pinch method to find an elliptic curve
    
    Input:
    
        r - prime
        k - embedding degree, r % k == 1
        D - (negative) fundamental discriminant where D is a square mod r
        max_trials - the number of integers q to test for primality in the CP method
        g - an element of order k in Z_r^*

    Output:
    
        (q,t) - tuple where q is a prime and t is chosen such that there exists
                an elliptic curve E over F_q with trace t, and r | q+1-t;
                if the algorithm fails to find (q,t), it will return (0,0)
    
    """
    assert test_promise(r, k, D), 'Invalid inputs'
    if g != 0:
        assert power_mod(g, k, r) == 1, 'Invalid inputs'
    else:
        g = find_element_of_order(k, r)
    D = Integer(D)
    t = Integer(g) + 1
    root_d = Integer(Mod(D, r).sqrt())
    u = Integer(Mod((t - 2) * root_d.inverse_mod(r), r))
    q = 1
    j = Integer(0)
    i = Integer(0)
    count = 0
    while (count < max_trials):
        q = Integer((t + i * r)**2 - D * (u + j * r)**2)
        if q % 4 == 0:
            q = q // 4
            if utils.is_suitable_q(q):
                return (q, t + i * r)
            q = 1
        if random() < 0.5:
            j += 1
        else:
            i += 1
        count += 1
    return (0, 0)  # no prime found, so end
예제 #5
0
 def order(h, k, p):
     bool = True
     g = h
     for i in range(1, k):
         bool = bool and g != 1
         g = Mod(g * h, p)
     bool = bool and g == 1
     return bool
예제 #6
0
def test_conrey(nranges=[(20, 100), (200, 1000), (500, 500000)]):
    for n, r in nranges:
        for i in range(n):
            q = randint(1, r)
            print("n, r, i, q = {}, {}, {}, {}".format(n, r, i, q))
            G = DirichletGroup_conrey(q)
            inv = G.invariants()
            cinv = tuple([Mod(g, q).multiplicative_order() for g in G.gens()])
            try:
                assert prod(inv) == G.order()
                assert q <= 2 or G.zeta_order() == inv[0]
                assert cinv == inv
            except:
                print('group error')
                return q, inv, G
            if q > 2:
                m = 0
                while gcd(m, q) != 1:
                    m = randint(1, q)
                chi = G[m]
                n = randint(1, q)
                try:
                    assert chi.multiplicative_order() == Mod(
                        m, q).multiplicative_order()
                    if gcd(n, q) != 1:
                        try:
                            assert chi.logvalue(n) == -1
                        except:
                            print('non unit value error')
                            return chi, n, r
                    elif q < 10 ^ 6:
                        try:
                            ref = chi.sage_character()(n).n().real()
                            new = N(chi(n).real)
                            assert abs(ref - new) < 1e-5
                        except:
                            print('unit value error')
                            return chi, n
                except:
                    print('char error')
                    return chi, n, r
예제 #7
0
 def parity(self):
     number = self.number
     par = 0
     for p, e in self.modfactor():
         if p == 2:
             if number % 4 == 3:
                 par = 1 - par
         else:
             phi2 = (p - 1) / Integer(2) * p**(e - 1)
             if Mod(number, p**e)**phi2 != 1:
                 par = 1 - par
     return par
예제 #8
0
def IsSquareInQp(x, p):
    if x == 0:
        return true
    # Check parity of valuation
    v = valuation(x, p)
    if v % 2:
        return false
    # Renormalise to get a unit
    x //= p**v
    # Reduce mod p and conclude
    if p == 2:
        return Mod(x, 8) == 1
    else:
        return kronecker_symbol(x, p) == 1
def _method_pt1(num_bits, k, D, y):
    a = Integer(-D * y**2)
    R = PolynomialRing(ZZ, 'x')
    f = R.cyclotomic_polynomial(k)(x - 1).polynomial(base_ring=R)
    g = (a + (x - 2)**2).polynomial(base_ring=R)
    r = Integer(f.resultant(g))
    if (Mod(r, k) == 1) and r > 2**(num_bits - 1) and utils.is_suitable_r(
            r):  # found a valid r, so use it
        F = GF(r)
        f = f.change_ring(F)
        g = g.change_ring(F)
        t = Integer(f.gcd(g).any_root())
        return t, r
    else:
        return 0, 0
예제 #10
0
 def conductor(self):
     cond = Integer(1)
     number = self.number
     for p, e in self.modfactor():
         mp = Mod(number, p**e)
         if mp == 1:
             continue
         if p == 2:
             cond = 4
             if number % 4 == 3:
                 mp = -mp
         else:
             cond *= p
             mp = mp**(p - 1)
         while mp != 1:
             cond *= p
             mp = mp**p
     return cond
예제 #11
0
def dirichlet_character_conrey_galois_orbit_embeddings(N, xi):
    r"""
       Returns a dictionary that maps the Conrey numbers
       of the Dirichlet characters in the Galois orbit of x
       to the powers of $\zeta_{\phi(N)}$ so that the corresponding
       embeddings map the labels.

       Let $\zeta_{\phi(N)}$ be the generator of the cyclotomic field
       of $N$-th roots of unity which is the base field
       for the coefficients of a modular form contained in the database.
       Considering the space $S_k(N,\chi)$, where $\chi = \chi_N(m, \cdot)$,
       if embeddings()[m] = n, then $\zeta_{\phi(N)}$ is mapped to
       $\zeta_{\phi(N)}^n = \mathrm{exp}(2\pi i n /\phi(N))$.
    """
    embeddings = {}
    base_number = 0
    base_number = xi
    embeddings[base_number] = 1
    for n in range(2, N):
        if gcd(n, N) == 1:
            embeddings[Mod(base_number, N)**n] = n
    return embeddings
예제 #12
0
 def multiplicative_order(self):
     return Mod(self.number, self.modulus).multiplicative_order()
예제 #13
0
def NChars(N):
    return ZZ(
        sum([
            1 / euler_phi(Mod(i, N).multiplicative_order()) for i in range(N)
            if gcd(i, N) == 1
        ]))