LCOV - code coverage report
Current view: top level - src - key.h (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 86.0 % 57 49
Test Date: 2025-10-25 04:38:23 Functions: 84.6 % 13 11
Branches: 44.6 % 240 107

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2                 :             : // Copyright (c) 2009-present The Bitcoin Core developers
       3                 :             : // Copyright (c) 2017 The Zcash developers
       4                 :             : // Distributed under the MIT software license, see the accompanying
       5                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6                 :             : 
       7                 :             : #ifndef BITCOIN_KEY_H
       8                 :             : #define BITCOIN_KEY_H
       9                 :             : 
      10                 :             : #include <musig.h>
      11                 :             : #include <pubkey.h>
      12                 :             : #include <serialize.h>
      13                 :             : #include <support/allocators/secure.h>
      14                 :             : #include <uint256.h>
      15                 :             : 
      16                 :             : #include <stdexcept>
      17                 :             : #include <vector>
      18                 :             : 
      19                 :             : 
      20                 :             : /**
      21                 :             :  * CPrivKey is a serialized private key, with all parameters included
      22                 :             :  * (SIZE bytes)
      23                 :             :  */
      24                 :             : typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
      25                 :             : 
      26                 :             : /** Size of ECDH shared secrets. */
      27                 :             : constexpr static size_t ECDH_SECRET_SIZE = CSHA256::OUTPUT_SIZE;
      28                 :             : 
      29                 :             : // Used to represent ECDH shared secret (ECDH_SECRET_SIZE bytes)
      30                 :             : using ECDHSecret = std::array<std::byte, ECDH_SECRET_SIZE>;
      31                 :             : 
      32                 :             : class KeyPair;
      33                 :             : 
      34                 :             : /** An encapsulated private key. */
      35   [ +  +  +  +  :       25150 : class CKey
          +  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
           +  - ][ +  - ]
      36                 :             : {
      37                 :             : public:
      38                 :             :     /**
      39                 :             :      * secp256k1:
      40                 :             :      */
      41                 :             :     static const unsigned int SIZE            = 279;
      42                 :             :     static const unsigned int COMPRESSED_SIZE = 214;
      43                 :             :     /**
      44                 :             :      * see www.keylength.com
      45                 :             :      * script supports up to 75 for single byte push
      46                 :             :      */
      47                 :             :     static_assert(
      48                 :             :         SIZE >= COMPRESSED_SIZE,
      49                 :             :         "COMPRESSED_SIZE is larger than SIZE");
      50                 :             : 
      51                 :             : private:
      52                 :             :     /** Internal data container for private key material. */
      53                 :             :     using KeyType = std::array<unsigned char, 32>;
      54                 :             : 
      55                 :             :     //! Whether the public key corresponding to this private key is (to be) compressed.
      56                 :             :     bool fCompressed{false};
      57                 :             : 
      58                 :             :     //! The actual byte data. nullptr for invalid keys.
      59                 :             :     secure_unique_ptr<KeyType> keydata;
      60                 :             : 
      61                 :             :     //! Check whether the 32-byte array pointed to by vch is valid keydata.
      62                 :             :     bool static Check(const unsigned char* vch);
      63                 :             : 
      64                 :       34107 :     void MakeKeyData()
      65                 :             :     {
      66         [ +  + ]:       34107 :         if (!keydata) keydata = make_secure_unique<KeyType>();
      67                 :       34107 :     }
      68                 :             : 
      69                 :           2 :     void ClearKeyData()
      70                 :             :     {
      71                 :           2 :         keydata.reset();
      72                 :           2 :     }
      73                 :             : 
      74                 :             : public:
      75 [ +  - ][ +  -  :        3119 :     CKey() noexcept = default;
             -  +  +  - ]
           [ +  -  +  -  
             +  -  +  - ]
      76                 :         636 :     CKey(CKey&&) noexcept = default;
      77                 :         599 :     CKey& operator=(CKey&&) noexcept = default;
      78                 :             : 
      79                 :       27258 :     CKey& operator=(const CKey& other)
      80                 :             :     {
      81         [ +  - ]:       27258 :         if (this != &other) {
      82         [ +  - ]:       27258 :             if (other.keydata) {
      83                 :       27258 :                 MakeKeyData();
      84                 :       27258 :                 *keydata = *other.keydata;
      85                 :             :             } else {
      86                 :           0 :                 ClearKeyData();
      87                 :             :             }
      88                 :       27258 :             fCompressed = other.fCompressed;
      89                 :             :         }
      90                 :       27258 :         return *this;
      91                 :             :     }
      92                 :             : 
      93         [ +  - ]:        9167 :     CKey(const CKey& other) { *this = other; }
      94                 :             : 
      95                 :         254 :     friend bool operator==(const CKey& a, const CKey& b)
      96                 :             :     {
      97                 :         508 :         return a.fCompressed == b.fCompressed &&
      98   [ +  -  +  - ]:         508 :             a.size() == b.size() &&
      99         [ -  + ]:         254 :             memcmp(a.data(), b.data(), a.size()) == 0;
     100                 :             :     }
     101                 :             : 
     102                 :             :     //! Initialize using begin and end iterators to byte data.
     103                 :             :     template <typename T>
     104         [ -  + ]:        6612 :     void Set(const T pbegin, const T pend, bool fCompressedIn)
     105                 :             :     {
     106         [ -  + ]:        6612 :         if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) {
     107                 :           0 :             ClearKeyData();
     108         [ +  + ]:        6612 :         } else if (Check(UCharCast(&pbegin[0]))) {
     109                 :        6610 :             MakeKeyData();
     110                 :        6610 :             memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size());
     111                 :        6610 :             fCompressed = fCompressedIn;
     112                 :             :         } else {
     113                 :           2 :             ClearKeyData();
     114                 :             :         }
     115                 :        6612 :     }
     116                 :             : 
     117                 :             :     //! Simple read-only vector-like interface.
     118   [ -  +  #  # ]:        5206 :     unsigned int size() const { return keydata ? keydata->size() : 0; }
           [ -  +  +  - ]
           [ -  +  -  +  
                   +  - ]
     119   [ +  -  #  # ]:       33979 :     const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; }
           [ +  -  +  - ]
     120   [ #  #  #  #  :       79025 :     const std::byte* begin() const { return data(); }
             #  #  #  # ]
           [ +  -  +  - ]
         [ +  - ][ -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     121   [ #  #  #  #  :         249 :     const std::byte* end() const { return data() + size(); }
             #  #  #  # ]
           [ +  -  +  - ]
     122                 :             : 
     123                 :             :     //! Check whether this private key is valid.
     124   [ +  -  +  - ]:        9415 :     bool IsValid() const { return !!keydata; }
           [ +  +  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  +  -  +  -  
          +  -  +  -  +  
           - ][ +  +  +  
             +  +  +  +  
                      + ]
     125                 :             : 
     126                 :             :     //! Check whether the public key corresponding to this private key is (to be) compressed.
     127   [ +  +  -  +  :       10927 :     bool IsCompressed() const { return fCompressed; }
          -  +  -  +  -  
              + ][ +  + ]
     128                 :             : 
     129                 :             :     //! Generate a new private key using a cryptographic PRNG.
     130                 :             :     void MakeNewKey(bool fCompressed);
     131                 :             : 
     132                 :             :     /**
     133                 :             :      * Convert the private key to a CPrivKey (serialized OpenSSL private key data).
     134                 :             :      * This is expensive.
     135                 :             :      */
     136                 :             :     CPrivKey GetPrivKey() const;
     137                 :             : 
     138                 :             :     /**
     139                 :             :      * Compute the public key from a private key.
     140                 :             :      * This is expensive.
     141                 :             :      */
     142                 :             :     CPubKey GetPubKey() const;
     143                 :             : 
     144                 :             :     /**
     145                 :             :      * Create a DER-serialized signature.
     146                 :             :      * The test_case parameter tweaks the deterministic nonce.
     147                 :             :      */
     148                 :             :     bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const;
     149                 :             : 
     150                 :             :     /**
     151                 :             :      * Create a compact signature (65 bytes), which allows reconstructing the used public key.
     152                 :             :      * The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
     153                 :             :      * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
     154                 :             :      *                  0x1D = second key with even y, 0x1E = second key with odd y,
     155                 :             :      *                  add 0x04 for compressed keys.
     156                 :             :      */
     157                 :             :     bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
     158                 :             : 
     159                 :             :     /**
     160                 :             :      * Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this,
     161                 :             :      * optionally tweaked by *merkle_root. Additional nonce entropy is provided through
     162                 :             :      * aux.
     163                 :             :      *
     164                 :             :      * merkle_root is used to optionally perform tweaking of the private key, as specified
     165                 :             :      * in BIP341:
     166                 :             :      * - If merkle_root == nullptr: no tweaking is done, sign with key directly (this is
     167                 :             :      *                              used for signatures in BIP342 script).
     168                 :             :      * - If merkle_root->IsNull():  sign with key + H_TapTweak(pubkey) (this is used for
     169                 :             :      *                              key path spending when no scripts are present).
     170                 :             :      * - Otherwise:                 sign with key + H_TapTweak(pubkey || *merkle_root)
     171                 :             :      *                              (this is used for key path spending, with specific
     172                 :             :      *                              Merkle root of the script tree).
     173                 :             :      */
     174                 :             :     bool SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const;
     175                 :             : 
     176                 :             :     //! Derive BIP32 child key.
     177                 :             :     [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
     178                 :             : 
     179                 :             :     /**
     180                 :             :      * Verify thoroughly whether a private key and a public key match.
     181                 :             :      * This is done using a different mechanism than just regenerating it.
     182                 :             :      */
     183                 :             :     bool VerifyPubKey(const CPubKey& vchPubKey) const;
     184                 :             : 
     185                 :             :     //! Load private key and check that public key matches.
     186                 :             :     bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck);
     187                 :             : 
     188                 :             :     /** Create an ellswift-encoded public key for this key, with specified entropy.
     189                 :             :      *
     190                 :             :      *  entropy must be a 32-byte span with additional entropy to use in the encoding. Every
     191                 :             :      *  public key has ~2^256 different encodings, and this function will deterministically pick
     192                 :             :      *  one of them, based on entropy. Note that even without truly random entropy, the
     193                 :             :      *  resulting encoding will be indistinguishable from uniform to any adversary who does not
     194                 :             :      *  know the private key (because the private key itself is always used as entropy as well).
     195                 :             :      */
     196                 :             :     EllSwiftPubKey EllSwiftCreate(std::span<const std::byte> entropy) const;
     197                 :             : 
     198                 :             :     /** Compute a BIP324-style ECDH shared secret.
     199                 :             :      *
     200                 :             :      *  - their_ellswift: EllSwiftPubKey that was received from the other side.
     201                 :             :      *  - our_ellswift: EllSwiftPubKey that was sent to the other side (must have been generated
     202                 :             :      *                  from *this using EllSwiftCreate()).
     203                 :             :      *  - initiating: whether we are the initiating party (true) or responding party (false).
     204                 :             :      */
     205                 :             :     ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift,
     206                 :             :                                        const EllSwiftPubKey& our_ellswift,
     207                 :             :                                        bool initiating) const;
     208                 :             :     /** Compute a KeyPair
     209                 :             :      *
     210                 :             :      *  Wraps a `secp256k1_keypair` type.
     211                 :             :      *
     212                 :             :      *  `merkle_root` is used to optionally perform tweaking of
     213                 :             :      *  the internal key, as specified in BIP341:
     214                 :             :      *
     215                 :             :      *  - If merkle_root == nullptr: no tweaking is done, use the internal key directly (this is
     216                 :             :      *                               used for signatures in BIP342 script).
     217                 :             :      *  - If merkle_root->IsNull():  tweak the internal key with H_TapTweak(pubkey) (this is used for
     218                 :             :      *                               key path spending when no scripts are present).
     219                 :             :      *  - Otherwise:                 tweak the internal key with H_TapTweak(pubkey || *merkle_root)
     220                 :             :      *                               (this is used for key path spending with the
     221                 :             :      *                               Merkle root of the script tree).
     222                 :             :      */
     223                 :             :     KeyPair ComputeKeyPair(const uint256* merkle_root) const;
     224                 :             : 
     225                 :             :     std::vector<uint8_t> CreateMuSig2Nonce(MuSig2SecNonce& secnonce, const uint256& sighash, const CPubKey& aggregate_pubkey, const std::vector<CPubKey>& pubkeys);
     226                 :             :     std::optional<uint256> CreateMuSig2PartialSig(const uint256& hash, const CPubKey& aggregate_pubkey, const std::vector<CPubKey>& pubkeys, const std::map<CPubKey, std::vector<uint8_t>>& pubnonces, MuSig2SecNonce& secnonce, const std::vector<std::pair<uint256, bool>>& tweaks);
     227                 :             : };
     228                 :             : 
     229                 :             : CKey GenerateRandomKey(bool compressed = true) noexcept;
     230                 :             : 
     231         [ +  - ]:        3588 : struct CExtKey {
     232                 :             :     unsigned char nDepth;
     233                 :             :     unsigned char vchFingerprint[4];
     234                 :             :     unsigned int nChild;
     235                 :             :     ChainCode chaincode;
     236                 :             :     CKey key;
     237                 :             : 
     238                 :          17 :     friend bool operator==(const CExtKey& a, const CExtKey& b)
     239                 :             :     {
     240                 :          34 :         return a.nDepth == b.nDepth &&
     241         [ +  - ]:          17 :             memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
     242   [ +  -  +  - ]:          17 :             a.nChild == b.nChild &&
     243   [ +  -  +  - ]:          34 :             a.chaincode == b.chaincode &&
     244         [ -  + ]:          17 :             a.key == b.key;
     245                 :             :     }
     246                 :             : 
     247 [ +  - ][ +  -  :        3079 :     CExtKey() = default;
             -  +  +  - ]
           [ +  -  -  +  
          +  -  +  -  +  
                      - ]
     248                 :           0 :     CExtKey(const CExtPubKey& xpub, const CKey& key_in) : nDepth(xpub.nDepth), nChild(xpub.nChild), chaincode(xpub.chaincode), key(key_in)
     249                 :             :     {
     250                 :           0 :         std::copy(xpub.vchFingerprint, xpub.vchFingerprint + sizeof(xpub.vchFingerprint), vchFingerprint);
     251                 :           0 :     }
     252                 :             : 
     253                 :             :     void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
     254                 :             :     void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
     255                 :             :     [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
     256                 :             :     CExtPubKey Neuter() const;
     257                 :             :     void SetSeed(std::span<const std::byte> seed);
     258                 :             : };
     259                 :             : 
     260                 :             : /** KeyPair
     261                 :             :  *
     262                 :             :  *  Wraps a `secp256k1_keypair` type, an opaque data structure for holding a secret and public key.
     263                 :             :  *  This is intended for BIP340 keys and allows us to easily determine if the secret key needs to
     264                 :             :  *  be negated by checking the parity of the public key. This class primarily intended for passing
     265                 :             :  *  secret keys to libsecp256k1 functions expecting a `secp256k1_keypair`. For all other cases,
     266                 :             :  *  CKey should be preferred.
     267                 :             :  *
     268                 :             :  *  A KeyPair can be created from a CKey with an optional merkle_root tweak (per BIP342). See
     269                 :             :  *  CKey::ComputeKeyPair for more details.
     270                 :             :  */
     271                 :         422 : class KeyPair
     272                 :             : {
     273                 :             : public:
     274                 :             :     KeyPair() noexcept = default;
     275                 :             :     KeyPair(KeyPair&&) noexcept = default;
     276                 :             :     KeyPair& operator=(KeyPair&&) noexcept = default;
     277                 :             :     KeyPair& operator=(const KeyPair& other)
     278                 :             :     {
     279                 :             :         if (this != &other) {
     280                 :             :             if (other.m_keypair) {
     281                 :             :                 MakeKeyPairData();
     282                 :             :                 *m_keypair = *other.m_keypair;
     283                 :             :             } else {
     284                 :             :                 ClearKeyPairData();
     285                 :             :             }
     286                 :             :         }
     287                 :             :         return *this;
     288                 :             :     }
     289                 :             : 
     290                 :             :     KeyPair(const KeyPair& other) { *this = other; }
     291                 :             : 
     292                 :             :     friend KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const;
     293                 :             :     [[nodiscard]] bool SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256& aux) const;
     294                 :             : 
     295                 :             :     //! Check whether this keypair is valid.
     296         [ +  - ]:         422 :     bool IsValid() const { return !!m_keypair; }
     297                 :             : 
     298                 :             : private:
     299                 :             :     KeyPair(const CKey& key, const uint256* merkle_root);
     300                 :             : 
     301                 :             :     using KeyType = std::array<unsigned char, 96>;
     302                 :             :     secure_unique_ptr<KeyType> m_keypair;
     303                 :             : 
     304                 :         422 :     void MakeKeyPairData()
     305                 :             :     {
     306         [ +  - ]:         422 :         if (!m_keypair) m_keypair = make_secure_unique<KeyType>();
     307                 :         422 :     }
     308                 :             : 
     309                 :           0 :     void ClearKeyPairData()
     310                 :             :     {
     311                 :           0 :         m_keypair.reset();
     312                 :           0 :     }
     313                 :             : };
     314                 :             : 
     315                 :             : /** Check that required EC support is available at runtime. */
     316                 :             : bool ECC_InitSanityCheck();
     317                 :             : 
     318                 :             : /**
     319                 :             :  * RAII class initializing and deinitializing global state for elliptic curve support.
     320                 :             :  * Only one instance may be initialized at a time.
     321                 :             :  *
     322                 :             :  * In the future global ECC state could be removed, and this class could contain
     323                 :             :  * state and be passed as an argument to ECC key functions.
     324                 :             :  */
     325                 :             : class ECC_Context
     326                 :             : {
     327                 :             : public:
     328                 :             :     ECC_Context();
     329                 :             :     ~ECC_Context();
     330                 :             : };
     331                 :             : 
     332                 :             : #endif // BITCOIN_KEY_H
        

Generated by: LCOV version 2.0-1