Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2021 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 3091948 : 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 3097125 : void MakeKeyData() 62 : { 63 3097125 : if (!keydata) keydata = make_secure_unique<KeyType>(); 64 3097125 : } 65 : 66 2 : void ClearKeyData() 67 : { 68 2 : keydata.reset(); 69 2 : } 70 : 71 : public: 72 8941554 : CKey() noexcept = default; 73 9066 : CKey(CKey&&) noexcept = default; 74 1537 : CKey& operator=(CKey&&) noexcept = default; 75 : 76 1684187 : CKey& operator=(const CKey& other) 77 : { 78 1684187 : if (other.keydata) { 79 1684187 : MakeKeyData(); 80 1684187 : *keydata = *other.keydata; 81 1684187 : } else { 82 0 : ClearKeyData(); 83 : } 84 1684187 : fCompressed = other.fCompressed; 85 1684187 : return *this; 86 : } 87 : 88 334290 : CKey(const CKey& other) { *this = other; } 89 : 90 2121 : friend bool operator==(const CKey& a, const CKey& b) 91 : { 92 4242 : return a.fCompressed == b.fCompressed && 93 2121 : a.size() == b.size() && 94 2121 : 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 1395467 : void Set(const T pbegin, const T pend, bool fCompressedIn) 100 : { 101 1395467 : if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) { 102 0 : ClearKeyData(); 103 1395467 : } else if (Check(&pbegin[0])) { 104 1395465 : MakeKeyData(); 105 1395465 : memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size()); 106 1395465 : fCompressed = fCompressedIn; 107 1395465 : } else { 108 2 : ClearKeyData(); 109 : } 110 1395467 : } 111 : 112 : //! Simple read-only vector-like interface. 113 220085 : unsigned int size() const { return keydata ? keydata->size() : 0; } 114 4266 : const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; } 115 3684472 : const unsigned char* begin() const { return keydata ? keydata->data() : nullptr; } 116 4577 : const unsigned char* end() const { return begin() + size(); } 117 : 118 : //! Check whether this private key is valid. 119 1376736 : bool IsValid() const { return !!keydata; } 120 : 121 : //! Check whether the public key corresponding to this private key is (to be) compressed. 122 341679 : 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 : //! Derive BIP32 child key. 158 : [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; 159 : 160 : /** 161 : * Verify thoroughly whether a private key and a public key match. 162 : * This is done using a different mechanism than just regenerating it. 163 : */ 164 : bool VerifyPubKey(const CPubKey& vchPubKey) const; 165 : 166 : //! Load private key and check that public key matches. 167 : bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck); 168 : 169 : /** Create an ellswift-encoded public key for this key, with specified entropy. 170 : * 171 : * entropy must be a 32-byte span with additional entropy to use in the encoding. Every 172 : * public key has ~2^256 different encodings, and this function will deterministically pick 173 : * one of them, based on entropy. Note that even without truly random entropy, the 174 : * resulting encoding will be indistinguishable from uniform to any adversary who does not 175 : * know the private key (because the private key itself is always used as entropy as well). 176 : */ 177 : EllSwiftPubKey EllSwiftCreate(Span<const std::byte> entropy) const; 178 : 179 : /** Compute a BIP324-style ECDH shared secret. 180 : * 181 : * - their_ellswift: EllSwiftPubKey that was received from the other side. 182 : * - our_ellswift: EllSwiftPubKey that was sent to the other side (must have been generated 183 : * from *this using EllSwiftCreate()). 184 : * - initiating: whether we are the initiating party (true) or responding party (false). 185 : */ 186 : ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, 187 : const EllSwiftPubKey& our_ellswift, 188 : bool initiating) const; 189 : }; 190 : 191 : CKey GenerateRandomKey(bool compressed = true) noexcept; 192 : 193 : struct CExtKey { 194 : unsigned char nDepth; 195 : unsigned char vchFingerprint[4]; 196 : unsigned int nChild; 197 : ChainCode chaincode; 198 : CKey key; 199 : 200 1196 : friend bool operator==(const CExtKey& a, const CExtKey& b) 201 : { 202 2392 : return a.nDepth == b.nDepth && 203 1196 : memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 && 204 1196 : a.nChild == b.nChild && 205 1196 : a.chaincode == b.chaincode && 206 1196 : a.key == b.key; 207 : } 208 : 209 : void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const; 210 : void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); 211 : [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const; 212 : CExtPubKey Neuter() const; 213 : void SetSeed(Span<const std::byte> seed); 214 : }; 215 : 216 : /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ 217 : void ECC_Start(); 218 : 219 : /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ 220 : void ECC_Stop(); 221 : 222 : /** Check that required EC support is available at runtime. */ 223 : bool ECC_InitSanityCheck(); 224 : 225 : #endif // BITCOIN_KEY_H