Compare commits

...

6 Commits

Author SHA1 Message Date
PastaPastaPasta
2387cbfb09
Merge 4d09138ff3 into a5d54006b3 2024-12-17 16:05:00 +00:00
pasta
4d09138ff3
feat: serialize on the stack 2024-12-16 22:20:35 -06:00
Kittywhiskers Van Gogh
cd115c2989
build: stop tracking cmake dependency relic_conf.h.in 2024-12-05 20:47:07 +00:00
Kittywhiskers Van Gogh
440a9dafba
depends: update 'src/dashbls' to PastaPastaPasta/bls-signatures@30aa085b as 3ac26192 2024-12-05 20:44:38 +00:00
Kittywhiskers Van Gogh
3ac26192a9 Squashed 'src/dashbls/' changes from 7e747e8a07..30aa085b2b
30aa085b2b fixup: apply code review comments
a3afed8669 refactor: continued reduced duplication
0f3705b7db simplify G1Element::Serialize by using G1Element::SerializeToArray
677db58fc3 add SerializeToArray for PrivateKey
d1b3d244f0 fixup add const
09ac2e90d5 feat: implement std::array based serialization
REVERT: 7e747e8a07 Merge pull request #105 from kwvg/bump_1.3.4
REVERT: f8703c9971 chore: bump version to 1.3.4

git-subtree-dir: src/dashbls
git-subtree-split: 30aa085b2b8a169c157d3dfcba2caf604e8d3e54
2024-12-05 20:44:38 +00:00
Kittywhiskers Van Gogh
64a454df7e
revert: stop tracking cmake dependency relic_conf.h.in 2024-12-05 20:43:53 +00:00
13 changed files with 121 additions and 37 deletions

View File

