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; }
BOOL zzn4_compare(zzn4 *x,zzn4 *y) { if (zzn2_compare(&(x->a),&(y->a)) && zzn2_compare(&(x->b),&(y->b))) return TRUE; return FALSE; }