void g(ECn& A,ECn& B,ZZn2& Qx,ZZn2& Qy,ZZn2& num) { ZZn lam,mQy; ZZn2 d,u; big ptr; ECn P=A; // Evaluate line from A A.add(B, &ptr, NULL, NULL); #ifndef SCOTT if (A.iszero()) { u=vertical(P,Qx); d=1; } else { #endif if (ptr==NULL) u=1; else { lam=ptr; u=line(P,A,lam,Qx,Qy); } #ifndef SCOTT d=vertical(A,Qx); } num*=(u*conj(d)); // 6 ZZn muls #else // denominator elimination! num*=u; #endif }
BOOL power_tate(ECn& P,ECn4 Q,Big& q,Big *cf,ZZn2 &Fr,Big &e,ZZn4& r) { int i,nb; ECn A; ZZn8 w,res,a[4]; ZZn4 Qx,Qy; ZZn2 x,y; Big carry,ex[4]; Big p=get_modulus(); Q.get(Qx,Qy); Qx=txd(Qx); Qy=txd(txd(Qy)); res=1; /* Left to right method */ A=P; nb=bits(q); for (i=nb-2;i>=0;i--) { res*=res; res*=g(A,A,Qx,Qy); if (bit(q,i)) res*=g(A,P,Qx,Qy); } if (!A.iszero() || res.iszero()) return FALSE; w=res; w.powq(Fr); w.powq(Fr); // ^(p^4-1) w.powq(Fr); w.powq(Fr); res=w/res; res.mark_as_unitary(); a[3]=res; a[2]=a[3]; a[2].powq(Fr); a[1]=a[2]; a[1].powq(Fr); a[0]=a[1]; a[0].powq(Fr); if (e.isone()) for (i=0;i<4;i++) ex[i]=cf[i]; else { // cf *= e carry=0; for (i=3;i>=0;i--) carry=mad(cf[i],e,carry,p,ex[i]); } res=pow(4,a,ex); r=real(res); // compression // r=powl(real(res),cf); // ^(p*p*p*p+1)/q if (r.isunity()) return FALSE; return TRUE; }
void g(ECn& A,ECn& B,ZZn& Qx,ZZn2& Qy,ZZn2& num,BOOL precomp,ZZn* store,int& ptr) { ZZn lam,x,y,m,nx; ZZn2 u; big pointer; if (num.iszero()) return; if (!precomp) { // Store line start point and slope. // Evaluate line from A, and then evaluate vertical through destination extract(A,x,y); pointer=A.add(B); if (pointer==NULL) {num=0; return;} lam=pointer; store[ptr++]=x; store[ptr++]=y; store[ptr++]=lam; if (A.iszero()) return; // line m=Qx; u=Qy; m-=x; m*=lam; // 1 ZZn muls u-=y; u-=m; } else { // extract precalculated values from the store.... - nx is a peek ahead x=store[ptr++]; y=store[ptr++]; lam=store[ptr++]; nx=store[ptr]; if (nx.iszero()) return; m=Qx; u=Qy; m-=x; m*=lam; // 1 ZZn muls u-=y; u-=m; } num*=u; // 3 ZZn muls }
void g(ECn& A,ECn& B,ZZn2& Qx,ZZn& Qy,ZZn2& num,ZZn2& denom,int as,BOOL first) { ZZn lam,mQy; ZZn2 d,u; big ptr; ECn P=A; if (as==ADD) { // Evaluate line from A, and then evaluate vertical through destination ptr=A.add(B); if (ptr==NULL) { num=0; return; } else lam=ptr; if (A.iszero()) { u=vertical(P,Qx); d=1; } else { u=line(P,A,lam,Qx,Qy); d=vertical(A,Qx); } } else // as==SUB { // Evaluate Vertical at A, and then line from A to destination // (Note swap num and denom, Qy=-Qy, process lines "backwards") u=vertical(A,Qx); ptr=A.sub(B); if (ptr==NULL) { num=0; return; } else lam=ptr; if (A.iszero()) { d=u; } else { mQy=-Qy; d=line(P,A,lam,Qx,mQy); } } if (first) {num= u; denom= d; } else {num*=u; denom*=d; } // 6 ZZn muls }
void g(ECn& A,ECn& B,ZZn6& Qx,ZZn6& Qy,ZZn6& num,BOOL first) { ZZn lam; ZZn6 u; big ptr; ECn P=A; // Evaluate line from A ptr=A.add(B); if (ptr==NULL) { num.clear(); return; } else lam=ptr; if (A.iszero()) return; u=line(P,A,lam,Qx,Qy); if (first) num= u; else num*=u; }
BOOL fast_tate_pairing(ECn& P,ZZn& Qx,ZZn2& Qy,Big& q,BOOL precomp,ZZn* store,ZZn2& res) { int i,ptr=0; Big p; ECn A; if (!precomp) get_mip()->coord=MR_AFFINE; // precompute using AFFINE // coordinates res=1; // q.P = 2^17*(2^142.P +P) + P A=P; for (i=0;i<142;i++) { res*=res; g(A,A,Qx,Qy,res,precomp,store,ptr); } // 6 ZZn muls after first g(A,P,Qx,Qy,res,precomp,store,ptr); for (i=0;i<17;i++) { res*=res; g(A,A,Qx,Qy,res,precomp,store,ptr); } g(A,P,Qx,Qy,res,precomp,store,ptr); if (res.iszero()) return FALSE; if (!precomp) { if (!A.iszero()) return FALSE; get_mip()->coord=MR_PROJECTIVE; // reset } p=get_modulus(); // get p res= pow(res,(p+1)/q); // raise to power of (p^2-1)/q res=conj(res)/res; if (res.isunity()) return FALSE; return TRUE; }
BOOL fast_tate_pairing(ECn& P,ZZn2& Qx,ZZn2& Qy,Big& q,ZZn2& res) { int i,nb; Big n,p; ECn A; // q.P = 2^17*(2^142.P +P) + P res=1; A=P; // reset A #ifdef SCOTT // we can avoid last iteration.. n=q-1; #else n=q; #endif nb=bits(n); for (i=nb-2;i>=0;i--) { res*=res; g(A,A,Qx,Qy,res); if (bit(n,i)) g(A,P,Qx,Qy,res); } #ifdef SCOTT if (A!=-P || res.iszero()) return FALSE; #else if (!A.iszero()) return FALSE; #endif p=get_modulus(); // get p res= pow(res,(p+1)/q); // raise to power of (p^2-1)/q res=conj(res)/res; if (res.isunity()) return FALSE; return TRUE; }
BOOL fast_tate_pairing(ECn& P,ZZn2& Qx,ZZn& Qy,Big& q,ZZn2& res) { int i; Big p; ECn A; ZZn2 ha,had; #ifndef SIMPLE Big q3; ECn P2,t[11]; ZZn2 hc,hcd,z2n,z2d,zn[11],zd[11]; #endif ha=had=1; #ifdef SIMPLE // q.P = 2^17*(2^142.P +P) + P A=P; // reset A for (i=0;i<142;i++) { ha*=ha; had*=had; g(A,A,Qx,Qy,ha,had,ADD,FALSE); // 16 ZZn muls + 1 inverse if (ha==0 || had==0) return FALSE; } // 30 ZZn muls (Projective) g(A,P,Qx,Qy,ha,had,ADD,FALSE); // 11 ZZn muls + 1 inverse if (ha==0 || had==0) return FALSE; // 34 ZZn muls (Projective) for (i=0;i<17;i++) { ha*=ha; had*=had; g(A,A,Qx,Qy,ha,had,ADD,FALSE); // 16 ZZn muls + 1 inverse if (ha==0 || had==0) return FALSE; } // 30 ZZn muls (Projective) g(A,P,Qx,Qy,ha,had,ADD,FALSE); // 11 ZZn muls + 1 inverse if (ha==0 || had==0) return FALSE; // 34 ZZn muls (Projective) #else q3=q*3; zn[0]=zd[0]=1; t[0]=P2=A=P; g(P2,P2,Qx,Qy,z2n,z2d,ADD,TRUE); // P2=P+P // // Build NAF windowing table // for (i=1;i<11;i++) { // 17 ZZn muls + 1 inverse (Affine) g(A,P2,Qx,Qy,hc,hcd,ADD,TRUE); // 40 ZZn muls (Projective) t[i]=A; // precalculate t[i] = (2i+1).P zn[i]=z2n*zn[i-1]*hc; zd[i]=z2d*zd[i-1]*hcd; } A=P; // reset A /* Left to right method */ nb=bits(q3); for (i=nb-2;i>=1;i-=(nbw+nzs)) { n=naf_window(q,q3,i,&nbw,&nzs); // standard MIRACL NAF windowing for (j=0;j<nbw;j++) { ha*=ha; had*=had; g(A,A,Qx,Qy,ha,had,ADD,FALSE); // 16 ZZn muls + 1 inverse } // 30 ZZn muls (Projective) if (n>0) { ha*= zn[n/2]; had*=zd[n/2]; g(A,t[n/2],Qx,Qy,ha,had,ADD,FALSE); // 17 ZZn muls + 1 inverse } // 40 ZZn muls (Projective) if (n<0) { n=(-n); ha*=zd[n/2]; had*=zn[n/2]; g(A,t[n/2],Qx,Qy,ha,had,SUB,FALSE); // 17 ZZn muls + 1 inverse } // 40 ZZn muls (Projective) for (j=0;j<nzs;j++) { ha*=ha; had*=had; g(A,A,Qx,Qy,ha,had,ADD,FALSE); // 16 ZZn muls + 1 inversion } // 30 ZZn muls (Projective) if (ha==0 || had==0) return FALSE; } #endif if (!A.iszero()) return FALSE; res=(ha/had); p=get_modulus(); // get p res= pow(res,(p+1)/q); // raise to power of (p^2-1)/q res=conj(res)/res; if (res.isunity()) return FALSE; return TRUE; }