示例#1
0
def id_dirichlet(fun, N, n):
    N = Integer(N)
    if N == 1:
        return (1, 1)
    p2 = valuation(N, 2)
    N2 = 2**p2
    Nodd = N // N2
    Nfact = list(factor(Nodd))
    #print "n = "+str(n)
    #for j in range(20):
    #    print "chi(%d) = e(%d/%d)"%(j+2, fun(j+2,n), n)
    plist = [z[0] for z in Nfact]
    ppows = [z[0]**z[1] for z in Nfact]
    ppows2 = list(ppows)
    idems = [1 for z in Nfact]
    proots = [primitive_root(z) for z in ppows]
    # Get CRT idempotents
    if p2 > 0:
        ppows2.append(N2)
    for j in range(len(plist)):
        exps = [1 for z in idems]
        if p2 > 0:
            exps.append(1)
        exps[j] = proots[j]
        idems[j] = crt(exps, ppows2)
    idemvals = [fun(z, n) for z in idems]
    # now normalize to right root of unity base
    idemvals = [
        idemvals[j] * euler_phi(ppows[j]) / n for j in range(len(idemvals))
    ]
    ans = [
        Integer(mod(proots[j], ppows[j])**idemvals[j])
        for j in range(len(proots))
    ]
    ans = crt(ans, ppows)
    # There are cases depending on 2-part of N
    if p2 == 0:
        return (N, ans)
    if p2 == 1:
        return (N, crt([1, ans], [2, Nodd]))
    if p2 == 2:
        my3 = crt([3, 1], [N2, Nodd])
        if fun(my3, n) == 0:
            return (N, crt([1, ans], [4, Nodd]))
        else:
            return (N, crt([3, ans], [4, Nodd]))
    # Final case 2^3 | N

    my5 = crt([5, 1], [N2, Nodd])
    test1 = fun(my5, n) * N2 / 4 / n
    test1 = Integer(mod(5, N2)**test1)
    minusone = crt([-1, 1], [N2, Nodd])
    test2 = (fun(minusone, n) * N2 / 4 / n) % (N2 / 4)
    if test2 > 0:
        test1 = Integer(mod(-test1, N2))
    return (N, crt([test1, ans], [N2, Nodd]))
示例#2
0
def id_dirichlet(fun, N, n):
    N = Integer(N)
    if N == 1:
        return (1, 1)
    p2 = valuation(N, 2)
    N2 = 2 ** p2
    Nodd = N / N2
    Nfact = list(factor(Nodd))
    # print "n = "+str(n)
    # for j in range(20):
    #    print "chi(%d) = e(%d/%d)"%(j+2, fun(j+2,n), n)
    plist = [z[0] for z in Nfact]
    ppows = [z[0] ** z[1] for z in Nfact]
    ppows2 = list(ppows)
    idems = [1 for z in Nfact]
    proots = [primitive_root(z) for z in ppows]
    # Get CRT idempotents
    if p2 > 0:
        ppows2.append(N2)
    for j in range(len(plist)):
        exps = [1 for z in idems]
        if p2 > 0:
            exps.append(1)
        exps[j] = proots[j]
        idems[j] = crt(exps, ppows2)
    idemvals = [fun(z, n) for z in idems]
    # now normalize to right root of unity base
    idemvals = [idemvals[j] * euler_phi(ppows[j]) / n for j in range(len(idemvals))]
    ans = [Integer(mod(proots[j], ppows[j]) ** idemvals[j]) for j in range(len(proots))]
    ans = crt(ans, ppows)
    # There are cases depending on 2-part of N
    if p2 == 0:
        return (N, ans)
    if p2 == 1:
        return (N, crt([1, ans], [2, Nodd]))
    if p2 == 2:
        my3 = crt([3, 1], [N2, Nodd])
        if fun(my3, n) == 0:
            return (N, crt([1, ans], [4, Nodd]))
        else:
            return (N, crt([3, ans], [4, Nodd]))
    # Final case 2^3 | N

    my5 = crt([5, 1], [N2, Nodd])
    test1 = fun(my5, n) * N2 / 4 / n
    test1 = Integer(mod(5, N2) ** test1)
    minusone = crt([-1, 1], [N2, Nodd])
    test2 = (fun(minusone, n) * N2 / 4 / n) % (N2 / 4)
    if test2 > 0:
        test1 = Integer(mod(-test1, N2))
    return (N, crt([test1, ans], [N2, Nodd]))
