Elliptic Curves
<Text-field layout="Heading 1" style="Heading 1">Cubic curves</Text-field>plot([sqrt(x^3-2*x+4),-sqrt(x^3-2*x+4)],x=-2..3);LSUlUExPVEc2Ji0lJ0NVUlZFU0c2JDdZNyQkISIjIiIhJEYsRiw3JCQhM0dMZWt5blAnKT4hIzwkIjNFZUAob1QkKWVuJCEjPTckJCEzZW07SGROdnM+RjEkIjMzOCpbWGxscjwmRjQ3JCQhMzMrdiRmTEkiZj5GMSQiMyZSInpTKFs0WUonRjQ3JCQhM09MTGU5cl1YPkYxJCIzdTFhIkhHaThFKEY0NyQkITM6K10oPW5nIz0+RjEkIjNhaEQkKikqKillPikpRjQ3JCQhM3NtbTtIVSwiKj1GMSQiM18uKjQqek0qKTQ1RjE3JCQhMyYqKlxQNEUrTyU9RjEkIjMhUUFCc0ciMyM+IkYxNyQkITNTTCQzRkgnPSd6IkYxJCIzKFFQNykqemQxTSJGMTckJCEzZ21tVGdCYSpvIkYxJCIzIVxxIio9dzUpKWYiRjE3JCQhM2FtbSJIXyI+I2UiRjEkIjNhKydwOERxKSp5IkYxNyQkITNNTCQzXyE0TnY5RjEkIjN5IUh1JFJOdUw+RjE3JCQhM2ttOy93Zkh3OEYxJCIzM0ghKjMtMzNPP0YxNyQkITM7K11QTS50dDdGMSQiMyRcJmYzcjckbzYjRjE3JCQhM2VtOy8sb2xuNkYxJCIzWWYqbyYpejd6PCNGMTckJCEzJSkqKlwob1dCPjEiRjEkIjMnNDk8KikpXGA+QUYxNyQkITNlSkxMZXBqSiYqRjQkIjM5JmYlMyM+dV1DI0YxNyQkITNVbG07ei9vdCYpRjQkIjNXVSc9ai4lKVtEI0YxNyQkITN1KSoqKipcUFtfXChGNCQiMzkzKlF3W09NRCNGMTckJCEzQSoqKioqXDcpUTdrRjQkIjNjb3Q/QChwLUMjRjE3JCQhM2UqKioqKlxpXilvYEY0JCIzZD1CPG1gKXlAI0YxNyQkITN2bG1UNTBBQFdGNCQiM1FBPTFRSVIhPiNGMTckJCEzT0tMTGVhUiVIJEY0JCIzIUdKNWpKWCw6I0YxNyQkITNrSkxMTG8jKVJCRjQkIjNPJFFMQSlRczVARjE3JCQhM2YqKipcUGZPJUg3RjQkIjNlcU5YRFQ1Zz9GMTckJCEzTVNMTEwzYGxDISM+JCIzJHlUInlwaEc3P0YxNyQkIjMrTCtdaSFmIz0kKUZlcyQiMykqZjtTKClSNmU+RjE3JCQiMystK3Y9eHBlPUY0JCIzdnFGdVpUWzE+RjE3JCQiMzxybTtIMjhJSEY0JCIzRVpwczYlKlthPUYxNyQkIjNgbm0ienBTUyJSRjQkIjNTOyEpWyU0Ikg1PUYxNyQkIjMpR0xMM18/YChcRjQkIjNbUEdsbj1rbzxGMTckJCIzIWZMJGUqKT5weGdGNCQiM2N2YnBGZWpNPEYxNyQkIjN3Kyt2JGY0dC4oRjQkIjNUOnhtRCZcXHIiRjE3JCQiM09QTCRlKkdzdCEpRjQkIjMqSCZwYlZRSzE8RjE3JCQiM1krKytdI1JXOSpGNCQiMzZVMEAjKTRUODxGMTckJCIzOisrREpFPj41RjEkIjMnZVphZVMtenQiRjE3JCQiM0YrXWkhUlUwNyJGMSQiM2kmKTNKI1wkSHo8RjE3JCQiMysrK3Y9UzJMN0YxJCIzdzsiW0w1b2klPUYxNyQkIjNKbW1tInApPU04RjEkIjNiYGcveEFDRD5GMTckJCIzQisrXSg9XUBXIkYxJCIzRyEpZURyZWNHP0YxNyQkIjM1TCRlKlskeipSOkYxJCIzbUItImZmZyNRQEYxNyQkIjNlKytdaUMkcGsiRjEkIjM/SXVJOSZ5V0YjRjE3JCQiM1ttO0gycWNaPEYxJCIzOStLMSI+MXFUI0YxNyQkIjNPK103LiJmRiY9RjEkIjMvbEV5QXZpekRGMTckJCIzWW1tOy9PZ2I+RjEkIjNhIVI3RikpZTR2I0YxNyQkIjN3KipcaWxBRmo/RjEkIjMvMllcKlF4QSVIRjE3JCQiM3lMTEwkKSpwcDsjRjEkIjNRZilbRyxQcjgkRjE3JCQiMylSTCQzeGUsdEFGMSQiM1N4dSlIbCxqTSRGMTckJCIzQ247SGRPPXlCRjEkIjM3IlE4UyNHKEdjJEYxNyQkIjNhKysrRD4jW1ojRjEkIjNjISkpZmQlM05wUEYxNyQkIjNTbm1UJkchZSZlI0YxJCIzLSpHXUcrR1UsJUYxNyQkIjMjUkxMTClRayVvI0YxJCIzImVGXmA2ZC1DJUYxNyQkIjM3K11pU2pFIXojRjEkIjNbOiNIcXVKIilbJUYxNyQkIjNhK11QNDBPIipHRjEkIjNaXCQ9Jm9tcEpaRjE3JCQiIiRGLCQiIiZGLC0lJkNPTE9SRzYmJSRSR0JHJCIjNSEiIiRGLEZfXWxGYF1sLUYmNiQ3WUYpNyRGLyQhM0VlQChvVCQpZW4kRjQ3JEY2JCEzMzgqW1hsbHI8JkY0NyRGOyQhMyZSInpTKFs0WUonRjQ3JEZAJCEzdTFhIkhHaThFKEY0NyRGRSQhM2FoRCQqKSoqKWU+KSlGNDckRkokITNfLio0KnpNKik0NUYxNyRGTyQhMyFRQUJzRyIzIz4iRjE3JEZUJCEzKFFQNykqemQxTSJGMTckRlkkITMhXHEiKj13NSkpZiJGMTckRmhuJCEzYSsncDhEcSkqeSJGMTckRl1vJCEzeSFIdSRSTnVMPkYxNyRGYm8kITMzSCEqMy0zM08/RjE3JEZnbyQhMyRcJmYzcjckbzYjRjE3JEZccCQhM1lmKm8mKXo3ejwjRjE3JEZhcCQhMyc0OTwqKSlcYD5BRjE3JEZmcCQhMzkmZiUzIz51XUMjRjE3JEZbcSQhM1dVJz1qLiUpW0QjRjE3JEZgcSQhMzkzKlF3W09NRCNGMTckRmVxJCEzY290P0AocC1DI0YxNyRGanEkITNkPUI8bWApeUAjRjE3JEZfciQhM1FBPTFRSVIhPiNGMTckRmRyJCEzIUdKNWpKWCw6I0YxNyRGaXIkITNPJFFMQSlRczVARjE3JEZecyQhM2VxTlhEVDVnP0YxNyRGY3MkITMkeVQieXBoRzc/RjE3JEZpcyQhMykqZjtTKClSNmU+RjE3JEZedCQhM3ZxRnVaVFsxPkYxNyRGY3QkITNFWnBzNiUqW2E9RjE3JEZodCQhM1M7ISlbJTQiSDU9RjE3JEZddSQhM1tQR2xuPWtvPEYxNyRGYnUkITNjdmJwRmVqTTxGMTckRmd1JCEzVDp4bUQmXFxyIkYxNyRGXHYkITMqSCZwYlZRSzE8RjE3JEZhdiQhMzZVMEAjKTRUODxGMTckRmZ2JCEzJ2VaYWVTLXp0IkYxNyRGW3ckITNpJikzSiNcJEh6PEYxNyRGYHckITN3OyJbTDVvaSU9RjE3JEZldyQhM2JgZy94QUNEPkYxNyRGanckITNHISllRHJlY0c/RjE3JEZfeCQhM21CLSJmZmcjUUBGMTckRmR4JCEzP0l1STkmeVdGI0YxNyRGaXgkITM5K0sxIj4xcVQjRjE3JEZeeSQhMy9sRXlBdml6REYxNyRGY3kkITNhIVI3RikpZTR2I0YxNyRGaHkkITMvMllcKlF4QSVIRjE3JEZdeiQhM1FmKVtHLFByOCRGMTckRmJ6JCEzU3h1KUhsLGpNJEYxNyRGZ3okITM3IlE4UyNHKEdjJEYxNyRGXFtsJCEzYyEpKWZkJTNOcFBGMTckRmFbbCQhMy0qR11HK0dVLCVGMTckRmZbbCQhMyJlRl5gNmQtQyVGMTckRltcbCQhM1s6I0hxdUoiKVslRjE3JEZgXGwkITNaXCQ9Jm9tcEpaRjE3JEZlXGwkISImRiwtRmpcbDYmRlxdbEZgXWxGXV1sRmBdbC0lK0FYRVNMQUJFTFNHNiRRIng2IlEhRlxobC0lJVZJRVdHNiQ7JCEjP0ZfXWwkIiNJRl9dbDskISNfRl9dbCQiI19GX11s
<Text-field layout="Section" style="Section">The group law and addition formulas</Text-field>ecadd:=proc(A,B,b1,b2) if A[1]=B[1] then if A[2]=-B[2] then "Identity"; else [((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))^2-b2-2*A[1], -(((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))*(((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))^2-b2-3*A[1])+A[2])]; end if; else [((B[2]-A[2])/(B[1]-A[1]))^2-b2-A[1]-B[1], -(((B[2]-A[2])/(B[1]-A[1]))*(((B[2]-A[2])/(B[1]-A[1]))^2-b2-2*A[1]-B[1])+A[2])]; end if; end proc:ecadd([-1,4],[2,5],0,0);NiM3JCMhIikiIiojISQ0IiIjRg==ecadd([2,-3],[2,-3],1,-2);NiM3JCMhI1oiI08jIiNgIiQ7Iw==ecadd([2,-3],[2,3],1,-2);NiNRKUlkZW50aXR5NiI=
<Text-field layout="Heading 1" style="Heading 1"><Font executable="false">Elliptic curves mod p</Font></Text-field>for x from 0 to 10 do [x,modp(x^3+1,11)] end do;NiM3JCIiISIiIg==NiM3JCIiIiIiIw==NiM3JCIiIyIiKg==NiM3JCIiJCIiJw==NiM3JCIiJSIjNQ==NiM3JCIiJkYkNiM3JCIiJyIiKQ==NiM3JCIiKCIiJA==NiM3JCIiKSIiKA==NiM3JCIiKiIiJQ==NiM3JCIjNSIiIQ==countpointsmodp:=proc(b0,b1,b2,p) local c, t; c:=1; for t from 0 to p-1 do c:=c+1+numtheory[legendre](t^3+b2*t^2+b1*t+b0,p); end do; c; end proc:countpointsmodp(1,0,0,11);NiMiIzc=countpointsmodp(1,1,0,541);NiMiJEom
<Text-field layout="Section" style="Section">Application: Encryption via elliptic curves</Text-field>countpointsmodp(1,2,0,1377359);NiMiKHBfUCI=converttopoint:=proc(m,b0,b1,b2,p) local x0, f; x0:=1000*m; f:=x->x^3+b2*x^2+b1*x+b0; while not numtheory[legendre](f(x0),p)= 1 do x0:=x0+1; end do; [x0,modp(f(x0)&^((p+1)/4),p)] end proc:converttopoint(1234,1,2,0,1377359);NiM3JCIoMFNCIiInTCVcJA==gcd(11111,1375269);NiMiIiI=gcd(22222,1375269);NiMiIiI=modp(1/11111,1375269);NiMiJ0FMRw==modp(1/22222,1375269);NiMiJ2g7OQ==
<Text-field layout="Section" style="Section">Application: Elliptic curve method of factorization</Text-field>gcd(modp(2&^(100!),137703491)-1,137703491);NiMiJipRPA==pollardfactor:=proc(m) local a, n; a:=2; n:=1; while gcd(a-1,m)=1 do a:=modp(a&^n,m); n:=n+1; end do; gcd(a-1,m); end proc: pollardfactor(137703491);NiMiJipRPA==modp(2/5,7);NiMiIic=
<Text-field layout="Section" style="Section">Fermat's last theorem</Text-field>sort(expand(q*product((1-q^(4*n))^2*(1-q^(8*n))^2,n = 1..2)),q,ascending);NiMsREkicUc2IiIiIiokRiQiIiYhIiMqJEYkIiIqISIkKiRGJCIjOCIiKSokRiQiI0AhIikqJEYkIiNERi8qJEYkIiNIRjIqJEYkIiNMISInKiRGJCIjUCIjPyokRiQiI1RGOSokRiQiI1hGMiokRiQiI1xGLyokRiQiI2BGMiokRiQiI2hGLyokRiQiI2xGLCokRiQiI3BGKSokRiQiI3RGJg==series(q*product((1-q^(4*n))^2*(1-q^(8*n))^2,n = 1..2),q = 0,10);NiMrK0kicUc2IiIiIkYmISIjIiImISIkIiIqLUkiT0dJKnByb3RlY3RlZEdGLTYjRiYiIzg=series(q*product((1-q^(4*n))^2*(1-q^(8*n))^2,n = 1 .. 7),q = 0,30);NiMrM0kicUc2IiIiIkYmISIjIiImISIkIiIqIiInIiM4IiIjIiM8ISIiIiNEISM1IiNILUkiT0dJKnByb3RlY3RlZEdGNTYjRiYiI0w=for t from 2 to 10 do [ithprime(t),countpointsmodp(0,-1,0,ithprime(t))] end do;NiM3JCIiJCIiJQ==NiM3JCIiJiIiKQ==NiM3JCIiKCIiKQ==NiM3JCIjNiIjNw==NiM3JCIjOCIiKQ==NiM3JCIjPCIjOw==NiM3JCIjPiIjPw==NiM3JCIjQiIjQw==NiM3JCIjSCIjUw==coeff(expand(q*product((1-q^(4*n))^2*(1-q^(8*n))^2,n = 1 .. 16)),q^65);NiMhIzc=
<Text-field layout="Section" style="Section">Notes: Elliptic Curve Calculations</Text-field>ecaddprojective:=proc(A,B,b1,b2) if A[3]=0 then return(B) else if B[3]=0 then return(A) else if A[1]=B[1] then if A[2]=-B[2] then return([0,1,0]) else return([((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))^2-b2-2*A[1], -(((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))*(((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))^2-b2-3*A[1])+A[2]),1]) end if; else return([((B[2]-A[2])/(B[1]-A[1]))^2-b2-A[1]-B[1], -(((B[2]-A[2])/(B[1]-A[1]))*(((B[2]-A[2])/(B[1]-A[1]))^2-b2-2*A[1]-B[1])+A[2]),1]) end if; end if; end if; end proc: ecpointmultiple:=proc(A,b1,b2,k) local q, r, l, i; l:=convert(k,base,2); q:=[0,1,0]; r:=[A[1],A[2],A[3]]; for i from 1 to nops(l) do if l[i]= 1 then q:=ecaddprojective(q,r,b1,b2) end if; r:=ecaddprojective(r,r,b1,b2); end do; return(q); end proc:ecpointmultiple([-1,4,1],0,0,3);NiM3JSMiJ0YqKUgiJiwvJSMiKiFRSW87IigsMTcpIiIiecaddprojectivemodp:=proc(A,B,b1,b2,p) if A[3]=0 then return(B) else if B[3]=0 then return(A) else if modp(A[1],p)=modp(B[1],p) then if modp(A[2],p)=modp(-B[2],p) then return([0,1,0]) else return([modp(((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))^2-b2-2*A[1],p), modp(-(((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))*(((3*A[1]^2+2*b2*A[1]+b1)/(2*A[2]))^2-b2-3*A[1])+A[2]),p),1]) end if; else return([modp(((B[2]-A[2])/(B[1]-A[1]))^2-b2-A[1]-B[1],p), modp(-(((B[2]-A[2])/(B[1]-A[1]))*(((B[2]-A[2])/(B[1]-A[1]))^2-b2-2*A[1]-B[1])+A[2]),p),1]) end if; end if; end if; end proc: ecpointmultiplemodp:=proc(A,b1,b2,k,p) local q, r, l, i; l:=convert(k,base,2); q:=[0,1,0]; r:=[A[1],A[2],A[3]]; for i from 1 to nops(l) do if l[i]= 1 then q:=ecaddprojectivemodp(q,r,b1,b2,p) end if; r:=ecaddprojectivemodp(r,r,b1,b2,p); end do; return(q); end proc:ecpointmultiplemodp([1234005, 349433, 1],2,0,11111,1377359);NiM3JSIoN1Y2IiInYScpXCIiIg==ecpointmultiplemodp([1114312, 498654, 1],2,0,22222,1377359);NiM3JSInMyxyIiheWEsiIiIiecpointmultiplemodp([710108, 1324551, 1],2,0,283322,1377359);NiM3JSIod2IyIiIoZHJJIiIiIg==ecpointmultiplemodp([1075576, 1307157, 1],2,0,141661,1377359);NiM3JSIoMFNCIiInTCVcJCIiIg==ecfactor:=proc(m) local k, kbinary, b0, b1, b2, n, a, q, r; for a from 1 to 40 do k:=(a+10)!; b2:=0; b1:=a; b0:=-a; if 1<gcd(-4*a^3-27*a^2,m) then return(gcd(-4*a^3-27*a^2,m)); end if; q:=[1,1,1]; r:=[0,1,0]; kbinary:=convert(k,base,2); for n from 1 to nops(kbinary) do if kbinary[n]=1 then r:=ecaddprojective(r,q,b1,b2); if gcd(denom(r[1]),m)>1 then return(gcd(denom(r[1]),m)) else r[1]:=modp(r[1],m) end if; if gcd(denom(r[2]),m)>1 then return(gcd(denom(r[2]),m)) else r[2]:=modp(r[2],m) end if; end if; q:=ecaddprojective(q,q,b1,b2); if gcd(denom(q[1]),m)>1 then return(gcd(denom(q[1]),m)) else q[1]:=modp(q[1],m) end if; if gcd(denom(q[2]),m)>1 then return(gcd(denom(q[2]),m)) else q[2]:=modp(q[2],m) end if; end do; end do; return([]); end proc: ecfactor(137703491);NiMiJipRPA==