@ -123,7 +123,15 @@ public:
cachedHash.SetNull(); cachedHash.SetNull();
} }
std::vector<uint8_t> ToByteVector(const bool specificLegacyScheme) const std::array<uint8_t, SerSize> ToBytes(const bool specificLegacyScheme) const
{
if (!fValid) {
return std::array<uint8_t, SerSize>{};
}
return impl.SerializeToArray(specificLegacyScheme);
}
std::vector<uint8_t> ToActualByteVector(const bool specificLegacyScheme) const
{ {
if (!fValid) { if (!fValid) {
return std::vector<uint8_t>(SerSize, 0); return std::vector<uint8_t>(SerSize, 0);
@ -131,9 +139,9 @@ public:
return impl.Serialize(specificLegacyScheme); return impl.Serialize(specificLegacyScheme);
} }
std::vector<uint8_t> ToByteVector() const std::array<uint8_t, SerSize> ToBytes() const
{ {
return ToByteVector(bls::bls_legacy_scheme.load()); return ToBytes(bls::bls_legacy_scheme.load());
} }
const uint256& GetHash() const const uint256& GetHash() const
@ -167,7 +175,7 @@ public:
template <typename Stream> template <typename Stream>
inline void Serialize(Stream& s, const bool specificLegacyScheme) const inline void Serialize(Stream& s, const bool specificLegacyScheme) const
{ {
s.write(AsBytes(Span{ToByteVector(specificLegacyScheme).data(), SerSize})); s.write(AsBytes(Span{ToBytes(specificLegacyScheme)}));
} }
template <typename Stream> template <typename Stream>
@ -206,7 +214,7 @@ public:
inline bool CheckMalleable(Span<uint8_t> vecBytes, const bool specificLegacyScheme) const inline bool CheckMalleable(Span<uint8_t> 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 // 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 // these libs masking might happen, so that 2 different binary representations could result in the same object
// representation // representation
@ -222,7 +230,7 @@ public:
inline std::string ToString(const bool specificLegacyScheme) const inline std::string ToString(const bool specificLegacyScheme) const
{ {
std::vector<uint8_t> buf = ToByteVector(specificLegacyScheme); auto buf = ToBytes(specificLegacyScheme);
return HexStr(buf); return HexStr(buf);
} }
@ -245,10 +253,12 @@ struct CBLSIdImplicit : public uint256
memcpy(instance.begin(), buffer, sizeof(CBLSIdImplicit)); memcpy(instance.begin(), buffer, sizeof(CBLSIdImplicit));
return instance; return instance;
} }
[[nodiscard]] std::vector<uint8_t> Serialize(const bool fLegacy) const [[nodiscard]] std::vector<uint8_t> SerializeToVec(const bool fLegacy) const
{ {
return {begin(), end()}; return {begin(), end()};
} }
[[nodiscard]] std::array<uint8_t, WIDTH> Serialize(const bool fLegacy) const { return m_data; }
[[nodiscard]] std::array<uint8_t, WIDTH> SerializeToArray(const bool fLegacy) const { return Serialize(fLegacy); }
}; };
class CBLSId : public CBLSWrapper<CBLSIdImplicit, BLS_CURVE_ID_SIZE, CBLSId> class CBLSId : public CBLSWrapper<CBLSIdImplicit, BLS_CURVE_ID_SIZE, CBLSId>
@ -381,7 +391,7 @@ class CBLSLazyWrapper
private: private:
mutable std::mutex mutex; mutable std::mutex mutex;
mutable std::vector<uint8_t> vecBytes; mutable std::array<uint8_t, BLSObject::SerSize> vecBytes{};
mutable bool bufValid{false}; mutable bool bufValid{false};
mutable bool bufLegacyScheme{true}; mutable bool bufLegacyScheme{true};
@ -392,7 +402,6 @@ private:
public: public:
CBLSLazyWrapper() : CBLSLazyWrapper() :
vecBytes(BLSObject::SerSize, 0),
bufLegacyScheme(bls::bls_legacy_scheme.load()) bufLegacyScheme(bls::bls_legacy_scheme.load())
{} {}
@ -410,7 +419,6 @@ public:
if (r.bufValid) { if (r.bufValid) {
vecBytes = r.vecBytes; vecBytes = r.vecBytes;
} else { } else {
vecBytes.resize(BLSObject::SerSize);
std::fill(vecBytes.begin(), vecBytes.end(), 0); std::fill(vecBytes.begin(), vecBytes.end(), 0);
} }
objInitialized = r.objInitialized; objInitialized = r.objInitialized;
@ -433,10 +441,9 @@ public:
{ {
std::unique_lock<std::mutex> l(mutex); std::unique_lock<std::mutex> l(mutex);
if (!objInitialized && !bufValid) { if (!objInitialized && !bufValid) {
vecBytes.resize(BLSObject::SerSize);
std::fill(vecBytes.begin(), vecBytes.end(), 0); std::fill(vecBytes.begin(), vecBytes.end(), 0);
} else if (!bufValid || (bufLegacyScheme != specificLegacyScheme)) { } else if (!bufValid || (bufLegacyScheme != specificLegacyScheme)) {
vecBytes = obj.ToByteVector(specificLegacyScheme); vecBytes = obj.ToBytes(specificLegacyScheme);
bufValid = true; bufValid = true;
bufLegacyScheme = specificLegacyScheme; bufLegacyScheme = specificLegacyScheme;
hash.SetNull(); hash.SetNull();
@ -518,11 +525,10 @@ public:
{ {
std::unique_lock<std::mutex> l(mutex); std::unique_lock<std::mutex> l(mutex);
if (!objInitialized && !bufValid) { if (!objInitialized && !bufValid) {
vecBytes.resize(BLSObject::SerSize);
std::fill(vecBytes.begin(), vecBytes.end(), 0); std::fill(vecBytes.begin(), vecBytes.end(), 0);
hash.SetNull(); hash.SetNull();
} else if (!bufValid) { } else if (!bufValid) {
vecBytes = obj.ToByteVector(bufLegacyScheme); vecBytes = obj.ToBytes(bufLegacyScheme);
bufValid = true; bufValid = true;
hash.SetNull(); hash.SetNull();
} }

View File

@ -49,8 +49,7 @@ bool CBLSIESEncryptedBlob::Encrypt(size_t idx, const CBLSPublicKey& peerPubKey,
return false; return false;
} }
std::vector<unsigned char> symKey = pk.ToByteVector(); auto symKey = pk.ToBytes();
symKey.resize(32);
uint256 iv = GetIV(idx); uint256 iv = GetIV(idx);
return EncryptBlob(plainTextData, dataSize, data, symKey.data(), iv.begin()); 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; return false;
} }
std::vector<unsigned char> symKey = pk.ToByteVector();
symKey.resize(32);
uint256 iv = GetIV(idx); uint256 iv = GetIV(idx);
auto symKey = pk.ToBytes();
return DecryptBlob(data.data(), data.size(), decryptedDataRet, symKey.data(), iv.begin()); 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; return false;
} }
std::vector<uint8_t> symKey = pk.ToByteVector(); auto symKey = pk.ToBytes();
symKey.resize(32);
return EncryptBlob(blob.data(), blob.size(), blobs[idx], symKey.data(), ivVector[idx].begin()); 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; return false;
} }
std::vector<uint8_t> symKey = pk.ToByteVector();
symKey.resize(32);
uint256 iv = ivSeed; uint256 iv = ivSeed;
for (size_t i = 0; i < idx; i++) { for (size_t i = 0; i < idx; i++) {
iv = ::SerializeHash(iv); iv = ::SerializeHash(iv);
} }
auto symKey = pk.ToBytes();
return DecryptBlob(blobs[idx].data(), blobs[idx].size(), blobRet, symKey.data(), iv.begin()); return DecryptBlob(blobs[idx].data(), blobs[idx].size(), blobRet, symKey.data(), iv.begin());
} }

