mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-15 09:09:46 +02:00
key: cleanse ChainCode on destruction
HMAC primitives cleanse their internal stack buffers, but a caller's ChainCode remains populated in memory after use. Promote ChainCode from `typedef uint256` to a `base_blob<256>` subclass with a memory_cleanse() destructor, so chain codes in CExtKey, CExtPubKey, and local variables are cleansed on scope exit. Retype MUSIG_CHAINCODE from `constexpr uint256` to `const ChainCode` to match its BIP328 semantic role. Dropping `constexpr` (ChainCode is no longer a literal type) also removes the GCC-14 consteval lambda workaround. Remove the duplicate typedef in pubkey.h (which includes hash.h transitively). Two fuzz-test call sites in test/fuzz/key.cpp now construct the chain-code argument explicitly rather than relying on the typedef.
This commit is contained in:
10
src/hash.h
10
src/hash.h
@@ -13,12 +13,20 @@
|
||||
#include <prevector.h>
|
||||
#include <serialize.h>
|
||||
#include <span.h>
|
||||
#include <support/cleanse.h>
|
||||
#include <uint256.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef uint256 ChainCode;
|
||||
/** A BIP32 chain code. Cleansed on destruction. */
|
||||
class ChainCode : public base_blob<256> {
|
||||
public:
|
||||
constexpr ChainCode() = default;
|
||||
constexpr explicit ChainCode(std::span<const unsigned char> vch) : base_blob<256>(vch) {}
|
||||
constexpr explicit ChainCode(const base_blob<256>& b) : base_blob<256>(b) {}
|
||||
~ChainCode() { memory_cleanse(data(), size()); }
|
||||
};
|
||||
|
||||
/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
|
||||
class CHash256 {
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
|
||||
//! MuSig2 chaincode as defined by BIP 328
|
||||
using namespace util::hex_literals;
|
||||
constexpr uint256 MUSIG_CHAINCODE{
|
||||
// Use immediate lambda to work around GCC-14 bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117966
|
||||
[]() consteval { return uint256{"868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965"_hex_u8}; }(),
|
||||
};
|
||||
const ChainCode MUSIG_CHAINCODE{"868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965"_hex_u8};
|
||||
|
||||
static bool GetMuSig2KeyAggCache(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache)
|
||||
{
|
||||
|
||||
@@ -27,8 +27,6 @@ public:
|
||||
explicit CKeyID(const uint160& in) : uint160(in) {}
|
||||
};
|
||||
|
||||
typedef uint256 ChainCode;
|
||||
|
||||
/** An encapsulated public key. */
|
||||
class CPubKey
|
||||
{
|
||||
|
||||
@@ -85,7 +85,7 @@ FUZZ_TARGET(key, .init = initialize_key)
|
||||
{
|
||||
CKey child_key;
|
||||
ChainCode child_chaincode;
|
||||
const bool ok = key.Derive(child_key, child_chaincode, 0, random_uint256);
|
||||
const bool ok = key.Derive(child_key, child_chaincode, 0, ChainCode{random_uint256});
|
||||
assert(ok);
|
||||
assert(child_key.IsValid());
|
||||
assert(!(child_key == key));
|
||||
@@ -275,7 +275,7 @@ FUZZ_TARGET(key, .init = initialize_key)
|
||||
{
|
||||
CPubKey child_pubkey;
|
||||
ChainCode child_chaincode;
|
||||
const bool ok = pubkey.Derive(child_pubkey, child_chaincode, 0, random_uint256);
|
||||
const bool ok = pubkey.Derive(child_pubkey, child_chaincode, 0, ChainCode{random_uint256});
|
||||
assert(ok);
|
||||
assert(child_pubkey != pubkey);
|
||||
assert(child_pubkey.IsCompressed());
|
||||
|
||||
Reference in New Issue
Block a user