diff --git a/src/bls/bls.h b/src/bls/bls.h index b1b0eb5f75..fb14698c7c 100644 --- a/src/bls/bls.h +++ b/src/bls/bls.h @@ -123,7 +123,15 @@ public: cachedHash.SetNull(); } - std::vector ToByteVector(const bool specificLegacyScheme) const + std::array ToBytes(const bool specificLegacyScheme) const + { + if (!fValid) { + return std::array{}; + } + return impl.SerializeToArray(specificLegacyScheme); + } + + std::vector ToActualByteVector(const bool specificLegacyScheme) const { if (!fValid) { return std::vector(SerSize, 0); @@ -131,9 +139,9 @@ public: return impl.Serialize(specificLegacyScheme); } - std::vector ToByteVector() const + std::array ToBytes() const { - return ToByteVector(bls::bls_legacy_scheme.load()); + return ToBytes(bls::bls_legacy_scheme.load()); } const uint256& GetHash() const @@ -167,7 +175,7 @@ public: template inline void Serialize(Stream& s, const bool specificLegacyScheme) const { - s.write(AsBytes(Span{ToByteVector(specificLegacyScheme).data(), SerSize})); + s.write(AsBytes(Span{ToBytes(specificLegacyScheme)})); } template @@ -206,7 +214,7 @@ public: inline bool CheckMalleable(Span vecBytes, const bool specificLegacyScheme) const { - if (memcmp(vecBytes.data(), ToByteVector(specificLegacyScheme).data(), SerSize)) { + if (memcmp(vecBytes.data(), ToBytes(specificLegacyScheme).data(), SerSize)) { // TODO not sure if this is actually possible with the BLS libs. I'm assuming here that somewhere deep inside // these libs masking might happen, so that 2 different binary representations could result in the same object // representation @@ -222,7 +230,7 @@ public: inline std::string ToString(const bool specificLegacyScheme) const { - std::vector buf = ToByteVector(specificLegacyScheme); + auto buf = ToBytes(specificLegacyScheme); return HexStr(buf); } @@ -245,10 +253,12 @@ struct CBLSIdImplicit : public uint256 memcpy(instance.begin(), buffer, sizeof(CBLSIdImplicit)); return instance; } - [[nodiscard]] std::vector Serialize(const bool fLegacy) const + [[nodiscard]] std::vector SerializeToVec(const bool fLegacy) const { return {begin(), end()}; } + [[nodiscard]] std::array Serialize(const bool fLegacy) const { return m_data; } + [[nodiscard]] std::array SerializeToArray(const bool fLegacy) const { return Serialize(fLegacy); } }; class CBLSId : public CBLSWrapper @@ -381,7 +391,7 @@ class CBLSLazyWrapper private: mutable std::mutex mutex; - mutable std::vector vecBytes; + mutable std::array vecBytes{}; mutable bool bufValid{false}; mutable bool bufLegacyScheme{true}; @@ -392,7 +402,6 @@ private: public: CBLSLazyWrapper() : - vecBytes(BLSObject::SerSize, 0), bufLegacyScheme(bls::bls_legacy_scheme.load()) {} @@ -410,7 +419,6 @@ public: if (r.bufValid) { vecBytes = r.vecBytes; } else { - vecBytes.resize(BLSObject::SerSize); std::fill(vecBytes.begin(), vecBytes.end(), 0); } objInitialized = r.objInitialized; @@ -433,10 +441,9 @@ public: { std::unique_lock l(mutex); if (!objInitialized && !bufValid) { - vecBytes.resize(BLSObject::SerSize); std::fill(vecBytes.begin(), vecBytes.end(), 0); } else if (!bufValid || (bufLegacyScheme != specificLegacyScheme)) { - vecBytes = obj.ToByteVector(specificLegacyScheme); + vecBytes = obj.ToBytes(specificLegacyScheme); bufValid = true; bufLegacyScheme = specificLegacyScheme; hash.SetNull(); @@ -518,11 +525,10 @@ public: { std::unique_lock l(mutex); if (!objInitialized && !bufValid) { - vecBytes.resize(BLSObject::SerSize); std::fill(vecBytes.begin(), vecBytes.end(), 0); hash.SetNull(); } else if (!bufValid) { - vecBytes = obj.ToByteVector(bufLegacyScheme); + vecBytes = obj.ToBytes(bufLegacyScheme); bufValid = true; hash.SetNull(); } diff --git a/src/bls/bls_ies.cpp b/src/bls/bls_ies.cpp index 1068e078fc..640e820910 100644 --- a/src/bls/bls_ies.cpp +++ b/src/bls/bls_ies.cpp @@ -49,8 +49,7 @@ bool CBLSIESEncryptedBlob::Encrypt(size_t idx, const CBLSPublicKey& peerPubKey, return false; } - std::vector symKey = pk.ToByteVector(); - symKey.resize(32); + auto symKey = pk.ToBytes(); uint256 iv = GetIV(idx); return EncryptBlob(plainTextData, dataSize, data, symKey.data(), iv.begin()); @@ -63,10 +62,9 @@ bool CBLSIESEncryptedBlob::Decrypt(size_t idx, const CBLSSecretKey& secretKey, C return false; } - std::vector symKey = pk.ToByteVector(); - symKey.resize(32); - uint256 iv = GetIV(idx); + auto symKey = pk.ToBytes(); + return DecryptBlob(data.data(), data.size(), decryptedDataRet, symKey.data(), iv.begin()); } @@ -117,8 +115,7 @@ bool CBLSIESMultiRecipientBlobs::Encrypt(size_t idx, const CBLSPublicKey& recipi return false; } - std::vector symKey = pk.ToByteVector(); - symKey.resize(32); + auto symKey = pk.ToBytes(); return EncryptBlob(blob.data(), blob.size(), blobs[idx], symKey.data(), ivVector[idx].begin()); } @@ -134,13 +131,11 @@ bool CBLSIESMultiRecipientBlobs::Decrypt(size_t idx, const CBLSSecretKey& sk, Bl return false; } - std::vector symKey = pk.ToByteVector(); - symKey.resize(32); - uint256 iv = ivSeed; for (size_t i = 0; i < idx; i++) { iv = ::SerializeHash(iv); } + auto symKey = pk.ToBytes(); return DecryptBlob(blobs[idx].data(), blobs[idx].size(), blobRet, symKey.data(), iv.begin()); } diff --git a/src/coinjoin/coinjoin.cpp b/src/coinjoin/coinjoin.cpp index 74fc644a70..2ac1b3d436 100644 --- a/src/coinjoin/coinjoin.cpp +++ b/src/coinjoin/coinjoin.cpp @@ -55,7 +55,7 @@ bool CCoinJoinQueue::Sign(const CActiveMasternodeManager& mn_activeman) if (!sig.IsValid()) { return false; } - vchSig = sig.ToByteVector(false); + vchSig = sig.ToBytes(false); return true; } @@ -94,7 +94,7 @@ bool CCoinJoinBroadcastTx::Sign(const CActiveMasternodeManager& mn_activeman) if (!sig.IsValid()) { return false; } - vchSig = sig.ToByteVector(false); + vchSig = sig.ToBytes(false); return true; } diff --git a/src/coinjoin/coinjoin.h b/src/coinjoin/coinjoin.h index 68e2f40c05..18885a3284 100644 --- a/src/coinjoin/coinjoin.h +++ b/src/coinjoin/coinjoin.h @@ -7,6 +7,7 @@ #include +#include #include #include #include @@ -183,7 +184,7 @@ public: uint256 m_protxHash; int64_t nTime{0}; bool fReady{false}; //ready for submit - std::vector vchSig; + std::array vchSig; // memory only bool fTried{false}; @@ -243,7 +244,7 @@ public: CTransactionRef tx; COutPoint masternodeOutpoint; uint256 m_protxHash; - std::vector vchSig; + std::array vchSig; int64_t sigTime{0}; CCoinJoinBroadcastTx() : tx(MakeTransactionRef(CMutableTransaction{})) diff --git a/src/dashbls/configure.ac b/src/dashbls/configure.ac index df411ced0c..737e74eb05 100644 --- a/src/dashbls/configure.ac +++ b/src/dashbls/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.60]) -AC_INIT([libdashbls],[1.3.4]) +AC_INIT([libdashbls],[1.3.3]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) diff --git a/src/dashbls/include/dashbls/elements.hpp b/src/dashbls/include/dashbls/elements.hpp index 6832b31f3a..95937f62db 100644 --- a/src/dashbls/include/dashbls/elements.hpp +++ b/src/dashbls/include/dashbls/elements.hpp @@ -59,6 +59,7 @@ public: GTElement Pair(const G2Element &b) const; uint32_t GetFingerprint(bool fLegacy = false) const; std::vector Serialize(bool fLegacy = false) const; + std::array SerializeToArray(bool fLegacy = false) const; G1Element Copy(); friend bool operator==(const G1Element &a, const G1Element &b); @@ -102,6 +103,7 @@ public: G2Element Negate() const; GTElement Pair(const G1Element &a) const; std::vector Serialize(bool fLegacy = false) const; + std::array SerializeToArray(bool fLegacy = false) const; G2Element Copy(); friend bool operator==(G2Element const &a, G2Element const &b); @@ -127,6 +129,7 @@ public: void Serialize(uint8_t *buffer) const; std::vector Serialize() const; + std::array SerializeToArray() const; friend bool operator==(GTElement const &a, GTElement const &b); friend bool operator!=(GTElement const &a, GTElement const &b); diff --git a/src/dashbls/include/dashbls/privatekey.hpp b/src/dashbls/include/dashbls/privatekey.hpp index beebbb05ab..d02a7d292c 100644 --- a/src/dashbls/include/dashbls/privatekey.hpp +++ b/src/dashbls/include/dashbls/privatekey.hpp @@ -82,6 +82,7 @@ class PrivateKey { // Serialize the key into bytes void Serialize(uint8_t *buffer) const; std::vector Serialize(bool fLegacy = false) const; + std::array SerializeToArray(bool fLegacy = false) const; G2Element SignG2( const uint8_t *msg, diff --git a/src/dashbls/src/elements.cpp b/src/dashbls/src/elements.cpp index 278af8cd8f..b0c747af82 100644 --- a/src/dashbls/src/elements.cpp +++ b/src/dashbls/src/elements.cpp @@ -171,11 +171,16 @@ uint32_t G1Element::GetFingerprint(const bool fLegacy) const } std::vector G1Element::Serialize(const bool fLegacy) const { + const auto arr = G1Element::SerializeToArray(fLegacy); + return std::vector{arr.begin(), arr.end()}; +} + +std::array G1Element::SerializeToArray(const bool fLegacy) const { uint8_t buffer[G1Element::SIZE + 1]; g1_write_bin(buffer, G1Element::SIZE + 1, p, 1); + std::array result{}; if (buffer[0] == 0x00) { // infinity - std::vector result(G1Element::SIZE, 0); result[0] = 0xc0; return result; } @@ -187,7 +192,9 @@ std::vector G1Element::Serialize(const bool fLegacy) const { if (!fLegacy) { buffer[1] |= 0x80; // indicate compression } - return std::vector(buffer + 1, buffer + 1 + G1Element::SIZE); + + std::copy_n(buffer + 1, G1Element::SIZE, result.begin()); + return result; } bool operator==(const G1Element & a, const G1Element &b) @@ -386,11 +393,18 @@ G2Element G2Element::Negate() const GTElement G2Element::Pair(const G1Element& a) const { return a & (*this); } std::vector G2Element::Serialize(const bool fLegacy) const { + const auto arr = G2Element::SerializeToArray(fLegacy); + return std::vector{arr.begin(), arr.end()}; +} + +std::array G2Element::SerializeToArray(const bool fLegacy) const { uint8_t buffer[G2Element::SIZE + 1]; g2_write_bin(buffer, G2Element::SIZE + 1, (g2_st*)q, 1); + std::array result{}; + if (buffer[0] == 0x00) { // infinity - std::vector result(G2Element::SIZE, 0); + result.fill(0); result[0] = 0xc0; return result; } @@ -410,7 +424,6 @@ std::vector G2Element::Serialize(const bool fLegacy) const { } } - std::vector result(G2Element::SIZE, 0); if (fLegacy) { std::memcpy(result.data(), buffer + 1, G2Element::SIZE); } else { @@ -551,4 +564,11 @@ std::vector GTElement::Serialize() const return data; } +std::array GTElement::SerializeToArray() const +{ + std::array data{}; + Serialize(data.data()); + return data; +} + } // end namespace bls diff --git a/src/dashbls/src/privatekey.cpp b/src/dashbls/src/privatekey.cpp index 865507dfc7..d4dd32d116 100644 --- a/src/dashbls/src/privatekey.cpp +++ b/src/dashbls/src/privatekey.cpp @@ -284,6 +284,13 @@ std::vector PrivateKey::Serialize(const bool fLegacy) const return data; } +std::array PrivateKey::SerializeToArray(bool fLegacy) const +{ + std::array data{}; + Serialize(data.data()); + return data; +} + G2Element PrivateKey::SignG2( const uint8_t *msg, size_t len, diff --git a/src/governance/object.cpp b/src/governance/object.cpp index 6ae0ed619b..eb571d23f6 100644 --- a/src/governance/object.cpp +++ b/src/governance/object.cpp @@ -258,7 +258,7 @@ bool CGovernanceObject::Sign(const CActiveMasternodeManager& mn_activeman) if (!sig.IsValid()) { return false; } - m_obj.vchSig = sig.ToByteVector(false); + m_obj.vchSig = sig.ToActualByteVector(false); return true; } diff --git a/src/governance/vote.cpp b/src/governance/vote.cpp index 5cfa2b1ac1..bf279d4f89 100644 --- a/src/governance/vote.cpp +++ b/src/governance/vote.cpp @@ -175,7 +175,7 @@ bool CGovernanceVote::Sign(const CActiveMasternodeManager& mn_activeman) if (!sig.IsValid()) { return false; } - vchSig = sig.ToByteVector(false); + vchSig = sig.ToActualByteVector(false); return true; } diff --git a/src/llmq/dkgsession.cpp b/src/llmq/dkgsession.cpp index b63ebf45a4..d4b4a18641 100644 --- a/src/llmq/dkgsession.cpp +++ b/src/llmq/dkgsession.cpp @@ -1016,12 +1016,12 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages, PeerManag if (lieType == 3) { const bool is_bls_legacy = bls::bls_legacy_scheme.load(); - std::vector buf = qc.sig.ToByteVector(is_bls_legacy); + auto buf = qc.sig.ToBytes(is_bls_legacy); buf[5]++; qc.sig.SetByteVector(buf, is_bls_legacy); } else if (lieType == 4) { const bool is_bls_legacy = bls::bls_legacy_scheme.load(); - std::vector buf = qc.quorumSig.ToByteVector(is_bls_legacy); + auto buf = qc.quorumSig.ToBytes(is_bls_legacy); buf[5]++; qc.quorumSig.SetByteVector(buf, is_bls_legacy); } diff --git a/src/serialize.h b/src/serialize.h index c8b57ad482..95dc35d0dc 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -820,6 +820,9 @@ template inline void Unserialize(St template inline void Serialize(Stream& os, const std::vector& v); template inline void Unserialize(Stream& is, std::vector& v); +template void Serialize(Stream& os, const std::array& a); +template void Unserialize(Stream& is, std::array& a); + /** * pair */ @@ -1051,6 +1054,54 @@ void Unserialize(Stream& is, std::vector& v) } } +/** + * array + */ +template +void Serialize(Stream& os, const std::array& a) +{ + if constexpr (std::is_same_v) { + // Directly write the byte data without writing the size + if (!a.empty()) { + os.write(MakeByteSpan(a)); + } + } + else if constexpr (std::is_same_v) { + // Serialize each bool individually + for (const bool& elem : a) { + ::Serialize(os, elem); + } + } + else { + // Serialize each element using the default Serialize function + for (const T& elem : a) { + ::Serialize(os, elem); + } + } +} + +template +void Unserialize(Stream& is, std::array& a) +{ + if constexpr (std::is_same_v) { + // Directly read the byte data without reading the size + if (N > 0) { + is.read(AsWritableBytes(Span{a})); + } + } + else if constexpr (std::is_same_v) { + // Unserialize each bool individually + for (bool& elem : a) { + ::Unserialize(is, elem); + } + } + else { + // Unserialize each element using the default Unserialize function + for (T& elem : a) { + ::Unserialize(is, elem); + } + } +} /** * pair