/Users/eugenesiegel/btc/bitcoin/src/key.h
| Line | Count | Source (jump to first uncovered line) | 
| 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 <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 |  | 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 |  |     void MakeKeyData() | 
| 64 | 0 |     { | 
| 65 | 0 |         if (!keydata) keydata = make_secure_unique<KeyType>(); | 
| 66 | 0 |     } | 
| 67 |  |  | 
| 68 |  |     void ClearKeyData() | 
| 69 | 0 |     { | 
| 70 | 0 |         keydata.reset(); | 
| 71 | 0 |     } | 
| 72 |  |  | 
| 73 |  | public: | 
| 74 | 0 |     CKey() noexcept = default; | 
| 75 | 0 |     CKey(CKey&&) noexcept = default; | 
| 76 | 0 |     CKey& operator=(CKey&&) noexcept = default; | 
| 77 |  |  | 
| 78 |  |     CKey& operator=(const CKey& other) | 
| 79 | 0 |     { | 
| 80 | 0 |         if (this != &other) { | 
| 81 | 0 |             if (other.keydata) { | 
| 82 | 0 |                 MakeKeyData(); | 
| 83 | 0 |                 *keydata = *other.keydata; | 
| 84 | 0 |             } else { | 
| 85 | 0 |                 ClearKeyData(); | 
| 86 | 0 |             } | 
| 87 | 0 |             fCompressed = other.fCompressed; | 
| 88 | 0 |         } | 
| 89 | 0 |         return *this; | 
| 90 | 0 |     } | 
| 91 |  |  | 
| 92 | 0 |     CKey(const CKey& other) { *this = other; } | 
| 93 |  |  | 
| 94 |  |     friend bool operator==(const CKey& a, const CKey& b) | 
| 95 | 0 |     { | 
| 96 | 0 |         return a.fCompressed == b.fCompressed && | 
| 97 | 0 |             a.size() == b.size() && | 
| 98 | 0 |             memcmp(a.data(), b.data(), a.size()) == 0; | 
| 99 | 0 |     } | 
| 100 |  |  | 
| 101 |  |     //! Initialize using begin and end iterators to byte data. | 
| 102 |  |     template <typename T> | 
| 103 |  |     void Set(const T pbegin, const T pend, bool fCompressedIn) | 
| 104 | 0 |     { | 
| 105 | 0 |         if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) { | 
| 106 | 0 |             ClearKeyData(); | 
| 107 | 0 |         } else if (Check(UCharCast(&pbegin[0]))) { | 
| 108 | 0 |             MakeKeyData(); | 
| 109 | 0 |             memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size()); | 
| 110 | 0 |             fCompressed = fCompressedIn; | 
| 111 | 0 |         } else { | 
| 112 | 0 |             ClearKeyData(); | 
| 113 | 0 |         } | 
| 114 | 0 |     } Unexecuted instantiation: _ZN4CKey3SetINSt3__111__wrap_iterIPKhEEEEvT_S6_bUnexecuted instantiation: _ZN4CKey3SetIPKSt4byteEEvT_S4_bUnexecuted instantiation: _ZN4CKey3SetIPhEEvT_S2_bUnexecuted instantiation: _ZN4CKey3SetIPSt4byteEEvT_S3_bUnexecuted instantiation: _ZN4CKey3SetINSt3__111__wrap_iterIPhEEEEvT_S5_bUnexecuted instantiation: _ZN4CKey3SetIPKhEEvT_S3_b | 
| 115 |  |  | 
| 116 |  |     //! Simple read-only vector-like interface. | 
| 117 | 0 |     unsigned int size() const { return keydata ? keydata->size() : 0; } | 
| 118 | 0 |     const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; } | 
| 119 | 0 |     const std::byte* begin() const { return data(); } | 
| 120 | 0 |     const std::byte* end() const { return data() + size(); } | 
| 121 |  |  | 
| 122 |  |     //! Check whether this private key is valid. | 
| 123 | 0 |     bool IsValid() const { return !!keydata; } | 
| 124 |  |  | 
| 125 |  |     //! Check whether the public key corresponding to this private key is (to be) compressed. | 
| 126 | 0 |     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, std::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(std::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 |  | struct CExtKey { | 
| 228 |  |     unsigned char nDepth; | 
| 229 |  |     unsigned char vchFingerprint[4]; | 
| 230 |  |     unsigned int nChild; | 
| 231 |  |     ChainCode chaincode; | 
| 232 |  |     CKey key; | 
| 233 |  |  | 
| 234 |  |     friend bool operator==(const CExtKey& a, const CExtKey& b) | 
| 235 | 0 |     { | 
| 236 | 0 |         return a.nDepth == b.nDepth && | 
| 237 | 0 |             memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 && | 
| 238 | 0 |             a.nChild == b.nChild && | 
| 239 | 0 |             a.chaincode == b.chaincode && | 
| 240 | 0 |             a.key == b.key; | 
| 241 | 0 |     } | 
| 242 |  |  | 
| 243 | 0 |     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 | 0 |     { | 
| 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(std::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 |  | 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 | 0 |     { | 
| 275 | 0 |         if (this != &other) { | 
| 276 | 0 |             if (other.m_keypair) { | 
| 277 | 0 |                 MakeKeyPairData(); | 
| 278 | 0 |                 *m_keypair = *other.m_keypair; | 
| 279 | 0 |             } else { | 
| 280 | 0 |                 ClearKeyPairData(); | 
| 281 | 0 |             } | 
| 282 | 0 |         } | 
| 283 | 0 |         return *this; | 
| 284 | 0 |     } | 
| 285 |  |  | 
| 286 | 0 |     KeyPair(const KeyPair& other) { *this = other; } | 
| 287 |  |  | 
| 288 |  |     friend KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const; | 
| 289 |  |     [[nodiscard]] bool SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256& aux) const; | 
| 290 |  |  | 
| 291 |  |     //! Check whether this keypair is valid. | 
| 292 | 0 |     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 |  |     void MakeKeyPairData() | 
| 301 | 0 |     { | 
| 302 | 0 |         if (!m_keypair) m_keypair = make_secure_unique<KeyType>(); | 
| 303 | 0 |     } | 
| 304 |  |  | 
| 305 |  |     void ClearKeyPairData() | 
| 306 | 0 |     { | 
| 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 |