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: 2024-11-04 04:45:35 Functions: 92.3 % 13 12
Branches: 42.2 % 282 119

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

Generated by: LCOV version 2.0-1