dash/src/bls/bls.h

603 lines
18 KiB
C
Raw Normal View History

// Copyright (c) 2018-2022 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DASH_CRYPTO_BLS_H
#define DASH_CRYPTO_BLS_H
Backport 11651 (#3358) * scripted-diff: Replace #include "" with #include <> (ryanofsky) -BEGIN VERIFY SCRIPT- for f in \ src/*.cpp \ src/*.h \ src/bench/*.cpp \ src/bench/*.h \ src/compat/*.cpp \ src/compat/*.h \ src/consensus/*.cpp \ src/consensus/*.h \ src/crypto/*.cpp \ src/crypto/*.h \ src/crypto/ctaes/*.h \ src/policy/*.cpp \ src/policy/*.h \ src/primitives/*.cpp \ src/primitives/*.h \ src/qt/*.cpp \ src/qt/*.h \ src/qt/test/*.cpp \ src/qt/test/*.h \ src/rpc/*.cpp \ src/rpc/*.h \ src/script/*.cpp \ src/script/*.h \ src/support/*.cpp \ src/support/*.h \ src/support/allocators/*.h \ src/test/*.cpp \ src/test/*.h \ src/wallet/*.cpp \ src/wallet/*.h \ src/wallet/test/*.cpp \ src/wallet/test/*.h \ src/zmq/*.cpp \ src/zmq/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * scripted-diff: Replace #include "" with #include <> (Dash Specific) -BEGIN VERIFY SCRIPT- for f in \ src/bls/*.cpp \ src/bls/*.h \ src/evo/*.cpp \ src/evo/*.h \ src/governance/*.cpp \ src/governance/*.h \ src/llmq/*.cpp \ src/llmq/*.h \ src/masternode/*.cpp \ src/masternode/*.h \ src/privatesend/*.cpp \ src/privatesend/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * build: Remove -I for everything but project root Remove -I from build system for everything but the project root, and built-in dependencies. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/Makefile.test.include * qt: refactor: Use absolute include paths in .ui files * qt: refactor: Changes to make include paths absolute This makes all include paths in the GUI absolute. Many changes are involved as every single source file in src/qt/ assumes to be able to use relative includes. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/qt/dash.cpp # src/qt/optionsmodel.cpp # src/qt/test/rpcnestedtests.cpp * test: refactor: Use absolute include paths for test data files * Recommend #include<> syntax in developer notes * refactor: Include obj/build.h instead of build.h * END BACKPORT #11651 Remove trailing whitespace causing travis failure * fix backport 11651 Signed-off-by: Pasta <pasta@dashboost.org> * More of 11651 * fix blockchain.cpp Signed-off-by: pasta <pasta@dashboost.org> * Add missing "qt/" in includes * Add missing "test/" in includes * Fix trailing whitespaces Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com> Co-authored-by: Russell Yanofsky <russ@yanofsky.org> Co-authored-by: MeshCollider <dobsonsa68@gmail.com> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-03-19 23:46:56 +01:00
#include <hash.h>
#include <serialize.h>
#include <uint256.h>
merge bitcoin#14555: Move util files to directory (script modified to account for Dash backports, doesn't account for rebasing) ------------- BEGIN SCRIPT --------------- mkdir -p src/util git mv src/util.h src/util/system.h git mv src/util.cpp src/util/system.cpp git mv src/utilmemory.h src/util/memory.h git mv src/utilmoneystr.h src/util/moneystr.h git mv src/utilmoneystr.cpp src/util/moneystr.cpp git mv src/utilstrencodings.h src/util/strencodings.h git mv src/utilstrencodings.cpp src/util/strencodings.cpp git mv src/utiltime.h src/util/time.h git mv src/utiltime.cpp src/util/time.cpp git mv src/utilasmap.h src/util/asmap.h git mv src/utilasmap.cpp src/util/asmap.cpp git mv src/utilstring.h src/util/string.h git mv src/utilstring.cpp src/util/string.cpp gsed -i 's/<util\.h>/<util\/system\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilmemory\.h>/<util\/memory\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilmoneystr\.h>/<util\/moneystr\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilstrencodings\.h>/<util\/strencodings\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utiltime\.h>/<util\/time\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilasmap\.h>/<util\/asmap\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilstring\.h>/<util\/string\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/BITCOIN_UTIL_H/BITCOIN_UTIL_SYSTEM_H/g' src/util/system.h gsed -i 's/BITCOIN_UTILMEMORY_H/BITCOIN_UTIL_MEMORY_H/g' src/util/memory.h gsed -i 's/BITCOIN_UTILMONEYSTR_H/BITCOIN_UTIL_MONEYSTR_H/g' src/util/moneystr.h gsed -i 's/BITCOIN_UTILSTRENCODINGS_H/BITCOIN_UTIL_STRENCODINGS_H/g' src/util/strencodings.h gsed -i 's/BITCOIN_UTILTIME_H/BITCOIN_UTIL_TIME_H/g' src/util/time.h gsed -i 's/BITCOIN_UTILASMAP_H/BITCOIN_UTIL_ASMAP_H/g' src/util/asmap.h gsed -i 's/BITCOIN_UTILSTRING_H/BITCOIN_UTIL_STRING_H/g' src/util/string.h gsed -i 's/ util\.\(h\|cpp\)/ util\/system\.\1/g' src/Makefile.am gsed -i 's/utilmemory\.\(h\|cpp\)/util\/memory\.\1/g' src/Makefile.am gsed -i 's/utilmoneystr\.\(h\|cpp\)/util\/moneystr\.\1/g' src/Makefile.am gsed -i 's/utilstrencodings\.\(h\|cpp\)/util\/strencodings\.\1/g' src/Makefile.am gsed -i 's/utiltime\.\(h\|cpp\)/util\/time\.\1/g' src/Makefile.am gsed -i 's/utilasmap\.\(h\|cpp\)/util\/asmap\.\1/g' src/Makefile.am gsed -i 's/utilstring\.\(h\|cpp\)/util\/string\.\1/g' src/Makefile.am gsed -i 's/-> util ->/-> util\/system ->/' test/lint/lint-circular-dependencies.sh gsed -i 's/src\/util\.cpp/src\/util\/system\.cpp/g' test/lint/lint-format-strings.py test/lint/lint-locale-dependence.sh gsed -i 's/src\/utilmoneystr\.cpp/src\/util\/moneystr\.cpp/g' test/lint/lint-locale-dependence.sh gsed -i 's/src\/utilstrencodings\.\(h\|cpp\)/src\/util\/strencodings\.\1/g' test/lint/lint-locale-dependence.sh ------------- END SCRIPT ---------------
2021-06-27 08:33:13 +02:00
#include <util/strencodings.h>
#include <util/ranges.h>
bls|depends: Upgrade to bls-signatures version 1.0.0 (#4027) * build: Add cmake as depends package (cmake.mk) The bls-signatures library requires cmake 3.14 * depends: Update chia_bls to version 1.0.0 of dashpay/bls-signatures * depends: Rename package chia_bls to bls-dash * depends: Disable blspy/tests/benchmarks build for chia_bls Note: Building with tests would require the following: depends: Fix macOS build for versions < 10.12 Seems like older versions of macOS pretend to support c++17 std libs but do not have/have issues with uncaught_exceptions. "Catch", the testing framework used in the bls lib wants those by default but setting `DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS` disables them which should be just fine to do in all cases here. --- depends/packages/chia_bls.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/depends/packages/chia_bls.mk b/depends/packages/chia_bls.mk index e79a85844f..25749b74ab 100644 --- a/depends/packages/chia_bls.mk +++ b/depends/packages/chia_bls.mk @@ -28,6 +28,8 @@ define $(package)_set_vars $(package)_config_opts_darwin+= -DCMAKE_AR="$(host_prefix)/native/bin/$($(package)_ar)" $(package)_config_opts_darwin+= -DCMAKE_RANLIB="$(host_prefix)/native/bin/$($(package)_ranlib)" endif + + $(package)_cppflags+= -DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS endef define $(package)_config_cmds -- * depends: Drop obsolete variable * bls: Integrate the upgraded version into the codebase * depends: Pre-fetch relic to fix gitian Can fetch apt packages only when building with lxc Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2021-03-26 13:32:31 +01:00
// bls-dash uses relic, which may define DEBUG and ERROR, which leads to many warnings in some build setups
#undef ERROR
#undef DEBUG
#include <dashbls/bls.hpp>
#include <dashbls/privatekey.hpp>
#include <dashbls/elements.hpp>
#include <dashbls/schemes.hpp>
#include <dashbls/threshold.hpp>
#undef DOUBLE
#undef SEED
#include <array>
#include <mutex>
#include <unistd.h>
#include <atomic>
namespace bls {
extern std::atomic<bool> bls_legacy_scheme;
}
bls|depends: Upgrade to bls-signatures version 1.0.0 (#4027) * build: Add cmake as depends package (cmake.mk) The bls-signatures library requires cmake 3.14 * depends: Update chia_bls to version 1.0.0 of dashpay/bls-signatures * depends: Rename package chia_bls to bls-dash * depends: Disable blspy/tests/benchmarks build for chia_bls Note: Building with tests would require the following: depends: Fix macOS build for versions < 10.12 Seems like older versions of macOS pretend to support c++17 std libs but do not have/have issues with uncaught_exceptions. "Catch", the testing framework used in the bls lib wants those by default but setting `DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS` disables them which should be just fine to do in all cases here. --- depends/packages/chia_bls.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/depends/packages/chia_bls.mk b/depends/packages/chia_bls.mk index e79a85844f..25749b74ab 100644 --- a/depends/packages/chia_bls.mk +++ b/depends/packages/chia_bls.mk @@ -28,6 +28,8 @@ define $(package)_set_vars $(package)_config_opts_darwin+= -DCMAKE_AR="$(host_prefix)/native/bin/$($(package)_ar)" $(package)_config_opts_darwin+= -DCMAKE_RANLIB="$(host_prefix)/native/bin/$($(package)_ranlib)" endif + + $(package)_cppflags+= -DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS endef define $(package)_config_cmds -- * depends: Drop obsolete variable * bls: Integrate the upgraded version into the codebase * depends: Pre-fetch relic to fix gitian Can fetch apt packages only when building with lxc Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2021-03-26 13:32:31 +01:00
// reversed BLS12-381
constexpr int BLS_CURVE_ID_SIZE{32};
constexpr int BLS_CURVE_SECKEY_SIZE{32};
constexpr int BLS_CURVE_PUBKEY_SIZE{48};
constexpr int BLS_CURVE_SIG_SIZE{96};
class CBLSSignature;
class CBLSPublicKey;
template <typename ImplType, size_t _SerSize, typename C>
class CBLSWrapper
{
friend class CBLSSecretKey;
friend class CBLSPublicKey;
friend class CBLSSignature;
protected:
ImplType impl;
bool fValid{false};
mutable uint256 cachedHash;
public:
static constexpr size_t SerSize = _SerSize;
explicit CBLSWrapper() = default;
explicit CBLSWrapper(const std::vector<unsigned char>& vecBytes) : CBLSWrapper<ImplType, _SerSize, C>()
{
SetByteVector(vecBytes);
}
CBLSWrapper(const CBLSWrapper& ref) = default;
CBLSWrapper& operator=(const CBLSWrapper& ref) = default;
CBLSWrapper(CBLSWrapper&& ref) noexcept
{
std::swap(impl, ref.impl);
std::swap(fValid, ref.fValid);
std::swap(cachedHash, ref.cachedHash);
}
CBLSWrapper& operator=(CBLSWrapper&& ref) noexcept
{
std::swap(impl, ref.impl);
std::swap(fValid, ref.fValid);
std::swap(cachedHash, ref.cachedHash);
return *this;
}
virtual ~CBLSWrapper() = default;
bool operator==(const C& r) const
{
return fValid == r.fValid && impl == r.impl;
}
bool operator!=(const C& r) const
{
return !((*this) == r);
}
bool IsValid() const
{
return fValid;
}
void Reset()
{
*(static_cast<C*>(this)) = C();
}
void SetByteVector(const std::vector<uint8_t>& vecBytes, const bool specificLegacyScheme)
{
if (vecBytes.size() != SerSize) {
Reset();
return;
}
if (ranges::all_of(vecBytes, [](uint8_t c) { return c == 0; })) {
Reset();
} else {
try {
impl = ImplType::FromBytes(bls::Bytes(vecBytes), specificLegacyScheme);
fValid = true;
} catch (...) {
Reset();
}
}
cachedHash.SetNull();
}
void SetByteVector(const std::vector<uint8_t>& vecBytes)
{
SetByteVector(vecBytes, bls::bls_legacy_scheme.load());
}
std::vector<uint8_t> ToByteVector(const bool specificLegacyScheme) const
{
if (!fValid) {
return std::vector<uint8_t>(SerSize, 0);
}
return impl.Serialize(specificLegacyScheme);
}
std::vector<uint8_t> ToByteVector() const
{
return ToByteVector(bls::bls_legacy_scheme.load());
}
const uint256& GetHash() const
{
if (cachedHash.IsNull()) {
cachedHash = ::SerializeHash(*this);
}
return cachedHash;
}
bool SetHexStr(const std::string& str, const bool specificLegacyScheme)
{
if (!IsHex(str)) {
Reset();
return false;
}
auto b = ParseHex(str);
if (b.size() != SerSize) {
Reset();
return false;
}
SetByteVector(b, specificLegacyScheme);
return IsValid();
}
bool SetHexStr(const std::string& str)
{
return SetHexStr(str, bls::bls_legacy_scheme.load());
}
inline void Serialize(CSizeComputer& s) const
{
s.seek(SerSize);
}
template <typename Stream>
inline void Serialize(Stream& s, const bool specificLegacyScheme) const
{
s.write(reinterpret_cast<const char*>(ToByteVector(specificLegacyScheme).data()), SerSize);
}
template <typename Stream>
inline void Serialize(Stream& s) const
{
Serialize(s, bls::bls_legacy_scheme.load());
}
template <typename Stream>
inline void Unserialize(Stream& s, const bool specificLegacyScheme, bool checkMalleable = true)
{
std::vector<uint8_t> vecBytes(SerSize, 0);
s.read(reinterpret_cast<char*>(vecBytes.data()), SerSize);
SetByteVector(vecBytes, specificLegacyScheme);
if (checkMalleable && !CheckMalleable(vecBytes, specificLegacyScheme)) {
fix: BLS checkMalleable protection (#5240) <!-- *** Please remove the following help text before submitting: *** Provide a general summary of your changes in the Title above Pull requests without a rationale and clear improvement may be closed immediately. Please provide clear motivation for your patch and explain how it improves Dash Core user experience or Dash Core developer experience significantly: * Any test improvements or new tests that improve coverage are always welcome. * All other changes should have accompanying unit tests (see `src/test/`) or functional tests (see `test/`). Contributors should note which tests cover modified code. If no tests exist for a region of modified code, new tests should accompany the change. * Bug fixes are most welcome when they come with steps to reproduce or an explanation of the potential issue as well as reasoning for the way the bug was fixed. * Features are welcome, but might be rejected due to design or scope issues. If a feature is based on a lot of dependencies, contributors should first consider building the system outside of Dash Core, if possible. --> ## Issue being fixed or feature implemented <!--- Why is this change required? What problem does it solve? --> <!--- If it fixes an open issue, please link to the issue here. --> ## What was done? <!--- Describe your changes in detail --> ## How Has This Been Tested? <!--- Please describe in detail how you tested your changes. --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> ## Breaking Changes <!--- Please describe any breaking changes your code introduces --> ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation **For repository code-owners and collaborators only** - [x] I have assigned this pull request to a milestone --------- Co-authored-by: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com>
2023-03-09 09:13:00 +01:00
// If CheckMalleable failed with specificLegacyScheme, we need to try again with the opposite scheme.
// Probably we received the BLS object sent with legacy scheme, but in the meanwhile the fork activated.
SetByteVector(vecBytes, !specificLegacyScheme);
if (!CheckMalleable(vecBytes, !specificLegacyScheme)) {
// Both attempts failed
throw std::ios_base::failure("malleable BLS object");
} else {
// Indeed the received vecBytes was in opposite scheme. But we can't keep it (mixing with the new scheme will lead to undefined behavior)
// Therefore, resetting current object (basically marking it as invalid).
Reset();
}
}
}
template <typename Stream>
inline void Unserialize(Stream& s, bool checkMalleable = true)
{
Unserialize(s, bls::bls_legacy_scheme.load(), checkMalleable);
}
inline bool CheckMalleable(const std::vector<uint8_t>& vecBytes, const bool specificLegacyScheme) const
{
if (memcmp(vecBytes.data(), ToByteVector(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
return false;
}
return true;
}
inline bool CheckMalleable(const std::vector<uint8_t>& vecBytes) const
{
return CheckMalleable(vecBytes, bls::bls_legacy_scheme.load());
}
inline std::string ToString(const bool specificLegacyScheme) const
{
std::vector<uint8_t> buf = ToByteVector(specificLegacyScheme);
return HexStr(buf);
}
inline std::string ToString() const
{
return ToString(bls::bls_legacy_scheme.load());
}
};
struct CBLSIdImplicit : public uint256
{
CBLSIdImplicit() = default;
CBLSIdImplicit(const uint256& id)
{
memcpy(begin(), id.begin(), sizeof(uint256));
}
static CBLSIdImplicit FromBytes(const uint8_t* buffer, const bool fLegacy)
{
CBLSIdImplicit instance;
memcpy(instance.begin(), buffer, sizeof(CBLSIdImplicit));
return instance;
}
[[nodiscard]] std::vector<uint8_t> Serialize(const bool fLegacy) const
{
return {begin(), end()};
}
};
class CBLSId : public CBLSWrapper<CBLSIdImplicit, BLS_CURVE_ID_SIZE, CBLSId>
{
public:
using CBLSWrapper::operator=;
using CBLSWrapper::operator==;
using CBLSWrapper::operator!=;
using CBLSWrapper::CBLSWrapper;
CBLSId() = default;
explicit CBLSId(const uint256& nHash);
};
class CBLSSecretKey : public CBLSWrapper<bls::PrivateKey, BLS_CURVE_SECKEY_SIZE, CBLSSecretKey>
{
public:
using CBLSWrapper::operator=;
using CBLSWrapper::operator==;
using CBLSWrapper::operator!=;
using CBLSWrapper::CBLSWrapper;
CBLSSecretKey() = default;
CBLSSecretKey(const CBLSSecretKey&) = default;
CBLSSecretKey& operator=(const CBLSSecretKey&) = default;
void AggregateInsecure(const CBLSSecretKey& o);
static CBLSSecretKey AggregateInsecure(const std::vector<CBLSSecretKey>& sks);
#ifndef BUILD_BITCOIN_INTERNAL
void MakeNewKey();
#endif
bool SecretKeyShare(const std::vector<CBLSSecretKey>& msk, const CBLSId& id);
[[nodiscard]] CBLSPublicKey GetPublicKey() const;
[[nodiscard]] CBLSSignature Sign(const uint256& hash) const;
};
bls|depends: Upgrade to bls-signatures version 1.0.0 (#4027) * build: Add cmake as depends package (cmake.mk) The bls-signatures library requires cmake 3.14 * depends: Update chia_bls to version 1.0.0 of dashpay/bls-signatures * depends: Rename package chia_bls to bls-dash * depends: Disable blspy/tests/benchmarks build for chia_bls Note: Building with tests would require the following: depends: Fix macOS build for versions < 10.12 Seems like older versions of macOS pretend to support c++17 std libs but do not have/have issues with uncaught_exceptions. "Catch", the testing framework used in the bls lib wants those by default but setting `DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS` disables them which should be just fine to do in all cases here. --- depends/packages/chia_bls.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/depends/packages/chia_bls.mk b/depends/packages/chia_bls.mk index e79a85844f..25749b74ab 100644 --- a/depends/packages/chia_bls.mk +++ b/depends/packages/chia_bls.mk @@ -28,6 +28,8 @@ define $(package)_set_vars $(package)_config_opts_darwin+= -DCMAKE_AR="$(host_prefix)/native/bin/$($(package)_ar)" $(package)_config_opts_darwin+= -DCMAKE_RANLIB="$(host_prefix)/native/bin/$($(package)_ranlib)" endif + + $(package)_cppflags+= -DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS endef define $(package)_config_cmds -- * depends: Drop obsolete variable * bls: Integrate the upgraded version into the codebase * depends: Pre-fetch relic to fix gitian Can fetch apt packages only when building with lxc Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2021-03-26 13:32:31 +01:00
class CBLSPublicKey : public CBLSWrapper<bls::G1Element, BLS_CURVE_PUBKEY_SIZE, CBLSPublicKey>
{
friend class CBLSSecretKey;
friend class CBLSSignature;
public:
using CBLSWrapper::operator=;
using CBLSWrapper::operator==;
using CBLSWrapper::operator!=;
using CBLSWrapper::CBLSWrapper;
CBLSPublicKey() = default;
void AggregateInsecure(const CBLSPublicKey& o);
static CBLSPublicKey AggregateInsecure(const std::vector<CBLSPublicKey>& pks);
bool PublicKeyShare(const std::vector<CBLSPublicKey>& mpk, const CBLSId& id);
bool DHKeyExchange(const CBLSSecretKey& sk, const CBLSPublicKey& pk);
};
class ConstCBLSPublicKeyVersionWrapper {
private:
const CBLSPublicKey& obj;
bool legacy;
public:
ConstCBLSPublicKeyVersionWrapper(const CBLSPublicKey& obj, bool legacy)
: obj(obj)
, legacy(legacy)
{}
template <typename Stream>
inline void Serialize(Stream& s) const {
obj.Serialize(s, legacy);
}
};
class CBLSPublicKeyVersionWrapper {
private:
CBLSPublicKey& obj;
bool legacy;
bool checkMalleable;
public:
CBLSPublicKeyVersionWrapper(CBLSPublicKey& obj, bool legacy, bool checkMalleable = true)
: obj(obj)
, legacy(legacy)
, checkMalleable(checkMalleable)
{}
template <typename Stream>
inline void Serialize(Stream& s) const {
obj.Serialize(s, legacy);
}
template <typename Stream>
inline void Unserialize(Stream& s) {
obj.Unserialize(s, legacy, checkMalleable);
}
};
bls|depends: Upgrade to bls-signatures version 1.0.0 (#4027) * build: Add cmake as depends package (cmake.mk) The bls-signatures library requires cmake 3.14 * depends: Update chia_bls to version 1.0.0 of dashpay/bls-signatures * depends: Rename package chia_bls to bls-dash * depends: Disable blspy/tests/benchmarks build for chia_bls Note: Building with tests would require the following: depends: Fix macOS build for versions < 10.12 Seems like older versions of macOS pretend to support c++17 std libs but do not have/have issues with uncaught_exceptions. "Catch", the testing framework used in the bls lib wants those by default but setting `DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS` disables them which should be just fine to do in all cases here. --- depends/packages/chia_bls.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/depends/packages/chia_bls.mk b/depends/packages/chia_bls.mk index e79a85844f..25749b74ab 100644 --- a/depends/packages/chia_bls.mk +++ b/depends/packages/chia_bls.mk @@ -28,6 +28,8 @@ define $(package)_set_vars $(package)_config_opts_darwin+= -DCMAKE_AR="$(host_prefix)/native/bin/$($(package)_ar)" $(package)_config_opts_darwin+= -DCMAKE_RANLIB="$(host_prefix)/native/bin/$($(package)_ranlib)" endif + + $(package)_cppflags+= -DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS endef define $(package)_config_cmds -- * depends: Drop obsolete variable * bls: Integrate the upgraded version into the codebase * depends: Pre-fetch relic to fix gitian Can fetch apt packages only when building with lxc Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2021-03-26 13:32:31 +01:00
class CBLSSignature : public CBLSWrapper<bls::G2Element, BLS_CURVE_SIG_SIZE, CBLSSignature>
{
friend class CBLSSecretKey;
public:
using CBLSWrapper::operator==;
using CBLSWrapper::operator!=;
using CBLSWrapper::CBLSWrapper;
CBLSSignature() = default;
CBLSSignature(const CBLSSignature&) = default;
CBLSSignature& operator=(const CBLSSignature&) = default;
void AggregateInsecure(const CBLSSignature& o);
static CBLSSignature AggregateInsecure(const std::vector<CBLSSignature>& sigs);
static CBLSSignature AggregateSecure(const std::vector<CBLSSignature>& sigs, const std::vector<CBLSPublicKey>& pks, const uint256& hash);
void SubInsecure(const CBLSSignature& o);
[[nodiscard]] bool VerifyInsecure(const CBLSPublicKey& pubKey, const uint256& hash, const bool specificLegacyScheme) const;
[[nodiscard]] bool VerifyInsecure(const CBLSPublicKey& pubKey, const uint256& hash) const;
[[nodiscard]] bool VerifyInsecureAggregated(const std::vector<CBLSPublicKey>& pubKeys, const std::vector<uint256>& hashes) const;
[[nodiscard]] bool VerifySecureAggregated(const std::vector<CBLSPublicKey>& pks, const uint256& hash) const;
bool Recover(const std::vector<CBLSSignature>& sigs, const std::vector<CBLSId>& ids);
};
class CBLSSignatureVersionWrapper {
private:
CBLSSignature& obj;
bool legacy;
bool checkMalleable;
public:
CBLSSignatureVersionWrapper(CBLSSignature& obj, bool legacy, bool checkMalleable = true)
: obj(obj)
, legacy(legacy)
, checkMalleable(checkMalleable)
{}
template <typename Stream>
inline void Serialize(Stream& s) const {
obj.Serialize(s, legacy);
}
template <typename Stream>
inline void Unserialize(Stream& s) {
obj.Unserialize(s, legacy, checkMalleable);
}
};
#ifndef BUILD_BITCOIN_INTERNAL
template<typename BLSObject>
class CBLSLazyWrapper
{
private:
mutable std::mutex mutex;
mutable std::vector<uint8_t> vecBytes;
mutable bool bufValid{false};
mutable bool bufLegacyScheme{true};
mutable BLSObject obj;
mutable bool objInitialized{false};
mutable uint256 hash;
public:
CBLSLazyWrapper() :
vecBytes(BLSObject::SerSize, 0),
bufLegacyScheme(bls::bls_legacy_scheme.load())
{
// the all-zero buf is considered a valid buf, but the resulting object will return false for IsValid
bufValid = true;
}
explicit CBLSLazyWrapper(const CBLSLazyWrapper& r)
{
*this = r;
}
virtual ~CBLSLazyWrapper() = default;
CBLSLazyWrapper& operator=(const CBLSLazyWrapper& r)
{
std::unique_lock<std::mutex> l(r.mutex);
bufValid = r.bufValid;
bufLegacyScheme = r.bufLegacyScheme;
if (r.bufValid) {
vecBytes = r.vecBytes;
} else {
std::fill(vecBytes.begin(), vecBytes.end(), 0);
}
objInitialized = r.objInitialized;
if (r.objInitialized) {
obj = r.obj;
} else {
obj.Reset();
}
hash = r.hash;
return *this;
}
inline void Serialize(CSizeComputer& s) const
{
s.seek(BLSObject::SerSize);
}
template<typename Stream>
inline void Serialize(Stream& s, const bool specificLegacyScheme) const
{
std::unique_lock<std::mutex> l(mutex);
if (!objInitialized && !bufValid) {
// the all-zero buf is considered a valid buf
std::fill(vecBytes.begin(), vecBytes.end(), 0);
bufLegacyScheme = specificLegacyScheme;
bufValid = true;
}
if (!bufValid || (bufLegacyScheme != specificLegacyScheme)) {
vecBytes = obj.ToByteVector(specificLegacyScheme);
bufValid = true;
bufLegacyScheme = specificLegacyScheme;
hash.SetNull();
}
s.write(reinterpret_cast<const char*>(vecBytes.data()), vecBytes.size());
}
template<typename Stream>
inline void Serialize(Stream& s) const
{
Serialize(s, bls::bls_legacy_scheme.load());
}
template<typename Stream>
inline void Unserialize(Stream& s, const bool specificLegacyScheme) const
{
std::unique_lock<std::mutex> l(mutex);
s.read(reinterpret_cast<char*>(vecBytes.data()), BLSObject::SerSize);
bufValid = true;
bufLegacyScheme = specificLegacyScheme;
objInitialized = false;
hash.SetNull();
}
template<typename Stream>
inline void Unserialize(Stream& s) const
{
Unserialize(s, bls::bls_legacy_scheme.load());
}
void Set(const BLSObject& _obj)
{
std::unique_lock<std::mutex> l(mutex);
bufValid = false;
objInitialized = true;
obj = _obj;
hash.SetNull();
}
const BLSObject& Get() const
{
std::unique_lock<std::mutex> l(mutex);
static BLSObject invalidObj;
if (!bufValid && !objInitialized) {
return invalidObj;
}
if (!objInitialized) {
obj.SetByteVector(vecBytes, bufLegacyScheme);
if (!obj.IsValid()) {
// If setting of BLS object using one scheme failed, then we need to attempt again with the opposite scheme.
// This is due to the fact that LazyBLSWrapper receives a serialised buffer but attempts to create actual BLS object when needed.
// That could happen when the fork has been activated and the enforced scheme has switched.
obj.SetByteVector(vecBytes, !bufLegacyScheme);
if (obj.IsValid()) {
bufLegacyScheme = !bufLegacyScheme;
}
}
if (!obj.CheckMalleable(vecBytes, bufLegacyScheme)) {
bufValid = false;
objInitialized = false;
obj = invalidObj;
} else {
objInitialized = true;
}
}
return obj;
}
bool operator==(const CBLSLazyWrapper& r) const
{
if (bufValid && r.bufValid && bufLegacyScheme == r.bufLegacyScheme) {
return vecBytes == r.vecBytes;
}
if (objInitialized && r.objInitialized) {
return obj == r.obj;
}
return Get() == r.Get();
}
bool operator!=(const CBLSLazyWrapper& r) const
{
return !(*this == r);
}
uint256 GetHash(const bool specificLegacyScheme = bls::bls_legacy_scheme.load()) const
{
std::unique_lock<std::mutex> l(mutex);
if (!bufValid || bufLegacyScheme != specificLegacyScheme) {
vecBytes = obj.ToByteVector(specificLegacyScheme);
bufValid = true;
bufLegacyScheme = specificLegacyScheme;
hash.SetNull();
}
if (hash.IsNull()) {
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss.write(reinterpret_cast<const char*>(vecBytes.data()), vecBytes.size());
hash = ss.GetHash();
}
return hash;
}
};
using CBLSLazySignature = CBLSLazyWrapper<CBLSSignature>;
using CBLSLazyPublicKey = CBLSLazyWrapper<CBLSPublicKey>;
class CBLSLazyPublicKeyVersionWrapper {
private:
CBLSLazyPublicKey& obj;
bool legacy;
public:
CBLSLazyPublicKeyVersionWrapper(CBLSLazyPublicKey& obj, bool legacy)
: obj(obj)
, legacy(legacy)
{}
template <typename Stream>
inline void Serialize(Stream& s) const {
obj.Serialize(s, legacy);
}
template <typename Stream>
inline void Unserialize(Stream& s) {
obj.Unserialize(s, legacy);
}
};
#endif
using BLSIdVector = std::vector<CBLSId>;
using BLSVerificationVector = std::vector<CBLSPublicKey>;
using BLSPublicKeyVector = std::vector<CBLSPublicKey>;
using BLSSecretKeyVector = std::vector<CBLSSecretKey>;
using BLSSignatureVector = std::vector<CBLSSignature>;
using BLSVerificationVectorPtr = std::shared_ptr<BLSVerificationVector>;
bool BLSInit();
#endif // DASH_CRYPTO_BLS_H