From 538fedde1d9c96a2bbe06cacc0cd6903135fbc83 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Tue, 7 May 2024 08:52:55 -0400 Subject: [PATCH 1/5] common: Add ECC_Context RAII wrapper for ECC_Start/ECC_Stop --- src/key.cpp | 10 ++++++++++ src/key.h | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/key.cpp b/src/key.cpp index 2bd639629818e..8f311463110d9 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -457,3 +457,13 @@ void ECC_Stop() { secp256k1_context_destroy(ctx); } } + +ECC_Context::ECC_Context() +{ + ECC_Start(); +} + +ECC_Context::~ECC_Context() +{ + ECC_Stop(); +} diff --git a/src/key.h b/src/key.h index 53acd179ba8f7..5454c007d36a9 100644 --- a/src/key.h +++ b/src/key.h @@ -245,4 +245,18 @@ void ECC_Stop(); /** Check that required EC support is available at runtime. */ bool ECC_InitSanityCheck(); +/** + * RAII class initializing and deinitializing global state for elliptic curve support. + * Only one instance may be initialized at a time. + * + * In the future global ECC state could be removed, and this class could contain + * state and be passed as an argument to ECC key functions. + */ +class ECC_Context +{ +public: + ECC_Context(); + ~ECC_Context(); +}; + #endif // BITCOIN_KEY_H From 28905c1a64a87a56f16aea8a4d23dea7eec9ca59 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Tue, 7 May 2024 08:54:19 -0400 Subject: [PATCH 2/5] test: Use ECC_Context helper in bench and fuzz tests --- src/bench/bip324_ecdh.cpp | 4 +--- src/bench/ccoins_caching.cpp | 3 +-- src/bench/checkqueue.cpp | 3 +-- src/bench/descriptors.cpp | 4 +--- src/bench/ellswift.cpp | 4 +--- src/bench/verify_script.cpp | 3 +-- src/test/fuzz/bip324.cpp | 2 +- src/test/fuzz/descriptor_parse.cpp | 2 +- src/test/fuzz/key.cpp | 2 +- src/test/fuzz/key_io.cpp | 2 +- src/test/fuzz/message.cpp | 2 +- src/test/fuzz/miniscript.cpp | 2 +- src/test/fuzz/p2p_transport_serialization.cpp | 2 +- src/test/fuzz/script_sign.cpp | 2 +- src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp | 3 +-- 15 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/bench/bip324_ecdh.cpp b/src/bench/bip324_ecdh.cpp index fb10c2957e0ed..88f3932ad85e8 100644 --- a/src/bench/bip324_ecdh.cpp +++ b/src/bench/bip324_ecdh.cpp @@ -14,7 +14,7 @@ static void BIP324_ECDH(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; FastRandomContext rng; std::array key_data; @@ -44,8 +44,6 @@ static void BIP324_ECDH(benchmark::Bench& bench) // - 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, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp index 4a3ec67c2b818..05b2f5435ce71 100644 --- a/src/bench/ccoins_caching.cpp +++ b/src/bench/ccoins_caching.cpp @@ -18,7 +18,7 @@ // (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484) static void CCoinsCaching(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; FillableSigningProvider keystore; CCoinsView coinsDummy; @@ -47,7 +47,6 @@ static void CCoinsCaching(benchmark::Bench& bench) bool success{AreInputsStandard(tx_1, coins)}; assert(success); }); - ECC_Stop(); } BENCHMARK(CCoinsCaching, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/checkqueue.cpp b/src/bench/checkqueue.cpp index 114dd9d39c86a..c973fe9f71706 100644 --- a/src/bench/checkqueue.cpp +++ b/src/bench/checkqueue.cpp @@ -25,7 +25,7 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench) // We shouldn't ever be running with the checkqueue on a single core machine. if (GetNumCores() <= 1) return; - ECC_Start(); + ECC_Context ecc_context{}; struct PrevectorJob { prevector p; @@ -62,6 +62,5 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench) // it is done explicitly here for clarity control.Wait(); }); - ECC_Stop(); } BENCHMARK(CCheckQueueSpeedPrevectorJob, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/descriptors.cpp b/src/bench/descriptors.cpp index fbef1395fba62..5d6bcb8ce8729 100644 --- a/src/bench/descriptors.cpp +++ b/src/bench/descriptors.cpp @@ -12,7 +12,7 @@ static void ExpandDescriptor(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; const auto desc_str = "sh(wsh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232)))"; const std::pair range = {0, 1000}; @@ -27,8 +27,6 @@ static void ExpandDescriptor(benchmark::Bench& bench) assert(success); } }); - - ECC_Stop(); } BENCHMARK(ExpandDescriptor, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/ellswift.cpp b/src/bench/ellswift.cpp index 9441b4863e2ca..4780db8e1c3cf 100644 --- a/src/bench/ellswift.cpp +++ b/src/bench/ellswift.cpp @@ -9,7 +9,7 @@ static void EllSwiftCreate(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; CKey key = GenerateRandomKey(); uint256 entropy = GetRandHash(); @@ -22,8 +22,6 @@ static void EllSwiftCreate(benchmark::Bench& bench) /* Use the last 32 bytes of the ellswift encoded public key as next entropy. */ std::copy(ret.begin() + 32, ret.begin() + 64, MakeWritableByteSpan(entropy).begin()); }); - - ECC_Stop(); } BENCHMARK(EllSwiftCreate, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index ee750bc1f8a35..f38aa49a23f2f 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -15,7 +15,7 @@ // modified to measure performance of other types of scripts. static void VerifyScriptBench(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; const uint32_t flags{SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH}; const int witnessversion = 0; @@ -57,7 +57,6 @@ static void VerifyScriptBench(benchmark::Bench& bench) assert(err == SCRIPT_ERR_OK); assert(success); }); - ECC_Stop(); } static void VerifyNestedIfScript(benchmark::Bench& bench) diff --git a/src/test/fuzz/bip324.cpp b/src/test/fuzz/bip324.cpp index 37c41f389537a..8210e75cee232 100644 --- a/src/test/fuzz/bip324.cpp +++ b/src/test/fuzz/bip324.cpp @@ -17,7 +17,7 @@ namespace { void Initialize() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::MAIN); } diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp index 6ea315d4e22df..b9a5560ffb905 100644 --- a/src/test/fuzz/descriptor_parse.cpp +++ b/src/test/fuzz/descriptor_parse.cpp @@ -55,7 +55,7 @@ static void TestDescriptor(const Descriptor& desc, FlatSigningProvider& sig_prov void initialize_descriptor_parse() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::MAIN); } diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp index 9e1e318e024f9..d389a29575f74 100644 --- a/src/test/fuzz/key.cpp +++ b/src/test/fuzz/key.cpp @@ -32,7 +32,7 @@ void initialize_key() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::REGTEST); } diff --git a/src/test/fuzz/key_io.cpp b/src/test/fuzz/key_io.cpp index 5f98f2b7f1b2b..aefdefe233551 100644 --- a/src/test/fuzz/key_io.cpp +++ b/src/test/fuzz/key_io.cpp @@ -14,7 +14,7 @@ void initialize_key_io() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::MAIN); } diff --git a/src/test/fuzz/message.cpp b/src/test/fuzz/message.cpp index b5c95441f8cc5..75baaa2754ea0 100644 --- a/src/test/fuzz/message.cpp +++ b/src/test/fuzz/message.cpp @@ -19,7 +19,7 @@ void initialize_message() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::REGTEST); } diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp index 947424c4ac463..f10007222c481 100644 --- a/src/test/fuzz/miniscript.cpp +++ b/src/test/fuzz/miniscript.cpp @@ -1201,7 +1201,7 @@ void TestNode(const MsCtx script_ctx, const NodeRef& node, FuzzedDataProvider& p void FuzzInit() { - ECC_Start(); + static ECC_Context ecc_context{}; TEST_DATA.Init(); } diff --git a/src/test/fuzz/p2p_transport_serialization.cpp b/src/test/fuzz/p2p_transport_serialization.cpp index 1b7a732260e15..f6d82c3001bbc 100644 --- a/src/test/fuzz/p2p_transport_serialization.cpp +++ b/src/test/fuzz/p2p_transport_serialization.cpp @@ -25,7 +25,7 @@ std::vector g_all_messages; void initialize_p2p_transport_serialization() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::REGTEST); g_all_messages = getAllNetMessageTypes(); std::sort(g_all_messages.begin(), g_all_messages.end()); diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp index 9ae150e553021..4695bc611b1d6 100644 --- a/src/test/fuzz/script_sign.cpp +++ b/src/test/fuzz/script_sign.cpp @@ -26,7 +26,7 @@ void initialize_script_sign() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::REGTEST); } diff --git a/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp b/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp index 74ef6bfd4ecfc..ae0c8479cb395 100644 --- a/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp +++ b/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp @@ -24,8 +24,7 @@ FUZZ_TARGET(secp256k1_ecdsa_signature_parse_der_lax) secp256k1_ecdsa_signature sig_der_lax; const bool parsed_der_lax = ecdsa_signature_parse_der_lax(&sig_der_lax, signature_bytes.data(), signature_bytes.size()) == 1; if (parsed_der_lax) { - ECC_Start(); + ECC_Context ecc_context{}; (void)SigHasLowR(&sig_der_lax); - ECC_Stop(); } } From a08d2b3cb971c68e9a50b991b2953fa4541cf48a Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Tue, 7 May 2024 08:55:34 -0400 Subject: [PATCH 3/5] tools: Use ECC_Context helper in bitcoin-tx and bitcoin-wallet tools --- src/bitcoin-tx.cpp | 19 ++++--------------- src/bitcoin-wallet.cpp | 3 +-- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 1c5b0c074c9e4..cfac50e0907d8 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -692,21 +692,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) tx = mergedTx; } -class Secp256k1Init -{ -public: - Secp256k1Init() { - ECC_Start(); - } - ~Secp256k1Init() { - ECC_Stop(); - } -}; - static void MutateTx(CMutableTransaction& tx, const std::string& command, const std::string& commandVal) { - std::unique_ptr ecc; + std::unique_ptr ecc; if (command == "nversion") MutateTxVersion(tx, commandVal); @@ -726,10 +715,10 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command, else if (command == "outaddr") MutateTxAddOutAddr(tx, commandVal); else if (command == "outpubkey") { - ecc.reset(new Secp256k1Init()); + ecc.reset(new ECC_Context()); MutateTxAddOutPubKey(tx, commandVal); } else if (command == "outmultisig") { - ecc.reset(new Secp256k1Init()); + ecc.reset(new ECC_Context()); MutateTxAddOutMultiSig(tx, commandVal); } else if (command == "outscript") MutateTxAddOutScript(tx, commandVal); @@ -737,7 +726,7 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command, MutateTxAddOutData(tx, commandVal); else if (command == "sign") { - ecc.reset(new Secp256k1Init()); + ecc.reset(new ECC_Context()); MutateTxSign(tx, commandVal); } diff --git a/src/bitcoin-wallet.cpp b/src/bitcoin-wallet.cpp index bee052bc46de2..e6d20b55c235b 100644 --- a/src/bitcoin-wallet.cpp +++ b/src/bitcoin-wallet.cpp @@ -128,10 +128,9 @@ MAIN_FUNCTION return EXIT_FAILURE; } - ECC_Start(); + ECC_Context ecc_context{}; if (!wallet::WalletTool::ExecuteWalletToolFunc(args, command->command)) { return EXIT_FAILURE; } - ECC_Stop(); return EXIT_SUCCESS; } From 41eba5bd716bea47c8731d156d053afee92a7f12 Mon Sep 17 00:00:00 2001 From: TheCharlatan Date: Mon, 15 Jan 2024 12:55:31 +0100 Subject: [PATCH 4/5] kernel: Remove key module from kernel library The key module's functionality is not used by the kernel library, but currently kernel users are still required to initialize the key module's `secp256k1_context_sign` global as part of the `kernel::Context` through `ECC_Start`. --- src/Makefile.am | 1 - src/bitcoin-chainstate.cpp | 1 + src/bitcoind.cpp | 3 +++ src/init.cpp | 8 ++++++++ src/kernel/checks.cpp | 6 +----- src/kernel/context.cpp | 7 ------- src/kernel/context.h | 5 ----- src/node/context.cpp | 2 ++ src/node/context.h | 11 ++++++++--- src/node/interfaces.cpp | 2 ++ src/node/kernel_notifications.cpp | 1 + src/rpc/mining.cpp | 1 + src/test/util/setup_common.cpp | 2 ++ src/test/util/setup_common.h | 2 ++ 14 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 639aecf3b352a..669bf403629ae 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -945,7 +945,6 @@ libbitcoinkernel_la_SOURCES = \ kernel/disconnected_transactions.cpp \ kernel/mempool_persist.cpp \ kernel/mempool_removal_reason.cpp \ - key.cpp \ logging.cpp \ node/blockstorage.cpp \ node/chainstate.cpp \ diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index 642af06e82d2c..4927634233310 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -26,6 +26,7 @@ #include