diff options
author | MITSUNARI Shigeo <herumi@nifty.com> | 2018-06-02 16:47:26 +0800 |
---|---|---|
committer | MITSUNARI Shigeo <herumi@nifty.com> | 2018-06-02 16:47:26 +0800 |
commit | c0bdae8ea7d47f5456b8000f3621d3c8f2d0f21a (patch) | |
tree | 62a2113cce622d3b4bfcd2634413f2e5ec7bc96a | |
parent | 9e0f60181ca9ab5e7f1b5effc6fcfcf714babb2e (diff) | |
download | tangerine-mcl-c0bdae8ea7d47f5456b8000f3621d3c8f2d0f21a.tar.gz tangerine-mcl-c0bdae8ea7d47f5456b8000f3621d3c8f2d0f21a.tar.zst tangerine-mcl-c0bdae8ea7d47f5456b8000f3621d3c8f2d0f21a.zip |
add initG1only mode for she
-rw-r--r-- | include/mcl/ec.hpp | 2 | ||||
-rw-r--r-- | include/mcl/she.hpp | 99 | ||||
-rw-r--r-- | sample/she_make_dlp_table.cpp | 6 | ||||
-rw-r--r-- | src/she_c_impl.hpp | 6 | ||||
-rw-r--r-- | test/she_test.cpp | 69 |
5 files changed, 150 insertions, 32 deletions
diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index d41ac48..7635eb0 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -171,8 +171,10 @@ public: } else { specialA_ = generic; } + ioMode_ = 0; verifyOrder_ = false; order_ = 0; + mulArrayGLV = 0; #ifdef MCL_EC_USE_AFFINE cybozu::disable_warning_unused_variable(mode); #else diff --git a/include/mcl/she.hpp b/include/mcl/she.hpp index 0eee669..6c3b0ed 100644 --- a/include/mcl/she.hpp +++ b/include/mcl/she.hpp @@ -340,6 +340,7 @@ struct SHET { static local::HashTable<GT, false> ePQhashTbl_; static bool useDecG1ViaGT_; static bool useDecG2ViaGT_; + static bool isG1only_; private: template<class G> class CipherTextAT : public fp::Serializable<CipherTextAT<G> > { @@ -554,6 +555,9 @@ public: pairing(ePQ_, P_, Q_); precomputeG2(Qcoeff_, Q_); setRangeForDLP(hashSize); + useDecG1ViaGT_ = false; + useDecG2ViaGT_ = false; + isG1only_ = false; setTryNum(tryNum); } static void init(size_t hashSize, size_t tryNum = local::defaultTryNum) @@ -561,6 +565,24 @@ public: init(mcl::BN254, hashSize, tryNum); } /* + standard lifted ElGamal encryption + */ + static void initG1only(const mcl::EcParam& para, size_t hashSize = 1024, size_t tryNum = local::defaultTryNum) + { + Fp::init(para.p); + Fr::init(para.n); + G1::init(para.a, para.b); + const Fp x0(para.gx); + const Fp y0(para.gy); + P_.set(x0, y0); + + setRangeForG1DLP(hashSize); + useDecG1ViaGT_ = false; + useDecG2ViaGT_ = false; + isG1only_ = true; + setTryNum(tryNum); + } + /* set range for G1-DLP */ static void setRangeForG1DLP(size_t hashSize) @@ -633,7 +655,7 @@ public: void setByCSPRNG() { x_.setRand(); - y_.setRand(); + if (!isG1only_) y_.setRand(); } /* set xP and yQ @@ -749,13 +771,14 @@ public: void load(bool *pb, InputStream& is, int ioMode = IoSerialize) { x_.load(pb, is, ioMode); if (!*pb) return; - y_.load(pb, is, ioMode); + if (!isG1only_) y_.load(pb, is, ioMode); } template<class OutputStream> void save(bool *pb, OutputStream& os, int ioMode = IoSerialize) const { const char sep = *fp::getIoSeparator(ioMode); x_.save(pb, os, ioMode); if (!*pb) return; + if (isG1only_) return; if (sep) { cybozu::writeChar(pb, os, sep); if (!*pb) return; @@ -788,7 +811,7 @@ public: } bool operator==(const SecretKey& rhs) const { - return x_ == rhs.x_ && y_ == rhs.y_; + return x_ == rhs.x_ && (isG1only_ || y_ == rhs.y_); } bool operator!=(const SecretKey& rhs) const { return !operator==(rhs); } }; @@ -1219,7 +1242,7 @@ public: void set(const Fr& x, const Fr& y) { G1::mul(xP_, P_, x); - G2::mul(yQ_, Q_, y); + if (!isG1only_) G2::mul(yQ_, Q_, y); } template<class INT> void encG1(CipherTextG1& c, const INT& m) const @@ -1329,13 +1352,14 @@ public: void load(bool *pb, InputStream& is, int ioMode = IoSerialize) { xP_.load(pb, is, ioMode); if (!*pb) return; - yQ_.load(pb, is, ioMode); + if (!isG1only_) yQ_.load(pb, is, ioMode); } template<class OutputStream> void save(bool *pb, OutputStream& os, int ioMode = IoSerialize) const { const char sep = *fp::getIoSeparator(ioMode); xP_.save(pb, os, ioMode); if (!*pb) return; + if (isG1only_) return; if (sep) { cybozu::writeChar(pb, os, sep); if (!*pb) return; @@ -1368,7 +1392,7 @@ public: } bool operator==(const PublicKey& rhs) const { - return xP_ == rhs.xP_ && yQ_ == rhs.yQ_; + return xP_ == rhs.xP_ && (isG1only_ || yQ_ == rhs.yQ_); } bool operator!=(const PublicKey& rhs) const { return !operator==(rhs); } }; @@ -1425,15 +1449,16 @@ public: public: void init(const PublicKey& pub) { + const size_t bitSize = Fr::getBitSize(); + xPwm_.init(pub.xP_, bitSize, local::winSize); + if (isG1only_) return; + yQwm_.init(pub.yQ_, bitSize, local::winSize); pairing(exPQ_, pub.xP_, Q_); pairing(eyPQ_, P_, pub.yQ_); pairing(exyPQ_, pub.xP_, pub.yQ_); - const size_t bitSize = Fr::getBitSize(); exPQwm_.init(static_cast<const GTasEC&>(exPQ_), bitSize, local::winSize); eyPQwm_.init(static_cast<const GTasEC&>(eyPQ_), bitSize, local::winSize); exyPQwm_.init(static_cast<const GTasEC&>(exyPQ_), bitSize, local::winSize); - xPwm_.init(pub.xP_, bitSize, local::winSize); - yQwm_.init(pub.yQ_, bitSize, local::winSize); } void encWithZkpBin(CipherTextG1& c, ZkpBin& zkp, int m) const { @@ -1740,6 +1765,18 @@ public: } throw cybozu::Exception("she:CipherText:sub:mixed CipherText"); } + static void neg(CipherText& y, const CipherText& x) + { + if (x.isMultiplied()) { + y.isMultiplied_ = true; + CipherTextGT::neg(y.m_, x.m_); + return; + } else { + y.isMultiplied_ = false; + CipherTextA::neg(y.a_, x.a_); + return; + } + } static void mul(CipherText& z, const CipherText& x, const CipherText& y) { if (x.isMultiplied() || y.isMultiplied()) { @@ -1821,16 +1858,20 @@ public: bool operator!=(const CipherTextGT& rhs) const { return !operator==(rhs); } }; }; +typedef local::HashTable<G1> HashTableG1; +typedef local::HashTable<G2> HashTableG2; +typedef local::HashTable<Fp12, false> HashTableGT; template<size_t dummyInpl> G1 SHET<dummyInpl>::P_; template<size_t dummyInpl> G2 SHET<dummyInpl>::Q_; template<size_t dummyInpl> Fp12 SHET<dummyInpl>::ePQ_; template<size_t dummyInpl> std::vector<Fp6> SHET<dummyInpl>::Qcoeff_; -template<size_t dummyInpl> local::HashTable<G1> SHET<dummyInpl>::PhashTbl_; -template<size_t dummyInpl> local::HashTable<G2> SHET<dummyInpl>::QhashTbl_; -template<size_t dummyInpl> local::HashTable<Fp12, false> SHET<dummyInpl>::ePQhashTbl_; +template<size_t dummyInpl> HashTableG1 SHET<dummyInpl>::PhashTbl_; +template<size_t dummyInpl> HashTableG2 SHET<dummyInpl>::QhashTbl_; +template<size_t dummyInpl> HashTableGT SHET<dummyInpl>::ePQhashTbl_; template<size_t dummyInpl> bool SHET<dummyInpl>::useDecG1ViaGT_; template<size_t dummyInpl> bool SHET<dummyInpl>::useDecG2ViaGT_; +template<size_t dummyInpl> bool SHET<dummyInpl>::isG1only_; typedef mcl::she::SHET<> SHE; typedef SHE::SecretKey SecretKey; typedef SHE::PublicKey PublicKey; @@ -1849,6 +1890,10 @@ inline void init(const mcl::CurveParam& cp = mcl::BN254, size_t hashSize = 1024, { SHE::init(cp, hashSize, tryNum); } +inline void initG1only(const mcl::EcParam& para, size_t hashSize = 1024, size_t tryNum = local::defaultTryNum) +{ + SHE::initG1only(para, hashSize, tryNum); +} inline void init(size_t hashSize, size_t tryNum = local::defaultTryNum) { SHE::init(hashSize, tryNum); } inline void setRangeForG1DLP(size_t hashSize) { SHE::setRangeForG1DLP(hashSize); } inline void setRangeForG2DLP(size_t hashSize) { SHE::setRangeForG2DLP(hashSize); } @@ -1857,6 +1902,36 @@ inline void setRangeForDLP(size_t hashSize) { SHE::setRangeForDLP(hashSize); } inline void setTryNum(size_t tryNum) { SHE::setTryNum(tryNum); } inline void useDecG1ViaGT(bool use = true) { SHE::useDecG1ViaGT(use); } inline void useDecG2ViaGT(bool use = true) { SHE::useDecG2ViaGT(use); } +inline HashTableG1& getHashTableG1() { return SHE::PhashTbl_; } +inline HashTableG2& getHashTableG2() { return SHE::QhashTbl_; } +inline HashTableGT& getHashTableGT() { return SHE::ePQhashTbl_; } + +inline void add(CipherTextG1& z, const CipherTextG1& x, const CipherTextG1& y) { CipherTextG1::add(z, x, y); } +inline void add(CipherTextG2& z, const CipherTextG2& x, const CipherTextG2& y) { CipherTextG2::add(z, x, y); } +inline void add(CipherTextGT& z, const CipherTextGT& x, const CipherTextGT& y) { CipherTextGT::add(z, x, y); } +inline void add(CipherText& z, const CipherText& x, const CipherText& y) { CipherText::add(z, x, y); } + +inline void sub(CipherTextG1& z, const CipherTextG1& x, const CipherTextG1& y) { CipherTextG1::sub(z, x, y); } +inline void sub(CipherTextG2& z, const CipherTextG2& x, const CipherTextG2& y) { CipherTextG2::sub(z, x, y); } +inline void sub(CipherTextGT& z, const CipherTextGT& x, const CipherTextGT& y) { CipherTextGT::sub(z, x, y); } +inline void sub(CipherText& z, const CipherText& x, const CipherText& y) { CipherText::sub(z, x, y); } + +inline void neg(CipherTextG1& y, const CipherTextG1& x) { CipherTextG1::neg(y, x); } +inline void neg(CipherTextG2& y, const CipherTextG2& x) { CipherTextG2::neg(y, x); } +inline void neg(CipherTextGT& y, const CipherTextGT& x) { CipherTextGT::neg(y, x); } +inline void neg(CipherText& y, const CipherText& x) { CipherText::neg(y, x); } + +template<class INT> +inline void mul(CipherTextG1& z, const CipherTextG1& x, const INT& y) { CipherTextG1::mul(z, x, y); } +template<class INT> +inline void mul(CipherTextG2& z, const CipherTextG2& x, const INT& y) { CipherTextG2::mul(z, x, y); } +template<class INT> +inline void mul(CipherTextGT& z, const CipherTextGT& x, const INT& y) { CipherTextGT::mul(z, x, y); } +template<class INT> +inline void mul(CipherText& z, const CipherText& x, const INT& y) { CipherText::mul(z, x, y); } + +inline void mul(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y) { CipherTextGT::mul(z, x, y); } +inline void mul(CipherText& z, const CipherText& x, const CipherText& y) { CipherText::mul(z, x, y); } } } // mcl::she diff --git a/sample/she_make_dlp_table.cpp b/sample/she_make_dlp_table.cpp index 6b57999..41f18e2 100644 --- a/sample/she_make_dlp_table.cpp +++ b/sample/she_make_dlp_table.cpp @@ -34,13 +34,13 @@ void run(const Param& param) switch (param.group) { case 1: - makeTable(param, "g1", SHE::PhashTbl_, SHE::P_); + makeTable(param, "g1", getHashTableG1(), SHE::P_); break; case 2: - makeTable(param, "g2", SHE::QhashTbl_, SHE::Q_); + makeTable(param, "g2", getHashTableG2(), SHE::Q_); break; case 3: - makeTable(param, "gt", SHE::ePQhashTbl_, SHE::ePQ_); + makeTable(param, "gt", getHashTableGT(), SHE::ePQ_); break; default: throw cybozu::Exception("bad group") << param.group; diff --git a/src/she_c_impl.hpp b/src/she_c_impl.hpp index 58afe2a..d025f24 100644 --- a/src/she_c_impl.hpp +++ b/src/she_c_impl.hpp @@ -217,15 +217,15 @@ mclSize loadTable(HashTable& table, const void *buf, mclSize bufSize) mclSize sheLoadTableForG1DLP(const void *buf, mclSize bufSize) { - return loadTable(SHE::PhashTbl_, buf, bufSize); + return loadTable(getHashTableG1(), buf, bufSize); } mclSize sheLoadTableForG2DLP(const void *buf, mclSize bufSize) { - return loadTable(SHE::QhashTbl_, buf, bufSize); + return loadTable(getHashTableG2(), buf, bufSize); } mclSize sheLoadTableForGTDLP(const void *buf, mclSize bufSize) { - return loadTable(SHE::ePQhashTbl_, buf, bufSize); + return loadTable(getHashTableGT(), buf, bufSize); } template<class HashTable> diff --git a/test/she_test.cpp b/test/she_test.cpp index 28ea730..6dff0e5 100644 --- a/test/she_test.cpp +++ b/test/she_test.cpp @@ -5,9 +5,9 @@ #include <fstream> #include <time.h> #include <mcl/she.hpp> +#include <mcl/ecparam.hpp> // for secp192k1 using namespace mcl::she; -using namespace mcl::bn; SecretKey g_sec; @@ -88,18 +88,18 @@ CYBOZU_TEST_AUTO(bench2) t1 = clk2msec(cybozu::bench::g_clk, C); printf("DEC L2 %.2e\n", t1); - CYBOZU_BENCH_C("", C, CipherTextG1::add, d1, d1, c1); + CYBOZU_BENCH_C("", C, add, d1, d1, c1); t1 = clk2msec(cybozu::bench::g_clk, C); - CYBOZU_BENCH_C("", C, CipherTextG2::add, d2, d2, c2); + CYBOZU_BENCH_C("", C, add, d2, d2, c2); t2 = clk2msec(cybozu::bench::g_clk, C); printf("Add L1 %.2e\n", t1 + t2); - CYBOZU_BENCH_C("", C, CipherTextGT::add, dt, dt, ct); + CYBOZU_BENCH_C("", C, add, dt, dt, ct); t1 = clk2msec(cybozu::bench::g_clk, C); printf("Add L2 %.2e\n", t1); - CYBOZU_BENCH_C("", C, CipherTextGT::mul, ct, c1, c2); + CYBOZU_BENCH_C("", C, mul, ct, c1, c2); t1 = clk2msec(cybozu::bench::g_clk, C); printf("Mul %.2e\n", t1); @@ -328,21 +328,21 @@ CYBOZU_TEST_AUTO(add_sub_mul) CipherText c1, c2, c3; pub.enc(c1, m1); pub.enc(c2, m2); - CipherText::add(c3, c1, c2); + add(c3, c1, c2); CYBOZU_TEST_EQUAL(m1 + m2, sec.dec(c3)); pub.reRand(c3); CYBOZU_TEST_EQUAL(m1 + m2, sec.dec(c3)); - CipherText::sub(c3, c1, c2); + sub(c3, c1, c2); CYBOZU_TEST_EQUAL(m1 - m2, sec.dec(c3)); - CipherText::mul(c3, c1, 5); + mul(c3, c1, 5); CYBOZU_TEST_EQUAL(m1 * 5, sec.dec(c3)); - CipherText::mul(c3, c1, -123); + mul(c3, c1, -123); CYBOZU_TEST_EQUAL(m1 * -123, sec.dec(c3)); - CipherText::mul(c3, c1, c2); + mul(c3, c1, c2); CYBOZU_TEST_EQUAL(m1 * m2, sec.dec(c3)); pub.reRand(c3); @@ -354,7 +354,7 @@ CYBOZU_TEST_AUTO(add_sub_mul) pub.enc(c1, m1, true); CYBOZU_TEST_EQUAL(m1, sec.dec(c1)); pub.enc(c2, m2, true); - CipherText::add(c3, c1, c2); + add(c3, c1, c2); CYBOZU_TEST_EQUAL(m1 + m2, sec.dec(c3)); } } @@ -372,14 +372,14 @@ CYBOZU_TEST_AUTO(largeEnc) pub.enc(c1, x); const int64_t m = 123; pub.enc(c2, x + m); - CipherTextG1::sub(c1, c1, c2); + sub(c1, c1, c2); CYBOZU_TEST_EQUAL(sec.dec(c1), -m); pub.enc(c1, 0); - CipherTextG1::mul(c1, c1, x); + mul(c1, c1, x); CYBOZU_TEST_ASSERT(sec.isZero(c1)); pub.enc(c1, 1); - CipherTextG1::mul(c1, c1, x); + mul(c1, c1, x); CYBOZU_TEST_ASSERT(!sec.isZero(c1)); } @@ -700,3 +700,44 @@ CYBOZU_TEST_AUTO(hashBench) } #endif +CYBOZU_TEST_AUTO(liftedElGamal) +{ + const size_t hashSize = 1024; + initG1only(mcl::ecparam::secp192k1, hashSize); + const size_t byteSize = 192 / 8; + SecretKey sec; + sec.setByCSPRNG(); + PublicKey pub; + sec.getPublicKey(pub); + CipherTextG1 c1, c2, c3; + int m1 = 12, m2 = 34; + pub.enc(c1, m1); + pub.enc(c2, m2); + CYBOZU_TEST_EQUAL(sec.dec(c1), m1); + CYBOZU_TEST_EQUAL(sec.dec(c2), m2); + add(c3, c1, c2); + CYBOZU_TEST_EQUAL(sec.dec(c3), m1 + m2); + neg(c1, c2); + CYBOZU_TEST_EQUAL(sec.dec(c1), -m2); + mul(c1, c2, m1); + CYBOZU_TEST_EQUAL(sec.dec(c1), m2 * m1); + + char buf[1024]; + size_t n = sec.serialize(buf, sizeof(buf)); + CYBOZU_TEST_EQUAL(n, byteSize); + SecretKey sec2; + n = sec2.deserialize(buf, n); + CYBOZU_TEST_EQUAL(n, byteSize); + CYBOZU_TEST_EQUAL(sec, sec2); + + n = pub.serialize(buf, sizeof(buf)); + CYBOZU_TEST_EQUAL(n, byteSize + 1); // +1 is for sign of y + PublicKey pub2; + n = pub2.deserialize(buf, n); + CYBOZU_TEST_EQUAL(n, byteSize + 1); + CYBOZU_TEST_EQUAL(pub, pub2); + + PublicKey pub3; + sec2.getPublicKey(pub3); + CYBOZU_TEST_EQUAL(pub, pub3); +} |