Bitcoin Core 22.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 <cstring>
16#include <optional>
17#include <vector>
18
19const unsigned int BIP32_EXTKEY_SIZE = 74;
20
22class CKeyID : public uint160
23{
24public:
25 CKeyID() : uint160() {}
26 explicit CKeyID(const uint160& in) : uint160(in) {}
27};
28
30
33{
34public:
38 static constexpr unsigned int SIZE = 65;
39 static constexpr unsigned int COMPRESSED_SIZE = 33;
40 static constexpr unsigned int SIGNATURE_SIZE = 72;
41 static constexpr unsigned int COMPACT_SIGNATURE_SIZE = 65;
46 static_assert(
48 "COMPRESSED_SIZE is larger than SIZE");
49
50private:
51
56 unsigned char vch[SIZE];
57
59 unsigned int static GetLen(unsigned char chHeader)
60 {
61 if (chHeader == 2 || chHeader == 3)
62 return COMPRESSED_SIZE;
63 if (chHeader == 4 || chHeader == 6 || chHeader == 7)
64 return SIZE;
65 return 0;
66 }
67
70 {
71 vch[0] = 0xFF;
72 }
73
74public:
75
76 bool static ValidSize(const std::vector<unsigned char> &vch) {
77 return vch.size() > 0 && GetLen(vch[0]) == vch.size();
78 }
79
82 {
83 Invalidate();
84 }
85
87 template <typename T>
88 void Set(const T pbegin, const T pend)
89 {
90 int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
91 if (len && len == (pend - pbegin))
92 memcpy(vch, (unsigned char*)&pbegin[0], len);
93 else
94 Invalidate();
95 }
96
98 template <typename T>
99 CPubKey(const T pbegin, const T pend)
100 {
101 Set(pbegin, pend);
102 }
103
106 {
107 Set(_vch.begin(), _vch.end());
108 }
109
111 unsigned int size() const { return GetLen(vch[0]); }
112 const unsigned char* data() const { return vch; }
113 const unsigned char* begin() const { return vch; }
114 const unsigned char* end() const { return vch + size(); }
115 const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
116
118 friend bool operator==(const CPubKey& a, const CPubKey& b)
119 {
120 return a.vch[0] == b.vch[0] &&
121 memcmp(a.vch, b.vch, a.size()) == 0;
122 }
123 friend bool operator!=(const CPubKey& a, const CPubKey& b)
124 {
125 return !(a == b);
126 }
127 friend bool operator<(const CPubKey& a, const CPubKey& b)
128 {
129 return a.vch[0] < b.vch[0] ||
130 (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
131 }
132
134 template <typename Stream>
135 void Serialize(Stream& s) const
136 {
137 unsigned int len = size();
138 ::WriteCompactSize(s, len);
139 s.write((char*)vch, len);
140 }
141 template <typename Stream>
142 void Unserialize(Stream& s)
143 {
144 unsigned int len = ::ReadCompactSize(s);
145 if (len <= SIZE) {
146 s.read((char*)vch, len);
147 if (len != size()) {
148 Invalidate();
149 }
150 } else {
151 // invalid pubkey, skip available data
152 char dummy;
153 while (len--)
154 s.read(&dummy, 1);
155 Invalidate();
156 }
157 }
158
160 CKeyID GetID() const
161 {
162 return CKeyID(Hash160(MakeSpan(vch).first(size())));
163 }
164
167 {
168 return Hash(MakeSpan(vch).first(size()));
169 }
170
171 /*
172 * Check syntactic correctness.
173 *
174 * When setting a pubkey (Set()) or deserializing fails (its header bytes
175 * don't match the length of the data), the size is set to 0. Thus,
176 * by checking size, one can observe whether Set() or deserialization has
177 * failed.
178 *
179 * This does not check for more than that. In particular, it does not verify
180 * that the coordinates correspond to a point on the curve (see IsFullyValid()
181 * for that instead).
182 *
183 * Note that this is consensus critical as CheckECDSASignature() calls it!
184 */
185 bool IsValid() const
186 {
187 return size() > 0;
188 }
189
191 bool IsFullyValid() const;
192
194 bool IsCompressed() const
195 {
196 return size() == COMPRESSED_SIZE;
197 }
198
203 bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
204
208 static bool CheckLowS(const std::vector<unsigned char>& vchSig);
209
211 bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
212
214 bool Decompress();
215
217 bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
218};
219
221{
222private:
224
225public:
227 XOnlyPubKey() = default;
228
229 XOnlyPubKey(const XOnlyPubKey&) = default;
231
235 bool IsFullyValid() const;
236
239 bool IsNull() const { return m_keydata.IsNull(); }
240
243
245 explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span<const unsigned char>(pubkey.begin() + 1, pubkey.begin() + 33)) {}
246
251 bool VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const;
252
261 uint256 ComputeTapTweakHash(const uint256* merkle_root) const;
262
265 bool CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const;
266
268 std::optional<std::pair<XOnlyPubKey, bool>> CreateTapTweak(const uint256* merkle_root) const;
269
273 std::vector<CKeyID> GetKeyIDs() const;
274
275 const unsigned char& operator[](int pos) const { return *(m_keydata.begin() + pos); }
276 const unsigned char* data() const { return m_keydata.begin(); }
277 static constexpr size_t size() { return decltype(m_keydata)::size(); }
278 const unsigned char* begin() const { return m_keydata.begin(); }
279 const unsigned char* end() const { return m_keydata.end(); }
280 unsigned char* begin() { return m_keydata.begin(); }
281 unsigned char* end() { return m_keydata.end(); }
282 bool operator==(const XOnlyPubKey& other) const { return m_keydata == other.m_keydata; }
283 bool operator!=(const XOnlyPubKey& other) const { return m_keydata != other.m_keydata; }
284 bool operator<(const XOnlyPubKey& other) const { return m_keydata < other.m_keydata; }
285};
286
288 unsigned char nDepth;
289 unsigned char vchFingerprint[4];
290 unsigned int nChild;
293
294 friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
295 {
296 return a.nDepth == b.nDepth &&
297 memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
298 a.nChild == b.nChild &&
299 a.chaincode == b.chaincode &&
300 a.pubkey == b.pubkey;
301 }
302
303 friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
304 {
305 return !(a == b);
306 }
307
308 void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
309 void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
310 bool Derive(CExtPubKey& out, unsigned int nChild) const;
311};
312
316{
317 static int refcount;
318
319public:
322};
323
325
329
330#endif // BITCOIN_PUBKEY_H
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:23
CKeyID()
Definition: pubkey.h:25
CKeyID(const uint160 &in)
Definition: pubkey.h:26
An encapsulated public key.
Definition: pubkey.h:33
const unsigned char * data() const
Definition: pubkey.h:112
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:271
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:194
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:160
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:39
CPubKey()
Construct an invalid public key.
Definition: pubkey.h:81
static bool CheckLowS(const std::vector< unsigned char > &vchSig)
Check whether a signature is normalized (lower-S).
Definition: pubkey.cpp:363
bool IsValid() const
Definition: pubkey.h:185
bool Decompress()
Turn this public key into an uncompressed public key.
Definition: pubkey.cpp:300
const unsigned char * end() const
Definition: pubkey.h:114
bool Verify(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Verify a DER signature (~72 bytes).
Definition: pubkey.cpp:253
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:38
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:292
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:111
const unsigned char * begin() const
Definition: pubkey.h:113
static bool ValidSize(const std::vector< unsigned char > &vch)
Definition: pubkey.h:76
unsigned static int GetLen(unsigned char chHeader)
Compute the length of a pubkey with a given first byte.
Definition: pubkey.h:59
friend bool operator==(const CPubKey &a, const CPubKey &b)
Comparator implementation.
Definition: pubkey.h:118
void Serialize(Stream &s) const
Implement serialization, as if this was a byte vector.
Definition: pubkey.h:135
unsigned char vch[SIZE]
see www.keylength.com script supports up to 75 for single byte push
Definition: pubkey.h:48
CPubKey(const T pbegin, const T pend)
Construct a public key using begin/end iterators to byte data.
Definition: pubkey.h:99
void Invalidate()
Set this key data to be invalid.
Definition: pubkey.h:69
CPubKey(Span< const uint8_t > _vch)
Construct a public key from a byte vector.
Definition: pubkey.h:105
void Unserialize(Stream &s)
Definition: pubkey.h:142
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition: pubkey.h:166
bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child pubkey.
Definition: pubkey.cpp:315
const unsigned char & operator[](unsigned int pos) const
Definition: pubkey.h:115
static constexpr unsigned int SIGNATURE_SIZE
Definition: pubkey.h:40
static constexpr unsigned int COMPACT_SIGNATURE_SIZE
Definition: pubkey.h:41
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:88
friend bool operator!=(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:123
friend bool operator<(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:127
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:316
static int refcount
Definition: pubkey.h:317
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
constexpr C * begin() const noexcept
Definition: span.h:170
constexpr C * end() const noexcept
Definition: span.h:171
unsigned char * end()
Definition: pubkey.h:281
unsigned char * begin()
Definition: pubkey.h:280
XOnlyPubKey & operator=(const XOnlyPubKey &)=default
const unsigned char * end() const
Definition: pubkey.h:279
bool IsNull() const
Test whether this is the 0 key (the result of default construction).
Definition: pubkey.h:239
const unsigned char * begin() const
Definition: pubkey.h:278
std::optional< std::pair< XOnlyPubKey, bool > > CreateTapTweak(const uint256 *merkle_root) const
Construct a Taproot tweaked output point with this point as internal key.
Definition: pubkey.cpp:235
bool CheckTapTweak(const XOnlyPubKey &internal, const uint256 &merkle_root, bool parity) const
Verify that this is a Taproot tweaked output point, against a specified internal key,...
Definition: pubkey.cpp:227
static constexpr size_t size()
Definition: pubkey.h:277
const unsigned char * data() const
Definition: pubkey.h:276
uint256 m_keydata
Definition: pubkey.h:223
bool operator!=(const XOnlyPubKey &other) const
Definition: pubkey.h:283
XOnlyPubKey(const XOnlyPubKey &)=default
XOnlyPubKey(const CPubKey &pubkey)
Construct an x-only pubkey from a normal pubkey.
Definition: pubkey.h:245
bool operator<(const XOnlyPubKey &other) const
Definition: pubkey.h:284
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition: pubkey.cpp:200
bool VerifySchnorr(const uint256 &msg, Span< const unsigned char > sigbytes) const
Verify a Schnorr signature against this public key.
Definition: pubkey.cpp:206
std::vector< CKeyID > GetKeyIDs() const
Returns a list of CKeyIDs for the CPubKeys that could have been used to create this XOnlyPubKey.
Definition: pubkey.cpp:183
uint256 ComputeTapTweakHash(const uint256 *merkle_root) const
Compute the Taproot tweak as specified in BIP341, with *this as internal key:
Definition: pubkey.cpp:216
const unsigned char & operator[](int pos) const
Definition: pubkey.h:275
XOnlyPubKey()=default
Construct an empty x-only pubkey.
bool operator==(const XOnlyPubKey &other) const
Definition: pubkey.h:282
unsigned char * end()
Definition: uint256.h:63
unsigned char * begin()
Definition: uint256.h:58
bool IsNull() const
Definition: uint256.h:31
160-bit opaque blob.
Definition: uint256.h:113
256-bit opaque blob.
Definition: uint256.h:124
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:75
#define T(expected, seed, data)
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:19
uint256 ChainCode
Definition: pubkey.h:29
const secp256k1_context * GetVerifyContext()
Access to the internal secp256k1 context used for verification.
Definition: pubkey.cpp:394
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:282
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:1074
constexpr Span< A > MakeSpan(A(&a)[N])
MakeSpan for arrays:
Definition: span.h:222
friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:294
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:337
ChainCode chaincode
Definition: pubkey.h:291
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:355
unsigned char vchFingerprint[4]
Definition: pubkey.h:289
unsigned char nDepth
Definition: pubkey.h:288
friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:303
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:346
CPubKey pubkey
Definition: pubkey.h:292
unsigned int nChild
Definition: pubkey.h:290