/* * Program to find Freeman pairing-friendly elliptic curves with embedding degree k=10 * * See http://www.hpl.hp.com/techreports/2005/HPL-2005-155.html * * Compile as (for example) * cl /O2 /GX freeman.cpp big.cpp miracl.lib * * Outputs curves to a file freeman.dat * * Mike Scott 6/10/2005 * */ #include #include #include #include #include "big.h" using namespace std; // Solve the Pell equation int pell(int max,Big D,Big F,Big& X,Big& Y,Big *SX,Big *SY,BOOL& complete) { int i,j,ns; BOOL SMALLD; Big A,P,Q,SD,G,B,OG,OB,NG,NB,T; complete=FALSE; SMALLD=FALSE; if (Dmax) return ns; // abort - these are only solutions T=G*G-D*B*B; if (T == F/4) { SX[ns]=2*G; SY[ns]=2*B; ns++; } if (T == F) { SX[ns]=G; SY[ns]=B; ns++; } if (i>0 && Q==1) break; } if (i%2==1) for (j=0;jmax) return ns; T=G*G-D*B*B; if (T == F/4) { SX[ns]=2*G; SY[ns]=2*B; ns++; } if (T == F) { SX[ns]=G; SY[ns]=B; ns++; } } complete=TRUE; // we got to the end.... X=G; Y=B; // minimal solution of x^2-dy^2=1 // can be used to find more solutions.... if (SMALLD) { // too small - do it the hard way Big ylim1,ylim2,R; ns=0; if (F<0) { ylim1=sqrt(-F/D); ylim2=sqrt(-F*(X+1)/(2*D)); } else { ylim1=0; ylim2=sqrt(F*(X-1)/(2*D)); } // This might take too long... // Should really implement LMM method here if (ylim2-ylim1>300) { cout << "." << flush; ylim2=ylim1+300; } for (B=ylim1;BPRIMES[i]; if ((d%(s*s))==0) return FALSE; if ((s*s)>d) break; } return TRUE; } void results(BOOL fout,ofstream& ofile,int d,Big p,Big cf,Big ord) { cout << "*** Found one - p=" << bits(p) << "-bits ord=" << bits(ord) << "-bits" << endl; cout << "D= " << d << endl; cout << "p= " << p << endl; cout << "ord= " << ord << endl; cout << "cf= " << cf << endl << endl; if (fout) { ofile << "*** Found one: p=" << bits(p) << "-bits ord=" << bits(ord) << "-bits p%8= " << p%8 << endl; ofile << "D= " << d << endl; ofile << "p= " << p << endl; ofile << "ord= " << ord << endl; ofile << "cf= " << cf << endl; ofile << "cm " << p << " -D" << d << " -K" << cf << endl << endl; } } int main(int argc,char **argv) { ofstream ofile; int MIN_SECURITY,MAX_SECURITY,MIN_D,MAX_D,MIN_P; int ip,j,d,d15,m,mm,solutions,mnt,start,N,precision,max; BOOL fout,complete; // Defaults fout=TRUE; precision=100; ofile.open("freeman.dat"); miracl *mip=mirsys(precision,0); Big F,T,M,D,W,K,C,mmax,td,X,Y,x,y,w,xn,yn,t0,u0,p,k,nrp,ord,R; Big SX[20],SY[20]; start=1; max=276; // 10+5120/20 gprime(100000); MAX_D=2000000000; // as far as I can reasonably go.... for (d=start;d<=MAX_D;d++) { // D must be square-free if (d%120!=43 && d%120!=67) continue; if (!squfree(d)) continue; td=(Big)d*15; F=-20; solutions=pell(max,td,F,t0,u0,SX,SY,complete); if (!solutions) continue; for (j=0;j512) break; if ((X-5)%15==0) { x=(X-5)/15; p=25*x*x*x*x+25*x*x*x+25*x*x+10*x+3; if (bits(p)>148) { if (prime(p)) { nrp=25*x*x*x*x+25*x*x*x+15*x*x+5*x+1; ord=trial_divide(nrp); if (prime(ord) && bits(ord)>148) results(fout,ofile,d,p,nrp/ord,ord); } } } if ((-X-5)%15==0) { x=(-X-5)/15; p=25*x*x*x*x+25*x*x*x+25*x*x+10*x+3; if (bits(p)>148) { if (prime(p)) { nrp=25*x*x*x*x+25*x*x*x+15*x*x+5*x+1; ord=trial_divide(nrp); if (prime(ord) && bits(ord)>148) results(fout,ofile,d,p,nrp/ord,ord); } } } if (!complete) break; // no more solutions multiply(td,t0,u0,X,Y); } } } return 0; }