Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2019 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 : * secure_allocator is defined in allocators.h 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 : /** An encapsulated private key. */ 27 2982056 : class CKey 28 : { 29 : public: 30 : /** 31 : * secp256k1: 32 : */ 33 : static const unsigned int SIZE = 279; 34 : static const unsigned int COMPRESSED_SIZE = 214; 35 : /** 36 : * see www.keylength.com 37 : * script supports up to 75 for single byte push 38 : */ 39 : static_assert( 40 : SIZE >= COMPRESSED_SIZE, 41 : "COMPRESSED_SIZE is larger than SIZE"); 42 : 43 : private: 44 : //! Whether this private key is valid. We check for correctness when modifying the key 45 : //! data, so fValid should always correspond to the actual state. 46 : bool fValid; 47 : 48 : //! Whether the public key corresponding to this private key is (to be) compressed. 49 : bool fCompressed; 50 : 51 : //! The actual byte data 52 : std::vector<unsigned char, secure_allocator<unsigned char> > keydata; 53 : 54 : //! Check whether the 32-byte array pointed to by vch is valid keydata. 55 : bool static Check(const unsigned char* vch); 56 : 57 : public: 58 : //! Construct an invalid private key. 59 2040816 : CKey() : fValid(false), fCompressed(false) 60 1020408 : { 61 : // Important: vch must be 32 bytes in length to not break serialization 62 1020408 : keydata.resize(32); 63 2040816 : } 64 : 65 14 : friend bool operator==(const CKey& a, const CKey& b) 66 : { 67 28 : return a.fCompressed == b.fCompressed && 68 14 : a.size() == b.size() && 69 14 : memcmp(a.keydata.data(), b.keydata.data(), a.size()) == 0; 70 : } 71 : 72 : //! Initialize using begin and end iterators to byte data. 73 : template <typename T> 74 24245 : void Set(const T pbegin, const T pend, bool fCompressedIn) 75 : { 76 24245 : if (size_t(pend - pbegin) != keydata.size()) { 77 0 : fValid = false; 78 24245 : } else if (Check(&pbegin[0])) { 79 24245 : memcpy(keydata.data(), (unsigned char*)&pbegin[0], keydata.size()); 80 24245 : fValid = true; 81 24245 : fCompressed = fCompressedIn; 82 24245 : } else { 83 0 : fValid = false; 84 : } 85 24245 : } 86 : 87 : //! Simple read-only vector-like interface. 88 97686 : unsigned int size() const { return (fValid ? keydata.size() : 0); } 89 1437018 : const unsigned char* begin() const { return keydata.data(); } 90 2472 : const unsigned char* end() const { return keydata.data() + size(); } 91 : 92 : //! Check whether this private key is valid. 93 87938 : bool IsValid() const { return fValid; } 94 : 95 : //! Check whether the public key corresponding to this private key is (to be) compressed. 96 101000 : bool IsCompressed() const { return fCompressed; } 97 : 98 : //! Generate a new private key using a cryptographic PRNG. 99 : void MakeNewKey(bool fCompressed); 100 : 101 : //! Negate private key 102 : bool Negate(); 103 : 104 : /** 105 : * Convert the private key to a CPrivKey (serialized OpenSSL private key data). 106 : * This is expensive. 107 : */ 108 : CPrivKey GetPrivKey() const; 109 : 110 : /** 111 : * Compute the public key from a private key. 112 : * This is expensive. 113 : */ 114 : CPubKey GetPubKey() const; 115 : 116 : /** 117 : * Create a DER-serialized signature. 118 : * The test_case parameter tweaks the deterministic nonce. 119 : */ 120 : bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const; 121 : 122 : /** 123 : * Create a compact signature (65 bytes), which allows reconstructing the used public key. 124 : * The format is one header byte, followed by two times 32 bytes for the serialized r and s values. 125 : * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, 126 : * 0x1D = second key with even y, 0x1E = second key with odd y, 127 : * add 0x04 for compressed keys. 128 : */ 129 : bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const; 130 : 131 : //! Derive BIP32 child key. 132 : bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; 133 : 134 : /** 135 : * Verify thoroughly whether a private key and a public key match. 136 : * This is done using a different mechanism than just regenerating it. 137 : */ 138 : bool VerifyPubKey(const CPubKey& vchPubKey) const; 139 : 140 : //! Load private key and check that public key matches. 141 : bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck); 142 : }; 143 : 144 352590 : struct CExtKey { 145 : unsigned char nDepth; 146 : unsigned char vchFingerprint[4]; 147 : unsigned int nChild; 148 : ChainCode chaincode; 149 : CKey key; 150 : 151 14 : friend bool operator==(const CExtKey& a, const CExtKey& b) 152 : { 153 28 : return a.nDepth == b.nDepth && 154 14 : memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], sizeof(vchFingerprint)) == 0 && 155 14 : a.nChild == b.nChild && 156 14 : a.chaincode == b.chaincode && 157 14 : a.key == b.key; 158 : } 159 : 160 : void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const; 161 : void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); 162 : bool Derive(CExtKey& out, unsigned int nChild) const; 163 : CExtPubKey Neuter() const; 164 : void SetSeed(const unsigned char* seed, unsigned int nSeedLen); 165 : }; 166 : 167 : /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ 168 : void ECC_Start(); 169 : 170 : /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ 171 : void ECC_Stop(); 172 : 173 : /** Check that required EC support is available at runtime. */ 174 : bool ECC_InitSanityCheck(); 175 : 176 : #endif // BITCOIN_KEY_H