diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index e1db56d..d8a0fc1 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -424,6 +424,55 @@ void addJacobi(E& R, const E& P, const E& Q) F::sub(R.y, U1, H3); } +/* + accept P == Q + https://github.com/apache/incubator-milagro-crypto-c/blob/fa0a45a3/src/ecp.c.in#L767-L976 + (x, y, z) is zero <=> x = 0, y = 1, z = 0 +*/ +template +void addCTProj(E& R, const E& P, const E& Q) +{ + typedef typename E::Fp F; + assert(E::a_ == 0); + F b3; + F::add(b3, E::b_, E::b_); + b3 += E::b_; + F t0, t1, t2, t3, t4, x3, y3, z3; + F::mul(t0, P.x, Q.x); + F::mul(t1, P.y, Q.y); + F::mul(t2, P.z, Q.z); + F::add(t3, P.x, P.y); + F::add(t4, Q.x, Q.y); + F::mul(t3, t3, t4); + F::add(t4, t0, t1); + F::sub(t3, t3, t4); + F::add(t4, P.y, P.z); + F::add(x3, Q.y, Q.z); + F::mul(t4, t4, x3); + F::add(x3, t1, t2); + F::sub(t4, t4, x3); + F::add(x3, P.x, P.z); + F::add(y3, Q.x, Q.z); + F::mul(x3, x3, y3); + F::add(y3, t0, t2); + F::sub(y3, x3, y3); + F::add(x3, t0, t0); + F::add(t0, t0, x3); + t2 *= b3; + F::add(z3, t1, t2); + F::sub(t1, t1, t2); + y3 *= b3; + F::mul(x3, y3, t4); + F::mul(t2, t3, t1); + F::sub(R.x, t2, x3); + F::mul(y3, y3, t0); + F::mul(t1, t1, z3); + F::add(R.y, y3, t1); + F::mul(t0, t0, t3); + F::mul(z3, z3, t4); + F::add(R.z, z3, t0); +} + template void normalizeProj(E& P) { diff --git a/include/mcl/util.hpp b/include/mcl/util.hpp index 0132405..8915c88 100644 --- a/include/mcl/util.hpp +++ b/include/mcl/util.hpp @@ -328,6 +328,7 @@ bool mulSmallUnit(T& z, const T& x, U y) case 9: { T t; T::add(t, x, x); T::add(t, t, t); T::add(t, t, t); T::add(z, t, x); break; } case 10: { T t; T::add(t, x, x); T::add(t, t, t); T::add(t, t, x); T::add(z, t, t); break; } case 11: { T t; T::add(t, x, x); T::add(t, t, x); T::add(t, t, t); T::add(t, t, t); T::sub(z, t, x); break; } + case 12: { T t; T::add(t, x, x); T::add(t, t, t); T::add(z, t, t); T::add(z, z, t); break; } default: return false; } diff --git a/readme.md b/readme.md index d99acba..d1c5619 100644 --- a/readme.md +++ b/readme.md @@ -102,7 +102,7 @@ env MCL_PROF=2 bin/bls12_test.exe ## How to build on 32-bit x86 Linux -Build GMP and for 32-bit mode and install `` at yourself. +Build GMP for 32-bit mode (`env ABI=32 ./configure --enable-cxx ...`) and install `` at yourself. ``` make ARCH=x86 CFLAGS_USER="-I /include" LDFLAGS_USER="-L /lib -Wl,-rpath,/lib" diff --git a/test/ec_test.cpp b/test/ec_test.cpp index 855ceba..f544714 100644 --- a/test/ec_test.cpp +++ b/test/ec_test.cpp @@ -491,6 +491,31 @@ struct Test { CYBOZU_TEST_ASSERT(!(P1 < P1)); CYBOZU_TEST_ASSERT((P1 <= P1)); } + void addCT() const + { + if (Ec::getMode() != mcl::ec::Proj) return; + if (Ec::a_ != 0) return; + Fp x(para.gx); + Fp y(para.gy); + Ec P(x, y), Q, R, Zero; + Zero.clear(); + Zero.y = 1; + mcl::ec::addCTProj(Q, P, P); + Ec::add(R, P, P); + CYBOZU_TEST_EQUAL(Q, R); + mcl::ec::addCTProj(Q, Q, P); + Ec::add(R, R, P); + CYBOZU_TEST_EQUAL(Q, R); + mcl::ec::addCTProj(Q, Q, Zero); + Ec::add(R, R, Zero); + CYBOZU_TEST_EQUAL(Q, R); + mcl::ec::addCTProj(Q, Zero, Q); + Ec::add(R, Zero, R); + CYBOZU_TEST_EQUAL(Q, R); + mcl::ec::addCTProj(Q, Zero, Zero); + Ec::add(R, Zero, Zero); + CYBOZU_TEST_EQUAL(Q, R); + } template void test(F f, const char *msg) const @@ -532,6 +557,7 @@ mul 499.00usec ioMode(); mulCT(); compare(); + addCT(); } private: Test(const Test&);