View File

@ -55,7 +55,7 @@ bool CCoinJoinQueue::Sign(const CActiveMasternodeManager& mn_activeman)
if (!sig.IsValid()) { if (!sig.IsValid()) {
return false; return false;
} }
vchSig = sig.ToByteVector(false); vchSig = sig.ToBytes(false);
return true; return true;
} }
@ -94,7 +94,7 @@ bool CCoinJoinBroadcastTx::Sign(const CActiveMasternodeManager& mn_activeman)
if (!sig.IsValid()) { if (!sig.IsValid()) {
return false; return false;
} }
vchSig = sig.ToByteVector(false); vchSig = sig.ToBytes(false);
return true; return true;
} }

View File

@ -7,6 +7,7 @@
#include <coinjoin/common.h> #include <coinjoin/common.h>
#include <bls/bls.h>
#include <core_io.h> #include <core_io.h>
#include <netaddress.h> #include <netaddress.h>
#include <primitives/block.h> #include <primitives/block.h>
@ -183,7 +184,7 @@ public:
uint256 m_protxHash; uint256 m_protxHash;
int64_t nTime{0}; int64_t nTime{0};
bool fReady{false}; //ready for submit bool fReady{false}; //ready for submit
std::vector<unsigned char> vchSig; std::array<unsigned char, BLS_CURVE_SIG_SIZE> vchSig;
// memory only // memory only
bool fTried{false}; bool fTried{false};
@ -243,7 +244,7 @@ public:
CTransactionRef tx; CTransactionRef tx;
COutPoint masternodeOutpoint; COutPoint masternodeOutpoint;
uint256 m_protxHash; uint256 m_protxHash;
std::vector<unsigned char> vchSig; std::array<unsigned char, BLS_CURVE_SIG_SIZE> vchSig;
int64_t sigTime{0}; int64_t sigTime{0};
CCoinJoinBroadcastTx() : CCoinJoinBroadcastTx() :
tx(MakeTransactionRef(CMutableTransaction{})) tx(MakeTransactionRef(CMutableTransaction{}))

View File

@ -1,5 +1,5 @@
AC_PREREQ([2.60]) AC_PREREQ([2.60])
AC_INIT([libdashbls],[1.3.4]) AC_INIT([libdashbls],[1.3.3])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([build-aux/m4]) AC_CONFIG_MACRO_DIR([build-aux/m4])

View File

