From 2dd76c7b670c3cc830fef8d6948d5f33624619d2 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Sun, 12 Apr 2020 21:43:00 +0900 Subject: [PATCH] unify ec operations --- include/mcl/mapto_wb19.hpp | 174 ++++--------------------------------- test/mapto_wb19_test.cpp | 23 +++-- 2 files changed, 29 insertions(+), 168 deletions(-) diff --git a/include/mcl/mapto_wb19.hpp b/include/mcl/mapto_wb19.hpp index 269ee12..07f5dfd 100644 --- a/include/mcl/mapto_wb19.hpp +++ b/include/mcl/mapto_wb19.hpp @@ -39,6 +39,7 @@ inline void hashToFp2(Fp2& out, const void *msg, size_t msgSize, uint8_t ctr, co namespace local { +// y^2 = x^3 + 4(1 + i) template struct PointT { typedef F Fp; @@ -56,12 +57,10 @@ struct PointT { y.clear(); z.clear(); } -#if 0 bool isEqual(const PointT& rhs) const { return ec::isEqualJacobi(*this, rhs); } -#endif }; template F PointT::a_; @@ -73,9 +72,10 @@ template int PointT::specialA_; template struct MapToG2_WB19 { typedef local::PointT Point; - Fp2 xi; Fp half; mpz_class sqrtConst; // (p^2 - 9) / 16 + Fp2 Ep_a; + Fp2 Ep_b; Fp2 root4[4]; Fp2 etas[4]; Fp2 xnum[4]; @@ -87,125 +87,17 @@ struct MapToG2_WB19 { { draftVersion_ = version; } - // should be merged into ec.hpp - template - void neg(G& Q, const G& P) const - { - Q.x = P.x; - Fp2::neg(Q.y, P.y); - Q.z = P.z; - } - // Jacobi : sqr 4, mul 12, add 11 - template - void add(G& R, const G& P, const G& Q) const - { - if (P.isZero()) { - R = Q; - return; - } - if (Q.isZero()) { - R = Q; - return; - } - Fp2 Z1Z1, Z2Z2, U1, U2, S1, S2; - Fp2::sqr(Z1Z1, P.z); - Fp2::sqr(Z2Z2, Q.z); - Fp2::mul(U1, P.x, Z2Z2); - Fp2::mul(U2, Q.x, Z1Z1); - Fp2::mul(S1, P.y, Q.z); - S1 *= Z2Z2; - Fp2::mul(S2, Q.y, P.z); - S2 *= Z1Z1; - if (U1 == U2 && S1 == S2) { - dbl(R, P); - return; - } - Fp2 H, I, J, rr, V; - Fp2::sub(H, U2, U1); - Fp2::add(I, H, H); - Fp2::sqr(I, I); - Fp2::mul(J, H, I); - Fp2::sub(rr, S2, S1); - rr += rr; - Fp2::mul(V, U1, I); - Fp2::mul(R.z, P.z, Q.z); - R.z *= H; - if (R.z.isZero()) { - R.x.clear(); - R.y.clear(); - return; - } - R.z += R.z; - Fp2::sqr(R.x, rr); - R.x -= J; - R.x -= V; - R.x -= V; - Fp2::sub(R.y, V, R.x); - R.y *= rr; - S1 *= J; - R.y -= S1; - R.y -= S1; - } - // jacobi : 2M + 5S + 14A - template - void dblT(G& Q, const G& P) const - { -#if 0 - ec::dblJacobi(Q, P, ec::GenericA, Ell2p_a); -#else - Fp2 A, B, C, D, e, f; - Fp2::sqr(A, P.x); - Fp2::sqr(B, P.y); - Fp2::sqr(C, B); - Fp2::add(D, P.x, B); - Fp2::sqr(D, D); - D -= A; - D -= C; - D += D; - Fp2::add(e, A, A); - e += A; - Fp2::sqr(f, e); - Fp2::sub(Q.x, f, D); - Q.x -= D; - Fp2::mul(Q.z, P.y, P.z); - if (Q.z.isZero()) { - Q.x.clear(); - Q.y.clear(); - return; - } - Q.z += Q.z; - Fp2::sub(Q.y, D, Q.x); - Q.y *= e; - C += C; - C += C; - C += C; - Q.y -= C; -#endif - } - void dbl(Point& Q, const Point& P) const - { - dblT(Q, P); -// ec::dblJacobi(Q, P); - } - // P is on y^2 = x^3 + Ell2p_a x + Ell2p_b - bool isValidPoint(const Point& P) const - { - return ec::isValidJacobi(P); - } - bool isValidPoint(const G2& P) const - { - return P.isValid(); - } void init() { bool b; - xi.a = -2; - xi.b = -1; - Point::a_.a = 0; - Point::a_.b = 240; - Point::b_.a = 1012; - Point::b_.b = 1012; - Point::specialA_ = ec::GenericA; + Ep_a.a = 0; + Ep_a.b = 240; + Ep_b.a = 1012; + Ep_b.b = 1012; + Point::a_.clear(); + Point::b_.a = 4; + Point::b_.b = 4; + Point::specialA_ = ec::Zero; half = -1; half /= 2; sqrtConst = Fp::getOp().mp; @@ -310,7 +202,6 @@ struct MapToG2_WB19 { // refer (xnum, xden, ynum, yden) void iso3(G2& Q, const Point& P) const { -// assert(isValidPoint(P)); Fp2 zpows[3]; Fp2::sqr(zpows[0], P.z); Fp2::sqr(zpows[1], zpows[0]); @@ -331,9 +222,9 @@ struct MapToG2_WB19 { Fp2::sqr(t, Q.z); Fp2::mul(Q.y, mapvals[2], mapvals[1]); Q.y *= t; -// assert(Q.isValid()); } /* + xi = -2-i (a+bi)*(-2-i) = (b-2a)-(a+2b)i */ void mul_xi(Fp2& y, const Fp2& x) const @@ -354,22 +245,6 @@ struct MapToG2_WB19 { if (!x.b.isZero()) return false; return false; } - /* - in : Jacobi [X:Y:Z] - out : Proj [A:B:C] - [X:Y:Z] as Jacobi - = (X/Z^2, Y/Z^3) as Affine - = [X/Z^2:Y/Z^3:1] as Proj - = [XZ:Y:Z^3] as Proj - */ - void toProj(G2& out, const G2& in) const - { - Fp2 z2; - Fp2::sqr(z2, in.z); - Fp2::mul(out.x, in.x, in.z); - out.y = in.y; - Fp2::mul(out.z, in.z, z2); - } // https://github.com/algorand/bls_sigs_ref void osswu2_help(Point& P, const Fp2& t) const { @@ -383,20 +258,20 @@ struct MapToG2_WB19 { den += den2; Fp2 x0_num, x0_den; Fp2::add(x0_num, den, 1); - x0_num *= Point::b_; + x0_num *= Ep_b; if (den.isZero()) { - Fp2::mul(x0_den, Point::a_, xi); + mul_xi(x0_den, Ep_a); } else { - Fp2::mul(x0_den, -Point::a_, den); + Fp2::mul(x0_den, -Ep_a, den); } Fp2 x0_den2, x0_den3, gx0_den, gx0_num; Fp2::sqr(x0_den2, x0_den); Fp2::mul(x0_den3, x0_den2, x0_den); gx0_den = x0_den3; - Fp2::mul(gx0_num, Point::b_, gx0_den); + Fp2::mul(gx0_num, Ep_b, gx0_den); Fp2 tmp, tmp1, tmp2; - Fp2::mul(tmp, Point::a_, x0_num); + Fp2::mul(tmp, Ep_a, x0_num); tmp *= x0_den2; gx0_num += tmp; Fp2::sqr(tmp, x0_num); @@ -537,18 +412,6 @@ struct MapToG2_WB19 { printf("y=%s\n", P.y.getStr(base).c_str()); printf("z=%s\n", P.z.getStr(base).c_str()); } - bool normalizeJacobi(Point& out, const Point& in) const - { - if (in.z.isZero()) return false; - Fp2 t; - Fp2::inv(t, in.z); - Fp2::mul(out.y, in.y, t); - Fp2::sqr(t, t); - Fp2::mul(out.x, in.x, t); - out.y *= t; - out.z = 1; - return true; - } void opt_swu2_map(G2& P, const Fp2& t, const Fp2 *t2 = 0) const { Point Pp; @@ -556,10 +419,11 @@ struct MapToG2_WB19 { if (t2) { Point P2; osswu2_help(P2, *t2); - add(Pp, Pp, P2); + ec::addJacobi(Pp, Pp, P2); } iso3(P, Pp); clear_h2(P, P); + // if (t2 && !ec::isValidJacobi(P)) { puts("QQQ"); } } // hash-to-curve-06 void hashToFp2v6(Fp2 out[2], const void *msg, size_t msgSize, const void *dst, size_t dstSize) const diff --git a/test/mapto_wb19_test.cpp b/test/mapto_wb19_test.cpp index 8d32c6f..30a166b 100644 --- a/test/mapto_wb19_test.cpp +++ b/test/mapto_wb19_test.cpp @@ -157,11 +157,11 @@ void py_ecc_optimized_swu_G2(const MapTo& mapto, Point& P, const Fp2& t) // (t^2 * xi)^2 + (t^2 * xi) Fp2::add(deno, t2xi2, t2xi); Fp2::add(nume, deno, 1); - nume *= Point::b_; + nume *= mapto.Ep_b; if (deno.isZero()) { - Fp2::mul(deno, Point::a_, mapto.xi); + mapto.mul_xi(deno, mapto.Ep_a); } else { - deno *= -Point::a_; + deno *= -mapto.Ep_a; } Fp2 u, v; { @@ -169,8 +169,8 @@ void py_ecc_optimized_swu_G2(const MapTo& mapto, Point& P, const Fp2& t) Fp2::sqr(deno2, deno); Fp2::mul(v, deno2, deno); - Fp2::mul(u, Point::b_, v); - Fp2::mul(tmp, Point::a_, nume); + Fp2::mul(u, mapto.Ep_b, v); + Fp2::mul(tmp, mapto.Ep_a, nume); tmp *= deno2; u += tmp; Fp2::sqr(tmp, nume); @@ -527,12 +527,11 @@ void osswu2_helpTest(const T& mapto) CYBOZU_TEST_EQUAL(P.x, x); CYBOZU_TEST_EQUAL(P.y, y); CYBOZU_TEST_EQUAL(P.z, z); - CYBOZU_TEST_ASSERT(mapto.isValidPoint(P)); +// CYBOZU_TEST_ASSERT(P.isValid()); } } -template -void addTest(const T& mapto) +void addTest() { const struct Tbl { PointStr P; @@ -590,10 +589,8 @@ void addTest(const T& mapto) set(Q, tbl[i].Q); set(R, tbl[i].R); Point E; - mapto.add(E, P, Q); - CYBOZU_TEST_EQUAL(R.x, E.x); - CYBOZU_TEST_EQUAL(R.y, E.y); - CYBOZU_TEST_EQUAL(R.z, E.z); + ec::addJacobi(E, P, Q); + CYBOZU_TEST_ASSERT(R.isEqual(E)); } } @@ -878,7 +875,7 @@ CYBOZU_TEST_AUTO(test) py_eccTest(mapto); py_eccTest2(mapto); osswu2_helpTest(mapto); - addTest(mapto); + addTest(); iso3Test(mapto); testSign(mapto); ethFp2ToG2test();