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)]
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
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)]