diff options
author | MITSUNARI Shigeo <herumi@nifty.com> | 2018-05-06 12:03:25 +0800 |
---|---|---|
committer | MITSUNARI Shigeo <herumi@nifty.com> | 2018-05-06 12:03:25 +0800 |
commit | 2ad5ebd99684e54d8ce6e4b25fa033875f9da4ec (patch) | |
tree | 9321fa7a583f82922bf37cd166f3e82214de2fe6 | |
parent | be71d27d9aa5410a0c6c489c3a70320fc74d4d3e (diff) | |
download | dexon-mcl-2ad5ebd99684e54d8ce6e4b25fa033875f9da4ec.tar.gz dexon-mcl-2ad5ebd99684e54d8ce6e4b25fa033875f9da4ec.tar.zst dexon-mcl-2ad5ebd99684e54d8ce6e4b25fa033875f9da4ec.zip |
IoSerialize for !isMSBserialize
-rw-r--r-- | include/mcl/ec.hpp | 53 | ||||
-rw-r--r-- | test/ec_test.cpp | 8 |
2 files changed, 41 insertions, 20 deletions
diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index 4a71bc0..4160d21 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -650,7 +650,7 @@ public: return z.isZero(); #endif } - static inline bool isFixedSizeByteSeq() + static inline bool isMSBserialize() { return !b_.isZero() && (Fp::BaseFp::getBitSize() & 7) != 0; } @@ -671,20 +671,33 @@ public: EcT P(*this); P.normalize(); if (ioMode & IoSerialize) { - if (!isFixedSizeByteSeq()) throw cybozu::Exception("EcT:save:not supported ioMode") << ioMode; + /* + if (isMSBserialize()) { + // n bytes + x | (y.isOdd ? 0x80 : 0) + } else { + // n + 1 bytes + (y.isOdd ? 3 : 2), x + } + */ const size_t n = Fp::getByteSize(); - char buf[sizeof(Fp)]; + const size_t adj = isMSBserialize() ? 0 : 1; + char buf[sizeof(Fp) + 1]; std::string str; if (isZero()) { - memset(buf, 0, n); + memset(buf, 0, n + adj); } else { - cybozu::MemoryOutputStream mos(buf, n); - P.x.save(mos, ioMode); - if (P.y.isOdd()) { - buf[n - 1] |= 0x80; + cybozu::MemoryOutputStream mos(buf + adj, n); + P.x.save(mos, IoSerialize); + if (adj) { + buf[0] = P.y.isOdd() ? 3 : 2; + } else { + if (P.y.isOdd()) { + buf[n - 1] |= 0x80; + } } } - cybozu::write(os, buf, n); + cybozu::write(os, buf, n + adj); return; } if (isZero()) { @@ -712,17 +725,25 @@ public: z = 1; #endif if (ioMode & IoSerialize) { - if (!isFixedSizeByteSeq()) throw cybozu::Exception("EcT:load:not supported ioMode") << ioMode; - char buf[sizeof(Fp)]; const size_t n = Fp::getByteSize(); - if (cybozu::readSome(buf, n, is) != n) throw cybozu::Exception("EcT:load:can't read") << n; - if (fp::isZeroArray(buf, n)) { + const size_t adj = isMSBserialize() ? 0 : 1; + const size_t n1 = n + adj; + char buf[sizeof(Fp) + 1]; + if (cybozu::readSome(buf, n1, is) != n1) throw cybozu::Exception("EcT:load:can't read") << n1; + if (fp::isZeroArray(buf, n1)) { clear(); return; } - bool isYodd = (buf[n - 1] >> 7) != 0; - buf[n - 1] &= 0x7f; - x.setStr(std::string(buf, n), ioMode); + bool isYodd; + if (adj) { + char c = buf[0]; + if (c != 2 && c != 3) throw cybozu::Exception("EcT:bad mode") << c; + isYodd = c == 3; + } else { + isYodd = (buf[n - 1] >> 7) != 0; + buf[n - 1] &= 0x7f; + } + x.setArray(buf + adj, n); getYfromX(y, x, isYodd); } else { char c = 0; diff --git a/test/ec_test.cpp b/test/ec_test.cpp index 6cf4b33..78963d2 100644 --- a/test/ec_test.cpp +++ b/test/ec_test.cpp @@ -287,25 +287,25 @@ struct Test { CYBOZU_TEST_EQUAL(P, Q); } // IoSerialize - if (!Ec::isFixedSizeByteSeq()) return; + const size_t adj = Ec::isMSBserialize() ? 0 : 1; P.set(x, y); { std::string s = P.getStr(mcl::IoSerialize); - CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize()); + CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize() + adj); Q.setStr(s, mcl::IoSerialize); CYBOZU_TEST_EQUAL(P, Q); } { P = -P; std::string s = P.getStr(mcl::IoSerialize); - CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize()); + CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize() + adj); Q.setStr(s, mcl::IoSerialize); CYBOZU_TEST_EQUAL(P, Q); } P.clear(); { std::string s = P.getStr(mcl::IoSerialize); - CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize()); + CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize() + adj); CYBOZU_TEST_ASSERT(mcl::fp::isZeroArray(s.c_str(), s.size())); Q.setStr(s, mcl::IoSerialize); CYBOZU_TEST_EQUAL(P, Q); |