void zzn4_smul(_MIPD_ zzn4 *x,zzn2 *y,zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(FUNC_BASE+7) if (!zzn2_iszero(&(x->a))) zzn2_mul(_MIPP_ &(x->a),y,&(w->a)); else zzn2_zero(&(w->a)); if (!zzn2_iszero(&(x->b))) zzn2_mul(_MIPP_ &(x->b),y,&(w->b)); else zzn2_zero(&(w->b)); w->unitary=FALSE; MR_OUT }
void zzn4_from_int(_MIPD_ int i,zzn4 *w) { zzn2_from_int(_MIPP_ i,&(w->x)); zzn2_zero(&(w->y)); if (i==1) w->unitary=TRUE; else w->unitary=FALSE; }
void zzn4_from_big(_MIPD_ big x, zzn4 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(FUNC_BASE+16) zzn2_from_big(_MIPP_ x,&(w->a)); zzn2_zero(&(w->b)); MR_OUT }
void zzn2_mul(_MIPD_ zzn2 *x,zzn2 *y,zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; if (x==y) {zzn2_sqr(_MIPP_ x,w); return; } MR_IN(162) /* Uses w1, w2, and w5 */ if (zzn2_iszero(x) || zzn2_iszero(y)) zzn2_zero(w); else { #ifdef MR_COUNT_OPS fpmq++; #endif #ifndef MR_NO_LAZY_REDUCTION if (x->a->len!=0 && x->b->len!=0 && y->a->len!=0 && y->b->len!=0) nres_lazy(_MIPP_ x->a,x->b,y->a,y->b,w->a,w->b); else { #endif nres_modmult(_MIPP_ x->a,y->a,mr_mip->w1); nres_modmult(_MIPP_ x->b,y->b,mr_mip->w2); nres_modadd(_MIPP_ x->a,x->b,mr_mip->w5); nres_modadd(_MIPP_ y->a,y->b,w->b); nres_modmult(_MIPP_ w->b,mr_mip->w5,w->b); nres_modsub(_MIPP_ w->b,mr_mip->w1,w->b); nres_modsub(_MIPP_ w->b,mr_mip->w2,w->b); nres_modsub(_MIPP_ mr_mip->w1,mr_mip->w2,w->a); if (mr_mip->qnr==-2) nres_modsub(_MIPP_ w->a,mr_mip->w2,w->a); #ifndef MR_NO_LAZY_REDUCTION } #endif } MR_OUT }
BOOL ecurve_fp2_add(_MIPD_ zzn2 *Zx, zzn2 *Zy, zzn2 *Zz, zzn2 *x, zzn2 *y, zzn2 *z, zzn2 *lam,zzn2 *ex1,zzn2 *ex2) { BOOL doubling,normed; zzn2 Xzz, Yzzz, xZZ, yZZZ, zz, ZZ; zzn2 t1, t2, t3, x3; #ifndef MR_STATIC char *mem = memalloc(_MIPP_ 20); #else char mem[MR_BIG_RESERVE(20)]; memset(mem, 0, MR_BIG_RESERVE(20)); #endif Xzz.a = mirvar_mem(_MIPP_ mem, 0); Xzz.b = mirvar_mem(_MIPP_ mem, 1); Yzzz.a = mirvar_mem(_MIPP_ mem, 2); Yzzz.b = mirvar_mem(_MIPP_ mem, 3); xZZ.a = mirvar_mem(_MIPP_ mem, 4); xZZ.b = mirvar_mem(_MIPP_ mem, 5); yZZZ.a = mirvar_mem(_MIPP_ mem, 6); yZZZ.b = mirvar_mem(_MIPP_ mem, 7); zz.a = mirvar_mem(_MIPP_ mem, 8); zz.b = mirvar_mem(_MIPP_ mem, 9); ZZ.a = mirvar_mem(_MIPP_ mem, 10); ZZ.b = mirvar_mem(_MIPP_ mem, 11); t1.a = mirvar_mem(_MIPP_ mem, 12); t1.b = mirvar_mem(_MIPP_ mem, 13); t2.a = mirvar_mem(_MIPP_ mem, 14); t2.b = mirvar_mem(_MIPP_ mem, 15); t3.a = mirvar_mem(_MIPP_ mem, 16); t3.b = mirvar_mem(_MIPP_ mem, 17); x3.a = mirvar_mem(_MIPP_ mem, 18); x3.b = mirvar_mem(_MIPP_ mem, 19); doubling=FALSE; if (z==Zz) doubling=TRUE; if (!doubling) { // maybe we are really doubling? Or P-=P? if (!zzn2_isunity(_MIPP_ Zz)) { zzn2_mul(_MIPP_ Zz, Zz, &ZZ); // ZZ = Zz^2 zzn2_mul(_MIPP_ x, &ZZ, &xZZ); // xZZ = x * Zz^2 zzn2_mul(_MIPP_ &ZZ, Zz, &yZZZ); // yZZZ = Zz^3 zzn2_mul(_MIPP_ &yZZZ, y, &yZZZ); // yZZZ = y * Zz^3 normed=FALSE; } else { zzn2_copy(x,&xZZ); zzn2_copy(y,&yZZZ); normed=TRUE; } if (!zzn2_isunity(_MIPP_ z)) { zzn2_mul(_MIPP_ z, z, &zz); // zz = z^2 zzn2_mul(_MIPP_ Zx, &zz, &Xzz); // Xzz = Zx * z^2 zzn2_mul(_MIPP_ &zz, z, &Yzzz); // Yzzz = z^3 zzn2_mul(_MIPP_ &Yzzz, Zy, &Yzzz); // Yzzz = Zy * z^3 } else { zzn2_copy(Zx,&Xzz); zzn2_copy(Zy,&Yzzz); } if (zzn2_compare(&Xzz,&xZZ)) { if (!zzn2_compare(&Yzzz,&yZZZ) || zzn2_iszero(y)) { zzn2_zero(x); zzn2_zero(y); zzn2_zero(z); zzn2_from_int(_MIPP_ 1,lam); #ifndef MR_STATIC memkill(_MIPP_ mem, 20); #else memset(mem, 0, MR_BIG_RESERVE(20)); #endif return doubling; } else doubling=TRUE; } } if (!doubling) { // point addition zzn2_sub(_MIPP_ &xZZ, &Xzz, &t1); // t1 = Xzz - xZZ zzn2_sub(_MIPP_ &yZZZ, &Yzzz, lam); // lam = yZZZ - yZZZ zzn2_mul(_MIPP_ z,&t1,z); if (!normed) zzn2_mul(_MIPP_ z,&ZZ,z); zzn2_mul(_MIPP_ &t1,&t1,&t2); zzn2_add(_MIPP_ &xZZ,&Xzz,&t3); zzn2_mul(_MIPP_ &t3,&t2,&t3); zzn2_mul(_MIPP_ lam, lam, &x3); // x3 = lam^2 zzn2_sub(_MIPP_ &x3,&t3,&x3); zzn2_sub(_MIPP_ &t3,&x3,&t3); zzn2_sub(_MIPP_ &t3,&x3,&t3); zzn2_mul(_MIPP_ &t3,lam,&t3); zzn2_mul(_MIPP_ &t2,&t1,&t2); zzn2_add(_MIPP_ &yZZZ,&Yzzz,&t1); zzn2_mul(_MIPP_ &t1,&t2,&t1); zzn2_sub(_MIPP_ &t3,&t1,y); zzn2_div2(_MIPP_ y); zzn2_copy(&x3,x); } else { // point doubling zzn2_mul(_MIPP_ y, y, &t2); // t2 = y^2 /* its on the twist so A=6! */ zzn2_mul(_MIPP_ z,z,ex2); zzn2_mul(_MIPP_ x,x,lam); zzn2_mul(_MIPP_ ex2,ex2,&t1); zzn2_add(_MIPP_ &t1,&t1,&t1); zzn2_add(_MIPP_ lam,&t1,lam); zzn2_copy(lam,&t1); zzn2_add(_MIPP_ lam,lam,lam); zzn2_add(_MIPP_ lam,&t1,lam); zzn2_mul(_MIPP_ x, &t2, &t1); // t1 = x * y^2 zzn2_add(_MIPP_ &t1, &t1, &t1); // t1 = 2(x*y^2) zzn2_add(_MIPP_ &t1, &t1, &t1); // t1 = 4(x*y^2) // x = lam^2 - t1 - t1 zzn2_mul(_MIPP_ lam, lam, x); // x = lam^2 zzn2_sub(_MIPP_ x, &t1, x); // x = lam^2 - t1 zzn2_sub(_MIPP_ x, &t1, x); // x = lam^2 - 2t1 zzn2_mul(_MIPP_ z, y , z); // z = yz zzn2_add(_MIPP_ z, z, z); // z = 2yz // 8 * y^2 zzn2_add(_MIPP_ &t2, &t2, &t2); // t2 = 2y^2 zzn2_copy(&t2,ex1); zzn2_mul(_MIPP_ &t2, &t2, &t2); // t2 = 4y^2 zzn2_add(_MIPP_ &t2, &t2, &t2); // t2 = 8y^2 // y = lam*(t - x) - y^2 zzn2_sub(_MIPP_ &t1, x, y); // y = t1 - x zzn2_mul(_MIPP_ y, lam, y); // y = lam(t1 - x) zzn2_sub(_MIPP_ y, &t2, y); // y = lam(t1 - x) * y^2 } #ifndef MR_STATIC memkill(_MIPP_ mem, 20); #else memset(mem, 0, MR_BIG_RESERVE(20)); #endif return doubling; }
void zzn4_from_zzn(big x,zzn4 *w) { zzn2_from_zzn(x,&(w->a)); zzn2_zero(&(w->b)); w->unitary=FALSE; }
void zzn4_from_zzn2h(zzn2 *x,zzn4 *w) { zzn2_copy(x,&(w->b)); zzn2_zero(&(w->a)); w->unitary=FALSE; }
void zzn4_zero(zzn4 *w) { zzn2_zero(&(w->a)); zzn2_zero(&(w->b)); w->unitary=FALSE; }