/************************************************************************* * lenstra.cc -- Use Lenstra's Elliptic Curves Algorithm to factor a * large integer. Works well when p+1+d is a product of small primes, * where p is some factor of n, and d depends on the curve. The algorithm * was taken from "Rational Points on Elliptic Curves", by Silverman/Tate, * pages 133-138. * * Compile: * g++ -s -O4 -o lenstra lenstra.cc * Invoke: * ./lenstra NumbertoFactor InitialK * * ChangeLog: * 951124 -- Created by Ami Fischman * 970204 to 970325 - minor bug fixes and cleaning up - Paul Herman **************************************************************************/ #include #define yes 1 #define no 0 #define K_incr 1 // K += K_incr get new curve when old one bonks out on us #define b_incr 30 // b += b_incr when trying a new curve #define max_tries_b 40 // number of b changes before changing K // Initial point (x, y) determines the shape of the curve #define START_X 1 // x coordinate of the initail point to try #define START_Y 1 // y coordinate of the initail point to try /*************************** * compute_k(Integer K) * * choose k suitible for lenstra's alg. * Lots of people have different "good" k's. ****************************/ Integer compute_k(Integer K) { return LCM(K); // return fact(K); } /*********************** * LenstraFactor(Integer n, Integer K) * * find a factor using Lenstra's eliptical curve algorithm ************************/ Integer LenstraFactor(Integer n, Integer K) { Integer b, c, t, k, g, x, y, tempx, tempy, sum_x, sum_y, slope; int i, bits, newcurve, b_tries; if (n == 6) return (Integer) 2; if (gcd(n,6) != 1) return gcd(n, 6); b = 1; // setup our starting curve k = compute_k(K); bits = log2(k); // i.e. log base 2 b_tries = 0; for (;;) { x = START_X; y = START_Y; // setup our starting points c = (y*y) - (x*x*x) - (b*x); // calc. curve coefficients: // Make sure curve is OK to use (check Discriminant) t = gcd( 4*(b*b*b) + 27*(c*c), n); // calc. Discriminant while (t != 1) { // if 1 max_tries_b) {newcurve = yes;} else for (i=1; i<=bits; i++) { // compute k*(x, y) // using powers of 2 // Double the point {x, y} tempx = x; tempy = 2*y; g = gcd(tempy, n); if (1