Example #1
0
GT PFC::miller_loop(const G2& QQ,const G1& PP)
{ 
	GT z;
	Big n;
	int i,j,nb,nbw,nzs;
    ECn2 A,KA,Q;
	ECn P;
	ZZn Px,Py;
	BOOL precomp;
    ZZn12 r;
	Big X=*x;

	Q=QQ.g; P=PP.g;

	precomp=FALSE;
	if (QQ.ptable!=NULL) precomp=TRUE;
	else Q.norm();

	normalise(P);
	extract(P,Px,Py);

	if (X<0) n=-(6*X+2);
    else n=6*X+2;
    A=Q;
    nb=bits(n);
    r=1;
// Short Miller loop
	r.mark_as_miller();
	j=0;
    for (i=nb-2;i>=0;i--)
    {
		r*=r;
		if (precomp) r*=gp(QQ.ptable,j,Px,Py);
		else         r*=g(A,A,Px,Py);
		if (bit(n,i))
		{
			if (precomp) r*=gp(QQ.ptable,j,Px,Py);
            else         r*=g(A,Q,Px,Py);
		}
    }
// Combining ideas due to Longa, Aranha et al. and Naehrig
	KA=Q;
	q_power_frobenius(KA,*frob);
	if (X<0) {A=-A; r.conj();}
	if (precomp) r*=gp(QQ.ptable,j,Px,Py);
	else         r*=g(A,KA,Px,Py);
	q_power_frobenius(KA,*frob); KA=-KA;
	if (precomp) r*=gp(QQ.ptable,j,Px,Py);
	else         r*=g(A,KA,Px,Py);

    z.g=r;
	return z;
}
Example #2
0
BOOL fast_pairing(ECn2& P,ZZn& Qx,ZZn& Qy,Big &x,ZZn2 &X,ZZn12& res)
{ 
    ECn2 A,KA;
    ZZn2 AX,AY;
    int i,nb;
    Big n;
    ZZn12 r;
    ZZn12 t0,t1;
    ZZn12 x0,x1,x2,x3,x4,x5;

#ifdef MR_COUNT_OPS
fpc=fpa=fpx=fpmq=fpsq=fpaq=0;
#endif

	if (x<0) n=-(6*x+2);
    else n=6*x+2;
    A=P;
    nb=bits(n);
    r=1;
// Short Miller loop
	r.mark_as_miller();

    for (i=nb-2;i>=0;i--)
    {
		r*=r;
		r*=g(A,A,Qx,Qy);
		if (bit(n,i))
            r*=g(A,P,Qx,Qy);
    }
// Combining ideas due to Longa, Aranha et al. and Naehrig
	KA=P;
	q_power_frobenius(KA,X);
	if (x<0) {A=-A; r.conj();}
	r*=g(A,KA,Qx,Qy);
	q_power_frobenius(KA,X); KA=-KA;
	r*=g(A,KA,Qx,Qy);

#ifdef MR_COUNT_OPS
cout << "Miller fpc= " << fpc << endl;
cout << "Miller fpa= " << fpa << endl;
cout << "Miller fpx= " << fpx << endl;
cout << "Miller fpmq= " << fpmq << endl;
cout << "Miller fpsq= " << fpsq << endl;
cout << "Miller fpaq= " << fpaq << endl;

fpa=fpc=fpx=fpmq=fpsq=fpaq=0;
#endif
    if (r.iszero()) return FALSE;

// The final exponentiation

    t0=r;

    r.conj();

    r/=t0;    // r^(p^6-1)
	r.mark_as_regular();  // no longer "miller"

    t0=r;
    r.powq(X); r.powq(X);
    r*=t0;    // r^[(p^6-1)*(p^2+1)]

    r.mark_as_unitary();  // from now on all inverses are just conjugates !! (and squarings are faster)

	res=r;
// Newer new idea...
// See "On the final exponentiation for calculating pairings on ordinary elliptic curves" 
// Michael Scott and Naomi Benger and Manuel Charlemagne and Luis J. Dominguez Perez and Ezekiel J. Kachisa 


    t0=res;    t0.powq(X);
    x0=t0;   x0.powq(X);

    x0*=(res*t0);
    x0.powq(X);

    x1=inverse(res);  // just a conjugation!

    x4=pow(res,-x);  // x is sparse..
    x3=x4; x3.powq(X);

    x2=pow(x4,-x);
    x5=inverse(x2);
	t0=pow(x2,-x);

	x2.powq(X); 
    x4/=x2;
   
    x2.powq(X);
   
    res=t0; res.powq(X); t0*=res;

    t0*=t0;
    t0*=x4;
    t0*=x5;
    res=x3*x5;
    res*=t0;
    t0*=x2;
    res*=res;
    res*=t0;
    res*=res;
    t0=res*x1;
    res*=x0;
    t0*=t0;
    t0*=res;

#ifdef MR_COUNT_OPS
cout << "FE fpc= " << fpc << endl;
cout << "FE fpa= " << fpa << endl;
cout << "FE fpx= " << fpx << endl;
cout << "FE fpmq= " << fpmq << endl;
cout << "FE fpsq= " << fpsq << endl;
cout << "FE fpaq= " << fpaq << endl;
fpa=fpc=fpx=fpmq=fpsq=fpaq=0;
#endif

    res= t0; 
    return TRUE;
}