GT PFC::miller_loop(const G2& QQ,const G1& PP) { GT z; int i,j,n,nb,nbw,nzs; ECn3 A,Q; ECn P; ZZn Px,Py; BOOL precomp; ZZn6 res; Big X=*x; P=PP.g; Q=QQ.g; #ifdef MR_ECN3_PROJECTIVE Q.norm(); #endif precomp=FALSE; if (QQ.ptable!=NULL) precomp=TRUE; normalise(P); extract(P,Px,Py); Px+=Px; // because x^6+2 is irreducible.. simplifies line function calculation Py+=Py; res=1; A=Q; // reset A nb=bits(X); res.mark_as_miller(); j=0; for (i=nb-2;i>=0;i--) { res*=res; if (precomp) res*=gp(QQ.ptable,j,Px,Py); else res*=g(A,A,Px,Py); if (bit(X,i)==1) { if (precomp) res*=gp(QQ.ptable,j,Px,Py); else res*=g(A,Q,Px,Py); } } z.g=res; return z; }
BOOL ate(ECn3& Q,ECn& P,Big &x,ZZn2& X,ZZn6& res) { int i,j,n,nb,nbw,nzs; ECn3 A; ZZn Px,Py; ZZn6 w; Big q=x*x-x+1; #ifdef MR_COUNT_OPS fpc=fpa=fpx=0; #endif normalise(P); #ifdef PROJECTIVE Q.norm(); #endif extract(P,Px,Py); Px+=Px; // because x^6+2 is irreducible.. simplifies line function calculation Py+=Py; res=1; A=Q; // reset A nb=bits(x); res.mark_as_miller(); for (i=nb-2;i>=0;i--) { res*=res; res*=g(A,A,Px,Py); if (bit(x,i)==1) res*=g(A,Q,Px,Py); if (res.iszero()) return FALSE; } #ifdef MR_COUNT_OPS printf("After Miller fpc= %d fpa= %d fpx= %d\n",fpc,fpa,fpx); #endif // if (!A.iszero() || res.iszero()) return FALSE; w=res; w.powq(X); res*=w; // ^(p+1) w=res; w.powq(X); w.powq(X); w.powq(X); res=w/res; // ^(p^3-1) // exploit the clever "trick" for a half-length exponentiation! res.mark_as_unitary(); w=res; res.powq(X); // res*=res; // res=pow(res,CF); if (x<0) res/=powu(w,-x); else res*=powu(w,x); #ifdef MR_COUNT_OPS printf("After pairing fpc= %d fpa= %d fpx= %d\n",fpc,fpa,fpx); fpa=fpc=fpx=0; #endif if (res==(ZZn6)1) return FALSE; return TRUE; }