The following tiny PARI function implements the ECM. It
generates an error message along with a usually nontrivial factor of
exactly when the ECM succeeds.
{ECM(N, m)= local(E); E = ellinit([0,0,0,random(N),1]*Mod(1,N)); print("E: y^2 = x^3 + ",lift(E[4]),"x+1, P=[0,1]"); ellpow(E,[0,1]*Mod(1,N),m); \\ this fails if and only if we win! }The following two functions are also useful:
{lcmfirst(B) = local(L,i); L=1; for(i=2,B,L=lcm(L,i)); return(L); } numpoints(a,p) = return(p+1 - ellap(ellinit([0,0,0,a,1]),p));
First we will try the program on a small integer , then we will try
it on the
at the top of this lecture. (ECM uses the random
function, so the results of your run may differ from the one below.)
? N = 5959; \\ This number motivated the ECM last time. \\ Recall what happened when we tried to factor 5959 using the p-1 method. ? m = lcmfirst(20); \\ B = 20. ? Mod(2,N)^m-1 %108 = Mod(5944, 5959) ? gcd(5944,5959) %109 = 1 \\ bummer! \\ Now we try the ECM: ? ECM(N,m) E: y^2 = x^3 + 1201x+1, P=[0,1] %112 = [Mod(666, 5959), Mod(3229, 5959)] ? ECM(N,m) E: y^2 = x^3 + 1913x+1, P=[0,1] *** impossible inverse modulo: Mod(101, 5959). \\ Wonderful!! There's a factor--------/\ ? factor(numpoints(1913,101)) %120 = [2 4] \\ #E(Z/101) is 16-power-smooth, [7 1] \\ so ECM sees 101. ? factor(numpoints(1913,59)) %119 = [2 1] \\ #E(Z/59) is 29-power-smooth, [29 1] \\ so ECM doesn't see 59. \\ Here's the view from another angle: ? E = ellinit([0,0,0,1752,0]*Mod(1,5959)); ? P = [0,1]*Mod(1,5959); ? ellpow(E,P,2) %127 = [Mod(4624, 5959), Mod(1495, 5959)] ? ellpow(E,P,3) %128 = [Mod(3435, 5959), Mod(1031, 5959)] ? ellpow(E,P,4) %129 = [Mod(803, 5959), Mod(5856, 5959)] ? ellpow(E,P,8) %133 = [Mod(1347, 5959), Mod(2438, 5959)] ? ellpow(E,P,m) *** impossible inverse modulo: Mod(101, 5959).
Now we are ready to try the big integer from the begining of the lecture.
? N = 800610470601655221392794180058088102053408423; ? B = 100; ? m = lcmfirst(B); ? ECM(N,m); E: y^2 = x^3 + 273687051132207711452727265152539544370874547x+1, P=[0,1] ... many tries .. ? ECM(N,m); E: y^2 = x^3 + 174264237886300715545169749498695137077020788x+1, P=[0,1] ? B=1000; \\ give up and try a bigger B. ? m=lcmfirst(B); ? ECM(N,m); E: y^2 = x^3 + 652986182461202633808585244537305097270008449x+1, P=[0,1] ... many tries ... ? ECM(N,m); E: y^2 = x^3 + 755060727645891482095225151281965348765197238x+1, P=[0,1] ? B=10000; \\ try an even bigger B ? m=lcmfirst(B); ? ECM(N,m); E: y^2 = x^3 + 722355978919416556225676818691766898771312229x+1, P=[0,1] ? ECM(N,m); E: y^2 = x^3 + 124781379199538996805045456359983628056546634x+1, P=[0,1] ? ECM(N,m); E: y^2 = x^3 + 350310715627251979278144271594744514052364663x+1, P=[0,1] ? ECM(N,m); E: y^2 = x^3 + 39638500146503230913823829562620410547947307x+1, P=[0,1] *** impossible inverse modulo: Mod(1004320322301182911, 800610470601655221392794180058088102053408423).Thus
? N1 = 1004320322301182911; N2 = N / N1; ? ECM(N1,m); E: y^2 = x^3 + 725771039569085210x+1, P=[0,1] *** impossible inverse modulo: Mod(1406051123, 1004320322301182911). ? ECM(N2,m); E: y^2 = x^3 + 573369475441522110156437806x+1, P=[0,1] *** impossible inverse modulo: Mod(2029256729, 797166454590134548773760793).Now
? N22 = 392836669307471617 %173 = 392836669307471617 ? ECM(N22,m) E: y^2 = x^3 + 133284810657519512x+1, P=[0,1] %174 = [0] ? ECM(N22,m) E: y^2 = x^3 + 368444010842952211x+1, P=[0,1] %175 = [Mod(236765299763600601, 392836669307471617), Mod(63845045623767003, 392836669307471617)] ? ECM(N22,m) E: y^2 = x^3 + 245772885854824846x+1, P=[0,1] %176 = [0] ? ECM(N22,m) E: y^2 = x^3 + 33588046732320063x+1, P=[0,1] *** impossible inverse modulo: Mod(615433499, 392836669307471617).This time it took a long time to factor