pubkey: Return tweaks from BIP32 derivation

MuSig2 needs the BIP32 derivation tweaks in order to sign with a key
derived from the aggregate pubkey.
This commit is contained in:
Ava Chow committed 2025-09-30 11:06:09 -07:00
1 parent f14876213a
commit 4b24bfeab9
2 files changed
+8 -5

No files matched your search

+6 -3
View File
@@ -338,13 +338,16 @@ bool CPubKey::Decompress() {
return true; 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(IsValid());
assert((nChild >> 31) == 0); assert((nChild >> 31) == 0);
assert(size() == COMPRESSED_SIZE); assert(size() == COMPRESSED_SIZE);
unsigned char out[64]; unsigned char out[64];
BIP32Hash(cc, nChild, *begin(), begin()+1, out); BIP32Hash(cc, nChild, *begin(), begin()+1, out);
memcpy(ccChild.begin(), out+32, 32); memcpy(ccChild.begin(), out+32, 32);
if (bip32_tweak_out) {
memcpy(bip32_tweak_out->begin(), out, 32);
}
secp256k1_pubkey pubkey; secp256k1_pubkey pubkey;
if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) { if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
return false; return false;
@@ -409,13 +412,13 @@ void CExtPubKey::DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VE
Decode(&code[4]); 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<unsigned char>::max()) return false; if (nDepth == std::numeric_limits<unsigned char>::max()) return false;
out.nDepth = nDepth + 1; out.nDepth = nDepth + 1;
CKeyID id = pubkey.GetID(); CKeyID id = pubkey.GetID();
memcpy(out.vchFingerprint, &id, 4); memcpy(out.vchFingerprint, &id, 4);
out.nChild = _nChild; 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<unsigned char>& vchSig) { /* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
+2 -2
View File
@@ -224,7 +224,7 @@ public:
bool Decompress(); bool Decompress();
//! Derive BIP32 child pubkey. //! 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 class XOnlyPubKey
@@ -379,7 +379,7 @@ struct CExtPubKey {
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
void EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const; void EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const;
void DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]); 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 #endif // BITCOIN_PUBKEY_H