def make_curve(q, t, r, k, D, debug=False):
    """
    Description:
    
        Finds the curve equation for the elliptic curve (q,t,r,k,D) using the Complex Multiplication method
    
    Input:
    
        q - size of prime field
        t - trace of Frobenius
        r - size of prime order subgroup
        k - embedding degree
        D - (negative) fundamental discriminant
    
    Output:
    
        E - elliptic curve over F_q with trace t,
            a subgroup of order r with embedding degree k,
            and fundamental discriminant D
    
    """
    assert is_valid_curve(q, t, r, k,
                          D), 'Invalid input. No curve exists.'  # check inputs
    if debug:
        print('Tested input')
    poly = hilbert_class_polynomial(D)  # compute hilbert class polynomial
    if debug:
        print('Computed Hilbert class polynomial')
    check = False
    j_inv = poly.any_root(GF(q))  # find j-invariant
    orig_curve = EllipticCurve(GF(q), j=j_inv)  # make a curve
    E = orig_curve
    check = test_curve(q, t, r, k, D, E)  # see if this is the right curve
    twist = False
    if not check:  # not the right curve, use quadratic twist
        E = E.quadratic_twist()
        check = test_curve(q, t, r, k, D, E)
        if check:
            twist = True
        else:  # twist didnt work => j = 0 or 1728
            if j_inv == 0:  # for j = 0, use sextic twists
                prim = primitive_root(q)
                i = 1
                while t != E.trace_of_frobenius() and i < 6:
                    E = orig_curve.sextic_twist(power_mod(prim, i, q))
                    i += 1
            elif j_inv == 1728:  # for j = 1728, use quartic twists
                prim = primitive_root(q)
                i = 1
                while t != E.trace_of_frobenius() and i < 4:
                    E = orig_curve.quartic_twist(power_mod(prim, i, q))
                    i += 1
            else:  # twist didnt work and j != 0, 1728. this should never happen, so write input to a file for debugging
                print(
                    'Error. Quadratic twist failed to find the correct curve with j != 0, 1728. Logging output to debug.txt'
                )  # this line should never be reached'
                f = open('debug.txt', 'w')
                f.write('Twist: ' + str(twist) + '\n')
                f.write('q: ' + str(q) + '\n')
                f.write('t: ' + str(t) + '\n')
                f.write('r: ' + str(r) + '\n')
                f.write('k: ' + str(k) + '\n')
                f.write('D: ' + str(D) + '\n')
                f.write('E: ' + str(E) + '\n')
                f.write('orig_curve: ' + str(orig_curve))
                f.close()
                return False
            check = test_curve(q, t, r, k, D, E)
            twist = True
    if not check:  # didnt find a curve. this should never happen, so write input to a file for debugging
        print('Error. Failed to find curve. Logging output to debug.txt')
        f = open('debug.txt', 'w')
        f.write('Twist: ' + str(twist) + '\n')
        f.write('q: ' + str(q) + '\n')
        f.write('t: ' + str(t) + '\n')
        f.write('r: ' + str(r) + '\n')
        f.write('k: ' + str(k) + '\n')
        f.write('D: ' + str(D) + '\n')
        f.write('E: ' + str(E) + '\n')
        f.write('orig_curve: ' + str(orig_curve))
        f.close()
        return False
    return E
def make_curve(q,t,r,k,D,debug=False):
    """
    Description:
    
        Finds the curve equation for the elliptic curve (q,t,r,k,D) using the Complex Multiplication method
    
    Input:
    
        q - size of prime field
        t - trace of Frobenius
        r - size of prime order subgroup
        k - embedding degree
        D - (negative) fundamental discriminant
    
    Output:
    
        E - elliptic curve over F_q with trace t,
            a subgroup of order r with embedding degree k,
            and fundamental discriminant D
    
    """
    assert is_valid_curve(q,t,r,k,D), 'Invalid input. No curve exists.' # check inputs
    if debug:
        print('Tested input')
    poly = hilbert_class_polynomial(D) # compute hilbert class polynomial
    if debug:
        print('Computed Hilbert class polynomial')
    check = False
    j_inv = poly.any_root(GF(q)) # find j-invariant    
    orig_curve = EllipticCurve(GF(q), j=j_inv) # make a curve
    E = orig_curve
    check = test_curve(q,t,r,k,D,E) # see if this is the right curve
    twist = False
    if not check: # not the right curve, use quadratic twist
        E = E.quadratic_twist()
        check = test_curve(q,t,r,k,D,E)
        if check:
            twist = True
        else: # twist didnt work => j = 0 or 1728
            if j_inv == 0: # for j = 0, use sextic twists
                prim = primitive_root(q)
                i = 1
                while t != E.trace_of_frobenius() and i < 6:
                    E = orig_curve.sextic_twist(power_mod(prim,i,q))
                    i+=1
            elif j_inv == 1728: # for j = 1728, use quartic twists
                prim = primitive_root(q)
                i = 1
                while t != E.trace_of_frobenius() and i < 4:
                    E = orig_curve.quartic_twist(power_mod(prim,i,q))
                    i+=1
            else: # twist didnt work and j != 0, 1728. this should never happen, so write input to a file for debugging
                print('Error. Quadratic twist failed to find the correct curve with j != 0, 1728. Logging output to debug.txt') # this line should never be reached'
                f = open('debug.txt', 'w')
                f.write('Twist: ' + str(twist) + '\n')
                f.write('q: ' + str(q) + '\n')
                f.write('t: ' + str(t) + '\n')
                f.write('r: ' + str(r) + '\n')
                f.write('k: ' + str(k) + '\n')
                f.write('D: ' + str(D) + '\n')
                f.write('E: ' + str(E) + '\n')
                f.write('orig_curve: ' + str(orig_curve))
                f.close()
                return False
            check = test_curve(q,t,r,k,D,E)
            twist = True
    if not check: # didnt find a curve. this should never happen, so write input to a file for debugging
        print('Error. Failed to find curve. Logging output to debug.txt')
        f = open('debug.txt', 'w')
        f.write('Twist: ' + str(twist) + '\n')
        f.write('q: ' + str(q) + '\n')
        f.write('t: ' + str(t) + '\n')
        f.write('r: ' + str(r) + '\n')
        f.write('k: ' + str(k) + '\n')
        f.write('D: ' + str(D) + '\n')
        f.write('E: ' + str(E) + '\n')
        f.write('orig_curve: ' + str(orig_curve))
        f.close()
        return False
    return E