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 : : /** An encapsulated private key. */ 32 : : class CKey 33 : : { 34 : : public: 35 : : /** 36 : : * secp256k1: 37 : : */ 38 : : static const unsigned int SIZE = 279; 39 : : static const unsigned int COMPRESSED_SIZE = 214; 40 : : /** 41 : : * see www.keylength.com 42 : : * script supports up to 75 for single byte push 43 : : */ 44 : : static_assert( 45 : : SIZE >= COMPRESSED_SIZE, 46 : : "COMPRESSED_SIZE is larger than SIZE"); 47 : : 48 : : private: 49 : : /** Internal data container for private key material. */ 50 : : using KeyType = std::array<unsigned char, 32>; 51 : : 52 : : //! Whether the public key corresponding to this private key is (to be) compressed. 53 : 10443 : bool fCompressed{false}; 54 : : 55 : : //! The actual byte data. nullptr for invalid keys. 56 : : secure_unique_ptr<KeyType> keydata; 57 : : 58 : : //! Check whether the 32-byte array pointed to by vch is valid keydata. 59 : : bool static Check(const unsigned char* vch); 60 : : 61 : 10108 : void MakeKeyData() 62 : : { 63 [ - + ]: 10108 : if (!keydata) keydata = make_secure_unique<KeyType>(); 64 : 10108 : } 65 : : 66 : 0 : void ClearKeyData() 67 : : { 68 : 0 : keydata.reset(); 69 : 0 : } 70 : : 71 : : public: 72 : 10778 : CKey() noexcept = default; 73 : 0 : CKey(CKey&&) noexcept = default; 74 : 335 : CKey& operator=(CKey&&) noexcept = default; 75 : : 76 : 5054 : CKey& operator=(const CKey& other) 77 : : { 78 [ + - ]: 5054 : if (other.keydata) { 79 : 5054 : MakeKeyData(); 80 : 5054 : *keydata = *other.keydata; 81 : 5054 : } else { 82 : 0 : ClearKeyData(); 83 : : } 84 : 5054 : fCompressed = other.fCompressed; 85 : 5054 : return *this; 86 : : } 87 : : 88 [ + - + - ]: 10108 : CKey(const CKey& other) { *this = other; } 89 : : 90 : 0 : friend bool operator==(const CKey& a, const CKey& b) 91 : : { 92 [ # # ]: 0 : return a.fCompressed == b.fCompressed && 93 [ # # ]: 0 : a.size() == b.size() && 94 : 0 : memcmp(a.data(), b.data(), a.size()) == 0; 95 : : } 96 : : 97 : : //! Initialize using begin and end iterators to byte data. 98 : : template <typename T> 99 : 0 : void Set(const T pbegin, const T pend, bool fCompressedIn) 100 : : { 101 [ # # # # ]: 0 : if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) { 102 : 0 : ClearKeyData(); 103 [ # # # # ]: 0 : } else if (Check(&pbegin[0])) { 104 : 0 : MakeKeyData(); 105 : 0 : memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size()); 106 : 0 : fCompressed = fCompressedIn; 107 : 0 : } else { 108 : 0 : ClearKeyData(); 109 : : } 110 : 0 : } 111 : : 112 : : //! Simple read-only vector-like interface. 113 [ # # ]: 0 : unsigned int size() const { return keydata ? keydata->size() : 0; } 114 [ # # ]: 0 : const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; } 115 [ # # ]: 0 : const unsigned char* begin() const { return keydata ? keydata->data() : nullptr; } 116 : 0 : const unsigned char* end() const { return begin() + size(); } 117 : : 118 : : //! Check whether this private key is valid. 119 : 0 : bool IsValid() const { return !!keydata; } 120 : : 121 : : //! Check whether the public key corresponding to this private key is (to be) compressed. 122 : 0 : bool IsCompressed() const { return fCompressed; } 123 : : 124 : : //! Generate a new private key using a cryptographic PRNG. 125 : : void MakeNewKey(bool fCompressed); 126 : : 127 : : //! Negate private key 128 : : bool Negate(); 129 : : 130 : : /** 131 : : * Convert the private key to a CPrivKey (serialized OpenSSL private key data). 132 : : * This is expensive. 133 : : */ 134 : : CPrivKey GetPrivKey() const; 135 : : 136 : : /** 137 : : * Compute the public key from a private key. 138 : : * This is expensive. 139 : : */ 140 : : CPubKey GetPubKey() const; 141 : : 142 : : /** 143 : : * Create a DER-serialized signature. 144 : : * The test_case parameter tweaks the deterministic nonce. 145 : : */ 146 : : bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const; 147 : : 148 : : /** 149 : : * Create a compact signature (65 bytes), which allows reconstructing the used public key. 150 : : * The format is one header byte, followed by two times 32 bytes for the serialized r and s values. 151 : : * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, 152 : : * 0x1D = second key with even y, 0x1E = second key with odd y, 153 : : * add 0x04 for compressed keys. 154 : : */ 155 : : bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const; 156 : : 157 : : /** 158 : : * Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this, 159 : : * optionally tweaked by *merkle_root. Additional nonce entropy is provided through 160 : : * aux. 161 : : * 162 : : * merkle_root is used to optionally perform tweaking of the private key, as specified 163 : : * in BIP341: 164 : : * - If merkle_root == nullptr: no tweaking is done, sign with key directly (this is 165 : : * used for signatures in BIP342 script). 166 : : * - If merkle_root->IsNull(): sign with key + H_TapTweak(pubkey) (this is used for 167 : : * key path spending when no scripts are present). 168 : : * - Otherwise: sign with key + H_TapTweak(pubkey || *merkle_root) 169 : : * (this is used for key path spending, with specific 170 : : * Merkle root of the script tree). 171 : : */ 172 : : bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const; 173 : : 174 : : //! Derive BIP32 child key. 175 : : [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; 176 : : 177 : : /** 178 : : * Verify thoroughly whether a private key and a public key match. 179 : : * This is done using a different mechanism than just regenerating it. 180 : : */ 181 : : bool VerifyPubKey(const CPubKey& vchPubKey) const; 182 : : 183 : : //! Load private key and check that public key matches. 184 : : bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck); 185 : : 186 : : /** Create an ellswift-encoded public key for this key, with specified entropy. 187 : : * 188 : : * entropy must be a 32-byte span with additional entropy to use in the encoding. Every 189 : : * public key has ~2^256 different encodings, and this function will deterministically pick 190 : : * one of them, based on entropy. Note that even without truly random entropy, the 191 : : * resulting encoding will be indistinguishable from uniform to any adversary who does not 192 : : * know the private key (because the private key itself is always used as entropy as well). 193 : : */ 194 : : EllSwiftPubKey EllSwiftCreate(Span<const std::byte> entropy) const; 195 : : 196 : : /** Compute a BIP324-style ECDH shared secret. 197 : : * 198 : : * - their_ellswift: EllSwiftPubKey that was received from the other side. 199 : : * - our_ellswift: EllSwiftPubKey that was sent to the other side (must have been generated 200 : : * from *this using EllSwiftCreate()). 201 : : * - initiating: whether we are the initiating party (true) or responding party (false). 202 : : */ 203 : : ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, 204 : : const EllSwiftPubKey& our_ellswift, 205 : : bool initiating) const; 206 : : }; 207 : : 208 : : struct CExtKey { 209 : : unsigned char nDepth; 210 : : unsigned char vchFingerprint[4]; 211 : : unsigned int nChild; 212 : : ChainCode chaincode; 213 : : CKey key; 214 : : 215 : 0 : friend bool operator==(const CExtKey& a, const CExtKey& b) 216 : : { 217 [ # # ]: 0 : return a.nDepth == b.nDepth && 218 [ # # ]: 0 : memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 && 219 [ # # ]: 0 : a.nChild == b.nChild && 220 [ # # ]: 0 : a.chaincode == b.chaincode && 221 : 0 : a.key == b.key; 222 : : } 223 : : 224 : : void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const; 225 : : void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); 226 : : [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const; 227 : : CExtPubKey Neuter() const; 228 : : void SetSeed(Span<const std::byte> seed); 229 : : }; 230 : : 231 : : /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ 232 : : void ECC_Start(); 233 : : 234 : : /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ 235 : : void ECC_Stop(); 236 : : 237 : : /** Check that required EC support is available at runtime. */ 238 : : bool ECC_InitSanityCheck(); 239 : : 240 : : #endif // BITCOIN_KEY_H