Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ci/dash/build_src.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ rm -rf build-ci
mkdir build-ci
cd build-ci

../configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
../configure $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
make distdir VERSION=$BUILD_TARGET

cd dashcore-$BUILD_TARGET
./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
./configure $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)

make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false )

Expand Down
10 changes: 1 addition & 9 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1863,15 +1863,7 @@ LIBS_TEMP="$LIBS"
unset LIBS
LIBS="$LIBS_TEMP"

PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
unset PKG_CONFIG_PATH
PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP"

PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR"
unset PKG_CONFIG_LIBDIR
PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP"

ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --disable-openssl-tests"
ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --disable-module-ecdh"
AC_CONFIG_SUBDIRS([src/dashbls src/secp256k1])

AC_OUTPUT
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.bench.include
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ bench_bench_dash_SOURCES = \
bench/bench_bitcoin.cpp \
bench/bench.cpp \
bench/bench.h \
bench/bip324_ecdh.cpp \
bench/block_assemble.cpp \
bench/bls.cpp \
bench/bls_dkg.cpp \
Expand All @@ -26,6 +27,7 @@ bench_bench_dash_SOURCES = \
bench/data.cpp \
bench/duplicate_inputs.cpp \
bench/ecdsa.cpp \
bench/ellswift.cpp \
bench/examples.cpp \
bench/rollingbloom.cpp \
bench/chacha20.cpp \
Expand Down
51 changes: 51 additions & 0 deletions src/bench/bip324_ecdh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>

#include <key.h>
#include <pubkey.h>
#include <random.h>
#include <span.h>

#include <array>
#include <cstddef>

static void BIP324_ECDH(benchmark::Bench& bench)
{
ECC_Start();
FastRandomContext rng;

std::array<std::byte, 32> key_data;
std::array<std::byte, EllSwiftPubKey::size()> our_ellswift_data;
std::array<std::byte, EllSwiftPubKey::size()> their_ellswift_data;

rng.fillrand(key_data);
rng.fillrand(our_ellswift_data);
rng.fillrand(their_ellswift_data);

bench.batch(1).unit("ecdh").run([&] {
CKey key;
key.Set(UCharCast(key_data.data()), UCharCast(key_data.data()) + 32, true);
EllSwiftPubKey our_ellswift(our_ellswift_data);
EllSwiftPubKey their_ellswift(their_ellswift_data);

auto ret = key.ComputeBIP324ECDHSecret(their_ellswift, our_ellswift, true);

// To make sure that the computation is not the same on every iteration (ellswift decoding
// is variable-time), distribute bytes from the shared secret over the 3 inputs. The most
// important one is their_ellswift, because that one is actually decoded, so it's given most
// bytes. The data is copied into the middle, so that both halves are affected:
// - Copy 8 bytes from the resulting shared secret into middle of the private key.
std::copy(ret.begin(), ret.begin() + 8, key_data.begin() + 12);
// - Copy 8 bytes from the resulting shared secret into the middle of our ellswift key.
std::copy(ret.begin() + 8, ret.begin() + 16, our_ellswift_data.begin() + 28);
// - Copy 16 bytes from the resulting shared secret into the middle of their ellswift key.
std::copy(ret.begin() + 16, ret.end(), their_ellswift_data.begin() + 24);
});

ECC_Stop();
}

