BOOL power_tate(ECn2& P,ECn Q,Big& T,Big *cf,ZZn2 &Fr,Big &e,ZZn2& r) { int i,nb; ECn2 A; ZZn4 w,res,a[2]; ZZn Qx,Qy; Big carry,ex[2],p=get_modulus(); extract(Q,Qx,Qy); res=1; /* Left to right method */ A=P; nb=bits(T); for (i=nb-2;i>=0;i--) { res*=res; res*=g(A,A,Qx,Qy); if (bit(T,i)) res*=g(A,P,Qx,Qy); } // if (!A.iszero() || res.iszero()) return FALSE; w=res; w.powq(Fr); w.powq(Fr); // ^(p^2-1) res=w/res; res.mark_as_unitary(); if (e.isone()) { ex[0]=cf[0]; ex[1]=cf[1]; } else { // cf *= e carry=mad(cf[1],e,(Big)0,p,ex[1]); mad(cf[0],e,carry,p,ex[0]); } a[0]=a[1]=res; a[0].powq(Fr); res=pow(2,a,ex); r=real(res); // compression if (r.isunity()) return FALSE; return TRUE; }
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; }
int main() { ofstream common("common.ibe"); ofstream master("master.ibe"); ECn P,Ppub; ZZn2 cube; Big s,p,q,t,n,cof,x,y; long seed; miracl *mip=&precision; cout << "Enter 9 digit random number seed = "; cin >> seed; irand(seed); // SET-UP #ifdef SIMPLE q=pow((Big)2,159)+pow((Big)2,17)+1; #else // generate random q forever { n=rand(QBITS-1,2); // 159 bit number, base 2 q=2*n+1; // 160 bit while (!prime(q)) q+=2; if (bits(q)>QBITS) continue; break; } #endif cout << "q= " << q << endl; // generate p t=(pow((Big)2,PBITS)-1)/(2*q); s=(pow((Big)2,PBITS-1)-1)/(2*q); forever { n=rand(t); if (n<s) continue; p=2*n*q-1; if (p%12!=11) continue; // must be 2 mod 3, also 3 mod 4 if (prime(p)) break; } cout << "p= " << p << endl; cof=2*n; ecurve(0,1,p,MR_PROJECTIVE); // elliptic curve y^2=x^3+1 mod p // // Find suitable cube root of unity (solution in Fp2 of x^3=1 mod p) // forever { // cube=pow(randn2(),(p+1)*(p-1)/3); cube=pow(randn2(),(p+1)/3); cube=pow(cube,p-1); if (!cube.isunity()) break; } cout << "Cube root of unity= " << cube << endl; if (!(cube*cube*cube).isunity()) { cout << "sanity check failed" << endl; exit(0); } // // Choosing an arbitrary P .... // forever { while (!P.set(randn())) ; P*=cof; if (!P.iszero()) break; } cout << "Point P= " << P << endl; // // Pick a random master key s // s=rand(q); Ppub=s*P; cout << "Secret s= " << s << endl; cout << "Point Ppub= " << Ppub << endl; common << PBITS << endl; mip->IOBASE=16; common << p << endl; common << q << endl; P.get(x,y); common << x << endl; common << y << endl; Ppub.get(x,y); common << x << endl; common << y << endl; cube.get(x,y); common << x << endl; common << y << endl; master << s << endl; return 0; }
BOOL tate(ECn& P,ECn2 Q,Big& q,ZZn2 &Fr,Big cof,ZZn2& r) { int i,j,n,nb,nbw,nzs; ECn A,P2,t[8]; ZZn4 w,hc,z2n,zn[8],res; ZZn2 Qx,Qy; #ifdef MR_COUNT_OPS fpc=fpa=fpx=0; #endif Q.get(Qx,Qy); Qx=txd(Qx); Qy=txd(txd(Qy)); normalise(P); res=zn[0]=1; t[0]=P2=A=P; z2n=g(P2,P2,Qx,Qy); // P2=P+P normalise(P2); // // Build windowing table // for (i=1;i<8;i++) { hc=g(A,P2,Qx,Qy); t[i]=A; zn[i]=z2n*zn[i-1]*hc; } multi_norm(8,t); // make t points Affine A=P; nb=bits(q); for (i=nb-2;i>=0;i-=(nbw+nzs)) { n=window(q,i,&nbw,&nzs,4); // standard MIRACL windowing for (j=0;j<nbw;j++) { res*=res; res*=g(A,A,Qx,Qy); } if (n>0) { res*=zn[n/2]; res*=g(A,t[n/2],Qx,Qy); } for (j=0;j<nzs;j++) { res*=res; res*=g(A,A,Qx,Qy); } } if (!A.iszero()) return FALSE; #ifdef MR_COUNT_OPS printf("After Miller fpc= %d fpa= %d fpx= %d\n",fpc,fpa,fpx); fpa=fpc=fpx=0; #endif w=res; w.powq(Fr); w.powq(Fr); // ^(p^2-1) res=w/res; res.mark_as_unitary(); res*=res; w=res; res*=res; res*=res; res*=res; res*=res; res*=w; // res=powu(res,34); w=res; res.powq(Fr); res*=powu(w,cof); #ifdef MR_COUNT_OPS printf("After Final exp. fpc= %d fpa= %d fpx= %d\n",fpc,fpa,fpx); fpa=fpc=fpx=0; #endif r=real(res); if (r.isunity()) return FALSE; return TRUE; }