@ -59,6 +59,7 @@ public:
GTElement Pair(const G2Element &b) const; GTElement Pair(const G2Element &b) const;
uint32_t GetFingerprint(bool fLegacy = false) const; uint32_t GetFingerprint(bool fLegacy = false) const;
std::vector<uint8_t> Serialize(bool fLegacy = false) const; std::vector<uint8_t> Serialize(bool fLegacy = false) const;
std::array<uint8_t, SIZE> SerializeToArray(bool fLegacy = false) const;
G1Element Copy(); G1Element Copy();
friend bool operator==(const G1Element &a, const G1Element &b); friend bool operator==(const G1Element &a, const G1Element &b);
@ -102,6 +103,7 @@ public:
G2Element Negate() const; G2Element Negate() const;
GTElement Pair(const G1Element &a) const; GTElement Pair(const G1Element &a) const;
std::vector<uint8_t> Serialize(bool fLegacy = false) const; std::vector<uint8_t> Serialize(bool fLegacy = false) const;
std::array<uint8_t, G2Element::SIZE> SerializeToArray(bool fLegacy = false) const;
G2Element Copy(); G2Element Copy();
friend bool operator==(G2Element const &a, G2Element const &b); friend bool operator==(G2Element const &a, G2Element const &b);
@ -127,6 +129,7 @@ public:
void Serialize(uint8_t *buffer) const; void Serialize(uint8_t *buffer) const;
std::vector<uint8_t> Serialize() const; std::vector<uint8_t> Serialize() const;
std::array<uint8_t, SIZE> SerializeToArray() const;
friend bool operator==(GTElement const &a, GTElement const &b); friend bool operator==(GTElement const &a, GTElement const &b);
friend bool operator!=(GTElement const &a, GTElement const &b); friend bool operator!=(GTElement const &a, GTElement const &b);

View File

@ -82,6 +82,7 @@ class PrivateKey {
// Serialize the key into bytes // Serialize the key into bytes
void Serialize(uint8_t *buffer) const; void Serialize(uint8_t *buffer) const;
std::vector<uint8_t> Serialize(bool fLegacy = false) const; std::vector<uint8_t> Serialize(bool fLegacy = false) const;
std::array<uint8_t, PrivateKey::PRIVATE_KEY_SIZE> SerializeToArray(bool fLegacy = false) const;
G2Element SignG2( G2Element SignG2(
const uint8_t *msg, const uint8_t *msg,

View File

@ -171,11 +171,16 @@ uint32_t G1Element::GetFingerprint(const bool fLegacy) const
} }
std::vector<uint8_t> G1Element::Serialize(const bool fLegacy) const { std::vector<uint8_t> G1Element::Serialize(const bool fLegacy) const {
const auto arr = G1Element::SerializeToArray(fLegacy);
return std::vector<uint8_t>{arr.begin(), arr.end()};
}
std::array<uint8_t, G1Element::SIZE> G1Element::SerializeToArray(const bool fLegacy) const {
uint8_t buffer[G1Element::SIZE + 1]; uint8_t buffer[G1Element::SIZE + 1];
g1_write_bin(buffer, G1Element::SIZE + 1, p, 1); g1_write_bin(buffer, G1Element::SIZE + 1, p, 1);
std::array<uint8_t, G1Element::SIZE> result{};
if (buffer[0] == 0x00) { // infinity if (buffer[0] == 0x00) { // infinity
std::vector<uint8_t> result(G1Element::SIZE, 0);
result[0] = 0xc0; result[0] = 0xc0;
return result; return result;
} }
@ -187,7 +192,9 @@ std::vector<uint8_t> G1Element::Serialize(const bool fLegacy) const {
if (!fLegacy) { if (!fLegacy) {
buffer[1] |= 0x80; // indicate compression buffer[1] |= 0x80; // indicate compression
} }
return std::vector<uint8_t>(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) 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); } GTElement G2Element::Pair(const G1Element& a) const { return a & (*this); }
std::vector<uint8_t> G2Element::Serialize(const bool fLegacy) const { std::vector<uint8_t> G2Element::Serialize(const bool fLegacy) const {
const auto arr = G2Element::SerializeToArray(fLegacy);
return std::vector<uint8_t>{arr.begin(), arr.end()};
}
std::array<uint8_t, G2Element::SIZE> G2Element::SerializeToArray(const bool fLegacy) const {
uint8_t buffer[G2Element::SIZE + 1]; uint8_t buffer[G2Element::SIZE + 1];
g2_write_bin(buffer, G2Element::SIZE + 1, (g2_st*)q, 1); g2_write_bin(buffer, G2Element::SIZE + 1, (g2_st*)q, 1);
std::array<uint8_t, G2Element::SIZE> result{};
if (buffer[0] == 0x00) { // infinity if (buffer[0] == 0x00) { // infinity
std::vector<uint8_t> result(G2Element::SIZE, 0); result.fill(0);
result[0] = 0xc0; result[0] = 0xc0;
return result; return result;
} }
@ -410,7 +424,6 @@ std::vector<uint8_t> G2Element::Serialize(const bool fLegacy) const {
} }
} }
std::vector<uint8_t> result(G2Element::SIZE, 0);
if (fLegacy) { if (fLegacy) {
std::memcpy(result.data(), buffer + 1, G2Element::SIZE); std::memcpy(result.data(), buffer + 1, G2Element::SIZE);
} else { } else {
@ -551,4 +564,11 @@ std::vector<uint8_t> GTElement::Serialize() const
return data; return data;
} }
std::array<uint8_t, GTElement::SIZE> GTElement::SerializeToArray() const
{
std::array<uint8_t, GTElement::SIZE> data{};
Serialize(data.data());
return data;
}
} // end namespace bls } // end namespace bls

