Bitcoin Core  21.99.0
P2P Digital Currency
pubkey.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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 <span.h>
13 #include <uint256.h>
14 
15 #include <stdexcept>
16 #include <vector>
17 
18 const unsigned int BIP32_EXTKEY_SIZE = 74;
19 
21 class CKeyID : public uint160
22 {
23 public:
24  CKeyID() : uint160() {}
25  explicit CKeyID(const uint160& in) : uint160(in) {}
26 };
27 
29 
31 class CPubKey
32 {
33 public:
37  static constexpr unsigned int SIZE = 65;
38  static constexpr unsigned int COMPRESSED_SIZE = 33;
39  static constexpr unsigned int SIGNATURE_SIZE = 72;
40  static constexpr unsigned int COMPACT_SIGNATURE_SIZE = 65;
45  static_assert(
47  "COMPRESSED_SIZE is larger than SIZE");
48 
49 private:
50 
55  unsigned char vch[SIZE];
56 
58  unsigned int static GetLen(unsigned char chHeader)
59  {
60  if (chHeader == 2 || chHeader == 3)
61  return COMPRESSED_SIZE;
62  if (chHeader == 4 || chHeader == 6 || chHeader == 7)
63  return SIZE;
64  return 0;
65  }
66 
68  void Invalidate()
69  {
70  vch[0] = 0xFF;
71  }
72 
73 public:
74 
75  bool static ValidSize(const std::vector<unsigned char> &vch) {
76  return vch.size() > 0 && GetLen(vch[0]) == vch.size();
77  }
78 
81  {
82  Invalidate();
83  }
84 
86  template <typename T>
87  void Set(const T pbegin, const T pend)
88  {
89  int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
90  if (len && len == (pend - pbegin))
91  memcpy(vch, (unsigned char*)&pbegin[0], len);
92  else
93  Invalidate();
94  }
95 
97  template <typename T>
98  CPubKey(const T pbegin, const T pend)
99  {
100  Set(pbegin, pend);
101  }
102 
104  explicit CPubKey(const std::vector<unsigned char>& _vch)
105  {
106  Set(_vch.begin(), _vch.end());
107  }
108 
110  unsigned int size() const { return GetLen(vch[0]); }
111  const unsigned char* data() const { return vch; }
112  const unsigned char* begin() const { return vch; }
113  const unsigned char* end() const { return vch + size(); }
114  const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
115 
117  friend bool operator==(const CPubKey& a, const CPubKey& b)
118  {
119  return a.vch[0] == b.vch[0] &&
120  memcmp(a.vch, b.vch, a.size()) == 0;
121  }
122  friend bool operator!=(const CPubKey& a, const CPubKey& b)
123  {
124  return !(a == b);
125  }
126  friend bool operator<(const CPubKey& a, const CPubKey& b)
127  {
128  return a.vch[0] < b.vch[0] ||
129  (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
130  }
131 
133  template <typename Stream>
134  void Serialize(Stream& s) const
135  {
136  unsigned int len = size();
137  ::WriteCompactSize(s, len);
138  s.write((char*)vch, len);
139  }
140  template <typename Stream>
141  void Unserialize(Stream& s)
142  {
143  unsigned int len = ::ReadCompactSize(s);
144  if (len <= SIZE) {
145  s.read((char*)vch, len);
146  if (len != size()) {
147  Invalidate();
148  }
149  } else {
150  // invalid pubkey, skip available data
151  char dummy;
152  while (len--)
153  s.read(&dummy, 1);
154  Invalidate();
155  }
156  }
157 
159  CKeyID GetID() const
160  {
161  return CKeyID(Hash160(MakeSpan(vch).first(size())));
162  }
163 
165  uint256 GetHash() const
166  {
167  return Hash(MakeSpan(vch).first(size()));
168  }
169 
170  /*
171  * Check syntactic correctness.
172  *
173  * When setting a pubkey (Set()) or deserializing fails (its header bytes
174  * don't match the length of the data), the size is set to 0. Thus,
175  * by checking size, one can observe whether Set() or deserialization has
176  * failed.
177  *
178  * This does not check for more than that. In particular, it does not verify
179  * that the coordinates correspond to a point on the curve (see IsFullyValid()
180  * for that instead).
181  *
182  * Note that this is consensus critical as CheckECDSASignature() calls it!
183  */
184  bool IsValid() const
185  {
186  return size() > 0;
187  }
188 
190  bool IsFullyValid() const;
191 
193  bool IsCompressed() const
194  {
195  return size() == COMPRESSED_SIZE;
196  }
197 
202  bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
203 
207  static bool CheckLowS(const std::vector<unsigned char>& vchSig);
208 
210  bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
211 
213  bool Decompress();
214 
216  bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
217 };
218 
220 {
221 private:
223 
224 public:
226  explicit XOnlyPubKey(Span<const unsigned char> bytes);
227 
232  bool VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const;
233  bool CheckPayToContract(const XOnlyPubKey& base, const uint256& hash, bool parity) const;
234 
235  const unsigned char& operator[](int pos) const { return *(m_keydata.begin() + pos); }
236  const unsigned char* data() const { return m_keydata.begin(); }
237  size_t size() const { return m_keydata.size(); }
238 };
239 
240 struct CExtPubKey {
241  unsigned char nDepth;
242  unsigned char vchFingerprint[4];
243  unsigned int nChild;
246 
247  friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
248  {
249  return a.nDepth == b.nDepth &&
250  memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], sizeof(vchFingerprint)) == 0 &&
251  a.nChild == b.nChild &&
252  a.chaincode == b.chaincode &&
253  a.pubkey == b.pubkey;
254  }
255 
256  friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
257  {
258  return !(a == b);
259  }
260 
261  void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
262  void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
263  bool Derive(CExtPubKey& out, unsigned int nChild) const;
264 };
265 
269 {
270  static int refcount;
271 
272 public:
273  ECCVerifyHandle();
275 };
276 
277 #endif // BITCOIN_PUBKEY_H
BIP32_EXTKEY_SIZE
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:18
CPubKey::SIGNATURE_SIZE
static constexpr unsigned int SIGNATURE_SIZE
Definition: pubkey.h:39
XOnlyPubKey::VerifySchnorr
bool VerifySchnorr(const uint256 &msg, Span< const unsigned char > sigbytes) const
Verify a Schnorr signature against this public key.
Definition: pubkey.cpp:176
CKeyID::CKeyID
CKeyID()
Definition: pubkey.h:24
CPubKey::Invalidate
void Invalidate()
Set this key data to be invalid.
Definition: pubkey.h:68
CPubKey::SIZE
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:37
uint256.h
CPubKey::Set
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:87
CPubKey::Derive
bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child pubkey.
Definition: pubkey.cpp:253
CPubKey::data
const unsigned char * data() const
Definition: pubkey.h:111
XOnlyPubKey::data
const unsigned char * data() const
Definition: pubkey.h:236
XOnlyPubKey
Definition: pubkey.h:219
CPubKey::vch
unsigned char vch[SIZE]
see www.keylength.com script supports up to 75 for single byte push
Definition: pubkey.h:47
ECCVerifyHandle::ECCVerifyHandle
ECCVerifyHandle()
Definition: pubkey.cpp:312
CPubKey::Decompress
bool Decompress()
Turn this public key into an uncompressed public key.
Definition: pubkey.cpp:238
CKeyID
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
CExtPubKey::nDepth
unsigned char nDepth
Definition: pubkey.h:241
CExtPubKey::operator!=
friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:256
ReadCompactSize
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:318
ECCVerifyHandle::refcount
static int refcount
Definition: pubkey.h:270
CPubKey::ValidSize
static bool ValidSize(const std::vector< unsigned char > &vch)
Definition: pubkey.h:75
CExtPubKey::Decode
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:285
CExtPubKey::Derive
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:293
ECCVerifyHandle::~ECCVerifyHandle
~ECCVerifyHandle()
Definition: pubkey.cpp:322
CExtPubKey::nChild
unsigned int nChild
Definition: pubkey.h:243
Span
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:92
CPubKey::begin
const unsigned char * begin() const
Definition: pubkey.h:112
XOnlyPubKey::size
size_t size() const
Definition: pubkey.h:237
Hash
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:75
CExtPubKey::operator==
friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:247
XOnlyPubKey::m_keydata
uint256 m_keydata
Definition: pubkey.h:222
XOnlyPubKey::CheckPayToContract
bool CheckPayToContract(const XOnlyPubKey &base, const uint256 &hash, bool parity) const
Definition: pubkey.cpp:184
CPubKey::GetLen
unsigned static int GetLen(unsigned char chHeader)
Compute the length of a pubkey with a given first byte.
Definition: pubkey.h:58
CExtPubKey::vchFingerprint
unsigned char vchFingerprint[4]
Definition: pubkey.h:242
CPubKey::Verify
bool Verify(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Verify a DER signature (~72 bytes).
Definition: pubkey.cpp:191
CPubKey::end
const unsigned char * end() const
Definition: pubkey.h:113
WriteCompactSize
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:1110
span.h
CPubKey::GetHash
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition: pubkey.h:165
CPubKey::Unserialize
void Unserialize(Stream &s)
Definition: pubkey.h:141
CPubKey::Serialize
void Serialize(Stream &s) const
Implement serialization, as if this was a byte vector.
Definition: pubkey.h:134
CPubKey::CPubKey
CPubKey()
Construct an invalid public key.
Definition: pubkey.h:80
ChainCode
uint256 ChainCode
Definition: pubkey.h:28
CPubKey::size
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:110
CPubKey::COMPRESSED_SIZE
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:38
uint256
256-bit opaque blob.
Definition: uint256.h:124
CExtPubKey::Encode
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:275
CPubKey::RecoverCompact
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:209
CPubKey::IsCompressed
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:193
CPubKey::operator==
friend bool operator==(const CPubKey &a, const CPubKey &b)
Comparator implementation.
Definition: pubkey.h:117
uint160
160-bit opaque blob.
Definition: uint256.h:113
CPubKey
An encapsulated public key.
Definition: pubkey.h:31
ECCVerifyHandle
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:268
CExtPubKey::chaincode
ChainCode chaincode
Definition: pubkey.h:244
Hash160
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
CPubKey::COMPACT_SIGNATURE_SIZE
static constexpr unsigned int COMPACT_SIGNATURE_SIZE
Definition: pubkey.h:40
CPubKey::operator<
friend bool operator<(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:126
CPubKey::CPubKey
CPubKey(const std::vector< unsigned char > &_vch)
Construct a public key from a byte vector.
Definition: pubkey.h:104
CPubKey::IsFullyValid
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:230
CPubKey::CPubKey
CPubKey(const T pbegin, const T pend)
Construct a public key using begin/end iterators to byte data.
Definition: pubkey.h:98
hash.h
serialize.h
CKeyID::CKeyID
CKeyID(const uint160 &in)
Definition: pubkey.h:25
CPubKey::IsValid
bool IsValid() const
Definition: pubkey.h:184
CExtPubKey::pubkey
CPubKey pubkey
Definition: pubkey.h:245
XOnlyPubKey::operator[]
const unsigned char & operator[](int pos) const
Definition: pubkey.h:235
CPubKey::operator[]
const unsigned char & operator[](unsigned int pos) const
Definition: pubkey.h:114
MakeSpan
constexpr Span< A > MakeSpan(A(&a)[N])
MakeSpan for arrays:
Definition: span.h:222
base_blob::size
unsigned int size() const
Definition: uint256.h:78
CExtPubKey
Definition: pubkey.h:240
base_blob::begin
unsigned char * begin()
Definition: uint256.h:58
CPubKey::GetID
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:159
CPubKey::CheckLowS
static bool CheckLowS(const std::vector< unsigned char > &vchSig)
Check whether a signature is normalized (lower-S).
Definition: pubkey.cpp:301
CPubKey::operator!=
friend bool operator!=(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:122
XOnlyPubKey::XOnlyPubKey
XOnlyPubKey(Span< const unsigned char > bytes)
Construct an x-only pubkey from exactly 32 bytes.
Definition: pubkey.cpp:170