diff options
author | MITSUNARI Shigeo <herumi@nifty.com> | 2019-04-25 15:08:42 +0800 |
---|---|---|
committer | MITSUNARI Shigeo <herumi@nifty.com> | 2019-04-25 15:50:25 +0800 |
commit | 838f081855e9fa00bbc8dda4b9f10635e1f5bc4f (patch) | |
tree | 3ebc801f656d7b6860f8f5d3f58b9bf50a53e173 | |
parent | cc9762f14f7f6d4bbc29c0ca418781af4a74f92d (diff) | |
download | tangerine-mcl-838f081855e9fa00bbc8dda4b9f10635e1f5bc4f.tar.gz tangerine-mcl-838f081855e9fa00bbc8dda4b9f10635e1f5bc4f.tar.zst tangerine-mcl-838f081855e9fa00bbc8dda4b9f10635e1f5bc4f.zip |
big endian serialization for eth2
-rw-r--r-- | include/mcl/fp.hpp | 36 | ||||
-rw-r--r-- | include/mcl/util.hpp | 2 | ||||
-rw-r--r-- | test/bls12_test.cpp | 26 |
3 files changed, 61 insertions, 3 deletions
diff --git a/include/mcl/fp.hpp b/include/mcl/fp.hpp index 2e69729..db44227 100644 --- a/include/mcl/fp.hpp +++ b/include/mcl/fp.hpp @@ -73,6 +73,18 @@ bool isEnableJIT(); // 1st call is not threadsafe uint32_t sha256(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize); uint32_t sha512(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize); +namespace local { + +inline void byteSwap(void *x, size_t n) +{ + char *p = (char *)x; + for (size_t i = 0; i < n / 2; i++) { + fp::swap_(p[i], p[n - 1 - i]); + } +} + +} // mcl::fp::local + } // mcl::fp template<class tag = FpTag, size_t maxBitSize = MCL_MAX_BIT_SIZE> @@ -89,6 +101,7 @@ private: static fp::Op op_; static FpT<tag, maxBitSize> inv2_; static int ioMode_; + static bool isETHserialization_; template<class Fp> friend class FpDblT; template<class Fp> friend class Fp2T; template<class Fp> friend struct Fp6T; @@ -131,6 +144,8 @@ public: if (!*pb) return; } inv(inv2_, 2); + ioMode_ = 0; + isETHserialization_ = false; #ifdef MCL_XBYAK_DIRECT_CALL add = fp::func_ptr_cast<void (*)(FpT& z, const FpT& x, const FpT& y)>(op_.fp_addA_); if (add == 0) add = addC; @@ -253,6 +268,9 @@ public: } else { readSize = cybozu::readSome(v_, n, is); } + if (isETHserialization_ && ioMode & (IoSerialize | IoSerializeHexStr)) { + fp::local::byteSwap(v_, n); + } if (readSize != n) return; } else { char buf[1024]; @@ -283,10 +301,18 @@ public: } else { fp::Block b; getBlock(b); + const char *src = (const char *)b.p; + char rev[fp::maxUnitSize * sizeof(fp::Unit)]; + if (isETHserialization_ && ioMode & (IoSerialize | IoSerializeHexStr)) { + for (size_t i = 0; i < n; i++) { + rev[i] = src[n - 1 - i]; + } + src = rev; + } if (ioMode & IoSerializeHexStr) { - mcl::fp::writeHexStr(pb, os, b.p, n); + mcl::fp::writeHexStr(pb, os, src, n); } else { - cybozu::write(pb, os, b.p, n); + cybozu::write(pb, os, src, n); } } return; @@ -498,6 +524,11 @@ public: { ioMode_ = ioMode; } + static void setETHserialization(bool ETHserialization) + { + if (getBitSize() != 381) return; + isETHserialization_ = ETHserialization; + } static inline int getIoMode() { return ioMode_; } static inline size_t getModBitLen() { return getBitSize(); } static inline void setHashFunc(uint32_t hash(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize)) @@ -622,6 +653,7 @@ public: template<class tag, size_t maxBitSize> fp::Op FpT<tag, maxBitSize>::op_; template<class tag, size_t maxBitSize> FpT<tag, maxBitSize> FpT<tag, maxBitSize>::inv2_; template<class tag, size_t maxBitSize> int FpT<tag, maxBitSize>::ioMode_ = IoAuto; +template<class tag, size_t maxBitSize> bool FpT<tag, maxBitSize>::isETHserialization_ = false; #ifdef MCL_XBYAK_DIRECT_CALL template<class tag, size_t maxBitSize> void (*FpT<tag, maxBitSize>::add)(FpT& z, const FpT& x, const FpT& y); template<class tag, size_t maxBitSize> void (*FpT<tag, maxBitSize>::sub)(FpT& z, const FpT& x, const FpT& y); diff --git a/include/mcl/util.hpp b/include/mcl/util.hpp index edef971..a406241 100644 --- a/include/mcl/util.hpp +++ b/include/mcl/util.hpp @@ -16,6 +16,7 @@ namespace mcl { namespace fp { +// some environments do not have utility template<class T> T abs_(T x) { return x < 0 ? -x : x; } @@ -34,7 +35,6 @@ void swap_(T& x, T& y) y = t; } - /* get pp such that p * pp = -1 mod M, where p is prime and M = 1 << 64(or 32). diff --git a/test/bls12_test.cpp b/test/bls12_test.cpp index 7011516..8b67ce6 100644 --- a/test/bls12_test.cpp +++ b/test/bls12_test.cpp @@ -307,6 +307,31 @@ void testTrivial(const G1& P, const G2& Q) CYBOZU_TEST_EQUAL(e, 1); } +void testSerialize() +{ + Fp::setETHserialization(true); // big endian + const struct FpTbl { + const char *in; + const char out[97]; + } fpTbl[] = { + { + "0x12345678901234567", + "000000000000000000000000000000000000000000000000000000000000000000000000000000012345678901234567" + }, + }; + char buf[1024]; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(fpTbl); i++) { + Fp x, y; + x.setStr(fpTbl[i].in); + size_t n = x.serialize(buf, sizeof(buf), mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(n, sizeof(fpTbl[i].out) - 1); + CYBOZU_TEST_EQUAL_ARRAY(buf, fpTbl[i].out, n); + CYBOZU_TEST_EQUAL(y.deserialize(buf, n, mcl::IoSerializeHexStr), n); + CYBOZU_TEST_EQUAL(x, y); + } + Fp::setETHserialization(false); +} + #include "bench.hpp" CYBOZU_TEST_AUTO(naive) @@ -325,6 +350,7 @@ CYBOZU_TEST_AUTO(naive) clk.put(); return; #endif + testSerialize(); testParam(ts); testIo(P, Q); // testFp12pow(P, Q); |