Repository: bitcoin/bitcoin
File: src/key.h (C/C++)

Code before:
    CKey key;

    friend bool operator==(const CExtKey& a, const CExtKey& b)
    {
        return a.nDepth == b.nDepth &&
            memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
            a.nChild == b.nChild &&
            a.chaincode == b.chaincode &&
            a.key == b.key;
    }

    CExtKey() = default;
    CExtKey(const CExtPubKey& xpub, const CKey& key_in) : nDepth(xpub.nDepth), nChild(xpub.nChild), chaincode(xpub.chaincode), key(key_in)
    {
        std::copy(xpub.vchFingerprint, xpub.vchFingerprint + sizeof(xpub.vchFingerprint), vchFingerprint);
    }

    void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
    void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
    [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
    CExtPubKey Neuter() const;
    void SetSeed(Span<const std::byte> seed);
};

/** KeyPair
 *
 *  Wraps a `secp256k1_keypair` type. `merkle_root` is used to optionally perform tweaking of
 *  the internal key, as specified in BIP341:
 *
 *  - If merkle_root == nullptr: no tweaking is done, use the internal key directly (this is
 *                               used for signatures in BIP342 script).
 *  - If merkle_root->IsNull():  tweak the internal key with H_TapTweak(pubkey) (this is used for
 *                               key path spending when no scripts are present).
 *  - Otherwise:                 tweak the internal key H_TapTweak(pubkey || *merkle_root)
 *                               (this is used for key path spending, with specific
 *                               Merkle root of the script tree).
 */
class KeyPair
{
public:
    KeyPair(KeyPair&&) noexcept = default;
    KeyPair& operator=(KeyPair&&) noexcept = default;

    friend KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const;
    [[nodiscard]] bool GetKey(CKey& key) const;
    [[nodiscard]] bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256& aux) const;

    //! Simple read-only vector-like interface.
    unsigned int size() const { return m_keydata ? m_keydata->size() : 0; }
    const std::byte* data() const { return m_keydata ? reinterpret_cast<const std::byte*>(m_keydata->data()) : nullptr; }
    const std::byte* begin() const { return data(); }

Review comment (suggestion):
The same header is already and very thoughtfully provided for the following function a few lines above

`KeyPair ComputeKeyPair(const uint256* merkle_root) const;` 

 Maybe here a shorter header would be more appropriate to avoid repeating ourselves and make maintenance easier to handle (at the comment level), like so

```
/** KeyPair
 *
 *  Wrapper class for the `secp256k1_keypair` type.
 */ 
```


Code after:
    ChainCode chaincode;
    CKey key;

    friend bool operator==(const CExtKey& a, const CExtKey& b)
    {
        return a.nDepth == b.nDepth &&
            memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
            a.nChild == b.nChild &&
            a.chaincode == b.chaincode &&
            a.key == b.key;
    }

    CExtKey() = default;
    CExtKey(const CExtPubKey& xpub, const CKey& key_in) : nDepth(xpub.nDepth), nChild(xpub.nChild), chaincode(xpub.chaincode), key(key_in)
    {
        std::copy(xpub.vchFingerprint, xpub.vchFingerprint + sizeof(xpub.vchFingerprint), vchFingerprint);
    }

    void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
    void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
    [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
    CExtPubKey Neuter() const;
    void SetSeed(Span<const std::byte> seed);
};

/** KeyPair
 *
 *  Wraps a `secp256k1_keypair` type, an opaque data structure for holding a secret and public key.
 *  This is intended for BIP340 keys and allows us to easily determine if the secret key needs to
 *  be negated by checking the parity of the public key. This class primarily intended for passing
 *  secret keys to libsecp256k1 functions expecting a `secp256k1_keypair`. For all other cases,
 *  CKey should be preferred.
 *
 *  A KeyPair can be created from a CKey with an optional merkle_root tweak (per BIP342). See
 *  CKey::ComputeKeyPair for more details.
 */
class KeyPair
{
public:
    KeyPair() noexcept = default;
    KeyPair(KeyPair&&) noexcept = default;
    KeyPair& operator=(KeyPair&&) noexcept = default;
    KeyPair& operator=(const KeyPair& other)
    {
        if (this != &other) {
            if (other.m_keypair) {
                MakeKeyPairData();
                *m_keypair = *other.m_keypair;
            } else {
                ClearKeyPairData();
            }