LCOV - code coverage report
Current view: top level - src - key.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 29 31 93.5 %
Date: 2020-09-26 01:30:44 Functions: 25 25 100.0 %

          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

Generated by: LCOV version 1.15