void SoftExpo(ZZn12 &f3, ZZn2 &X){ ZZn12 t0; int i; t0=f3; f3.conj(); f3/=t0; f3.mark_as_regular(); t0=f3; f3.powq(X); f3.powq(X); f3*=t0; f3.mark_as_unitary(); }
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; }