Beispiel #1
0
def siegel_series_dim2(q, p):
    det_4 = q.Gram_det() * ZZ(4)
    c = q.content_order()
    fd = fundamental_discriminant(-det_4)
    f = (valuation(det_4, p) - valuation(fd, p)) / ZZ(2)
    return (_siegel_series_dim2(p, c, f + 1) -
            kronecker_symbol(fd, p) * p * X * _siegel_series_dim2(p, c, f))
Beispiel #2
0
def make_curve(k,D):
    """
    Description:
    
        Find all MNT curves with embedding degree k and fundamental discriminant D
    
    Input:
    
        k - embedding degree
        D - (negative) fundamental discriminant
    
    Output:
    
        curves - list of the aforementioned elliptic curves;
                 each curve is represented as a tuple (q,t,r,k,D)
    
    """
    assert k == 3 or k== 4 or k == 6, 'Invalid embedding degree'
    assert fundamental_discriminant(D) == D, 'Invalid discriminant'
    if k == 3:
        curves = _mnt_subcall(k,D, 24,lambda x: ((x % 24 == 19) and kronecker(6,x) == 1), 6, 3, -3, lambda x: (x -3 )//6, lambda x: (x+3)//6, lambda l: 6*l - 1, lambda l: -6*l - 1, lambda l: 12*l*l - 1)
    if k == 4:
        curves = _mnt_subcall(k,D,-8, lambda x: ( (x % 8 == 3) and kronecker(-2, x) ==1) or (x == 2) or (x == 8), 3, 2, 1, lambda x: (x-2)//3, lambda x: (x-1)//3, lambda l: -l, lambda l: l+1, lambda l: l*l + l + 1)
    if k == 6:
        curves = _mnt_subcall(k,D,-8, lambda x: (x % 8 == 3) and kronecker(-2, x) == 1, 6, 5, 1, lambda x: (x+1)//6, lambda x: (x-1)//6, lambda l: 2*l + 1, lambda l: -2*l + 1, lambda l: 4*l*l + 1)
    for c in curves:
        assert is_valid_curve(c[0],c[1],c[2],c[3],c[4]), 'Invalid output'
        assert k == c[3], 'Bug in code'
        assert D == c[4], 'Bug in code'
    return curves
Beispiel #3
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 method(num_bits,k,D,y,max_trials=10000): 
    """
    Description:
    
        Runs the Dupont-Enge-Morain method
    
    Input:
    
        num_bits - number of bits for the prime order r
        k - embedding degree
        D - (negative) fundamental discriminant
        y - coefficient of D in the CM equation
        num_times - number of iterations of the while loop when searching for q
        
    Output:
    
        (q,t,r,k,D) - elliptic curve;
                      returns (0,0,0,k,D) if no r was found, and (0,0,r,k,D) if no q was found
    
    """
    assert fundamental_discriminant(D) == D, 'Invalid discriminant'
    assert k >= 1, 'Invalid embedding degree'
    t,r = _method_pt1(num_bits,k,D,y)
    if r == 0:
        return 0,0,0,k,D
    return _method_pt2(t,r,k,D,y,max_trials)
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 method(num_bits, k, D, y, max_trials=10000):
    """
    Description:
    
        Runs the Dupont-Enge-Morain method
    
    Input:
    
        num_bits - number of bits for the prime order r
        k - embedding degree
        D - (negative) fundamental discriminant
        y - coefficient of D in the CM equation
        num_times - number of iterations of the while loop when searching for q
        
    Output:
    
        (q,t,r,k,D) - elliptic curve;
                      returns (0,0,0,k,D) if no r was found, and (0,0,r,k,D) if no q was found
    
    """
    assert fundamental_discriminant(D) == D, 'Invalid discriminant'
    assert k >= 1, 'Invalid embedding degree'
    t, r = _method_pt1(num_bits, k, D, y)
    if r == 0:
        return 0, 0, 0, k, D
    return _method_pt2(t, r, k, D, y, max_trials)
 def _fc__unramfactor(self, content, det_4):
     chi = kronecker_character(-det_4)
     pfacs = prime_factors(det_4)
     fd = fundamental_discriminant(-det_4)
     l = [(p, valuation(content, p),
           (valuation(det_4, p) - valuation(fd, p)) / 2) for p in pfacs]
     return reduce(operator.mul,
                   [self._fc__unramfactor_at_p(p, ci, fi, chi)
                    for (p, ci, fi) in l])
def make_curve(k, D):
    """
    Description:
    
        Find all MNT curves with embedding degree k and fundamental discriminant D
    
    Input:
    
        k - embedding degree
        D - (negative) fundamental discriminant
    
    Output:
    
        curves - list of the aforementioned elliptic curves;
                 each curve is represented as a tuple (q,t,r,k,D)
    
    """
    assert k == 3 or k == 4 or k == 6, 'Invalid embedding degree'
    assert fundamental_discriminant(D) == D, 'Invalid discriminant'
    if k == 3:
        curves = _mnt_subcall(
            k, D, 24, lambda x: (
                (x % 24 == 19) and kronecker(6, x) == 1), 6, 3, -3, lambda x:
            (x - 3) // 6, lambda x: (x + 3) // 6, lambda l: 6 * l - 1,
            lambda l: -6 * l - 1, lambda l: 12 * l * l - 1)
    if k == 4:
        curves = _mnt_subcall(
            k, D, -8, lambda x:
            ((x % 8 == 3) and kronecker(-2, x) == 1) or (x == 2) or (x == 8),
            3, 2, 1, lambda x: (x - 2) // 3, lambda x: (x - 1) // 3,
            lambda l: -l, lambda l: l + 1, lambda l: l * l + l + 1)
    if k == 6:
        curves = _mnt_subcall(k, D, -8, lambda x:
                              (x % 8 == 3) and kronecker(-2, x) == 1, 6, 5, 1,
                              lambda x: (x + 1) // 6, lambda x: (x - 1) // 6,
                              lambda l: 2 * l + 1, lambda l: -2 * l + 1,
                              lambda l: 4 * l * l + 1)
    for c in curves:
        assert is_valid_curve(c[0], c[1], c[2], c[3], c[4]), 'Invalid output'
        assert k == c[3], 'Bug in code'
        assert D == c[4], 'Bug in code'
    return curves
Beispiel #9
0
def test_promise(r,k,D):
    """
    Description:
    
        Tests that r,k,D is a valid input to the Cocks-Pinch method
    
    Input:
    
        r - prime
        k - embedding degree    
        D - (negative) funadmental discriminant
    
    Output:
    
        bool - true iff (r,k,D) is a valid input to the Cocks-Pinch method
    
    """
    bool = (kronecker(D,r) == 1) # D is a square mod r
    bool = bool and ( (r-1) % k ==0) # k | r-1
    bool = bool and (D == fundamental_discriminant(D)) # check that D is a fundamental discriminant
    return bool
def test_promise(r, k, D):
    """
    Description:
    
        Tests that r,k,D is a valid input to the Cocks-Pinch method
    
    Input:
    
        r - prime
        k - embedding degree    
        D - (negative) funadmental discriminant
    
    Output:
    
        bool - true iff (r,k,D) is a valid input to the Cocks-Pinch method
    
    """
    bool = (kronecker(D, r) == 1)  # D is a square mod r
    bool = bool and ((r - 1) % k == 0)  # k | r-1
    bool = bool and (D == fundamental_discriminant(D)
                     )  # check that D is a fundamental discriminant
    return bool
Beispiel #11
0
def is_valid_curve(q,t,r,k,D): 
    """
    Description:
    
        Tests that (q,t,r,k,D) is a valid elliptic curve
    
    Input:
    
        q - size of prime field
        t - trace of Frobenius
        r - size of prime order subgroup
        k - embedding degree
        D - (negative) fundamental discriminant
    
    Output:
    
        bool - true iff there exists an elliptic curve over F_q with trace t, a subgroup of order r with embedding degree k, and fundamental discriminant D
    
    """
    if q == 0 or t == 0 or r == 0 or k == 0 or D == 0:
        return False
    if not is_prime(q):
        return False 
    if not is_prime(r):
        return False
    if not fundamental_discriminant(D) == D:
        return False
    if D % 4 == 0: #check CM equation
        if not is_square(4*(t*t - 4*q)//D):
            return False
    if D % 4 == 1:
        if not is_square((t*t - 4*q)//D):
            return False
    if not (q+1-t) % r == 0: #check r | #E(F_q)
        return False
    if not power_mod(q,k,r) == 1: #check embedding degree is k
        return False
    return True
def run(num_bits, k):
    """
    Description:
    
        Runs the Dupont-Enge-Morain method multiple times until a valid curve is found
    
    Input:
    
        num_bits - number of bits
        k - an embedding degree
    
    Output:
    
        (q,t,r,k,D) - an elliptic curve;
                      if no curve is found, the algorithm returns (0,0,0,k,0)
    
    """
    j, r, q, t = 0, 0, 0, 0
    num_generates = 512
    h = num_bits / (euler_phi(k))
    tried = [(0, 0)]  # keep track of random values tried for efficiency
    for i in range(0, num_generates):
        D = 0
        y = 0
        while (D, y) in tried:  # find a pair that we have not tried
            D = -randint(1,
                         1024)  # pick a small D so that the CM method is fast
            D = fundamental_discriminant(D)
            m = 0.5 * (h - log(-D).n() / (2 * log(2)).n())
            if m < 1:
                m = 1
            y = randint(floor(2**(m - 1)), floor(2**m))
        tried.append((D, y))
        q, t, r, k, D = method(num_bits, k, D, y)  # run DEM
        if q != 0 and t != 0 and r != 0 and k != 0 and D != 0:  # found an answer, so output it
            assert is_valid_curve(q, t, r, k, D), 'Invalid output'
            return q, t, r, k, D
    return 0, 0, 0, k, 0  # found nothing
Beispiel #13
0
def is_valid_curve(q, t, r, k, D):
    """
    Description:
    
        Tests that (q,t,r,k,D) is a valid elliptic curve
    
    Input:
    
        q - size of prime field
        t - trace of Frobenius
        r - size of prime order subgroup
        k - embedding degree
        D - (negative) fundamental discriminant
    
    Output:
    
        bool - true iff there exists an elliptic curve over F_q with trace t, a subgroup of order r with embedding degree k, and fundamental discriminant D
    
    """
    if q == 0 or t == 0 or r == 0 or k == 0 or D == 0:
        return False
    if not is_prime(q):
        return False
    if not is_prime(r):
        return False
    if not fundamental_discriminant(D) == D:
        return False
    if D % 4 == 0:  #check CM equation
        if not is_square(4 * (t * t - 4 * q) // D):
            return False
    if D % 4 == 1:
        if not is_square((t * t - 4 * q) // D):
            return False
    if not (q + 1 - t) % r == 0:  #check r | #E(F_q)
        return False
    if not power_mod(q, k, r) == 1:  #check embedding degree is k
        return False
    return True
def run(num_bits,k):
    """
    Description:
    
        Runs the Dupont-Enge-Morain method multiple times until a valid curve is found
    
    Input:
    
        num_bits - number of bits
        k - an embedding degree
    
    Output:
    
        (q,t,r,k,D) - an elliptic curve;
                      if no curve is found, the algorithm returns (0,0,0,k,0)
    
    """
    j,r,q,t = 0,0,0,0
    num_generates = 512
    h = num_bits/(euler_phi(k))
    tried = [(0,0)] # keep track of random values tried for efficiency
    for i in range(0,num_generates):
        D = 0
        y = 0
        while (D,y) in tried: # find a pair that we have not tried
            D = -randint(1, 1024) # pick a small D so that the CM method is fast
            D = fundamental_discriminant(D)
            m = 0.5*(h - log(-D).n()/(2*log(2)).n())
            if m < 1:
                m = 1
            y = randint(floor(2**(m-1)), floor(2**m))
        tried.append((D,y))
        q,t,r,k,D = method(num_bits,k,D,y) # run DEM
        if q != 0 and t != 0 and r != 0 and k != 0 and D != 0: # found an answer, so output it
            assert is_valid_curve(q,t,r,k,D), 'Invalid output'
            return q,t,r,k,D
    return 0,0,0,k,0 # found nothing
Beispiel #15
0
 def __init__(self, num_zeros, min_D, **kwds):
     self.min_D = min_D
     params = fundamental_discriminant(min_D, -1)
     super(QuadraticImaginary, self).__init__(num_zeros, params, **kwds)