Branch data Line data Source code
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 : : using KeyFingerprint = std::array<unsigned char, 4>;
23 : :
24 : : /** A reference to a CKey: the Hash160 of its serialized public key */
25 : : class CKeyID : public uint160
26 : : {
27 : : public:
28 [ + + + + : 533833 : CKeyID() : uint160() {}
+ + + ]
29 [ + + ]: 6112267 : explicit CKeyID(const uint160& in) : uint160(in) {}
[ + - + - ]
30 : 2549480 : KeyFingerprint fingerprint() const
31 : : {
32 : 2549480 : KeyFingerprint ret;
33 : 2549480 : std::copy_n(begin(), ret.size(), ret.begin());
34 : 2549480 : return ret;
35 : : }
36 : : };
37 : :
38 : : /** An encapsulated public key. */
39 : : class CPubKey
40 : : {
41 : : public:
42 : : /**
43 : : * secp256k1:
44 : : */
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;
49 : : /**
50 : : * see www.keylength.com
51 : : * script supports up to 75 for single byte push
52 : : */
53 : : static_assert(
54 : : SIZE >= COMPRESSED_SIZE,
55 : : "COMPRESSED_SIZE is larger than SIZE");
56 : :
57 : : private:
58 : :
59 : : /**
60 : : * Just store the serialized data.
61 : : * Its length can very cheaply be computed from the first byte.
62 : : */
63 : : unsigned char vch[SIZE];
64 : :
65 : : //! Compute the length of a pubkey with a given first byte.
66 : 23570942 : unsigned int static GetLen(unsigned char chHeader)
67 : : {
68 [ + + ]: 23570942 : if (chHeader == 2 || chHeader == 3)
69 : : return COMPRESSED_SIZE;
70 [ + + + + ]: 100106 : if (chHeader == 4 || chHeader == 6 || chHeader == 7)
71 : 36796 : return SIZE;
72 : : return 0;
73 : : }
74 : :
75 : : //! Set this key data to be invalid
76 : 3070587 : void Invalidate()
77 : : {
78 : 3070587 : vch[0] = 0xFF;
79 : 22231 : }
80 : :
81 : : public:
82 : :
83 : 28482 : bool static ValidSize(const std::vector<unsigned char> &vch) {
84 [ - + + + : 28482 : return vch.size() > 0 && GetLen(vch[0]) == vch.size();
+ + ]
85 : : }
86 : :
87 : : //! Construct an invalid public key.
88 : 3048356 : CPubKey()
89 : 2918045 : {
90 [ + - + - : 2942129 : Invalidate();
- - + - +
- ][ + + +
+ # # # #
# # ][ + + ]
[ + + + +
+ - ][ + -
+ - + - +
- + - + +
+ + + + ]
91 : : }
92 : :
93 : : //! Initialize a public key using begin/end iterators to byte data.
94 : : template <typename T>
95 [ + + ]: 1967862 : void Set(const T pbegin, const T pend)
96 : : {
97 [ + + ]: 1967862 : int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
98 [ + + + + ]: 1965718 : if (len && len == (pend - pbegin))
99 : 1945637 : memcpy(vch, (unsigned char*)&pbegin[0], len);
100 : : else
101 : 22225 : Invalidate();
102 : 1967862 : }
103 : :
104 : : //! Construct a public key using begin/end iterators to byte data.
105 : : template <typename T>
106 : 4230 : CPubKey(const T pbegin, const T pend)
107 : : {
108 : 4230 : Set(pbegin, pend);
109 : : }
110 : :
111 : : //! Construct a public key from a byte vector.
112 : 398937 : explicit CPubKey(std::span<const uint8_t> _vch)
113 : 398937 : {
114 : 398937 : Set(_vch.begin(), _vch.end());
115 : 398937 : }
116 : :
117 : : //! Simple read-only vector-like interface to the pubkey data.
118 [ + + ][ + + : 9190279 : unsigned int size() const { return GetLen(vch[0]); }
+ + # # ]
[ + - + -
+ - ][ + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
[ + - + -
+ - + - ]
119 [ + - ][ + - : 1780388 : const unsigned char* data() const { return vch; }
+ - # # ]
[ + - + -
+ - ][ + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
[ + - + -
+ - + - ]
120 [ - + ]: 469309 : const unsigned char* begin() const { return vch; }
121 [ + - ]: 159346 : const unsigned char* end() const { return vch + size(); }
122 [ + - ]: 13076 : const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
123 : :
124 : : //! Comparator implementation.
125 : 72772 : friend bool operator==(const CPubKey& a, const CPubKey& b)
126 : : {
127 [ + + ]: 72772 : return a.vch[0] == b.vch[0] &&
128 [ + + ]: 72336 : memcmp(a.vch, b.vch, a.size()) == 0;
129 : : }
130 : 11825063 : friend bool operator<(const CPubKey& a, const CPubKey& b)
131 : : {
132 [ + + + + ]: 11825063 : return a.vch[0] < b.vch[0] ||
133 [ + + ]: 10951012 : (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
134 : : }
135 : 697 : friend bool operator>(const CPubKey& a, const CPubKey& b)
136 : : {
137 [ + + + - ]: 697 : return a.vch[0] > b.vch[0] ||
138 [ + + ]: 690 : (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) > 0);
139 : : }
140 : :
141 : : //! Implement serialization, as if this was a byte vector.
142 : : template <typename Stream>
143 : 5728 : void Serialize(Stream& s) const
144 : : {
145 : 5728 : unsigned int len = size();
146 : 5728 : ::WriteCompactSize(s, len);
147 : 5728 : s << std::span{vch, len};
148 : 5728 : }
149 : : template <typename Stream>
150 : 2978 : void Unserialize(Stream& s)
151 : : {
152 : 2978 : const unsigned int len(::ReadCompactSize(s));
153 [ + - ]: 2978 : if (len <= SIZE) {
154 : 2978 : s >> std::span{vch, len};
155 [ + + ]: 2978 : if (len != size()) {
156 : 6 : Invalidate();
157 : : }
158 : : } else {
159 : : // invalid pubkey, skip available data
160 : 0 : s.ignore(len);
161 : 0 : Invalidate();
162 : : }
163 : 2978 : }
164 : :
165 : : //! Get the KeyID of this public key (hash of its serialization)
166 : 5778666 : CKeyID GetID() const
167 : : {
168 : 5778666 : return CKeyID(Hash160(std::span{vch}.first(size())));
169 : : }
170 : :
171 : : //! Get the 256-bit hash of this public key.
172 : 3170 : uint256 GetHash() const
173 : : {
174 : 3170 : 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 : 1105936 : bool IsValid() const
192 : : {
193 [ - + - + : 1419793 : return size() > 0;
- - - + -
+ ][ + + ]
[ + + + + ]
[ + + + +
- + + + -
+ + + ][ -
+ + - + +
+ - ][ + -
+ - + - ]
194 : : }
195 : :
196 : : /** Check if a public key is a syntactically valid compressed or uncompressed key. */
197 : 272449 : bool IsValidNonHybrid() const noexcept
198 : : {
199 [ + + + + ]: 272449 : return size() > 0 && (vch[0] == 0x02 || vch[0] == 0x03 || vch[0] == 0x04);
200 : : }
201 : :
202 : : //! fully validate whether this is a valid public key (more expensive than IsValid())
203 : : bool IsFullyValid() const;
204 : :
205 : : //! Check whether this is a compressed public key.
206 : 200770 : bool IsCompressed() const
207 : : {
208 [ + + ]: 200770 : return size() == COMPRESSED_SIZE;
[ + + + + ]
[ + + + +
+ + ]
209 : : }
210 : :
211 : : /**
212 : : * Verify a DER signature (~72 bytes).
213 : : * If this public key is not fully valid, the return value will be false.
214 : : */
215 : : bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
216 : :
217 : : /**
218 : : * Check whether a signature is normalized (lower-S).
219 : : */
220 : : static bool CheckLowS(const std::vector<unsigned char>& vchSig);
221 : :
222 : : //! Recover a public key from a compact signature.
223 : : bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
224 : :
225 : : //! Turn this public key into an uncompressed public key.
226 : : bool Decompress();
227 : :
228 : : //! Derive BIP32 child pubkey.
229 : : [[nodiscard]] bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc, uint256* bip32_tweak_out = nullptr) const;
230 : : };
231 : :
232 : : class XOnlyPubKey
233 : : {
234 : : private:
235 : : uint256 m_keydata;
236 : :
237 : : public:
238 : : /** Nothing Up My Sleeve point H
239 : : * Used as an internal key for provably disabling the key path spend
240 : : * see BIP341 for more details */
241 : : static const XOnlyPubKey NUMS_H;
242 : :
243 : : /** Construct an empty x-only pubkey. */
244 [ - + + + : 730226 : XOnlyPubKey() = default;
+ + ]
[ + - + + ]
[ + + ]
245 : :
246 : : XOnlyPubKey(const XOnlyPubKey&) = default;
247 : : XOnlyPubKey& operator=(const XOnlyPubKey&) = default;
248 : :
249 : : /** Determine if this pubkey is fully valid. This is true for approximately 50% of all
250 : : * possible 32-byte arrays. If false, VerifySchnorr, CheckTapTweak and CreateTapTweak
251 : : * will always fail. */
252 : : bool IsFullyValid() const;
253 : :
254 : : /** Test whether this is the 0 key (the result of default construction). This implies
255 : : * !IsFullyValid(). */
256 [ + + + + ]: 116945 : bool IsNull() const { return m_keydata.IsNull(); }
[ + + + +
+ + + + ]
[ + + - +
+ + + + -
+ + + +
+ ]
257 : :
258 : : /** Construct an x-only pubkey from exactly 32 bytes. */
259 [ + - ][ - + : 1660084 : constexpr explicit XOnlyPubKey(std::span<const unsigned char> bytes) : m_keydata{bytes} {}
- + + + +
+ ]
[ + - + + ]
260 : :
261 : : /** Construct an x-only pubkey from a normal pubkey. */
262 : 1415164 : explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(std::span{pubkey}.subspan(1, 32)) {}
263 : :
264 : : /** Verify a Schnorr signature against this public key.
265 : : *
266 : : * sigbytes must be exactly 64 bytes.
267 : : */
268 : : bool VerifySchnorr(const uint256& msg, std::span<const unsigned char> sigbytes) const;
269 : :
270 : : /** Compute the Taproot tweak as specified in BIP341, with *this as internal
271 : : * key:
272 : : * - if merkle_root == nullptr: H_TapTweak(xonly_pubkey)
273 : : * - otherwise: H_TapTweak(xonly_pubkey || *merkle_root)
274 : : *
275 : : * Note that the behavior of this function with merkle_root != nullptr is
276 : : * consensus critical.
277 : : */
278 : : uint256 ComputeTapTweakHash(const uint256* merkle_root) const;
279 : :
280 : : /** Verify that this is a Taproot tweaked output point, against a specified internal key,
281 : : * Merkle root, and parity. */
282 : : bool CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const;
283 : :
284 : : /** Construct a Taproot tweaked output point with this point as internal key. */
285 : : std::optional<std::pair<XOnlyPubKey, bool>> CreateTapTweak(const uint256* merkle_root) const;
286 : :
287 : : /** Returns a list of CKeyIDs for the CPubKeys that could have been used to create this XOnlyPubKey.
288 : : * As the CKeyID is the Hash160(full pubkey), the produced CKeyIDs are for the versions of this
289 : : * XOnlyPubKey with 0x02 and 0x03 prefixes.
290 : : * This is needed for key lookups since keys are indexed by CKeyID.
291 : : */
292 : : std::vector<CKeyID> GetKeyIDs() const;
293 : : /** Returns this XOnlyPubKey with 0x02 and 0x03 prefixes */
294 : : std::vector<CPubKey> GetCPubKeys() const;
295 : :
296 : : CPubKey GetEvenCorrespondingCPubKey() const;
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 [ + - + - : 270028 : const unsigned char* data() const { return m_keydata.begin(); }
+ - + - +
- ][ + - ]
301 [ + - ]: 1347866 : const unsigned char* begin() const { return m_keydata.begin(); }
302 [ + - ]: 1347866 : const unsigned char* end() const { return m_keydata.end(); }
303 [ + - ]: 7 : unsigned char* data() { return m_keydata.begin(); }
304 [ + - ]: 269312 : unsigned char* begin() { return m_keydata.begin(); }
305 [ + - ]: 6 : unsigned char* end() { return m_keydata.end(); }
306 [ + + # # ]: 20561 : bool operator==(const XOnlyPubKey& other) const { return m_keydata == other.m_keydata; }
[ + + - + ]
307 [ + - - - : 2893718 : bool operator<(const XOnlyPubKey& other) const { return m_keydata < other.m_keydata; }
- + + + +
- + - - -
- - + + +
+ - + + +
+ + - + ]
[ - + + -
+ + + - -
- - - - +
+ - + - +
- - - + +
+ + + + +
+ + + + -
+ - + + -
+ + - +
- ][ - - -
- - - - -
+ + # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ][ +
+ + + - -
- - - - -
- + + + +
+ + - - -
- - - - -
- - - - -
- - - - -
- - - - +
+ + - -
- ]
[ + + + + ]
[ - + + -
+ - + - -
- - - + +
- - - - -
- - - -
- ]
308 : :
309 : : //! Implement serialization without length prefixes since it is a fixed length
310 : 19332 : SERIALIZE_METHODS(XOnlyPubKey, obj) { READWRITE(obj.m_keydata); }
311 : : };
312 : :
313 : : /** An ElligatorSwift-encoded public key. */
314 : : struct EllSwiftPubKey
315 : : {
316 : : private:
317 : : static constexpr size_t SIZE = 64;
318 : : std::array<std::byte, SIZE> m_pubkey;
319 : :
320 : : public:
321 : : /** Default constructor creates all-zero pubkey (which is valid). */
322 : : EllSwiftPubKey() noexcept = default;
323 : :
324 : : /** Construct a new ellswift public key from a given serialization. */
325 : : EllSwiftPubKey(std::span<const std::byte> ellswift) noexcept;
326 : :
327 : : /** Decode to normal compressed CPubKey (for debugging purposes). */
328 : : CPubKey Decode() const;
329 : :
330 : : // Read-only access for serialization.
331 [ + - + - : 507 : const std::byte* data() const { return m_pubkey.data(); }
+ - + - +
- + - +
- ]
332 : : static constexpr size_t size() { return SIZE; }
333 : 277 : auto begin() const { return m_pubkey.cbegin(); }
334 : 277 : auto end() const { return m_pubkey.cend(); }
335 : :
336 : 98 : bool friend operator==(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
337 : : {
338 [ + - + - ]: 98 : return a.m_pubkey == b.m_pubkey;
339 : : }
340 : : };
341 : :
342 [ + - + - ]: 18029472 : struct CExtPubKey {
[ + + + +
+ - ][ + - ]
[ + - + -
+ - + - +
+ + + + +
+ + ]
343 : : unsigned char version[4];
344 : : unsigned char nDepth;
345 : : KeyFingerprint fingerprint;
346 : : unsigned int nChild;
347 : : ChainCode chaincode;
348 : : CPubKey pubkey;
349 : :
350 : 33 : friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
351 : : {
352 [ + - ]: 33 : return a.nDepth == b.nDepth &&
353 [ + - ]: 33 : a.fingerprint == b.fingerprint &&
354 [ + - + - ]: 33 : a.nChild == b.nChild &&
355 [ + - + - ]: 66 : a.chaincode == b.chaincode &&
356 [ - + ]: 33 : a.pubkey == b.pubkey;
357 : : }
358 : :
359 : 747 : friend bool operator<(const CExtPubKey &a, const CExtPubKey &b)
360 : : {
361 [ + + ]: 747 : if (a.pubkey < b.pubkey) {
362 : : return true;
363 [ + + ]: 697 : } else if (a.pubkey > b.pubkey) {
364 : : return false;
365 : : }
366 : 664 : return a.chaincode < b.chaincode;
367 : : }
368 : :
369 : 1394828 : KeyFingerprint id_key_fingerprint() const
370 : : {
371 : 1394828 : 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
|