diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index 8cf3a49..ee74779 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -752,6 +752,23 @@ public: } EcT P(*this); P.normalize(); + if (ioMode & IoEcAffineSerialize) { + if (b_ == 0) { // assume Zero if x = y = 0 + *pb = false; + return; + } + if (isZero()) { + // all zero + P.z.save(pb, os, IoSerialize); + if (!*pb) return; + P.z.save(pb, os, IoSerialize); + return; + } + P.x.save(pb, os, IoSerialize); + if (!*pb) return; + P.y.save(pb, os, IoSerialize); + return; + } if (ioMode & (IoSerialize | IoSerializeHexStr)) { const size_t n = Fp::getByteSize(); const size_t adj = isMSBserialize() ? 0 : 1; @@ -835,6 +852,21 @@ public: #else z = 1; #endif + if (ioMode & IoEcAffineSerialize) { + if (b_ == 0) { // assume Zero if x = y = 0 + *pb = false; + return; + } + x.load(pb, is, IoSerialize); + if (!*pb) return; + y.load(pb, is, IoSerialize); + if (!*pb) return; + if (x.isZero() && y.isZero()) { + z.clear(); + return; + } + goto verifyValidness; + } if (ioMode & (IoSerialize | IoSerializeHexStr)) { const size_t n = Fp::getByteSize(); const size_t adj = isMSBserialize() ? 0 : 1; @@ -917,10 +949,7 @@ public: x.load(pb, is, ioMode); if (!*pb) return; if (c == '1') { y.load(pb, is, ioMode); if (!*pb) return; - if (!isValid(x, y)) { - *pb = false; - return; - } + goto verifyValidness; } else if (c == '2' || c == '3') { bool isYodd = c == '3'; *pb = getYfromX(y, x, isYodd); @@ -941,6 +970,13 @@ public: } else { *pb = true; } + return; + verifyValidness: + if (!isValid(x, y)) { + *pb = false; + return; + } + goto verifyOrder; } // deplicated static void setCompressedExpression(bool compressedExpression = true) diff --git a/include/mcl/fp.hpp b/include/mcl/fp.hpp index 894d939..d49fd45 100644 --- a/include/mcl/fp.hpp +++ b/include/mcl/fp.hpp @@ -263,7 +263,7 @@ public: { bool isMinus = false; *pb = false; - if (ioMode & (IoArray | IoArrayRaw | IoSerialize | IoSerializeHexStr)) { + if (fp::isIoSerializeMode(ioMode)) { const size_t n = getByteSize(); v_[op_.N - 1] = 0; size_t readSize; @@ -299,7 +299,7 @@ public: void save(bool *pb, OutputStream& os, int ioMode) const { const size_t n = getByteSize(); - if (ioMode & (IoArray | IoArrayRaw | IoSerialize | IoSerializeHexStr)) { + if (fp::isIoSerializeMode(ioMode)) { if (ioMode & IoArrayRaw) { cybozu::write(pb, os, v_, n); } else { diff --git a/include/mcl/op.hpp b/include/mcl/op.hpp index d6132a4..021d415 100644 --- a/include/mcl/op.hpp +++ b/include/mcl/op.hpp @@ -101,11 +101,17 @@ enum IoMode { IoSerialize = 512, // use MBS for 1-bit y IoFixedSizeByteSeq = IoSerialize, // obsolete IoEcProj = 1024, // projective or jacobi coordinate - IoSerializeHexStr = 2048 // printable hex string + IoSerializeHexStr = 2048, // printable hex string + IoEcAffineSerialize = 4096 // serialize [x:y] }; namespace fp { +inline bool isIoSerializeMode(int ioMode) +{ + return ioMode & (IoArray | IoArrayRaw | IoSerialize | IoEcAffineSerialize | IoSerializeHexStr); +} + const size_t UnitBitSize = sizeof(Unit) * 8; const size_t maxUnitSize = (MCL_MAX_BIT_SIZE + UnitBitSize - 1) / UnitBitSize; @@ -366,7 +372,7 @@ private: inline const char* getIoSeparator(int ioMode) { - return (ioMode & (IoArray | IoArrayRaw | IoSerialize | IoSerializeHexStr)) ? "" : " "; + return (ioMode & (IoArray | IoArrayRaw | IoSerialize | IoSerializeHexStr | IoEcAffineSerialize)) ? "" : " "; } inline void dump(const void *buf, size_t n) diff --git a/test/bls12_test.cpp b/test/bls12_test.cpp index fe0ca7a..df8b127 100644 --- a/test/bls12_test.cpp +++ b/test/bls12_test.cpp @@ -104,7 +104,7 @@ void pairingC(Fp12& e, const G1& P, const G2& Q) void testIoAll(const G1& P, const G2& Q) { const int FpTbl[] = { 0, 2, 2|mcl::IoPrefix, 10, 16, 16|mcl::IoPrefix, mcl::IoArray, mcl::IoArrayRaw }; - const int EcTbl[] = { mcl::IoEcAffine, mcl::IoEcProj, mcl::IoEcCompY, mcl::IoSerialize }; + const int EcTbl[] = { mcl::IoEcAffine, mcl::IoEcProj, mcl::IoEcCompY, mcl::IoSerialize, mcl::IoEcAffineSerialize }; for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(FpTbl); i++) { for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(EcTbl); j++) { G1 P2 = P, P3; diff --git a/test/bn_test.cpp b/test/bn_test.cpp index 15f6f45..e6139b3 100644 --- a/test/bn_test.cpp +++ b/test/bn_test.cpp @@ -338,7 +338,7 @@ void testTrivial(const G1& P, const G2& Q) void testIoAll(const G1& P, const G2& Q) { const int FpTbl[] = { 0, 2, 2|mcl::IoPrefix, 10, 16, 16|mcl::IoPrefix, mcl::IoArray, mcl::IoArrayRaw }; - const int EcTbl[] = { mcl::IoEcAffine, mcl::IoEcProj, mcl::IoEcCompY, mcl::IoSerialize }; + const int EcTbl[] = { mcl::IoEcAffine, mcl::IoEcProj, mcl::IoEcCompY, mcl::IoSerialize, mcl::IoEcAffineSerialize }; for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(FpTbl); i++) { for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(EcTbl); j++) { G1 P2 = P, P3;