void zzn6_inv(_MIPD_ zzn6 *w) { zzn3 t1,t2; if (w->unitary) { zzn6_conj(_MIPP_ w,w); return; } t1.a=mr_mip->w7; t1.b=mr_mip->w8; t1.c=mr_mip->w9; t2.a=mr_mip->w10; t2.b=mr_mip->w11; t2.c=mr_mip->w12; zzn3_copy(&(w->x),&t1); zzn3_copy(&(w->y),&t2); zzn3_mul(_MIPP_ &t1,&t1,&t1); zzn3_mul(_MIPP_ &t2,&t2,&t2); zzn3_timesi(_MIPP_ &t2); zzn3_sub(_MIPP_ &t1,&t2,&t2); zzn3_inv(_MIPP_ &t2); zzn3_mul(_MIPP_ &(w->x),&t2,&(w->x)); zzn3_negate(_MIPP_ &(w->y),&(w->y)); zzn3_mul(_MIPP_ &(w->y),&t2,&(w->y)); }
void zzn6_copy(zzn6 *u,zzn6 *w) { if (u==w) return; zzn3_copy(&(u->x),&(w->x)); zzn3_copy(&(u->y),&(w->y)); w->unitary=u->unitary; }
void zzn3_powl(_MIPD_ zzn3 *x,big e,zzn3 *w) { int i,s; zzn3 t1,t3,t4; t1.a=mr_mip->w7; t1.b=mr_mip->w8; t1.c=mr_mip->w9; t3.a=mr_mip->w10; t3.b=mr_mip->w11; t3.c=mr_mip->w12; t4.a=mr_mip->w13; t4.b=mr_mip->w14; t4.c=mr_mip->w15; zzn3_from_int(_MIPP_ 1,&t1); s=size(e); if (s==0) { zzn3_copy(&t1,w); return; } zzn3_copy(x,w); if (s==1 || s==(-1)) return; i=logb2(_MIPP_ e)-1; zzn3_copy(w,&t3); zzn3_mul(_MIPP_ w,w,&t4); zzn3_add(_MIPP_ &t4,&t4,&t4); zzn3_sub(_MIPP_ &t4,&t1,&t4); while (i--) { if (mr_testbit(_MIPP_ e,i)) { zzn3_mul(_MIPP_ &t3,&t4,&t3); zzn3_add(_MIPP_ &t3,&t3,&t3); zzn3_sub(_MIPP_ &t3,w,&t3); zzn3_mul(_MIPP_ &t4,&t4,&t4); zzn3_add(_MIPP_ &t4,&t4,&t4); zzn3_sub(_MIPP_ &t4,&t1,&t4); } else { zzn3_mul(_MIPP_ &t4,&t3,&t4); zzn3_add(_MIPP_ &t4,&t4,&t4); zzn3_sub(_MIPP_ &t4,w,&t4); zzn3_mul(_MIPP_ &t3,&t3,&t3); zzn3_add(_MIPP_ &t3,&t3,&t3); zzn3_sub(_MIPP_ &t3,&t1,&t3); } } zzn3_copy(&t3,w); }
void zzn3_negate(_MIPD_ zzn3 *x,zzn3 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(177) zzn3_copy(x,w); nres_negate(_MIPP_ w->a,w->a); nres_negate(_MIPP_ w->b,w->b); nres_negate(_MIPP_ w->c,w->c); MR_OUT }
void zzn3_powq(_MIPD_ zzn3 *x,zzn3 *w) { /* sru - precalculated sixth root of unity */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif MR_IN(178) zzn3_copy(x,w); nres_modmult(_MIPP_ mr_mip->sru,mr_mip->sru,mr_mip->w1); /* cube root of unity */ nres_modmult(_MIPP_ w->b,mr_mip->w1,w->b); nres_modmult(_MIPP_ w->c,mr_mip->w1,w->c); nres_modmult(_MIPP_ w->c,mr_mip->w1,w->c); MR_OUT }
void ecap(_MIPD_ epoint *P,zzn3 *Qx,zzn3 *Qy,big q,big cf,zzn3* r) { zzn6 res,w; #ifndef MR_STATIC char *mem=memalloc(_MIPP_ 12); #else char mem[MR_BIG_RESERVE(12)]; memset(mem,0,MR_BIG_RESERVE(12)); #endif res.x.a=mirvar_mem(_MIPP_ mem,0); res.x.b=mirvar_mem(_MIPP_ mem,1); res.x.c=mirvar_mem(_MIPP_ mem,2); res.y.a=mirvar_mem(_MIPP_ mem,3); res.y.b=mirvar_mem(_MIPP_ mem,4); res.y.c=mirvar_mem(_MIPP_ mem,5); w.x.a=mirvar_mem(_MIPP_ mem,6); w.x.b=mirvar_mem(_MIPP_ mem,7); w.x.c=mirvar_mem(_MIPP_ mem,8); w.y.a=mirvar_mem(_MIPP_ mem,9); w.y.b=mirvar_mem(_MIPP_ mem,10); w.y.c=mirvar_mem(_MIPP_ mem,11); res.unitary=FALSE; w.unitary=FALSE; epoint_norm(_MIPP_ P); fast_tate_pairing(_MIPP_ P,Qx,Qy,q,cf,&w,&res); zzn6_copy(&res,&w); zzn6_powq(_MIPP_ &res); zzn6_mul(_MIPP_ &res,&res,&res); zzn6_powu(_MIPP_ &w,cf,&w); zzn6_mul(_MIPP_ &res,&w,&res); zzn3_copy(&(res.x),r); #ifndef MR_STATIC memkill(_MIPP_ mem,12); #else memset(mem,0,MR_BIG_RESERVE(12)); #endif }
void g(_MIPD_ epoint *A,epoint *B,zzn3 *Qx,zzn3 *Qy,zzn6 *w) { int type; big slope; zzn3 nn,dd; copy(A->X,mr_mip->w10); type=ecurve_add(_MIPP_ B,A); if (!type) { zzn6_from_int(_MIPP_ 1,w); return; } slope=mr_mip->w8; /* slope in w8 */ nn.a=mr_mip->w13; nn.b=mr_mip->w14; nn.c=mr_mip->w15; dd.a=mr_mip->w5; dd.b=mr_mip->w11; dd.c=mr_mip->w9; zzn3_copy(Qx,&nn); zzn3_copy(Qy,&dd); zzn3_negate(_MIPP_ &dd,&dd); #ifndef MR_AFFINE_ONLY if (A->marker!=MR_EPOINT_GENERAL) copy(mr_mip->one,mr_mip->w12); else copy(A->Z,mr_mip->w12); #else copy(mr_mip->one,mr_mip->w12); #endif if (type==MR_ADD) { zzn3_ssub(_MIPP_ &nn,B->X,&nn); zzn3_smul(_MIPP_ &nn,slope,&nn); nres_modmult(_MIPP_ mr_mip->w12,B->Y,mr_mip->w2); zzn3_sadd(_MIPP_ &nn,mr_mip->w2,&nn); zzn3_smul(_MIPP_ &dd,mr_mip->w12,&dd); zzn3_copy(&nn,&(w->x)); zzn3_copy(&dd,&(w->y)); return; } if (type==MR_DOUBLE) { /* note that ecurve_add has left useful things for us in w6 and w7! */ nres_modmult(_MIPP_ slope,mr_mip->w6,mr_mip->w2); zzn3_smul(_MIPP_ &nn,mr_mip->w2,&nn); nres_modmult(_MIPP_ slope,mr_mip->w10,slope); zzn3_ssub(_MIPP_ &nn,slope,&nn); zzn3_sadd(_MIPP_ &nn,mr_mip->w7,&nn); nres_modmult(_MIPP_ mr_mip->w12,mr_mip->w6,mr_mip->w12); zzn3_smul(_MIPP_ &dd,mr_mip->w12,&dd); zzn3_copy(&nn,&(w->x)); zzn3_copy(&dd,&(w->y)); return; } }
void zzn6_mul(_MIPD_ zzn6 *u,zzn6 *v,zzn6 *w) { zzn3 t1,t2,t3; t1.a=mr_mip->w7; t1.b=mr_mip->w8; t1.c=mr_mip->w9; t2.a=mr_mip->w10; t2.b=mr_mip->w11; t2.c=mr_mip->w12; t3.a=mr_mip->w13; t3.b=mr_mip->w14; t3.c=mr_mip->w15; if (u==v) { /* See Stam & Lenstra, "Efficient subgroup exponentiation in Quadratic .. Extensions", CHES 2002 */ if (u->unitary) { /* this is a lot faster.. */ zzn6_copy(u,w); zzn3_mul(_MIPP_ &(w->y),&(w->y),&t1); zzn3_add(_MIPP_ &(w->y),&(w->x),&(w->y)); zzn3_mul(_MIPP_ &(w->y),&(w->y),&(w->y)); zzn3_sub(_MIPP_ &(w->y),&t1,&(w->y)); zzn3_timesi(_MIPP_ &t1); zzn3_copy(&t1,&(w->x)); zzn3_sub(_MIPP_ &(w->y),&(w->x),&(w->y)); zzn3_add(_MIPP_ &(w->x),&(w->x),&(w->x)); zzn3_sadd(_MIPP_ &(w->x),mr_mip->one,&(w->x)); zzn3_ssub(_MIPP_ &(w->y),mr_mip->one,&(w->y)); } else { zzn6_copy(u,w); zzn3_add(_MIPP_ &(w->x),&(w->y),&t1); zzn3_copy(&(w->y),&t3); zzn3_timesi(_MIPP_ &t3); zzn3_add(_MIPP_ &(w->x),&t3,&t2); zzn3_mul(_MIPP_ &t1,&t2,&t1); zzn3_mul(_MIPP_ &(w->y),&(w->x),&(w->y)); zzn3_sub(_MIPP_ &t1,&(w->y),&t1); zzn3_copy(&(w->y),&t3); zzn3_timesi(_MIPP_ &t3); zzn3_sub(_MIPP_ &t1,&t3,&t1); zzn3_add(_MIPP_ &(w->y),&(w->y),&(w->y)); zzn3_copy(&t1,&(w->x)); } } else { zzn3_mul(_MIPP_ &(u->x),&(v->x),&t1); zzn3_mul(_MIPP_ &(u->y),&(v->y),&t2); zzn3_add(_MIPP_ &(v->x),&(v->y),&t3); zzn3_add(_MIPP_ &(u->x),&(u->y),&(w->y)); zzn3_mul(_MIPP_ &(w->y),&t3,&(w->y)); zzn3_sub(_MIPP_ &(w->y),&t1,&(w->y)); zzn3_sub(_MIPP_ &(w->y),&t2,&(w->y)); zzn3_copy(&t1,&(w->x)); zzn3_timesi(_MIPP_ &t2); zzn3_add(_MIPP_ &(w->x),&t2,&(w->x)); if (u->unitary && v->unitary) w->unitary=TRUE; else w->unitary=FALSE; } }