pubkey.h raw
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
19 const unsigned int BIP32_EXTKEY_SIZE = 74;
20 const unsigned int BIP32_EXTKEY_WITH_VERSION_SIZE = 78;
21
22 /** A reference to a CKey: the Hash160 of its serialized public key */
23 class CKeyID : public uint160
24 {
25 public:
26 CKeyID() : uint160() {}
27 explicit CKeyID(const uint160& in) : uint160(in) {}
28 };
29
30 /** An encapsulated public key. */
31 class CPubKey
32 {
33 public:
34 /**
35 * secp256k1:
36 */
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;
41 /**
42 * see www.keylength.com
43 * script supports up to 75 for single byte push
44 */
45 static_assert(
46 SIZE >= COMPRESSED_SIZE,
47 "COMPRESSED_SIZE is larger than SIZE");
48
49 private:
50
51 /**
52 * Just store the serialized data.
53 * Its length can very cheaply be computed from the first byte.
54 */
55 unsigned char vch[SIZE];
56
57 //! Compute the length of a pubkey with a given first byte.
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
67 //! Set this key data to be invalid
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
79 //! Construct an invalid public key.
80 CPubKey()
81 {
82 Invalidate();
83 }
84
85 //! Initialize a public key using begin/end iterators to byte data.
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
96 //! Construct a public key using begin/end iterators to byte data.
97 template <typename T>
98 CPubKey(const T pbegin, const T pend)
99 {
100 Set(pbegin, pend);
101 }
102
103 //! Construct a public key from a byte vector.
104 explicit CPubKey(std::span<const uint8_t> _vch)
105 {
106 Set(_vch.begin(), _vch.end());
107 }
108
109 //! Simple read-only vector-like interface to the pubkey data.
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
116 //! Comparator implementation.
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.vch[0] < b.vch[0] ||
125 (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
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
133 //! Implement serialization, as if this was a byte vector.
134 template <typename Stream>
135 void Serialize(Stream& s) const
136 {
137 unsigned int len = size();
138 ::WriteCompactSize(s, len);
139 s << std::span{vch, len};
140 }
141 template <typename Stream>
142 void Unserialize(Stream& s)
143 {
144 const unsigned int len(::ReadCompactSize(s));
145 if (len <= SIZE) {
146 s >> std::span{vch, len};
147 if (len != size()) {
148 Invalidate();
149 }
150 } else {
151 // invalid pubkey, skip available data
152 s.ignore(len);
153 Invalidate();
154 }
155 }
156
157 //! Get the KeyID of this public key (hash of its serialization)
158 CKeyID GetID() const
159 {
160 return CKeyID(Hash160(std::span{vch}.first(size())));
161 }
162
163 //! Get the 256-bit hash of this public key.
164 uint256 GetHash() const
165 {
166 return Hash(std::span{vch}.first(size()));
167 }
168
169 /*
170 * Check syntactic correctness.
171 *
172 * When setting a pubkey (Set()) or deserializing fails (its header bytes
173 * don't match the length of the data), the size is set to 0. Thus,
174 * by checking size, one can observe whether Set() or deserialization has
175 * failed.
176 *
177 * This does not check for more than that. In particular, it does not verify
178 * that the coordinates correspond to a point on the curve (see IsFullyValid()
179 * for that instead).
180 *
181 * Note that this is consensus critical as CheckECDSASignature() calls it!
182 */
183 bool IsValid() const
184 {
185 return size() > 0;
186 }
187
188 /** Check if a public key is a syntactically valid compressed or uncompressed key. */
189 bool IsValidNonHybrid() const noexcept
190 {
191 return size() > 0 && (vch[0] == 0x02 || vch[0] == 0x03 || vch[0] == 0x04);
192 }
193
194 //! fully validate whether this is a valid public key (more expensive than IsValid())
195 bool IsFullyValid() const;
196
197 //! Check whether this is a compressed public key.
198 bool IsCompressed() const
199 {
200 return size() == COMPRESSED_SIZE;
201 }
202
203 /**
204 * Verify a DER signature (~72 bytes).
205 * If this public key is not fully valid, the return value will be false.
206 */
207 bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
208
209 /**
210 * Check whether a signature is normalized (lower-S).
211 */
212 static bool CheckLowS(const std::vector<unsigned char>& vchSig);
213
214 //! Recover a public key from a compact signature.
215 bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
216
217 //! Turn this public key into an uncompressed public key.
218 bool Decompress();
219
220 //! Derive BIP32 child pubkey.
221 [[nodiscard]] bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc, uint256* bip32_tweak_out = nullptr) const;
222 };
223
224 class XOnlyPubKey
225 {
226 private:
227 uint256 m_keydata;
228
229 public:
230 /** Nothing Up My Sleeve point H
231 * Used as an internal key for provably disabling the key path spend
232 * see BIP341 for more details */
233 static const XOnlyPubKey NUMS_H;
234
235 /** Construct an empty x-only pubkey. */
236 XOnlyPubKey() = default;
237
238 XOnlyPubKey(const XOnlyPubKey&) = default;
239 XOnlyPubKey& operator=(const XOnlyPubKey&) = default;
240
241 /** Determine if this pubkey is fully valid. This is true for approximately 50% of all
242 * possible 32-byte arrays. If false, VerifySchnorr, CheckTapTweak and CreateTapTweak
243 * will always fail. */
244 bool IsFullyValid() const;
245
246 /** Test whether this is the 0 key (the result of default construction). This implies
247 * !IsFullyValid(). */
248 bool IsNull() const { return m_keydata.IsNull(); }
249
250 /** Construct an x-only pubkey from exactly 32 bytes. */
251 constexpr explicit XOnlyPubKey(std::span<const unsigned char> bytes) : m_keydata{bytes} {}
252
253 /** Construct an x-only pubkey from a normal pubkey. */
254 explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(std::span{pubkey}.subspan(1, 32)) {}
255
256 /** Verify a Schnorr signature against this public key.
257 *
258 * sigbytes must be exactly 64 bytes.
259 */
260 bool VerifySchnorr(const uint256& msg, std::span<const unsigned char> sigbytes) const;
261
262 /** Compute the Taproot tweak as specified in BIP341, with *this as internal
263 * key:
264 * - if merkle_root == nullptr: H_TapTweak(xonly_pubkey)
265 * - otherwise: H_TapTweak(xonly_pubkey || *merkle_root)
266 *
267 * Note that the behavior of this function with merkle_root != nullptr is
268 * consensus critical.
269 */
270 uint256 ComputeTapTweakHash(const uint256* merkle_root) const;
271
272 /** Verify that this is a Taproot tweaked output point, against a specified internal key,
273 * Merkle root, and parity. */
274 bool CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const;
275
276 /** Construct a Taproot tweaked output point with this point as internal key. */
277 std::optional<std::pair<XOnlyPubKey, bool>> CreateTapTweak(const uint256* merkle_root) const;
278
279 /** Returns a list of CKeyIDs for the CPubKeys that could have been used to create this XOnlyPubKey.
280 * As the CKeyID is the Hash160(full pubkey), the produced CKeyIDs are for the versions of this
281 * XOnlyPubKey with 0x02 and 0x03 prefixes.
282 * This is needed for key lookups since keys are indexed by CKeyID.
283 */
284 std::vector<CKeyID> GetKeyIDs() const;
285 /** Returns this XOnlyPubKey with 0x02 and 0x03 prefixes */
286 std::vector<CPubKey> GetCPubKeys() const;
287
288 CPubKey GetEvenCorrespondingCPubKey() const;
289
290 const unsigned char& operator[](int pos) const { return *(m_keydata.begin() + pos); }
291 static constexpr size_t size() { return decltype(m_keydata)::size(); }
292 const unsigned char* data() const { return m_keydata.begin(); }
293 const unsigned char* begin() const { return m_keydata.begin(); }
294 const unsigned char* end() const { return m_keydata.end(); }
295 unsigned char* data() { return m_keydata.begin(); }
296 unsigned char* begin() { return m_keydata.begin(); }
297 unsigned char* end() { return m_keydata.end(); }
298 bool operator==(const XOnlyPubKey& other) const { return m_keydata == other.m_keydata; }
299 bool operator<(const XOnlyPubKey& other) const { return m_keydata < other.m_keydata; }
300
301 //! Implement serialization without length prefixes since it is a fixed length
302 SERIALIZE_METHODS(XOnlyPubKey, obj) { READWRITE(obj.m_keydata); }
303 };
304
305 /** An ElligatorSwift-encoded public key. */
306 struct EllSwiftPubKey
307 {
308 private:
309 static constexpr size_t SIZE = 64;
310 std::array<std::byte, SIZE> m_pubkey;
311
312 public:
313 /** Default constructor creates all-zero pubkey (which is valid). */
314 EllSwiftPubKey() noexcept = default;
315
316 /** Construct a new ellswift public key from a given serialization. */
317 EllSwiftPubKey(std::span<const std::byte> ellswift) noexcept;
318
319 /** Decode to normal compressed CPubKey (for debugging purposes). */
320 CPubKey Decode() const;
321
322 // Read-only access for serialization.
323 const std::byte* data() const { return m_pubkey.data(); }
324 static constexpr size_t size() { return SIZE; }
325 auto begin() const { return m_pubkey.cbegin(); }
326 auto end() const { return m_pubkey.cend(); }
327
328 bool friend operator==(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
329 {
330 return a.m_pubkey == b.m_pubkey;
331 }
332 };
333
334 struct CExtPubKey {
335 unsigned char version[4];
336 unsigned char nDepth;
337 unsigned char vchFingerprint[4];
338 unsigned int nChild;
339 ChainCode chaincode;
340 CPubKey pubkey;
341
342 friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
343 {
344 return a.nDepth == b.nDepth &&
345 memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
346 a.nChild == b.nChild &&
347 a.chaincode == b.chaincode &&
348 a.pubkey == b.pubkey;
349 }
350
351 friend bool operator<(const CExtPubKey &a, const CExtPubKey &b)
352 {
353 if (a.pubkey < b.pubkey) {
354 return true;
355 } else if (a.pubkey > b.pubkey) {
356 return false;
357 }
358 return a.chaincode < b.chaincode;
359 }
360
361 void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
362 void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
363 void EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const;
364 void DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]);
365 [[nodiscard]] bool Derive(CExtPubKey& out, unsigned int nChild, uint256* bip32_tweak_out = nullptr) const;
366 };
367
368 #endif // BITCOIN_PUBKEY_H
369