From 4b24bfeab9d6732aae3e69efd33105792ef1198f Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Mon, 4 Mar 2024 15:40:00 -0500 Subject: [PATCH] pubkey: Return tweaks from BIP32 derivation MuSig2 needs the BIP32 derivation tweaks in order to sign with a key derived from the aggregate pubkey. --- src/pubkey.cpp | 9 ++++++--- src/pubkey.h | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 6041c89e7f1..264f861bc7a 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -338,13 +338,16 @@ bool CPubKey::Decompress() { return true; } -bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const { +bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc, uint256* bip32_tweak_out) const { assert(IsValid()); assert((nChild >> 31) == 0); assert(size() == COMPRESSED_SIZE); unsigned char out[64]; BIP32Hash(cc, nChild, *begin(), begin()+1, out); memcpy(ccChild.begin(), out+32, 32); + if (bip32_tweak_out) { + memcpy(bip32_tweak_out->begin(), out, 32); + } secp256k1_pubkey pubkey; if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) { return false; @@ -409,13 +412,13 @@ void CExtPubKey::DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VE Decode(&code[4]); } -bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const { +bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild, uint256* bip32_tweak_out) const { if (nDepth == std::numeric_limits::max()) return false; out.nDepth = nDepth + 1; CKeyID id = pubkey.GetID(); memcpy(out.vchFingerprint, &id, 4); out.nChild = _nChild; - return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode); + return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode, bip32_tweak_out); } /* static */ bool CPubKey::CheckLowS(const std::vector& vchSig) { diff --git a/src/pubkey.h b/src/pubkey.h index 442dc2d6431..5ae7f75dde9 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -224,7 +224,7 @@ public: bool Decompress(); //! Derive BIP32 child pubkey. - [[nodiscard]] bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; + [[nodiscard]] bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc, uint256* bip32_tweak_out = nullptr) const; }; class XOnlyPubKey @@ -379,7 +379,7 @@ struct CExtPubKey { void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); void EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const; void DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]); - [[nodiscard]] bool Derive(CExtPubKey& out, unsigned int nChild) const; + [[nodiscard]] bool Derive(CExtPubKey& out, unsigned int nChild, uint256* bip32_tweak_out = nullptr) const; }; #endif // BITCOIN_PUBKEY_H