Branch data 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 : : 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 : : CKey() : fValid(false), fCompressed(false)
# 60 : 1537187 : {
# 61 : : // Important: vch must be 32 bytes in length to not break serialization
# 62 : 1537187 : keydata.resize(32);
# 63 : 1537187 : }
# 64 : :
# 65 : : friend bool operator==(const CKey& a, const CKey& b)
# 66 : 34 : {
# 67 [ + - ]: 34 : return a.fCompressed == b.fCompressed &&
# 68 [ + - ]: 34 : a.size() == b.size() &&
# 69 [ + - ]: 34 : memcmp(a.keydata.data(), b.keydata.data(), a.size()) == 0;
# 70 : 34 : }
# 71 : :
# 72 : : //! Initialize using begin and end iterators to byte data.
# 73 : : template <typename T>
# 74 : : void Set(const T pbegin, const T pend, bool fCompressedIn)
# 75 : 32671 : {
# 76 [ - + ][ - + ]: 32671 : if (size_t(pend - pbegin) != keydata.size()) {
# [ - + ]
# 77 : 0 : fValid = false;
# 78 [ + - ][ + - ]: 32671 : } else if (Check(&pbegin[0])) {
# [ + - ]
# 79 : 32671 : memcpy(keydata.data(), (unsigned char*)&pbegin[0], keydata.size());
# 80 : 32671 : fValid = true;
# 81 : 32671 : fCompressed = fCompressedIn;
# 82 : 32671 : } else {
# 83 : 0 : fValid = false;
# 84 : 0 : }
# 85 : 32671 : }
# 86 : :
# 87 : : //! Simple read-only vector-like interface.
# 88 [ + - ]: 125176 : unsigned int size() const { return (fValid ? keydata.size() : 0); }
# 89 : 2094143 : const unsigned char* begin() const { return keydata.data(); }
# 90 : 3095 : const unsigned char* end() const { return keydata.data() + size(); }
# 91 : :
# 92 : : //! Check whether this private key is valid.
# 93 : 119223 : bool IsValid() const { return fValid; }
# 94 : :
# 95 : : //! Check whether the public key corresponding to this private key is (to be) compressed.
# 96 : 138071 : 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 : : struct CExtKey {
# 145 : : unsigned char nDepth;
# 146 : : unsigned char vchFingerprint[4];
# 147 : : unsigned int nChild;
# 148 : : ChainCode chaincode;
# 149 : : CKey key;
# 150 : :
# 151 : : friend bool operator==(const CExtKey& a, const CExtKey& b)
# 152 : 34 : {
# 153 [ + - ]: 34 : return a.nDepth == b.nDepth &&
# 154 [ + - ]: 34 : memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
# 155 [ + - ]: 34 : a.nChild == b.nChild &&
# 156 [ + - ]: 34 : a.chaincode == b.chaincode &&
# 157 [ + - ]: 34 : a.key == b.key;
# 158 : 34 : }
# 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
|