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; }
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; }