View File

@ -284,6 +284,13 @@ std::vector<uint8_t> PrivateKey::Serialize(const bool fLegacy) const
return data; return data;
} }
std::array<uint8_t, PrivateKey::PRIVATE_KEY_SIZE> PrivateKey::SerializeToArray(bool fLegacy) const
{
std::array<uint8_t, PRIVATE_KEY_SIZE> data{};
Serialize(data.data());
return data;
}
G2Element PrivateKey::SignG2( G2Element PrivateKey::SignG2(
const uint8_t *msg, const uint8_t *msg,
size_t len, size_t len,

View File

@ -258,7 +258,7 @@ bool CGovernanceObject::Sign(const CActiveMasternodeManager& mn_activeman)
if (!sig.IsValid()) { if (!sig.IsValid()) {
return false; return false;
} }
m_obj.vchSig = sig.ToByteVector(false); m_obj.vchSig = sig.ToActualByteVector(false);
return true; return true;
} }

View File

@ -175,7 +175,7 @@ bool CGovernanceVote::Sign(const CActiveMasternodeManager& mn_activeman)
if (!sig.IsValid()) { if (!sig.IsValid()) {
return false; return false;
} }
vchSig = sig.ToByteVector(false); vchSig = sig.ToActualByteVector(false);
return true; return true;
} }

View File

@ -1016,12 +1016,12 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages, PeerManag
if (lieType == 3) { if (lieType == 3) {
const bool is_bls_legacy = bls::bls_legacy_scheme.load(); const bool is_bls_legacy = bls::bls_legacy_scheme.load();
std::vector<uint8_t> buf = qc.sig.ToByteVector(is_bls_legacy); auto buf = qc.sig.ToBytes(is_bls_legacy);
buf[5]++; buf[5]++;
qc.sig.SetByteVector(buf, is_bls_legacy); qc.sig.SetByteVector(buf, is_bls_legacy);
} else if (lieType == 4) { } else if (lieType == 4) {
const bool is_bls_legacy = bls::bls_legacy_scheme.load(); const bool is_bls_legacy = bls::bls_legacy_scheme.load();
std::vector<uint8_t> buf = qc.quorumSig.ToByteVector(is_bls_legacy); auto buf = qc.quorumSig.ToBytes(is_bls_legacy);
buf[5]++; buf[5]++;
qc.quorumSig.SetByteVector(buf, is_bls_legacy); qc.quorumSig.SetByteVector(buf, is_bls_legacy);
} }

View File

@ -820,6 +820,9 @@ template<typename Stream, unsigned int N, typename T> inline void Unserialize(St
template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v); template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v);
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v); template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v);
template <typename Stream, typename T, std::size_t N> void Serialize(Stream& os, const std::array<T, N>& a);
template <typename Stream, typename T, std::size_t N> void Unserialize(Stream& is, std::array<T, N>& a);
/** /**
* pair * pair
*/ */
@ -1051,6 +1054,54 @@ void Unserialize(Stream& is, std::vector<T, A>& v)
} }
} }
/**
* array
*/
template <typename Stream, typename T, std::size_t N>
void Serialize(Stream& os, const std::array<T, N>& a)
{
if constexpr (std::is_same_v<T, unsigned char>) {
// Directly write the byte data without writing the size
if (!a.empty()) {
os.write(MakeByteSpan(a));
}
}
else if constexpr (std::is_same_v<T, bool>) {
// 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 <typename Stream, typename T, std::size_t N>
void Unserialize(Stream& is, std::array<T, N>& a)
{
if constexpr (std::is_same_v<T, unsigned char>) {
// Directly read the byte data without reading the size
if (N > 0) {
is.read(AsWritableBytes(Span{a}));
}
}
else if constexpr (std::is_same_v<T, bool>) {
// 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 * pair