BENCHMARK(BIP324_ECDH);
1 change: 0 additions & 1 deletion src/bench/ccoins_caching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
static void CCoinsCaching(benchmark::Bench& bench)
{
const ECCVerifyHandle verify_handle;
ECC_Start();

FillableSigningProvider keystore;
Expand Down
1 change: 0 additions & 1 deletion src/bench/checkqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ static const unsigned int QUEUE_BATCH_SIZE = 128;
// and there is a little bit of work done between calls to Add.
static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench)
{
const ECCVerifyHandle verify_handle;
ECC_Start();

struct PrevectorJob {
Expand Down
31 changes: 31 additions & 0 deletions src/bench/ellswift.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2022-2023 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>

#include <key.h>
#include <random.h>

static void EllSwiftCreate(benchmark::Bench& bench)
{
ECC_Start();

CKey key;
key.MakeNewKey(true);

uint256 entropy = GetRandHash();

bench.batch(1).unit("pubkey").run([&] {
auto ret = key.EllSwiftCreate(AsBytes(Span{entropy}));
/* Use the first 32 bytes of the ellswift encoded public key as next private key. */
key.Set(UCharCast(ret.data()), UCharCast(ret.data()) + 32, true);
assert(key.IsValid());
/* Use the last 32 bytes of the ellswift encoded public key as next entropy. */
std::copy(ret.begin() + 32, ret.begin() + 64, BytePtr(entropy.data()));
});

ECC_Stop();
}

BENCHMARK(EllSwiftCreate);
12 changes: 2 additions & 10 deletions src/bitcoin-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <chainparamsbase.h>
#include <clientversion.h>
#include <compat.h>
#include <rpc/client.h>
#include <rpc/mining.h>
#include <rpc/protocol.h>
Expand Down Expand Up @@ -914,16 +915,7 @@ static int CommandLineRPC(int argc, char *argv[])
return nRet;
}

#ifdef WIN32
// Export main() and ensure working ASLR on Windows.
// Exporting a symbol will prevent the linker from stripping
// the .reloc section from the binary, which is a requirement
// for ASLR. This is a temporary workaround until a fixed
// version of binutils is used for releases.
__declspec(dllexport) int main(int argc, char* argv[])
#else
int main(int argc, char* argv[])
#endif
MAIN_FUNCTION
{
RegisterPrettyTerminateHander();
RegisterPrettySignalHandlers();
Expand Down
5 changes: 2 additions & 3 deletions src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <chainparams.h>
#include <clientversion.h>
#include <coins.h>
#include <compat.h>
#include <consensus/consensus.h>
#include <core_io.h>
#include <key_io.h>
Expand Down Expand Up @@ -616,8 +617,6 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)

class Secp256k1Init
{
ECCVerifyHandle globalVerifyHandle;

public:
Secp256k1Init() {
ECC_Start();
Expand Down Expand Up @@ -786,7 +785,7 @@ static int CommandLineRawTx(int argc, char* argv[])
return nRet;
}

int main(int argc, char* argv[])
MAIN_FUNCTION
{
RegisterPrettyTerminateHander();
RegisterPrettySignalHandlers();
Expand Down
4 changes: 2 additions & 2 deletions src/bitcoin-wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <chainparams.h>
#include <chainparamsbase.h>
#include <compat.h>
#include <logging.h>
#include <util/strencodings.h>
#include <util/system.h>
Expand Down Expand Up @@ -73,7 +74,7 @@ static bool WalletAppInit(int argc, char* argv[])
return true;
}

int main(int argc, char* argv[])
MAIN_FUNCTION
{
#ifdef WIN32
util::WinCmdLineArgs winArgs;
Expand Down Expand Up @@ -112,7 +113,6 @@ int main(int argc, char* argv[])

std::string name = gArgs.GetArg("-wallet", "");

ECCVerifyHandle globalVerifyHandle;
ECC_Start();
if (!WalletTool::ExecuteWalletToolFunc(method, name))
return EXIT_FAILURE;
Expand Down
2 changes: 1 addition & 1 deletion src/bitcoind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ static bool AppInit(int argc, char* argv[])
return fRet;
}

int main(int argc, char* argv[])
MAIN_FUNCTION
{
RegisterPrettyTerminateHander();
RegisterPrettySignalHandlers();
Expand Down
11 changes: 11 additions & 0 deletions src/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ typedef void* sockopt_arg_type;
typedef char* sockopt_arg_type;
#endif

#ifdef WIN32
// Export main() and ensure working ASLR when using mingw-w64.
// Exporting a symbol will prevent the linker from stripping
// the .reloc section from the binary, which is a requirement
// for ASLR. While release builds are not affected, anyone
// building with a binutils < 2.36 is subject to this ld bug.
#define MAIN_FUNCTION __declspec(dllexport) int main(int argc, char* argv[])
#else
#define MAIN_FUNCTION int main(int argc, char* argv[])
#endif

// Note these both should work with the current usage of poll, but best to be safe
// WIN32 poll is broken https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/
// __APPLE__ poll is broke https://github.com/bitcoin/bitcoin/pull/14336#issuecomment-437384408
Expand Down
4 changes: 0 additions & 4 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,6 @@ static fs::path GetPidFile(const ArgsManager& args)
// shutdown thing.
//

static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;

void Interrupt(NodeContext& node)
{
InterruptHTTPServer();
Expand Down Expand Up @@ -399,7 +397,6 @@ void Shutdown(NodeContext& node)
PrepareShutdown(node);
}
// Shutdown part 2: delete wallet instance
globalVerifyHandle.reset();
ECC_Stop();
node.mempool.reset();
node.fee_estimator.reset();
Expand Down Expand Up @@ -1467,7 +1464,6 @@ bool AppInitSanityChecks()
LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
RandomInit();
ECC_Start();
globalVerifyHandle.reset(new ECCVerifyHandle());

// Sanity check
if (!InitSanityCheck())
Expand Down
59 changes: 55 additions & 4 deletions src/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <random.h>

#include <secp256k1.h>
#include <secp256k1_ellswift.h>
#include <secp256k1_recovery.h>

static secp256k1_context* secp256k1_context_sign = nullptr;
Expand Down Expand Up @@ -226,6 +227,12 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool gr
assert(ret);
secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, vchSig.data(), &nSigLen, &sig);
vchSig.resize(nSigLen);
// Additional verification step to prevent using a potentially corrupted signature
secp256k1_pubkey pk;
ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pk, begin());
assert(ret);
ret = secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pk);
assert(ret);
return true;
}

