Bitcoin Core 31.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-present 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;
20const unsigned int BIP32_EXTKEY_WITH_VERSION_SIZE = 78;
21
22using KeyFingerprint = std::array<unsigned char, 4>;
23
25class CKeyID : public uint160
26{
27public:
28 CKeyID() : uint160() {}
29 explicit CKeyID(const uint160& in) : uint160(in) {}
31 {
33 std::copy_n(begin(), ret.size(), ret.begin());
34 return ret;
35 }
36};
37
40{
41public:
45 static constexpr unsigned int SIZE = 65;
46 static constexpr unsigned int COMPRESSED_SIZE = 33;
47 static constexpr unsigned int SIGNATURE_SIZE = 72;
48 static constexpr unsigned int COMPACT_SIGNATURE_SIZE = 65;
53 static_assert(
55 "COMPRESSED_SIZE is larger than SIZE");
56
57private:
58
63 unsigned char vch[SIZE];
64
66 unsigned int static GetLen(unsigned char chHeader)
67 {
68 if (chHeader == 2 || chHeader == 3)
69 return COMPRESSED_SIZE;
70 if (chHeader == 4 || chHeader == 6 || chHeader == 7)
71 return SIZE;
72 return 0;
73 }
74
77 {
78 vch[0] = 0xFF;
79 }
80
81public:
82
83 bool static ValidSize(const std::vector<unsigned char> &vch) {
84 return vch.size() > 0 && GetLen(vch[0]) == vch.size();
85 }
86
89 {
90 Invalidate();
91 }
92
94 template <typename T>
95 void Set(const T pbegin, const T pend)
96 {
97 int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
98 if (len && len == (pend - pbegin))
99 memcpy(vch, (unsigned char*)&pbegin[0], len);
100 else
101 Invalidate();
102 }
103
105 template <typename T>
106 CPubKey(const T pbegin, const T pend)
107 {
108 Set(pbegin, pend);
109 }
110
112 explicit CPubKey(std::span<const uint8_t> _vch)
113 {
114 Set(_vch.begin(), _vch.end());
115 }
116
118 unsigned int size() const { return GetLen(vch[0]); }
119 const unsigned char* data() const { return vch; }
120 const unsigned char* begin() const { return vch; }
121 const unsigned char* end() const { return vch + size(); }
122 const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
123
125 friend bool operator==(const CPubKey& a, const CPubKey& b)
126 {
127 return a.vch[0] == b.vch[0] &&
128 memcmp(a.vch, b.vch, a.size()) == 0;
129 }
130 friend bool operator<(const CPubKey& a, const CPubKey& b)
131 {
132 return a.vch[0] < b.vch[0] ||
133 (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
134 }
135 friend bool operator>(const CPubKey& a, const CPubKey& b)
136 {
137 return a.vch[0] > b.vch[0] ||
138 (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) > 0);
139 }
140
142 template <typename Stream>
143 void Serialize(Stream& s) const
144 {
145 unsigned int len = size();
146 ::WriteCompactSize(s, len);
147 s << std::span{vch, len};
148 }
149 template <typename Stream>
151 {
152 const unsigned int len(::ReadCompactSize(s));
153 if (len <= SIZE) {
154 s >> std::span{vch, len};
155 if (len != size()) {
156 Invalidate();
157 }
158 } else {
159 // invalid pubkey, skip available data
160 s.ignore(len);
161 Invalidate();
162 }
163 }
164
166 CKeyID GetID() const
167 {
168 return CKeyID(Hash160(std::span{vch}.first(size())));
169 }
170
173 {
174 return Hash(std::span{vch}.first(size()));
175 }
176
177 /*
178 * Check syntactic correctness.
179 *
180 * When setting a pubkey (Set()) or deserializing fails (its header bytes
181 * don't match the length of the data), the size is set to 0. Thus,
182 * by checking size, one can observe whether Set() or deserialization has
183 * failed.
184 *
185 * This does not check for more than that. In particular, it does not verify
186 * that the coordinates correspond to a point on the curve (see IsFullyValid()
187 * for that instead).
188 *
189 * Note that this is consensus critical as CheckECDSASignature() calls it!
190 */
191 bool IsValid() const
192 {
193 return size() > 0;
194 }
195
197 bool IsValidNonHybrid() const noexcept
198 {
199 return size() > 0 && (vch[0] == 0x02 || vch[0] == 0x03 || vch[0] == 0x04);
200 }
201
203 bool IsFullyValid() const;
204
206 bool IsCompressed() const
207 {
208 return size() == COMPRESSED_SIZE;
209 }
210
215 bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
216
220 static bool CheckLowS(const std::vector<unsigned char>& vchSig);
221
223 bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
224
226 bool Decompress();
227
229 [[nodiscard]] bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc, uint256* bip32_tweak_out = nullptr) const;
230};
231
233{
234private:
236
237public:
241 static const XOnlyPubKey NUMS_H;
242
244 XOnlyPubKey() = default;
245
246 XOnlyPubKey(const XOnlyPubKey&) = default;
248
252 bool IsFullyValid() const;
253
256 bool IsNull() const { return m_keydata.IsNull(); }
257
259 constexpr explicit XOnlyPubKey(std::span<const unsigned char> bytes) : m_keydata{bytes} {}
260
262 explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(std::span{pubkey}.subspan(1, 32)) {}
263
268 bool VerifySchnorr(const uint256& msg, std::span<const unsigned char> sigbytes) const;
269
278 uint256 ComputeTapTweakHash(const uint256* merkle_root) const;
279
282 bool CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const;
283
285 std::optional<std::pair<XOnlyPubKey, bool>> CreateTapTweak(const uint256* merkle_root) const;
286
292 std::vector<CKeyID> GetKeyIDs() const;
294 std::vector<CPubKey> GetCPubKeys() const;
295
297
298 const unsigned char& operator[](int pos) const { return *(m_keydata.begin() + pos); }
299 static constexpr size_t size() { return decltype(m_keydata)::size(); }
300 const unsigned char* data() const { return m_keydata.begin(); }
301 const unsigned char* begin() const { return m_keydata.begin(); }
302 const unsigned char* end() const { return m_keydata.end(); }
303 unsigned char* data() { return m_keydata.begin(); }
304 unsigned char* begin() { return m_keydata.begin(); }
305 unsigned char* end() { return m_keydata.end(); }
306 bool operator==(const XOnlyPubKey& other) const { return m_keydata == other.m_keydata; }
307 bool operator<(const XOnlyPubKey& other) const { return m_keydata < other.m_keydata; }
308
310 SERIALIZE_METHODS(XOnlyPubKey, obj) { READWRITE(obj.m_keydata); }
311};
312
315{
316private:
317 static constexpr size_t SIZE = 64;
318 std::array<std::byte, SIZE> m_pubkey;
319
320public:
322 EllSwiftPubKey() noexcept = default;
323
325 EllSwiftPubKey(std::span<const std::byte> ellswift) noexcept;
326
328 CPubKey Decode() const;
329
330 // Read-only access for serialization.
331 const std::byte* data() const { return m_pubkey.data(); }
332 static constexpr size_t size() { return SIZE; }
333 auto begin() const { return m_pubkey.cbegin(); }
334 auto end() const { return m_pubkey.cend(); }
335
336 bool friend operator==(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
337 {
338 return a.m_pubkey == b.m_pubkey;
339 }
340};
341
343 unsigned char version[4];
344 unsigned char nDepth;
346 unsigned int nChild;
349
350 friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
351 {
352 return a.nDepth == b.nDepth &&
353 a.fingerprint == b.fingerprint &&
354 a.nChild == b.nChild &&
355 a.chaincode == b.chaincode &&
356 a.pubkey == b.pubkey;
357 }
358
359 friend bool operator<(const CExtPubKey &a, const CExtPubKey &b)
360 {
361 if (a.pubkey < b.pubkey) {
362 return true;
363 } else if (a.pubkey > b.pubkey) {
364 return false;
365 }
366 return a.chaincode < b.chaincode;
367 }
368
370 {
371 return pubkey.GetID().fingerprint();
372 }
373
374 void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
375 void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
376 void EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const;
377 void DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]);
378 [[nodiscard]] bool Derive(CExtPubKey& out, unsigned int nChild, uint256* bip32_tweak_out = nullptr) const;
379};
380
381#endif // BITCOIN_PUBKEY_H
int ret
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:26
CKeyID()
Definition: pubkey.h:28
CKeyID(const uint160 &in)
Definition: pubkey.h:29
KeyFingerprint fingerprint() const
Definition: pubkey.h:30
An encapsulated public key.
Definition: pubkey.h:40
const unsigned char * data() const
Definition: pubkey.h:119
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:300
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:206
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:166
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:46
CPubKey()
Construct an invalid public key.
Definition: pubkey.h:88
static bool CheckLowS(const std::vector< unsigned char > &vchSig)
Check whether a signature is normalized (lower-S).
Definition: pubkey.cpp:423
CPubKey(std::span< const uint8_t > _vch)
Construct a public key from a byte vector.
Definition: pubkey.h:112
bool IsValid() const
Definition: pubkey.h:191
friend bool operator>(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:135
bool Decompress()
Turn this public key into an uncompressed public key.
Definition: pubkey.cpp:327
const unsigned char * end() const
Definition: pubkey.h:121
bool Verify(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Verify a DER signature (~72 bytes).
Definition: pubkey.cpp:283
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:45
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:320
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:118
const unsigned char * begin() const
Definition: pubkey.h:120
bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc, uint256 *bip32_tweak_out=nullptr) const
Derive BIP32 child pubkey.
Definition: pubkey.cpp:341
static bool ValidSize(const std::vector< unsigned char > &vch)
Definition: pubkey.h:83
unsigned static int GetLen(unsigned char chHeader)
Compute the length of a pubkey with a given first byte.
Definition: pubkey.h:66
friend bool operator==(const CPubKey &a, const CPubKey &b)
Comparator implementation.
Definition: pubkey.h:125
void Serialize(Stream &s) const
Implement serialization, as if this was a byte vector.
Definition: pubkey.h:143
unsigned char vch[SIZE]
see www.keylength.com script supports up to 75 for single byte push
Definition: pubkey.h:63
CPubKey(const T pbegin, const T pend)
Construct a public key using begin/end iterators to byte data.
Definition: pubkey.h:106
void Invalidate()
Set this key data to be invalid.
Definition: pubkey.h:76
void Unserialize(Stream &s)
Definition: pubkey.h:150
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition: pubkey.h:172
const unsigned char & operator[](unsigned int pos) const
Definition: pubkey.h:122
static constexpr unsigned int SIGNATURE_SIZE
Definition: pubkey.h:47
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
Definition: pubkey.h:197
static constexpr unsigned int COMPACT_SIGNATURE_SIZE
Definition: pubkey.h:48
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:95
friend bool operator<(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:130
A BIP32 chain code.
Definition: hash.h:23
unsigned char * end()
Definition: pubkey.h:305
unsigned char * begin()
Definition: pubkey.h:304
XOnlyPubKey & operator=(const XOnlyPubKey &)=default
const unsigned char * end() const
Definition: pubkey.h:302
std::vector< CPubKey > GetCPubKeys() const
Returns this XOnlyPubKey with 0x02 and 0x03 prefixes.
Definition: pubkey.cpp:200
bool IsNull() const
Test whether this is the 0 key (the result of default construction).
Definition: pubkey.h:256
unsigned char * data()
Definition: pubkey.h:303
const unsigned char * begin() const
Definition: pubkey.h:301
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:265
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:257
static const XOnlyPubKey NUMS_H
Nothing Up My Sleeve point H Used as an internal key for provably disabling the key path spend see BI...
Definition: pubkey.h:241
static constexpr size_t size()
Definition: pubkey.h:299
constexpr XOnlyPubKey(std::span< const unsigned char > bytes)
Construct an x-only pubkey from exactly 32 bytes.
Definition: pubkey.h:259
const unsigned char * data() const
Definition: pubkey.h:300
bool VerifySchnorr(const uint256 &msg, std::span< const unsigned char > sigbytes) const
Verify a Schnorr signature against this public key.
Definition: pubkey.cpp:236
SERIALIZE_METHODS(XOnlyPubKey, obj)
Implement serialization without length prefixes since it is a fixed length.
Definition: pubkey.h:310
CPubKey GetEvenCorrespondingCPubKey() const
Definition: pubkey.cpp:223
uint256 m_keydata
Definition: pubkey.h:235
XOnlyPubKey(const XOnlyPubKey &)=default
XOnlyPubKey(const CPubKey &pubkey)
Construct an x-only pubkey from a normal pubkey.
Definition: pubkey.h:262
bool operator<(const XOnlyPubKey &other) const
Definition: pubkey.h:307
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition: pubkey.cpp:230
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:214
uint256 ComputeTapTweakHash(const uint256 *merkle_root) const
Compute the Taproot tweak as specified in BIP341, with *this as internal key:
Definition: pubkey.cpp:246
const unsigned char & operator[](int pos) const
Definition: pubkey.h:298
XOnlyPubKey()=default
Construct an empty x-only pubkey.
bool operator==(const XOnlyPubKey &other) const
Definition: pubkey.h:306
constexpr bool IsNull() const
Definition: uint256.h:50
constexpr unsigned char * end()
Definition: uint256.h:102
constexpr unsigned char * begin()
Definition: uint256.h:101
160-bit opaque blob.
Definition: uint256.h:184
256-bit opaque blob.
Definition: uint256.h:196
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:100
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:83
SocketId Stream
Definition: util.h:30
const unsigned int BIP32_EXTKEY_WITH_VERSION_SIZE
Definition: pubkey.h:20
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:19
std::array< unsigned char, 4 > KeyFingerprint
Definition: pubkey.h:22
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
Definition: serialize.h:1151
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:333
#define READWRITE(...)
Definition: serialize.h:148
friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:350
unsigned char version[4]
Definition: pubkey.h:343
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:385
ChainCode chaincode
Definition: pubkey.h:347
KeyFingerprint fingerprint
Definition: pubkey.h:345
void DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE])
Definition: pubkey.cpp:409
void EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const
Definition: pubkey.cpp:403
unsigned char nDepth
Definition: pubkey.h:344
KeyFingerprint id_key_fingerprint() const
Definition: pubkey.h:369
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:394
CPubKey pubkey
Definition: pubkey.h:348
unsigned int nChild
Definition: pubkey.h:346
friend bool operator<(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:359
bool Derive(CExtPubKey &out, unsigned int nChild, uint256 *bip32_tweak_out=nullptr) const
Definition: pubkey.cpp:415
An ElligatorSwift-encoded public key.
Definition: pubkey.h:315
auto begin() const
Definition: pubkey.h:333
bool friend operator==(const EllSwiftPubKey &a, const EllSwiftPubKey &b)
Definition: pubkey.h:336
std::array< std::byte, SIZE > m_pubkey
Definition: pubkey.h:318
CPubKey Decode() const
Decode to normal compressed CPubKey (for debugging purposes).
Definition: pubkey.cpp:371
static constexpr size_t SIZE
Definition: pubkey.h:317
static constexpr size_t size()
Definition: pubkey.h:332
const std::byte * data() const
Definition: pubkey.h:331
EllSwiftPubKey() noexcept=default
Default constructor creates all-zero pubkey (which is valid).
auto end() const
Definition: pubkey.h:334