LCOV - code coverage report
Current view: top level - src - pubkey.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 42 54 77.8 %
Date: 2015-10-12 22:39:14 Functions: 11 22 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #ifndef BITCOIN_PUBKEY_H
       7             : #define BITCOIN_PUBKEY_H
       8             : 
       9             : #include "hash.h"
      10             : #include "serialize.h"
      11             : #include "uint256.h"
      12             : 
      13             : #include <stdexcept>
      14             : #include <vector>
      15             : 
      16             : /** 
      17             :  * secp256k1:
      18             :  * const unsigned int PRIVATE_KEY_SIZE = 279;
      19             :  * const unsigned int PUBLIC_KEY_SIZE  = 65;
      20             :  * const unsigned int SIGNATURE_SIZE   = 72;
      21             :  *
      22             :  * see www.keylength.com
      23             :  * script supports up to 75 for single byte push
      24             :  */
      25             : 
      26             : /** A reference to a CKey: the Hash160 of its serialized public key */
      27             : class CKeyID : public uint160
      28             : {
      29             : public:
      30       51736 :     CKeyID() : uint160() {}
      31       49896 :     CKeyID(const uint160& in) : uint160(in) {}
      32             : };
      33             : 
      34             : typedef uint256 ChainCode;
      35             : 
      36             : /** An encapsulated public key. */
      37             : class CPubKey
      38             : {
      39             : private:
      40             : 
      41             :     /**
      42             :      * Just store the serialized data.
      43             :      * Its length can very cheaply be computed from the first byte.
      44             :      */
      45             :     unsigned char vch[65];
      46             : 
      47             :     //! Compute the length of a pubkey with a given first byte.
      48             :     unsigned int static GetLen(unsigned char chHeader)
      49             :     {
      50      125309 :         if (chHeader == 2 || chHeader == 3)
      51             :             return 33;
      52        3827 :         if (chHeader == 4 || chHeader == 6 || chHeader == 7)
      53             :             return 65;
      54             :         return 0;
      55             :     }
      56             : 
      57             :     //! Set this key data to be invalid
      58           0 :     void Invalidate()
      59             :     {
      60       24239 :         vch[0] = 0xFF;
      61           0 :     }
      62             : 
      63             : public:
      64             :     //! Construct an invalid public key.
      65           0 :     CPubKey()
      66             :     {
      67       26804 :         Invalidate();
      68           0 :     }
      69             : 
      70             :     //! Initialize a public key using begin/end iterators to byte data.
      71             :     template <typename T>
      72       38096 :     void Set(const T pbegin, const T pend)
      73             :     {
      74       76172 :         int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
      75       63904 :         if (len && len == (pend - pbegin))
      76       38076 :             memcpy(vch, (unsigned char*)&pbegin[0], len);
      77             :         else
      78          20 :             Invalidate();
      79       38096 :     }
      80             : 
      81             :     //! Construct a public key using begin/end iterators to byte data.
      82             :     template <typename T>
      83           0 :     CPubKey(const T pbegin, const T pend)
      84             :     {
      85           8 :         Set(pbegin, pend);
      86           0 :     }
      87             : 
      88             :     //! Construct a public key from a byte vector.
      89           0 :     CPubKey(const std::vector<unsigned char>& vch)
      90             :     {
      91       77238 :         Set(vch.begin(), vch.end());
      92           0 :     }
      93             : 
      94             :     //! Simple read-only vector-like interface to the pubkey data.
      95           0 :     unsigned int size() const { return GetLen(vch[0]); }
      96        8486 :     const unsigned char* begin() const { return vch; }
      97       12946 :     const unsigned char* end() const { return vch + size(); }
      98             :     const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
      99             : 
     100             :     //! Comparator implementation.
     101          84 :     friend bool operator==(const CPubKey& a, const CPubKey& b)
     102             :     {
     103         168 :         return a.vch[0] == b.vch[0] &&
     104         252 :                memcmp(a.vch, b.vch, a.size()) == 0;
     105             :     }
     106             :     friend bool operator!=(const CPubKey& a, const CPubKey& b)
     107             :     {
     108             :         return !(a == b);
     109             :     }
     110       10538 :     friend bool operator<(const CPubKey& a, const CPubKey& b)
     111             :     {
     112       10538 :         return a.vch[0] < b.vch[0] ||
     113       21056 :                (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
     114             :     }
     115             : 
     116             :     //! Implement serialization, as if this was a byte vector.
     117             :     unsigned int GetSerializeSize(int nType, int nVersion) const
     118             :     {
     119             :         return size() + 1;
     120             :     }
     121             :     template <typename Stream>
     122        4054 :     void Serialize(Stream& s, int nType, int nVersion) const
     123             :     {
     124        8108 :         unsigned int len = size();
     125        4054 :         ::WriteCompactSize(s, len);
     126        4054 :         s.write((char*)vch, len);
     127        4054 :     }
     128             :     template <typename Stream>
     129        6568 :     void Unserialize(Stream& s, int nType, int nVersion)
     130             :     {
     131        6568 :         unsigned int len = ::ReadCompactSize(s);
     132        6568 :         if (len <= 65) {
     133        6568 :             s.read((char*)vch, len);
     134             :         } else {
     135             :             // invalid pubkey, skip available data
     136             :             char dummy;
     137           0 :             while (len--)
     138           0 :                 s.read(&dummy, 1);
     139           0 :             Invalidate();
     140             :         }
     141        6568 :     }
     142             : 
     143             :     //! Get the KeyID of this public key (hash of its serialization)
     144       33504 :     CKeyID GetID() const
     145             :     {
     146      100512 :         return CKeyID(Hash160(vch, vch + size()));
     147             :     }
     148             : 
     149             :     //! Get the 256-bit hash of this public key.
     150         258 :     uint256 GetHash() const
     151             :     {
     152         516 :         return Hash(vch, vch + size());
     153             :     }
     154             : 
     155             :     /*
     156             :      * Check syntactic correctness.
     157             :      * 
     158             :      * Note that this is consensus critical as CheckSig() calls it!
     159             :      */
     160             :     bool IsValid() const
     161             :     {
     162       17089 :         return size() > 0;
     163             :     }
     164             : 
     165             :     //! fully validate whether this is a valid public key (more expensive than IsValid())
     166             :     bool IsFullyValid() const;
     167             : 
     168             :     //! Check whether this is a compressed public key.
     169             :     bool IsCompressed() const
     170             :     {
     171        9006 :         return size() == 33;
     172             :     }
     173             : 
     174             :     /**
     175             :      * Verify a DER signature (~72 bytes).
     176             :      * If this public key is not fully valid, the return value will be false.
     177             :      */
     178             :     bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
     179             : 
     180             :     //! Recover a public key from a compact signature.
     181             :     bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
     182             : 
     183             :     //! Turn this public key into an uncompressed public key.
     184             :     bool Decompress();
     185             : 
     186             :     //! Derive BIP32 child pubkey.
     187             :     bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
     188             : };
     189             : 
     190          72 : struct CExtPubKey {
     191             :     unsigned char nDepth;
     192             :     unsigned char vchFingerprint[4];
     193             :     unsigned int nChild;
     194             :     ChainCode chaincode;
     195             :     CPubKey pubkey;
     196             : 
     197          20 :     friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
     198             :     {
     199          60 :         return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
     200          60 :                a.chaincode == b.chaincode && a.pubkey == b.pubkey;
     201             :     }
     202             : 
     203             :     void Encode(unsigned char code[74]) const;
     204             :     void Decode(const unsigned char code[74]);
     205             :     bool Derive(CExtPubKey& out, unsigned int nChild) const;
     206             : };
     207             : 
     208             : #endif // BITCOIN_PUBKEY_H

Generated by: LCOV version 1.11