/* Once we have found a D and q, this will find a curve and point. * Returns: 0 (composite), 1 (didn't work), 2 (success) * It's debatable what to do with a 1 return. */ static int find_curve(mpz_t a, mpz_t b, mpz_t x, mpz_t y, long D, int poly_index, mpz_t m, mpz_t q, mpz_t N, int maxroots) { long nroots, npoints, i, rooti, unity, result; mpz_t g, t, t2; mpz_t* roots = 0; /* TODO: A better way to do this, I believe, would be to have the root * finder set up as an iterator. That way we'd get the first root, * try to find a curve, and probably we'd be done. Only if we tried * 10+ points on that root would we get another root. This would * probably be set up as a stack (array) of polynomials plus one * saved root (for when we solve a degree 2 poly). */ /* Step 1: Get the roots of the Hilbert class polynomial. */ nroots = find_roots(D, poly_index, N, &roots, maxroots); if (nroots == 0) return 1; /* Step 2: Loop selecting curves and trying points. * On average it takes about 3 points, but we'll try 100+. */ mpz_init(g); mpz_init(t); mpz_init(t2); npoints = 0; result = 1; for (rooti = 0; result == 1 && rooti < 50*nroots; rooti++) { /* Given this D and root, select curve a,b */ select_curve_params(a, b, g, D, roots, rooti % nroots, N, t); if (mpz_sgn(g) == 0) { result = 0; break; } /* See Cohen 5.3.1, page 231 */ unity = (D == -3) ? 6 : (D == -4) ? 4 : 2; for (i = 0; result == 1 && i < unity; i++) { if (i > 0) update_ab(a, b, D, g, N); npoints++; select_point(x, y, a, b, N, t, t2); result = ecpp_check_point(x, y, m, q, a, N, t, t2); } } if (npoints > 10 && get_verbose_level() > 0) printf(" # point finding took %ld points\n", npoints); if (roots != 0) { for (rooti = 0; rooti < nroots; rooti++) mpz_clear(roots[rooti]); Safefree(roots); } mpz_clear(g); mpz_clear(t); mpz_clear(t2); return result; }
/* Once we have found a D and q, this will find a curve and point. * Returns: 0 (composite), 1 (didn't work), 2 (success) * It's debatable what to do with a 1 return. */ static int find_curve(mpz_t a, mpz_t b, mpz_t x, mpz_t y, long D, mpz_t m, mpz_t q, mpz_t N) { long nroots, npoints, i, rooti, unity, result; mpz_t g, t, t2; mpz_t* roots = 0; int verbose = get_verbose_level(); /* Step 1: Get the roots of the Hilbert class polynomial. */ nroots = find_roots(D, N, &roots); if (nroots == 0) return 1; /* Step 2: Loop selecting curves and trying points. * On average it takes about 3 points, but we'll try 100+. */ mpz_init(g); mpz_init(t); mpz_init(t2); npoints = 0; result = 1; for (rooti = 0; result == 1 && rooti < 50*nroots; rooti++) { /* Given this D and root, select curve a,b */ select_curve_params(a, b, g, D, roots, rooti % nroots, N, t); if (mpz_sgn(g) == 0) { result = 0; break; } /* See Cohen 5.3.1, page 231 */ unity = (D == -3) ? 6 : (D == -4) ? 4 : 2; for (i = 0; result == 1 && i < unity; i++) { if (i > 0) update_ab(a, b, D, g, N); npoints++; select_point(x, y, a, b, N, t, t2); result = ecpp_check_point(x, y, m, q, a, N, t, t2); } } if (verbose && npoints > 10) printf(" # point finding took %ld points\n", npoints); if (roots != 0) { for (rooti = 0; rooti < nroots; rooti++) mpz_clear(roots[rooti]); Safefree(roots); } mpz_clear(g); mpz_clear(t); mpz_clear(t2); return result; }