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_PUBKEY_H 8 : #define BITCOIN_PUBKEY_H 9 : 10 : #include <hash.h> 11 : #include <serialize.h> 12 : #include <uint256.h> 13 : 14 : #include <stdexcept> 15 : #include <vector> 16 : 17 : const unsigned int BIP32_EXTKEY_SIZE = 74; 18 : 19 : /** A reference to a CKey: the Hash160 of its serialized public key */ 20 : class CKeyID : public uint160 21 : { 22 : public: 23 5923986 : CKeyID() : uint160() {} 24 6526018 : explicit CKeyID(const uint160& in) : uint160(in) {} 25 : }; 26 : 27 : typedef uint256 ChainCode; 28 : 29 : /** An encapsulated public key. */ 30 : class CPubKey 31 : { 32 : public: 33 : /** 34 : * secp256k1: 35 : */ 36 : static constexpr unsigned int SIZE = 65; 37 : static constexpr unsigned int COMPRESSED_SIZE = 33; 38 : static constexpr unsigned int SIGNATURE_SIZE = 72; 39 : static constexpr unsigned int COMPACT_SIGNATURE_SIZE = 65; 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 : 50 : /** 51 : * Just store the serialized data. 52 : * Its length can very cheaply be computed from the first byte. 53 : */ 54 : unsigned char vch[SIZE]; 55 : 56 : //! Compute the length of a pubkey with a given first byte. 57 6494104 : unsigned int static GetLen(unsigned char chHeader) 58 : { 59 6494104 : if (chHeader == 2 || chHeader == 3) 60 6370464 : return COMPRESSED_SIZE; 61 123749 : if (chHeader == 4 || chHeader == 6 || chHeader == 7) 62 122400 : return SIZE; 63 1349 : return 0; 64 6494203 : } 65 : 66 : //! Set this key data to be invalid 67 2575454 : void Invalidate() 68 : { 69 2575454 : vch[0] = 0xFF; 70 2575454 : } 71 : 72 : public: 73 : 74 61464 : bool static ValidSize(const std::vector<unsigned char> &vch) { 75 61464 : return vch.size() > 0 && GetLen(vch[0]) == vch.size(); 76 : } 77 : 78 : //! Construct an invalid public key. 79 5150364 : CPubKey() 80 2575182 : { 81 2575182 : Invalidate(); 82 5150364 : } 83 : 84 : //! Initialize a public key using begin/end iterators to byte data. 85 : template <typename T> 86 348383 : void Set(const T pbegin, const T pend) 87 : { 88 348383 : int len = pend == pbegin ? 0 : GetLen(pbegin[0]); 89 348384 : if (len && len == (pend - pbegin)) 90 348148 : memcpy(vch, (unsigned char*)&pbegin[0], len); 91 : else 92 266 : Invalidate(); 93 348437 : } 94 : 95 : //! Construct a public key using begin/end iterators to byte data. 96 : template <typename T> 97 51634 : CPubKey(const T pbegin, const T pend) 98 25817 : { 99 25817 : Set(pbegin, pend); 100 51634 : } 101 : 102 : //! Construct a public key from a byte vector. 103 515200 : explicit CPubKey(const std::vector<unsigned char>& _vch) 104 257687 : { 105 257513 : Set(_vch.begin(), _vch.end()); 106 515200 : } 107 : 108 : //! Simple read-only vector-like interface to the pubkey data. 109 6095477 : unsigned int size() const { return GetLen(vch[0]); } 110 115192 : const unsigned char* data() const { return vch; } 111 1741450 : const unsigned char* begin() const { return vch; } 112 642140 : const unsigned char* end() const { return vch + size(); } 113 209787 : const unsigned char& operator[](unsigned int pos) const { return vch[pos]; } 114 : 115 : //! Comparator implementation. 116 1998 : friend bool operator==(const CPubKey& a, const CPubKey& b) 117 : { 118 3996 : return a.vch[0] == b.vch[0] && 119 1998 : memcmp(a.vch, b.vch, a.size()) == 0; 120 : } 121 : friend bool operator!=(const CPubKey& a, const CPubKey& b) 122 : { 123 : return !(a == b); 124 : } 125 158190 : friend bool operator<(const CPubKey& a, const CPubKey& b) 126 : { 127 300658 : return a.vch[0] < b.vch[0] || 128 142468 : (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0); 129 : } 130 : 131 : //! Implement serialization, as if this was a byte vector. 132 : template <typename Stream> 133 80156 : void Serialize(Stream& s) const 134 : { 135 80156 : unsigned int len = size(); 136 80156 : ::WriteCompactSize(s, len); 137 80156 : s.write((char*)vch, len); 138 80156 : } 139 : template <typename Stream> 140 41158 : void Unserialize(Stream& s) 141 : { 142 41158 : unsigned int len = ::ReadCompactSize(s); 143 41158 : if (len <= SIZE) { 144 41158 : s.read((char*)vch, len); 145 41158 : if (len != size()) { 146 6 : Invalidate(); 147 6 : } 148 : } else { 149 : // invalid pubkey, skip available data 150 0 : char dummy; 151 0 : while (len--) 152 0 : s.read(&dummy, 1); 153 0 : Invalidate(); 154 0 : } 155 41158 : } 156 : 157 : //! Get the KeyID of this public key (hash of its serialization) 158 1649894 : CKeyID GetID() const 159 : { 160 1649894 : return CKeyID(Hash160(MakeSpan(vch).first(size()))); 161 : } 162 : 163 : //! Get the 256-bit hash of this public key. 164 3268 : uint256 GetHash() const 165 : { 166 3268 : return Hash(MakeSpan(vch).first(size())); 167 : } 168 : 169 : /* 170 : * Check syntactic correctness. 171 : * 172 : * Note that this is consensus critical as CheckSig() calls it! 173 : */ 174 1521658 : bool IsValid() const 175 : { 176 1521658 : return size() > 0; 177 : } 178 : 179 : //! fully validate whether this is a valid public key (more expensive than IsValid()) 180 : bool IsFullyValid() const; 181 : 182 : //! Check whether this is a compressed public key. 183 433207 : bool IsCompressed() const 184 : { 185 433207 : return size() == COMPRESSED_SIZE; 186 : } 187 : 188 : /** 189 : * Verify a DER signature (~72 bytes). 190 : * If this public key is not fully valid, the return value will be false. 191 : */ 192 : bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const; 193 : 194 : /** 195 : * Check whether a signature is normalized (lower-S). 196 : */ 197 : static bool CheckLowS(const std::vector<unsigned char>& vchSig); 198 : 199 : //! Recover a public key from a compact signature. 200 : bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig); 201 : 202 : //! Turn this public key into an uncompressed public key. 203 : bool Decompress(); 204 : 205 : //! Derive BIP32 child pubkey. 206 : bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; 207 : }; 208 : 209 38494 : struct CExtPubKey { 210 : unsigned char nDepth; 211 : unsigned char vchFingerprint[4]; 212 : unsigned int nChild; 213 : ChainCode chaincode; 214 : CPubKey pubkey; 215 : 216 23 : friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) 217 : { 218 46 : return a.nDepth == b.nDepth && 219 23 : memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], sizeof(vchFingerprint)) == 0 && 220 23 : a.nChild == b.nChild && 221 23 : a.chaincode == b.chaincode && 222 23 : a.pubkey == b.pubkey; 223 : } 224 : 225 0 : friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b) 226 : { 227 0 : return !(a == b); 228 : } 229 : 230 : void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const; 231 : void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); 232 : bool Derive(CExtPubKey& out, unsigned int nChild) const; 233 : }; 234 : 235 : /** Users of this module must hold an ECCVerifyHandle. The constructor and 236 : * destructor of these are not allowed to run in parallel, though. */ 237 : class ECCVerifyHandle 238 : { 239 : static int refcount; 240 : 241 : public: 242 : ECCVerifyHandle(); 243 : ~ECCVerifyHandle(); 244 : }; 245 : 246 : #endif // BITCOIN_PUBKEY_H