void power4(_MIPD_ big *a,big k,big *u) { int i,j,m,nb,n,nbw,nzs; big u2[4],t[4][4]; #ifndef MR_STATIC char *mem=(char *)memalloc(_MIPP_ 20); #else char mem[MR_BIG_RESERVE(20)]; memset(mem,0,MR_BIG_RESERVE(20)); #endif m=0; for (i=0;i<4;i++) for (j=0;j<4;j++) t[i][j]=mirvar_mem(_MIPP_ mem,m++); u2[0]=mirvar_mem(_MIPP_ mem,16); u2[1]=mirvar_mem(_MIPP_ mem,17); u2[2]=mirvar_mem(_MIPP_ mem,18); u2[3]=mirvar_mem(_MIPP_ mem,19); if(size(k)==0) { convert(_MIPP_ 1,u[0]); zero(u[1]); zero(u[2]); zero(u[3]); #ifndef MR_STATIC memkill(_MIPP_ mem,20); #else memset(mem,0,MR_BIG_RESERVE(20)); #endif return; } for (i=0;i<4;i++) fcopy2(a[i],u[i]); if (size(k)==1) { #ifndef MR_STATIC memkill(_MIPP_ mem,20); #else memset(mem,0,MR_BIG_RESERVE(20)); #endif return; } square4(_MIPP_ u,u2); for (i=0;i<4;i++) fcopy2(u[i],t[0][i]); for(i=1;i<4;i++) mult4(_MIPP_ u2,t[i-1],t[i]); nb=logb2(_MIPP_ k); if(nb>1) for(i=nb-2;i>=0;) { n=mr_window(_MIPP_ k,i,&nbw,&nzs,3); /* small 3 bit window to save RAM */ for(j=0;j<nbw;j++) square4(_MIPP_ u,u); if(n>0) mult4(_MIPP_ u,t[n/2],u); i-=nbw; if(nzs!=0) { for (j=0;j<nzs;j++) square4(_MIPP_ u,u); i-=nzs; } } #ifndef MR_STATIC memkill(_MIPP_ mem,20); #else memset(mem,0,MR_BIG_RESERVE(20)); #endif }
void fast_tate_pairing(_MIPD_ epoint *P,zzn3 *Qx,zzn3 *Qy,big q,big cf,zzn6 *w,zzn6* res) { int i,j,n,nb,nbw,nzs; epoint *t[4],*A,*P2; zzn6 zn[4]; big work[4]; #ifndef MR_STATIC char *mem=memalloc(_MIPP_ 28); char *mem1=ecp_memalloc(_MIPP_ 6); #else char mem[MR_BIG_RESERVE(28)]; char mem1[MR_ECP_RESERVE(6)]; memset(mem,0,MR_BIG_RESERVE(28)); memset(mem1,0,MR_ECP_RESERVE(6)); #endif for (i=0;i<4;i++) t[i]=epoint_init_mem(_MIPP_ mem1,i); A=epoint_init_mem(_MIPP_ mem1,4); P2=epoint_init_mem(_MIPP_ mem1,5); for (j=i=0;i<4;i++) { work[i]=mirvar_mem(_MIPP_ mem,j++); zn[i].x.a=mirvar_mem(_MIPP_ mem,j++); zn[i].x.b=mirvar_mem(_MIPP_ mem,j++); zn[i].x.c=mirvar_mem(_MIPP_ mem,j++); zn[i].y.a=mirvar_mem(_MIPP_ mem,j++); zn[i].y.b=mirvar_mem(_MIPP_ mem,j++); zn[i].y.c=mirvar_mem(_MIPP_ mem,j++); zn[i].unitary=FALSE; } zzn6_from_int(_MIPP_ 1,&zn[0]); epoint_copy(P,A); epoint_copy(P,P2); epoint_copy(P,t[0]); g(_MIPP_ P2,P2,Qx,Qy,res); epoint_norm(_MIPP_ P2); for (i=1;i<4;i++) { g(_MIPP_ A,P2,Qx,Qy,w); epoint_copy(A,t[i]); zzn6_mul(_MIPP_ &zn[i-1],w,&zn[i]); zzn6_mul(_MIPP_ &zn[i],res,&zn[i]); } epoint_multi_norm(_MIPP_ 4,work,t); epoint_copy(P,A); zzn6_from_int(_MIPP_ 1,res); nb=logb2(_MIPP_ q); for (i=nb-2;i>=0;i-=(nbw+nzs)) { n=mr_window(_MIPP_ q,i,&nbw,&nzs,3); for (j=0;j<nbw;j++) { zzn6_mul(_MIPP_ res,res,res); g(_MIPP_ A,A,Qx,Qy,w); zzn6_mul(_MIPP_ res,w,res); } if (n>0) { zzn6_mul(_MIPP_ res,&zn[n/2],res); g(_MIPP_ A,t[n/2],Qx,Qy,w); zzn6_mul(_MIPP_ res,w,res); } for (j=0;j<nzs;j++) { zzn6_mul(_MIPP_ res,res,res); g(_MIPP_ A,A,Qx,Qy,w); zzn6_mul(_MIPP_ res,w,res); } } zzn6_copy(res,w); zzn6_powq(_MIPP_ w); zzn6_mul(_MIPP_ res,w,res); zzn6_copy(res,w); zzn6_powq(_MIPP_ w); zzn6_powq(_MIPP_ w); zzn6_powq(_MIPP_ w); zzn6_inv(_MIPP_ res); zzn6_mul(_MIPP_ res,w,res); res->unitary=TRUE; #ifndef MR_STATIC memkill(_MIPP_ mem,28); ecp_memkill(_MIPP_ mem1,6); #else memset(mem,0,MR_BIG_RESERVE(28)); memset(mem1,0,MR_ECP_RESERVE(6)); #endif }