Expand All @@ -248,13 +255,21 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
return false;
vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE);
int rec = -1;
secp256k1_ecdsa_recoverable_signature sig;
int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, nullptr);
secp256k1_ecdsa_recoverable_signature rsig;
int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &rsig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, nullptr);
assert(ret);
ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_sign, &vchSig[1], &rec, &sig);
ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_sign, &vchSig[1], &rec, &rsig);
assert(ret);
assert(rec != -1);
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
// Additional verification step to prevent using a potentially corrupted signature
secp256k1_pubkey epk, rpk;
ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &epk, begin());
assert(ret);
ret = secp256k1_ecdsa_recover(secp256k1_context_static, &rpk, &rsig, hash.begin());
assert(ret);
ret = secp256k1_ec_pubkey_cmp(secp256k1_context_static, &epk, &rpk);
assert(ret == 0);
return true;
}

Expand Down Expand Up @@ -290,6 +305,42 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const
return ret;
}

EllSwiftPubKey CKey::EllSwiftCreate(Span<const std::byte> ent32) const
{
assert(fValid);
assert(ent32.size() == 32);
std::array<std::byte, EllSwiftPubKey::size()> encoded_pubkey;

auto success = secp256k1_ellswift_create(secp256k1_context_sign,
UCharCast(encoded_pubkey.data()),
keydata.data(),
UCharCast(ent32.data()));

// Should always succeed for valid keys (asserted above).
assert(success);
return {encoded_pubkey};
}

ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, const EllSwiftPubKey& our_ellswift, bool initiating) const
{
assert(fValid);

ECDHSecret output;
// BIP324 uses the initiator as party A, and the responder as party B. Remap the inputs
// accordingly:
bool success = secp256k1_ellswift_xdh(secp256k1_context_sign,
UCharCast(output.data()),
UCharCast(initiating ? our_ellswift.data() : their_ellswift.data()),
UCharCast(initiating ? their_ellswift.data() : our_ellswift.data()),
keydata.data(),
initiating ? 0 : 1,
secp256k1_ellswift_xdh_hash_function_bip324,
nullptr);
// Should always succeed for valid keys (assert above).
assert(success);
return output;
}

bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const {
out.nDepth = nDepth + 1;
CKeyID id = key.GetPubKey().GetID();
Expand Down Expand Up @@ -348,7 +399,7 @@ bool ECC_InitSanityCheck() {
void ECC_Start() {
assert(secp256k1_context_sign == nullptr);

secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
assert(ctx != nullptr);

{
Expand Down
Loading