Exemplo n.º 1
0
def generate_curve(p, d):
    '''
    Essentially Algorithm 7.5.9
    Args:
        p:

    Returns:
        parameters a, b for the curve
    '''
    # calculate quadratic nonresidue
    g = gen_QNR(p, d)
    # find discriminant
    new_d = gen_discriminant(0)
    uv = cornacchia_smith(p, new_d)
    while jacobi(new_d, p) != 1 or uv is None:
        new_d = gen_discriminant(new_d)
        uv = cornacchia_smith(p, new_d)
    u, v = uv   # storing the result of cornacchia. u^2 + v^2 * |D| = 4*p

    # check for -d = 3 or 4
    # Choose one possible output
    # Look at param_gen for comparison.
    answer = []

    if new_d == -3:
        x = -1
        for i in range(0, 6):
            answer.append((0, x))
            x = (x * g) % p
        return answer

    if new_d == -4:
        x = -1
        for i in range(0, 4):
            answer.append((x, 0))
            x = (x * g) % p
        return answer

    # otherwise compute the hilbert polynomial
    _, t, _ = hilbert(new_d)
    s = [i % p for i in t]
    j = equation.root_Fp(s, p) # Find a root for s in Fp. Algorithm 2.3.10
    c = j * inverse(j - 1728, p) % p
    r = -3 * c % p
    s = 2 * c % p

    return [(r, s), (r * g * g % p, s * (g**3) % p)]
Exemplo n.º 2
0
def choose_discriminant(n, start=0):
    '''
    First step of Algorithm
    Args:
        n:
        start:

    Returns:
        d: The discriminant
        ms: The possible orders

    '''
    d = gen_discriminant(start)
    uv = cornacchia_smith(n, d)
    jac = jacobi(d, n)
    if jac == 0:
        raise ValueError("n is not prime.")
    while jac != 1 or uv is None:
        if n % d == 0:
            raise ValueError("n is not prime.")
        d = gen_discriminant(d)
        if d < -10**6:
            raise ValueError("Discriminant cannot be found under bound 10^7.")
        uv = cornacchia_smith(n, d)
        jac = jacobi(d, n)
        if jac == 0:
            raise ValueError("n is not prime.")
    u, v = uv

    default = [n+1+u, n+1-u]
    if d == -4:
        ms = default + [n+1+2*v, n+1-2*v]
    elif d == -3:
        ms = default + [n+1+(u+3*v)/2, n+1-(u+3*v)/2, n+1+(u-3*v)/2, n+1-(u-3*v)/2]
    else:
        ms = default

    return d, ms
Exemplo n.º 3
0
def curve_parameters(d, p):
    '''
    Modified Algorithm 7.5.9 for the use of ecpp
    Args:
        d: discriminant
        p: number for prime proving

    Returns:
        a list of (a, b) parameters for
    '''
    g = gen_QNR(p, d)
    #g = nzmath.ecpp.quasi_primitive(p, d==-3)

    u, v = cornacchia_smith(p, d)
    # go without the check for result of cornacchia because it's done by previous methods.
    if jacobi(d, p) != 1:
        raise ValueError('jacobi(d, p) not equal to 1.')

        # check for -d = 3 or 4
    # Choose one possible output
    # Look at param_gen for comparison.
    answer = []

    if d == -3:
        x = -1 % p
        for i in range(0, 6):
            answer.append((0, x))
            x = (x * g) % p
        return answer

    if d == -4:
        x = -1 % p
        for i in range(0, 4):
            answer.append((x, 0))
            x = (x * g) % p
        return answer

    # otherwise compute the hilbert polynomial
    _, t, _ = hilbert(d)
    s = [int(i % p) for i in t]
    j = equation.root_Fp(s, p) # Find a root for s in Fp. Algorithm 2.3.10
    c = j * inverse(j - 1728, p) % p
    r = -3 * c % p
    s = 2 * c % p

    return [(r, s), (r * g * g % p, s * (g**3) % p)]