Esempio n. 1
0
BOOL MiraclInitBrick(ebrick2* brick, EC2 point, fparams* param)
{
	Big x, y;
	point.getxy(x, y);
	return ebrick2_init(brick, x.getbig(), y.getbig(), param->eccparams.BA->getbig(), param->eccparams.BB->getbig(),
			param->eccparams.m, param->eccparams.a, param->eccparams.b, param->eccparams.c, 8, param->secparam);
}
Esempio n. 2
0
void SampleRandomPoint(EC2 &point, fparams* params) {

	Big bigtmp;
	int itmp = rand()%2;
	do
	{
		bigtmp = rand(params->secparam, 2);
		point = EC2(bigtmp, itmp);
	}
	while (point_at_infinity(point.get_point()));
}
Esempio n. 3
0
void BaseOT::PointToByteArray(BYTE* pBufIdx, int field_size, EC2 &point)
{
	int itmp;
	Big bigtmp;
	//compress to x-point and y-bit and convert to byte array
	itmp = point.get(bigtmp);

	//first store the y-bit
	pBufIdx[0] = (BYTE) (itmp & 0x01);

	//then store the x-coordinate (sec-param/8 + 4 byte size)
	big_to_bytes(field_size, bigtmp.getbig(), (char*) pBufIdx+1, true);

}
Esempio n. 4
0
void extract(EC2& A,GF2m& x,GF2m& y)
{ 
    x=(A.get_point())->X;
    y=(A.get_point())->Y;
}
Esempio n. 5
0
int main(int argc,char **argv)
{
    ofstream ofile;
    int TR,M,a,b,c,low,lower,ip,lp,i,j,jj,m,n,nl,L,k,tau,lambda,cf;
    mr_utype t[100];
    Big aa,bb,p,nrp,x,y,d,s;
    Poly2Mod X2,XP,YP,YPy,XP2,XPP,YPP,YPPy,TT,SX,XK[600];
    Poly2Mod Pf[600],P2f[600],P3f[600];
    Poly2 Fl,X,G,P[100],P2[100],P3[100],FX,Y4;
    EC2 GG;
    miracl *mip=&precision;
    BOOL eigen,found,escape,search,fout,gotM,gotA,gotB,gota,gotb,gotc;
    static BOOL permisso[600];
    int Base;

    argv++; argc--;
    if (argc<1)
    {
        cout << "Incorrect Usage" << endl;
        cout << "Program finds the number of points (NP) on an Elliptic curve" << endl;
        cout << "which is defined over the Galois field GF(2^M)" << endl;
        cout << "The Elliptic Curve has the equation Y^2 +XY = X^3 + AX^2 + B " << endl;
        cout << "A suitable trinomial or Pentanomial basis must" << endl;
        cout << "also be specified t^m+t^a+1 or t^m+t^a+t^b+t^c+1" << endl;
        cout << "These can be found in e.g. the IEEE P1363 standard" << endl;
        cout << "or can be generated using the MIRACL findbase example program" << endl;
        cout << "schoof2 <A> <B> <M> <a> <b> <c>" << endl << endl;
        cout << "e.g. schoof2 1 52 191 9" << endl << endl;
        cout << "To input A and B in Hex, precede with -h" << endl;
        cout << "To output to a file, use flag -o <filename>" << endl;
        cout << "To search for NP a near-prime, incrementing B, use flag -s" << endl;
        cout << "\nFreeware from Certivox, Dublin, Ireland" << endl;
        cout << "Full C++ source code and MIRACL multiprecision library available" << endl;
        cout << "email [email protected]" << endl;
        return 0;
    }

    ip=0;
    gprime(10000);                 // generate small primes < 1000
    search=fout=gotM=gotA=gotB=gota=gotb=gotc=FALSE;
    M=a=b=c=0;

// Interpret command line
    Base=10;
    while (ip<argc)
    {
        if (strcmp(argv[ip],"-o")==0)
        {
            ip++;
            if (ip<argc)
            {
                fout=TRUE;
                ofile.open(argv[ip++]);
                continue;
            }
            else
            {
                cout << "Error in command line" << endl;
                return 0;
            }
        }
        if (strcmp(argv[ip],"-s")==0)
        {
            ip++;
            search=TRUE;
            continue;
        }
        if (strcmp(argv[ip],"-h")==0)
        {
            ip++;
            Base=16;
            continue;
        }
        if (!gotA) 
        {
            mip->IOBASE=Base;
            aa=argv[ip++]; 
            mip->IOBASE=10;
            gotA=TRUE;
            continue;
        }
        if (!gotB) 
        {
            mip->IOBASE=Base;
            bb=argv[ip++];
            mip->IOBASE=10;
            gotB=TRUE;
            continue;
        }
        if (!gotM) 
        {
            M=atoi(argv[ip++]);
            gotM=TRUE;
            continue;
        }
        if (!gota)
        {
            a=atoi(argv[ip++]);
            gota=TRUE;
            continue;
        } 
        if (!gotb)
        {
            b=atoi(argv[ip++]);
            gotb=TRUE;
            continue;
        } 
        if (!gotc)
        {
            c=atoi(argv[ip++]);
            gotc=TRUE;
            continue;
        } 
        cout << "Error in command line" << endl;
        return 0;
    }    

    if ((!gotM || !gotA || !gotB) || a==0)
    {
        cout << "Error in command line" << endl;
        return 0;
    }

// loop for "-s" search option
    p=pow((Big)2,M);
    forever {
 
    A=aa;
    if (bb>=p) bb%=p;
  
    B=bb;
    if (!ecurve2(M,a,b,c,A,B,TRUE,MR_AFFINE))    // initialise Elliptic Curve
    {
        cout << "Illegal Curve Parameters" << endl;
        return 0;
    }

//    D=mip->C;
    GF2m At=B;
    for (i=1;i<M-1;i++) At*=At;
    D=At;

    At=A;
    TR=trace(At);

// The elliptic curve as a Polynomial

    FX=0;
    FX.addterm(B,0);
    FX.addterm((GF2m)A,2);

    FX.addterm((GF2m)1,3);

    X=0; X.addterm(1,1);

    cout << "Counting the number of points (NP) on the curve" << endl;
    cout << "y^2 + xy = " << FX << " mod 2^" << M << endl;   

    if (B==0)
    {
        cout << "Not Allowed! B = 0" << endl;
        if (search) {bb+=1; continue; }
        else return 0;
    }

    if (M<12)
    { // do it the simple way
        nrp=2;
        x=1;
        while (x< (1<<M))
        { /* check if two points exist for each x */
            if (GG.set(x,0)) nrp+=2;
            x+=1;
        }
 
        do 
        {
            x=rand(p);
        } while (!GG.set(x,x));

        GG*=nrp;
        if (!GG.iszero())
        {
            cout << "Sanity Check 2 Failed. Please report to [email protected]" << endl;
            exit(0);
        }

        if (prime(nrp/2))
        {
            cout << "NP is 2*Prime!" << endl;
            cout << "NP= 2*" << nrp/2 << endl;
            break;
        }
        if (nrp%4==0)
        {
            if (A==0 && prime(nrp/4))
            {
                cout << "NP is 4*Prime!" << endl;
                cout << "NP= 4*" << nrp/4 << endl;
                break;
            }
        }
        cout << "NP= " << nrp << endl;
        if (search) {bb+=1; continue; }

        break;
        
    } 
    else if (M<56) 
    {
        nrp=kangaroo(p,(Big)0,(Big)2,TR,found);
        if (found) break;
        if (search) {bb+=1; continue; }
        break;
    }

    if (M<=100) d=pow((Big)2,48);  
    if (M>100 && M<=120) d=pow((Big)2,56); 
    if (M>120 && M<=160) d=pow((Big)2,64); 
    if (M>160 && M<=200) d=pow((Big)2,72);
    if (M>200) d=pow((Big)2,80);
    d=sqrt(p/d);
    if (d<256) d=256;

    mr_utype l[100]; 
    int pp[100];   // primes and powers 

// see how many primes will be needed
// l[.] is the prime, pp[.] is the power

    for (s=1,nl=0;s<=d;nl++)
    {
        int tp=mip->PRIMES[nl];
        pp[nl]=1;     // every prime included once...
        s*=tp;
        for (i=0;i<nl;i++)
        { // if a new prime power is now in range, include its contribution
            int cp=mip->PRIMES[i];
            int p=qpow(cp,pp[i]+1);
            if (p<tp  || (cp==2 && p<16*tp) )
            { // new largest prime power
                s*=cp;
                pp[i]++;
            } 
        }
    }  
    L=mip->PRIMES[nl-1];

    cout << nl << " primes used (plus largest prime powers), largest is " << L << endl;

    for (i=0;i<nl;i++)
        l[i]=mip->PRIMES[i];

    int start_prime;   // start of primes & largest prime powers
    for (i=0;;i++)
    {
        if (pp[i]!=1)
        {
            int p=qpow(l[i],pp[i]);
            for (j=0;l[j]<p && j<nl;j++) ;
            nl++;
            for (m=nl-1;m>j;m--) l[m]=l[m-1];
            l[j]=p;   // insert largest prime power in table
        }
        else 
        {
            start_prime=i;
            break;
        } 
    }

// table of primes and prime powers now looks like:-
// 2 3 5 7 9 11 13 16 17 19 ....
//     S   p        p

// where S is start_prime, and p marks the largest prime powers in the range
// CRT uses primes starting from S, but small primes are kept in anyway, 
// as they allow quick abort if searching for prime NP.

// Calculate Divisor Polynomials 
// Set the first few by hand....

    P[0]=0; P[1]=1; P[2]=0; P[3]=0; P[4]=0;

    P2[1]=1; P3[1]=1;

    P[2].addterm(1,1);

    P2[2]=P[2]*P[2];
    P3[2]=P2[2]*P[2];

    P[3].addterm(B,0);   
    P[3].addterm(1,3);
    P[3].addterm(1,4);  

    P2[3]=P[3]*P[3];
    P3[3]=P2[3]*P[3];

    P[4].addterm(B,2);
    P[4].addterm(1,6);

    P2[4]=P[4]*P[4];
    P3[4]=P2[4]*P[4];

    lower=5;     // next one to be calculated

    t[0]=0;

    Poly2Mod zero,one,XT,XTy,YT,YTy,ZT,XL,YL,ZL,ZL2,ZT2;
    one=1;                  // polynomial = 1
    zero=0;                 // polynomial = 0
    
    Crt CRT(nl-start_prime,&l[start_prime]);  // initialise for application of 
                                              // chinese remainder thereom

// now look for trace%prime for prime=3,5,7,11 etc
// actual trace is found by combining these via CRT

    l[0]=4;
    if (TR==0) l[0]=8;

    escape=FALSE;
    for (i=0;i<nl;i++)      
    {
        lp=l[i];       // next prime
        k=p%lp;

// generation of Divisor polynomials as needed
// See Schoof p. 485

        if (lp<=8 || lp%2!=0)
        {
            for (j=lower;j<=lp+1;j++)
            { // different for even and odd 
                if (j%2==1)
                { 
                    n=(j-1)/2;
                    P[j]=P[n+2]*P3[n]+P3[n+1]*P[n-1];
                }
                else
                {
                    n=j/2;
                    P[j]=P[n]*(P[n+2]*P2[n-1]+P[n-2]*P2[n+1]);
                    P[j]=divxn(P[j],1);
                }
                if (j <= 1+(L+1)/2)
                { // precalculate for later
                    P2[j]=P[j]*P[j];
                    P3[j]=P2[j]*P[j];
                }
            }

            if (lp+2>lower) lower=lp+2;
        }    
        for (tau=0;tau<=lp/2;tau++) permisso[tau]=TRUE;

        eigen=FALSE;
        if (lp%2==0)
        { // its 2^c
            Poly2 G,G2,PI;
            GF2m S;
            int t=lp,c=0;
            while (t!=1) {t/=2; c++;}

//
// When lp is a power of 2, we can construct a root of the Division Polynomial
// directly. See Menezes P.107. This is much quicker. Then the eigenvalue
// heuristic can be used.
//

            S=sqrt(sqrt((GF2m)B));
            G=X+S;
            G2=G*G;
            PI=1;

            for (jj=2;jj<c;jj++)
            {
                S=sqrt(S);
                G=G2+S*X*PI;
                PI=PI*G2;
                G2=G*G;
            }  
            eigen=TRUE;
            Fl=G;          // G is a root of degree lp/4
        }
        else
        {
            Poly2Mod Xcoord,batch;
            setmod(P[lp]);
            MFX=FX;
            XX=X;
            XP2=1;
  
//
// Calculate X^P. Save intermediates, as they can be used to
// calculate Y^P (if we need to.. )
//

            cout << "X^P " << flush;
            for (jj=0;jj<M-1;jj++)
            {
                XP2*=XX;
                XP2*=XP2;
                XK[jj]=XP2;
            }
            XP=XP2*(XX*XX);

// Eigenvalue search - see Menezes
// Batch the GCDs as they are slow. 
// This gives us product of both eigenvalues - a polynomial of degree (lp-1)
// But thats a lot better than (lp^2-1)/2

            if (prime((Big)lp))
            {
                batch=1;
                cout << "\b\b\b\bGCD " << flush;  
                for (tau=1;tau<=(lp-1)/2;tau++)
                {
                    Xcoord=(XP+XX)*P2[tau]+(Poly2Mod)P[tau-1]*P[tau+1];
                    batch*=Xcoord;
                }
                Fl=gcd(batch);
                if (degree(Fl)==(lp-1)) eigen=TRUE;
            }
            cout << "\b\b\b\b";
        }   

        if (eigen)
        { // eigenvalue found!
            Poly2Mod one;
            setmod(Fl);
            one=1;
            MFX=FX;
            XX=X;
            YP=MFX;
            XP2=1;

// Find X^P and Y^P together wrt new small modulus

            cout << "Y^P" << flush;

            for (jj=0;jj<M-1;jj++)
            {
                XP2*=XX;
                XP2*=XP2;
                YP*=YP;
                YP+=(XP2*MFX);
            }
            YPy=XP2*XX;
            XP=YPy*XX;
            cout << "\b\b\b";

            cout << "NP mod " << lp << " = " << flush;
            SX=inverse(XX);
            for (jj=0;jj<5;jj++)
            {
                Pf[jj]=(Poly2Mod)P[jj];
                P2f[jj]=(Poly2Mod)P2[jj];
                P3f[jj]=(Poly2Mod)P3[jj];
            }         

// if (lp%2==0) cout << "\n GCD(XX,Fl)= " << gcd(XX) << endl;

            low=5;
            for (lambda=1;lambda<=lp/2;lambda++)
            { // eigenvalue search
                Poly2Mod Tx,Hx,Ax,Bx,Pf3,Pft;
                tau=(lambda+invers(lambda,lp)*p)%lp;

                cout << setw(4) << (p+1-tau)%lp << flush;
                
                for (jj=low;jj<=lambda+2;jj++)
                { 
                    if (jj%2==1)
                    {
                        n=(jj-1)/2;
                        Pf[jj]=Pf[n+2]*P3f[n]+P3f[n+1]*Pf[n-1];
                    }
                    else
                    {
                        n=jj/2;
                        Pf[jj]=SX*Pf[n]*(Pf[n+2]*P2f[n-1]+Pf[n-2]*P2f[n+1]);
                    }
                    P2f[jj]=Pf[jj]*Pf[jj];
                    P3f[jj]=P2f[jj]*Pf[jj];
                }
                if (lambda+3>low) low=lambda+3;

                Pft=Pf[lambda-1]*Pf[lambda+1];

                Tx=(XP+XX)*P2f[lambda]+Pft;

                if (degree(gcd(Tx))!=0)
                { // Got it! Now check Y-coord for correct sign
                    if (lambda==1)
                    {
                        Ax=YP;
                        Bx=YPy+one;
                    }
                    else
                    {
                        Pf3=P3f[lambda];
                        Pft*=Pf[lambda];

                        Ax=XX*Pf3*(YP+XX)+Pf[lambda-2]*P2f[lambda+1]+(XX*XX+XX)*Pft;  
                        Bx=XX*Pf3*(YPy+one)+Pft; 
                    }              

                    Hx=Ax*Ax+XX*Ax*Bx+MFX*(Bx*Bx); // substitue y into curve

                    if (degree(gcd(Hx))==0)
                    { // its the other one
                        tau=(lp-tau)%lp;
                        cout << "\b\b\b\b";
                        cout << setw(4) << (p+1-tau)%lp << flush;
                    }
                    t[i]=tau;
                    if ((p+1-tau)%lp==0)
                    {
                        cout << " ***" << endl;
                        if (search) escape=TRUE;
                    }
                    else cout << endl;
                    break;
                }
                cout << "\b\b\b\b";
            }
            for (jj=0;jj<low;jj++)
            {
                Pf[jj].clear();
                P2f[jj].clear();
                P2f[jj].clear();
            }  
            if (escape) break;
            continue;
        }   

 // no eigenvalue found, but some tau values can be eliminated...       

        if (prime((Big)lp))
        {
            if (degree(Fl)==0) 
            {
                for (tau=0;tau<=lp/2;tau++)
                {
                    jj=(lp+tau*tau-(4*p)%lp)%lp;
                    if (jac(jj,lp)!=(-1)) permisso[tau]=FALSE;
                }
            }
            else
            { // Fl==P[lp] so tau=+/- sqrt(p) mod lp
                jj=(2*sqrmp(p%lp,lp))%lp;
                for (tau=0;tau<=lp/2;tau++) permisso[tau]=FALSE;
                if (jj<=lp/2) permisso[jj]=TRUE;
                else          permisso[lp-jj]=TRUE;
            }
        }
        else
        { // prime power
            for (jj=0;jj<start_prime;jj++)
                if (lp%l[jj]==0)
                {
                    for (tau=0;tau<=lp/2;tau++)
                    {
                        permisso[tau]=FALSE;
                        if (tau%l[jj]==t[jj])      permisso[tau]=TRUE;
                        if ((lp-tau)%l[jj]==t[jj]) permisso[tau]=TRUE;
                    }
                    break;
                }  
        }

// These next are time-consuming calculations of Y^P, X^PP and Y^PP

        cout << "Y^P " << flush;
        YP=MFX;
        for (jj=0;jj<M-1;jj++)
        {
            XP2=XK[jj];     // use values stored during generation of X^P
            XK[jj].clear();
            YP*=YP;
            YP+=(XP2*MFX);
        }
        YPy=XP2*XX;
        cout << "\b\b\b\bX^PP" << flush;

// Composition is faster for smaller lp

        if (lp<40)
        {
            TT=compose(YPy,XP);
            XPP=XP*TT;
            cout << "\b\b\b\bY^PP" << flush;
            YPP=compose(YP,XP)+YP*TT;
            YPPy=TT*YPy;
        }
        else
        { // XPP and YPP are calculated together
            YPP=YP;
            for (jj=0;jj<M;jj++)
            {
                XP2*=XX;
                XP2*=XP2;
                YPP*=YPP;
                YPP+=(XP2*MFX);  
                if (jj==M/2) cout << "\b\b\b\bY^PP" << flush;
            }
            YPPy=XP2*XX;
            XPP=YPPy*XX;
        }
        cout << "\b\b\b\b";

        Poly2Mod Pk,P2k,P3k,PkP1,PkM1,PkP2,Pt;
        Pk=P[k]; PkP1=P[k+1]; PkM1=P[k-1]; PkP2=P[k+2];

//
// This is Schoof's algorithm
//
// Now looking for the value of tau which satisfies 
// (X^PP,Y^PP) + k.(X,Y) =  tau.(X^P,Y^P)
// 
// Note that (X,Y) are rational polynomial expressions for points on
// an elliptic curve, so "+" means elliptic curve point addition
// 
// Note also that Y is of the form A(x)+B(x).y. After the addition
// the X coordinate of the sum will also be of this form.
//
// k.(X,Y) can be found directly from Divisor polynomials
// Schoof Prop (2.2)
//
// Points are converted to projective (X,Y,Z) form
// Observe that (X/Z^2,Y/Z^3,1) is the same
// point in projective co-ordinates as (X,Y,Z)
//

        if (k==1)
        { // easy case
            XT=XX;
            YT=0;
            YTy=one;
            ZT=one;
        }
        else
        {
            P2k=Pk*Pk;
            P3k=P2k*Pk;
            Pt=PkP1*PkM1;
            X2=XX*XX;
            XT=X2*(XX*P2k+Pt);
            Pt*=Pk;
            YT=X2*(X2*P3k+P[k-2]*PkP1*PkP1+(X2+XX)*Pt);
            YTy=X2*(XX*P3k+Pt);  
            ZT=XX*Pk;
        }

        elliptic_add(XT,XTy,YT,YTy,ZT,XPP,YPP,YPPy);
// 
// Test for Schoof's case 1 - LHS (XT,YT,ZT) is point at infinity
//

        cout << "NP mod " << lp << " = " << flush;
        if (iszero(ZT))
        { // Is it zero point? (XPP,YPP) = - K(X,Y)
            t[i]=0;
            cout << setw(4) << (p+1)%lp;
            if ((p+1)%lp==0)
            {      
                cout << " ***" << endl;
                if (search) {escape=TRUE; break;}
            }
            else cout << endl;
            continue;         
        }

        Poly2Mod XP3,XP4,XP6;
        Poly2Mod ZT2,ZT3,ZT2XP;

        ZT2=ZT*ZT;
        ZT3=ZT2*ZT;
        ZT2XP=XP*ZT2;
        XP2=XP*XP;
        XP3=XP*XP2;
        XP4=XP2*XP2;
        XP6=XP3*XP3;

        SX=inverse(XP);   // we need 1/XP mod Fl

        Pf[0]=0; Pf[1]=1; Pf[2]=XP;
        P2f[1]=1; P3f[1]=1;
        P2f[2]=Pf[2]*Pf[2];
        P3f[2]=P2f[2]*Pf[2];

        Pf[3]=XP4+XP3+B;
        P2f[3]=Pf[3]*Pf[3];
        P3f[3]=P2f[3]*Pf[3];

        Pf[4]=XP6+B*XP2;
        P2f[4]=Pf[4]*Pf[4];
        P3f[4]=P2f[4]*Pf[4];
         
        low=5;

        for (tau=1;tau<=lp/2;tau++)
        {
            int res=0;
            Poly2Mod Hx,Ax,Bx,Rx,Tx,Ry,Ty,Pt;
            if (!permisso[tau]) continue;

            cout << setw(4) << (p+1-tau)%lp << flush;     

            for (jj=low;jj<=tau+2;jj++)
            { // different for odd and even
                if (jj%2==1)
                { // 2 mod-muls/
                    n=(jj-1)/2;
                    Pf[jj]=Pf[n+2]*P3f[n]+P3f[n+1]*Pf[n-1];
                }
                else
                { // 4 mod-muls
                    n=jj/2;
                    Pf[jj]=SX*Pf[n]*(Pf[n+2]*P2f[n-1]+Pf[n-2]*P2f[n+1]);
                }
                P2f[jj]=Pf[jj]*Pf[jj];    // square
                if (jj<=1+(1+(lp/2))/2) P3f[jj]=P2f[jj]*Pf[jj];   // cube
            } 
            if (tau+3>low) low=tau+3;

            if (tau==1)
            { // easy case
                Ax=ZT2XP+XT;
                Bx=XTy;
            }
            else
            {
                Pt=Pf[tau-1]*Pf[tau+1];
                Ax=ZT2*(XP*P2f[tau]+Pt)+P2f[tau]*XT;
                Bx=P2f[tau]*XTy;
            }
               
            Hx=Ax*Ax+XX*Ax*Bx+MFX*(Bx*Bx);

            if (iszero(Hx))   // NOTE: GCD not needed
            { // found it. Now compare Y coordinates to determine sign

                if (tau==1)
                {
                    Ax=YT+ZT3*YP;
                    Bx=YTy+ZT3*YPy;
                }
                else
                {
                    Tx=XP*P2f[tau]*Pf[tau];
                    Pt*=Pf[tau];
                    Ax=YT*Tx+ZT3*(Tx*(XP+YP)+(XP2+XP+YP)*Pt+Pf[tau-2]*P2f[tau+1]);
                    Bx=YTy*Tx+ZT3*YPy*(Tx+Pt);                                                                
                }

                Hx=Ax*Ax+XX*Ax*Bx+MFX*(Bx*Bx);  // substitute into curve
                if (!iszero(Hx))
                { // its the other one
                    tau=(lp-tau)%lp;
                    cout << "\b\b\b\b";
                    cout << setw(4) << (p+1-tau)%lp << flush;
                }
                t[i]=tau;
                if ((p+1-tau)%lp==0)
                {
                    cout << " ***" << endl;
                    if (search) escape=TRUE;
                }
                else cout << endl;
                break;
            }
            cout << "\b\b\b\b";
        }

        for (jj=0;jj<low;jj++)
        {
            Pf[jj].clear();
            P2f[jj].clear();
            P3f[jj].clear();
        }
        if (escape) break;
    }
    Modulus.clear();

    for (i=0;i<=L+1;i++) 
    {
        P[i].clear(); // reclaim space
        P2[i].clear();
        P3[i].clear();
    }

    if (escape) {bb+=1; continue;}
    Big order,ordermod;
    ordermod=1; for (i=0;i<nl-start_prime;i++) ordermod*=l[start_prime+i];
    order=(p+1-CRT.eval(&t[start_prime]))%ordermod;    // get order mod product of primes

    nrp=kangaroo(p,order,ordermod,TR,found);

    if (!found && search) {bb+=1; continue; }
    else break;

    }

    if (fout) 
    {
        cf=1;      // set co-factor=1
        if (found)
        { // An "ideal" curve was found 
            if (TR==1)
            {
                nrp/=2;
                cf=2;
            }
            else
            {
                nrp/=4;
                cf=4;
            }
        }

    // generate a random point on the curve 
    // point will be of prime order for "ideal" curve, otherwise any point
        forever
        {
            EC2 P;
            do {
                x=rand(p);
            } while (!GG.set(x,x));
            if (!found) break;
            P=GG;
            
            P*=(Big)cf;
            if (P.iszero()) continue;
            P=GG;
            P*=nrp;
            if (!P.iszero()) continue;
            break;
        }

        GG.get(x,y);
        ofile << M << endl;
        mip->IOBASE=16;
        ofile << aa << endl;
        ofile << bb << endl;
        ofile << nrp << endl;
        ofile << x << endl;
        ofile << y << endl;
        mip->IOBASE=10;
        ofile << a << endl;
        ofile << b << endl;
        ofile << c << endl;
    }

    if (p==nrp) 
    {
        cout << "WARNING: Curve is anomalous" << endl;
        return 0;
    }

// check MOV condition for curves of Cryptographic interest
//    if (M<128) return 0;

    nrp/=2;
    if (nrp%2==0) nrp/=2;
    
    d=1;
    for (i=0;i<50;i++)
    {
        d=modmult(d,p,nrp);
        if (d==1) 
        {
           if (i==1 || prime(nrp))   cout << "WARNING: Curve fails MOV condition, k= " << i << endl;
           else                      cout << "WARNING: Curve fails MOV condition, k<= " << i << endl;
           return 0;
        }
    }

    return 0;
}
Esempio n. 6
0
EC2 mul(const Big& e1,const EC2& p1,const Big& e2,const EC2& p2)
{ 
    EC2 t; 
    ecurve2_mult2(e1.getbig(),p1.get_point(),e2.getbig(),p2.get_point(),t.get_point());
    return t;
}
Esempio n. 7
0
int main()
{
    ifstream common("common2.ecs");    /* construct file I/O streams */
    ifstream private_key("private.ecs");
    ifstream message;
    ofstream signature;
    char ifname[50],ofname[50];
    EC2 G;
    Big a2,a6,q,x,y,h,r,s,d,k;
    long seed;
    int m,a,b,c; 
    miracl *mip=&precision;

/* randomise */
    cout << "Enter 9 digit random number seed  = ";
    cin >> seed;
    irand(seed);

/* get common data */

    common >> m;
    mip->IOBASE=16;
    common >> a2 >> a6 >> q >> x >> y;
    mip->IOBASE=10;
    common >> a >> b >> c;

/* calculate r - this can be done off-line,
   and hence amortized to almost nothing    */
    ecurve2(m,a,b,c,a2,a6,FALSE,MR_PROJECTIVE);
    G=EC2(x,y);
    k=rand(q);
    G*=k;            /* see ebrick2.cpp for technique to speed this up */
    G.get(r);
    r%=q;

/* get private key of recipient */
    private_key >> d;

/* get message */
    cout << "file to be signed = " ;
    cin >> ifname;
    strcpy(ofname,ifname);
    strip(ofname);
    strcat(ofname,".ecs");
    message.open(ifname,ios::binary|ios::in); 
    if (!message)
    {
        cout << "Unable to open file " << ifname << "\n";
        return 0;
    }
    h=hash(message);

/* calculate s */
    k=inverse(k,q);
    s=((h+d*r)*k)%q;
    signature.open(ofname);
    mip->IOBASE=10;
    signature << r << endl;
    signature << s << endl;
    return 0;
}