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 : : /** A reference to a CKey: the Hash160 of its serialized public key */
23 : : class CKeyID : public uint160
24 : : {
25 : : public:
26 [ + + + + : 3514569 : CKeyID() : uint160() {}
+ + + ]
27 [ + + ]: 19837010 : 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 : 63194842 : unsigned int static GetLen(unsigned char chHeader)
59 : : {
60 [ + + ]: 63194842 : if (chHeader == 2 || chHeader == 3)
61 : : return COMPRESSED_SIZE;
62 [ + + + + ]: 2239958 : if (chHeader == 4 || chHeader == 6 || chHeader == 7)
63 : 838160 : return SIZE;
64 : : return 0;
65 : : }
66 : :
67 : : //! Set this key data to be invalid
68 : 14419851 : void Invalidate()
69 : : {
70 : 14419851 : vch[0] = 0xFF;
71 : 193619 : }
72 : :
73 : : public:
74 : :
75 : 988075 : bool static ValidSize(const std::vector<unsigned char> &vch) {
76 [ - + + + : 988075 : return vch.size() > 0 && GetLen(vch[0]) == vch.size();
+ + ]
77 : : }
78 : :
79 : : //! Construct an invalid public key.
80 : 14226232 : CPubKey()
81 : 12958012 : {
82 [ + + + + : 13010091 : Invalidate();
+ - + + ]
[ + - + -
- + + - +
- ][ # # #
# # # # #
# # ][ + +
# # # # #
# ]
[ + - + - ]
[ + - + -
+ - + - +
- + + + +
+ + ]
83 : : }
84 : :
85 : : //! Initialize a public key using begin/end iterators to byte data.
86 : : template <typename T>
87 [ + + ]: 4007673 : void Set(const T pbegin, const T pend)
88 : : {
89 [ + + ]: 4007673 : int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
90 [ + + + + ]: 3979010 : if (len && len == (pend - pbegin))
91 : 3818251 : memcpy(vch, (unsigned char*)&pbegin[0], len);
92 : : else
93 : 189422 : Invalidate();
94 : 4007673 : }
95 : :
96 : : //! Construct a public key using begin/end iterators to byte data.
97 : : template <typename T>
98 : 124304 : CPubKey(const T pbegin, const T pend)
99 : : {
100 : 124304 : Set(pbegin, pend);
101 : : }
102 : :
103 : : //! Construct a public key from a byte vector.
104 : 1304867 : explicit CPubKey(std::span<const uint8_t> _vch)
105 : 1304867 : {
106 : 1304867 : Set(_vch.begin(), _vch.end());
107 : 1304867 : }
108 : :
109 : : //! Simple read-only vector-like interface to the pubkey data.
110 [ + + ][ + + : 33460116 : unsigned int size() const { return GetLen(vch[0]); }
+ + # # ]
[ - + + -
+ + ][ - -
- - - - +
- + - + -
- - - - +
- + - + -
+ - + - ]
111 [ + - ][ + - : 5587763 : const unsigned char* data() const { return vch; }
+ - # # ]
[ - - - -
+ - ][ - -
- - - - +
- + - + -
- - - - +
- + - + -
+ - + - ]
112 [ + + ]: 6307141 : const unsigned char* begin() const { return vch; }
113 [ - + + - ]: 367295 : const unsigned char* end() const { return vch + size(); }
[ + - ]
114 [ + - ]: 74773 : const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
115 : :
116 : : //! Comparator implementation.
117 : 1331897 : friend bool operator==(const CPubKey& a, const CPubKey& b)
118 : : {
119 [ + + ]: 1331897 : return a.vch[0] == b.vch[0] &&
120 [ + + ]: 1330283 : memcmp(a.vch, b.vch, a.size()) == 0;
121 : : }
122 : 21687578 : friend bool operator<(const CPubKey& a, const CPubKey& b)
123 : : {
124 [ + + + + ]: 21687578 : return a.vch[0] < b.vch[0] ||
125 [ + + ]: 18904403 : (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
126 : : }
127 : 61800 : friend bool operator>(const CPubKey& a, const CPubKey& b)
128 : : {
129 [ + + + - ]: 61800 : return a.vch[0] > b.vch[0] ||
130 [ + + ]: 58565 : (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 : 25707 : void Serialize(Stream& s) const
136 : : {
137 : 25707 : unsigned int len = size();
138 : 25707 : ::WriteCompactSize(s, len);
139 : 25707 : s << std::span{vch, len};
140 : 25707 : }
141 : : template <typename Stream>
142 : 19847 : void Unserialize(Stream& s)
143 : : {
144 : 19847 : const unsigned int len(::ReadCompactSize(s));
145 [ + + ]: 18962 : if (len <= SIZE) {
146 : 17305 : s >> std::span{vch, len};
147 [ + + ]: 16507 : if (len != size()) {
148 : 3141 : Invalidate();
149 : : }
150 : : } else {
151 : : // invalid pubkey, skip available data
152 : 1657 : s.ignore(len);
153 : 1056 : Invalidate();
154 : : }
155 : 17563 : }
156 : :
157 : : //! Get the KeyID of this public key (hash of its serialization)
158 : 19626032 : CKeyID GetID() const
159 : : {
160 : 19626032 : return CKeyID(Hash160(std::span{vch}.first(size())));
161 : : }
162 : :
163 : : //! Get the 256-bit hash of this public key.
164 : 32569 : uint256 GetHash() const
165 : : {
166 : 32569 : 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 : 3756455 : bool IsValid() const
184 : : {
185 [ + + ][ - + : 7470828 : return size() > 0;
- + - + ]
[ # # # #
# # # # #
# ]
[ + - + + ]
[ + + + +
+ - + + -
+ + + ][ -
+ + - + +
+ + ]
186 : : }
187 : :
188 : : /** Check if a public key is a syntactically valid compressed or uncompressed key. */
189 : 345899 : bool IsValidNonHybrid() const noexcept
190 : : {
191 [ + + + + ]: 345899 : 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 : 213819 : bool IsCompressed() const
199 : : {
200 [ - + - + : 214899 : 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 [ - + + - : 663867 : 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 [ + + + + ]: 422511 : bool IsNull() const { return m_keydata.IsNull(); }
[ - - - -
+ + + + ]
[ + + + +
+ + + + +
+ + + +
+ ]
249 : :
250 : : /** Construct an x-only pubkey from exactly 32 bytes. */
251 [ + + ][ - + : 2947018 : constexpr explicit XOnlyPubKey(std::span<const unsigned char> bytes) : m_keydata{bytes} {}
- + + + +
+ ]
252 : :
253 : : /** Construct an x-only pubkey from a normal pubkey. */
254 : 2568558 : 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 [ + - ][ + - : 324547 : const unsigned char* data() const { return m_keydata.begin(); }
+ - + - +
- + - ]
293 [ + - ]: 2977349 : const unsigned char* begin() const { return m_keydata.begin(); }
294 [ + - ]: 2977349 : const unsigned char* end() const { return m_keydata.end(); }
295 : 768 : unsigned char* data() { return m_keydata.begin(); }
296 : 456405 : unsigned char* begin() { return m_keydata.begin(); }
297 : 6058 : unsigned char* end() { return m_keydata.end(); }
298 [ + - + - : 31830 : bool operator==(const XOnlyPubKey& other) const { return m_keydata == other.m_keydata; }
- + + - +
- ]
[ + - - - ]
[ - + # # ]
299 [ - + + + : 7524855 : 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 : 46632 : 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 : 10561 : const std::byte* data() const { return m_pubkey.data(); }
324 : : static constexpr size_t size() { return SIZE; }
325 : 2763 : auto begin() const { return m_pubkey.cbegin(); }
326 : 2763 : auto end() const { return m_pubkey.cend(); }
327 : :
328 : 4584 : bool friend operator==(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
329 : : {
330 [ - + + + : 4568 : return a.m_pubkey == b.m_pubkey;
+ + ]
331 : : }
332 : : };
333 : :
334 [ + - ]: 17946824 : 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 : 301702 : friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
343 : : {
344 : 603404 : return a.nDepth == b.nDepth &&
345 [ + - ]: 301702 : memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
346 [ + - + - ]: 301702 : a.nChild == b.nChild &&
347 [ + - + - ]: 603404 : a.chaincode == b.chaincode &&
348 [ - + ]: 301702 : a.pubkey == b.pubkey;
349 : : }
350 : :
351 : 103010 : friend bool operator<(const CExtPubKey &a, const CExtPubKey &b)
352 : : {
353 [ + + ]: 103010 : if (a.pubkey < b.pubkey) {
354 : : return true;
355 [ + + ]: 61800 : } else if (a.pubkey > b.pubkey) {
356 : : return false;
357 : : }
358 : 22699 : 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
|