void zzn4_conj(_MIPD_ zzn4 *x,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif MR_IN(FUNC_BASE+2) if (mr_mip->ERNUM) return; zzn4_copy(x,w); zzn2_negate(_MIPP_ &(w->b),&(w->b)); MR_OUT }
void zzn4_sqr(_MIPD_ zzn4 *x,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif zzn2 t1,t2; if (mr_mip->ERNUM) return; MR_IN(FUNC_BASE+8) t1.a=mr_mip->w10; t1.b=mr_mip->w11; t2.a=mr_mip->w8; t2.b=mr_mip->w9; zzn4_copy(x,w); if (x->unitary) { /* this is a lot faster.. - see Lenstra & Stam */ zzn2_mul(_MIPP_ &(w->b),&(w->b),&t1); zzn2_add(_MIPP_ &(w->b),&(w->a),&(w->b)); zzn2_mul(_MIPP_ &(w->b),&(w->b),&(w->b)); zzn2_sub(_MIPP_ &(w->b),&t1,&(w->b)); zzn2_txx(_MIPP_ &t1); zzn2_copy(&t1,&(w->a)); zzn2_sub(_MIPP_ &(w->b),&(w->a),&(w->b)); zzn2_add(_MIPP_ &(w->a),&(w->a),&(w->a)); zzn2_sadd(_MIPP_ &(w->a),mr_mip->one,&(w->a)); zzn2_ssub(_MIPP_ &(w->b),mr_mip->one,&(w->b)); } else { zzn2_copy(&(w->b),&t2); // t2=b; zzn2_add(_MIPP_ &(w->a),&t2,&t1); // t1=a+b zzn2_txx(_MIPP_ &t2); zzn2_add(_MIPP_ &t2,&(w->a),&t2); // t2=a+txx(b) zzn2_mul(_MIPP_ &(w->b),&(w->a),&(w->b)); // b*=a zzn2_mul(_MIPP_ &t1,&t2,&(w->a)); // a=t1*t2 zzn2_copy(&(w->b),&t2); //t2=b zzn2_sub(_MIPP_ &(w->a),&t2,&(w->a)); //a-=b zzn2_txx(_MIPP_ &t2); // t2=txx(b) zzn2_sub(_MIPP_ &(w->a),&t2,&(w->a)); // a-=txx(b); zzn2_add(_MIPP_ &(w->b),&(w->b),&(w->b)); // b+=b; } MR_OUT }
void ecap(_MIPD_ zzn2 *Qx,zzn2 *Qy,epoint *P,big T,big fr,big delta,zzn2* r) { zzn4 res,w; #ifndef MR_STATIC char *mem=memalloc(_MIPP_ 8); #else char mem[MR_BIG_RESERVE(8)]; memset(mem,0,MR_BIG_RESERVE(8)); #endif res.x.a=mirvar_mem(_MIPP_ mem,0); res.x.b=mirvar_mem(_MIPP_ mem,1); res.y.a=mirvar_mem(_MIPP_ mem,2); res.y.b=mirvar_mem(_MIPP_ mem,3); w.x.a=mirvar_mem(_MIPP_ mem,4); w.x.b=mirvar_mem(_MIPP_ mem,5); w.y.a=mirvar_mem(_MIPP_ mem,6); w.y.b=mirvar_mem(_MIPP_ mem,7); res.unitary=FALSE; w.unitary=FALSE; epoint_norm(_MIPP_ P); fast_tate_pairing(_MIPP_ Qx,Qy,P,T,fr,delta,&w,&res); zzn4_copy(&res,&w); zzn4_powq(_MIPP_ fr,&res); zzn4_powu(_MIPP_ &w,delta,&w); zzn4_mul(_MIPP_ &res,&w,&res); zzn2_copy(&(res.x),r); #ifdef MR_COUNT_OPS printf("Final Exponentiation cost\n"); printf("fpc= %d\n",fpc); printf("fpa= %d\n",fpa); printf("fpx= %d\n",fpx); fpa=fpc=fpx=0; #endif #ifndef MR_STATIC memkill(_MIPP_ mem,8); #else memset(mem,0,MR_BIG_RESERVE(8)); #endif }
void fast_tate_pairing(_MIPD_ zzn2 *Qx,zzn2 *Qy,epoint *P,big T,big fr,big delta,zzn4 *w,zzn4* res) { int i,j,nb; zzn2 Ax,Ay,Az,Qz; zzn Px,Py; #ifndef MR_STATIC char *mem=memalloc(_MIPP_ 10); #else char mem[MR_BIG_RESERVE(10)]; memset(mem,0,MR_BIG_RESERVE(10)); #endif #ifdef MR_COUNT_OPS fpa=fpc=fpx=0; #endif Ax.a=mirvar_mem(_MIPP_ mem,0); Ax.b=mirvar_mem(_MIPP_ mem,1); Ay.a=mirvar_mem(_MIPP_ mem,2); Ay.b=mirvar_mem(_MIPP_ mem,3); Az.a=mirvar_mem(_MIPP_ mem,4); Az.b=mirvar_mem(_MIPP_ mem,5); Qz.a=mirvar_mem(_MIPP_ mem,6); Qz.b=mirvar_mem(_MIPP_ mem,7); Px=mirvar_mem(_MIPP_ mem,8); Py=mirvar_mem(_MIPP_ mem,9); copy(P->X,Px); copy(P->Y,Py); nres_modadd(_MIPP_ Px,Px,Px); /* removes a factor of 2 from g() */ nres_modadd(_MIPP_ Py,Py,Py); zzn2_from_int(_MIPP_ 1,&Qz); zzn2_copy(Qx,&Ax); zzn2_copy(Qy,&Ay); zzn2_copy(&Qz,&Az); zzn4_from_int(_MIPP_ 1,res); /* Simple Miller loop */ nb=logb2(_MIPP_ T); for (i=nb-2; i>=0; i--) { zzn4_mul(_MIPP_ res,res,res); g(_MIPP_ &Ax,&Ay,&Az,&Ax,&Ay,&Az,Px,Py,w); zzn4_mul(_MIPP_ res,w,res); if (mr_testbit(_MIPP_ T,i)) { g(_MIPP_ &Ax,&Ay,&Az,Qx,Qy,&Qz,Px,Py,w); zzn4_mul(_MIPP_ res,w,res); } } #ifdef MR_COUNT_OPS printf("Millers loop Cost\n"); printf("fpc= %d\n",fpc); printf("fpa= %d\n",fpa); printf("fpx= %d\n",fpx); fpa=fpc=fpx=0; #endif zzn4_copy(res,w); zzn4_powq(_MIPP_ fr,w); zzn4_powq(_MIPP_ fr,w); zzn4_inv(_MIPP_ res); zzn4_mul(_MIPP_ res,w,res); /* ^(p*p-1) */ res->unitary=TRUE; zzn4_mul(_MIPP_ res,res,res); zzn4_copy(res,w); zzn4_mul(_MIPP_ res,res,res); zzn4_mul(_MIPP_ res,res,res); zzn4_mul(_MIPP_ res,res,res); zzn4_mul(_MIPP_ res,res,res); zzn4_mul(_MIPP_ res,w,res); /* res=powu(res,CF) for CF=34 */ #ifndef MR_STATIC memkill(_MIPP_ mem,10); #else memset(mem,0,MR_BIG_RESERVE(10)); #endif }
void zzn4_powu(_MIPD_ zzn4 *x,big k,zzn4 *u) { zzn4 t[5],u2; big k3; int i,j,n,nb,nbw,nzs; #ifndef MR_STATIC char *mem=memalloc(_MIPP_ 25); #else char mem[MR_BIG_RESERVE(25)]; memset(mem,0,MR_BIG_RESERVE(25)); #endif if (size(k)==0) { zzn4_from_int(_MIPP_ 1,u); return; } zzn4_copy(x,u); if (size(k)==1) return; for (j=i=0; i<5; i++) { t[i].x.a=mirvar_mem(_MIPP_ mem,j++); t[i].x.b=mirvar_mem(_MIPP_ mem,j++); t[i].y.a=mirvar_mem(_MIPP_ mem,j++); t[i].y.b=mirvar_mem(_MIPP_ mem,j++); t[i].unitary=FALSE; } u2.x.a=mirvar_mem(_MIPP_ mem,j++); u2.x.b=mirvar_mem(_MIPP_ mem,j++); u2.y.a=mirvar_mem(_MIPP_ mem,j++); u2.y.b=mirvar_mem(_MIPP_ mem,j++); u2.unitary=FALSE; k3=mirvar_mem(_MIPP_ mem,j); premult(_MIPP_ k,3,k3); zzn4_mul(_MIPP_ u,u,&u2); zzn4_copy(u,&t[0]); for (i=1; i<=4; i++) zzn4_mul(_MIPP_ &u2,&t[i-1],&t[i]); nb=logb2(_MIPP_ k3); for (i=nb-2; i>=1;) { n=mr_naf_window(_MIPP_ k,k3,i,&nbw,&nzs,5); for (j=0; j<nbw; j++) zzn4_mul(_MIPP_ u,u,u); if (n>0) zzn4_mul(_MIPP_ u,&t[n/2],u); if (n<0) { zzn4_conj(_MIPP_ &t[-n/2],&u2); zzn4_mul(_MIPP_ u,&u2,u); } i-=nbw; if (nzs) { for (j=0; j<nzs; j++) zzn4_mul(_MIPP_ u,u,u); i-=nzs; } } #ifndef MR_STATIC memkill(_MIPP_ mem,25); #else memset(mem,0,MR_BIG_RESERVE(25)); #endif }
void zzn4_mul(_MIPD_ zzn4 *u,zzn4 *v,zzn4 *w) { zzn2 t1,t2,t3; t1.a=mr_mip->w3; t1.b=mr_mip->w4; t2.a=mr_mip->w8; t2.b=mr_mip->w9; if (u==v) { if (u->unitary) { /* this is faster.. - see Lenstra & Stam */ zzn4_copy(u,w); zzn2_mul(_MIPP_ &(w->y),&(w->y),&t1); zzn2_add(_MIPP_ &(w->y),&(w->x),&(w->y)); zzn2_mul(_MIPP_ &(w->y),&(w->y),&(w->y)); zzn2_sub(_MIPP_ &(w->y),&t1,&(w->y)); zzn2_timesi(_MIPP_ &t1); zzn2_copy(&t1,&(w->x)); zzn2_sub(_MIPP_ &(w->y),&(w->x),&(w->y)); zzn2_add(_MIPP_ &(w->x),&(w->x),&(w->x)); zzn2_sadd(_MIPP_ &(w->x),mr_mip->one,&(w->x)); zzn2_ssub(_MIPP_ &(w->y),mr_mip->one,&(w->y)); } else { zzn4_copy(u,w); zzn2_copy(&(w->y),&t2); // t2=b; zzn2_add(_MIPP_ &(w->x),&t2,&t1); // t1=a+b zzn2_times_irp(_MIPP_ &t2); // t2=txx(b); zzn2_add(_MIPP_ &t2,&(w->x),&t2); // t2=a+txx(b) zzn2_mul(_MIPP_ &(w->y),&(w->x),&(w->y)); // b*=a zzn2_mul(_MIPP_ &t1,&t2,&(w->x)); // a=t1*t2 zzn2_copy(&(w->y),&t2); //t2=b zzn2_sub(_MIPP_ &(w->x),&t2,&(w->x)); //a-=b zzn2_times_irp(_MIPP_ &t2); // t2=txx(b) zzn2_sub(_MIPP_ &(w->x),&t2,&(w->x)); // a-=txx(b); zzn2_add(_MIPP_ &(w->y),&(w->y),&(w->y)); // b+=b; } } else { t3.a=mr_mip->w10; t3.b=mr_mip->w11; zzn2_copy(&(u->x),&t1); zzn2_copy(&(u->y),&t2); zzn2_mul(_MIPP_ &t1,&(v->x),&t1); zzn2_mul(_MIPP_ &t2,&(v->y),&t2); zzn2_copy(&(v->x),&t3); zzn2_add(_MIPP_ &t3,&(v->y),&t3); zzn2_add(_MIPP_ &(u->y),&(u->x),&(w->y)); zzn2_mul(_MIPP_ &(w->y),&t3,&(w->y)); zzn2_sub(_MIPP_ &(w->y),&t1,&(w->y)); zzn2_sub(_MIPP_ &(w->y),&t2,&(w->y)); zzn2_copy(&t1,&(w->x)); zzn2_times_irp(_MIPP_ &t2); zzn2_add(_MIPP_ &(w->x),&t2,&(w->x)); if (u->unitary && v->unitary) w->unitary=TRUE; else w->unitary=FALSE; } }
void zzn4_conj(_MIPD_ zzn4 *u,zzn4 *w) { zzn4_copy(u,w); zzn2_negate(_MIPP_ &(w->y),&(w->y)); }