aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2019-04-25 15:08:42 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2019-04-25 15:50:25 +0800
commit838f081855e9fa00bbc8dda4b9f10635e1f5bc4f (patch)
tree3ebc801f656d7b6860f8f5d3f58b9bf50a53e173
parentcc9762f14f7f6d4bbc29c0ca418781af4a74f92d (diff)
downloadtangerine-mcl-838f081855e9fa00bbc8dda4b9f10635e1f5bc4f.tar.gz
tangerine-mcl-838f081855e9fa00bbc8dda4b9f10635e1f5bc4f.tar.zst
tangerine-mcl-838f081855e9fa00bbc8dda4b9f10635e1f5bc4f.zip
big endian serialization for eth2
-rw-r--r--include/mcl/fp.hpp36
-rw-r--r--include/mcl/util.hpp2
-rw-r--r--test/bls12_test.cpp26
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);