Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2022 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 0 : CKeyID() : uint160() {}
27 0 : explicit CKeyID(const uint160& in) : uint160(in) {}
28 : };
29 :
30 : typedef uint256 ChainCode;
31 :
32 : /** An encapsulated public key. */
33 : class CPubKey
34 : {
35 : public:
36 : /**
37 : * secp256k1:
38 : */
39 : static constexpr unsigned int SIZE = 65;
40 : static constexpr unsigned int COMPRESSED_SIZE = 33;
41 : static constexpr unsigned int SIGNATURE_SIZE = 72;
42 : static constexpr unsigned int COMPACT_SIGNATURE_SIZE = 65;
43 : /**
44 : * see www.keylength.com
45 : * script supports up to 75 for single byte push
46 : */
47 : static_assert(
48 : SIZE >= COMPRESSED_SIZE,
49 : "COMPRESSED_SIZE is larger than SIZE");
50 :
51 : private:
52 :
53 : /**
54 : * Just store the serialized data.
55 : * Its length can very cheaply be computed from the first byte.
56 : */
57 : unsigned char vch[SIZE];
58 :
59 : //! Compute the length of a pubkey with a given first byte.
60 0 : unsigned int static GetLen(unsigned char chHeader)
61 : {
62 0 : if (chHeader == 2 || chHeader == 3)
63 0 : return COMPRESSED_SIZE;
64 0 : if (chHeader == 4 || chHeader == 6 || chHeader == 7)
65 0 : return SIZE;
66 0 : return 0;
67 0 : }
68 :
69 : //! Set this key data to be invalid
70 0 : void Invalidate()
71 : {
72 0 : vch[0] = 0xFF;
73 0 : }
74 :
75 : public:
76 :
77 0 : bool static ValidSize(const std::vector<unsigned char> &vch) {
78 0 : return vch.size() > 0 && GetLen(vch[0]) == vch.size();
79 : }
80 :
81 : //! Construct an invalid public key.
82 0 : CPubKey()
83 : {
84 0 : Invalidate();
85 0 : }
86 :
87 : //! Initialize a public key using begin/end iterators to byte data.
88 : template <typename T>
89 0 : void Set(const T pbegin, const T pend)
90 : {
91 0 : int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
92 0 : if (len && len == (pend - pbegin))
93 0 : memcpy(vch, (unsigned char*)&pbegin[0], len);
94 : else
95 0 : Invalidate();
96 0 : }
97 :
98 : //! Construct a public key using begin/end iterators to byte data.
99 : template <typename T>
100 0 : CPubKey(const T pbegin, const T pend)
101 : {
102 0 : Set(pbegin, pend);
103 0 : }
104 :
105 : //! Construct a public key from a byte vector.
106 0 : explicit CPubKey(Span<const uint8_t> _vch)
107 : {
108 0 : Set(_vch.begin(), _vch.end());
109 0 : }
110 :
111 : //! Simple read-only vector-like interface to the pubkey data.
112 0 : unsigned int size() const { return GetLen(vch[0]); }
113 0 : const unsigned char* data() const { return vch; }
114 0 : const unsigned char* begin() const { return vch; }
115 0 : const unsigned char* end() const { return vch + size(); }
116 0 : const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
117 :
118 : //! Comparator implementation.
119 0 : friend bool operator==(const CPubKey& a, const CPubKey& b)
120 : {
121 0 : return a.vch[0] == b.vch[0] &&
122 0 : memcmp(a.vch, b.vch, a.size()) == 0;
123 : }
124 0 : friend bool operator!=(const CPubKey& a, const CPubKey& b)
125 : {
126 0 : return !(a == b);
127 : }
128 0 : friend bool operator<(const CPubKey& a, const CPubKey& b)
129 : {
130 0 : return a.vch[0] < b.vch[0] ||
131 0 : (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
132 : }
133 0 : friend bool operator>(const CPubKey& a, const CPubKey& b)
134 : {
135 0 : return a.vch[0] > b.vch[0] ||
136 0 : (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) > 0);
137 : }
138 :
139 : //! Implement serialization, as if this was a byte vector.
140 : template <typename Stream>
141 0 : void Serialize(Stream& s) const
142 : {
143 0 : unsigned int len = size();
144 0 : ::WriteCompactSize(s, len);
145 0 : s << Span{vch, len};
146 0 : }
147 : template <typename Stream>
148 0 : void Unserialize(Stream& s)
149 : {
150 0 : const unsigned int len(::ReadCompactSize(s));
151 0 : if (len <= SIZE) {
152 0 : s >> Span{vch, len};
153 0 : if (len != size()) {
154 0 : Invalidate();
155 0 : }
156 0 : } else {
157 : // invalid pubkey, skip available data
158 0 : s.ignore(len);
159 0 : Invalidate();
160 : }
161 0 : }
162 :
163 : //! Get the KeyID of this public key (hash of its serialization)
164 0 : CKeyID GetID() const
165 : {
166 0 : return CKeyID(Hash160(Span{vch}.first(size())));
167 : }
168 :
169 : //! Get the 256-bit hash of this public key.
170 0 : uint256 GetHash() const
171 : {
172 0 : return Hash(Span{vch}.first(size()));
173 : }
174 :
175 : /*
176 : * Check syntactic correctness.
177 : *
178 : * When setting a pubkey (Set()) or deserializing fails (its header bytes
179 : * don't match the length of the data), the size is set to 0. Thus,
180 : * by checking size, one can observe whether Set() or deserialization has
181 : * failed.
182 : *
183 : * This does not check for more than that. In particular, it does not verify
184 : * that the coordinates correspond to a point on the curve (see IsFullyValid()
185 : * for that instead).
186 : *
187 : * Note that this is consensus critical as CheckECDSASignature() calls it!
188 : */
189 0 : bool IsValid() const
190 : {
191 0 : return size() > 0;
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 0 : bool IsCompressed() const
199 : {
200 0 : 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) const;
222 : };
223 :
224 : class XOnlyPubKey
225 : {
226 : private:
227 : uint256 m_keydata;
228 :
229 : public:
230 : /** Construct an empty x-only pubkey. */
231 0 : XOnlyPubKey() = default;
232 :
233 : XOnlyPubKey(const XOnlyPubKey&) = default;
234 : XOnlyPubKey& operator=(const XOnlyPubKey&) = default;
235 :
236 : /** Determine if this pubkey is fully valid. This is true for approximately 50% of all
237 : * possible 32-byte arrays. If false, VerifySchnorr, CheckTapTweak and CreateTapTweak
238 : * will always fail. */
239 : bool IsFullyValid() const;
240 :
241 : /** Test whether this is the 0 key (the result of default construction). This implies
242 : * !IsFullyValid(). */
243 0 : bool IsNull() const { return m_keydata.IsNull(); }
244 :
245 : /** Construct an x-only pubkey from exactly 32 bytes. */
246 : explicit XOnlyPubKey(Span<const unsigned char> bytes);
247 :
248 : /** Construct an x-only pubkey from a normal pubkey. */
249 0 : explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span{pubkey}.subspan(1, 32)) {}
250 :
251 : /** Verify a Schnorr signature against this public key.
252 : *
253 : * sigbytes must be exactly 64 bytes.
254 : */
255 : bool VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const;
256 :
257 : /** Compute the Taproot tweak as specified in BIP341, with *this as internal
258 : * key:
259 : * - if merkle_root == nullptr: H_TapTweak(xonly_pubkey)
260 : * - otherwise: H_TapTweak(xonly_pubkey || *merkle_root)
261 : *
262 : * Note that the behavior of this function with merkle_root != nullptr is
263 : * consensus critical.
264 : */
265 : uint256 ComputeTapTweakHash(const uint256* merkle_root) const;
266 :
267 : /** Verify that this is a Taproot tweaked output point, against a specified internal key,
268 : * Merkle root, and parity. */
269 : bool CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const;
270 :
271 : /** Construct a Taproot tweaked output point with this point as internal key. */
272 : std::optional<std::pair<XOnlyPubKey, bool>> CreateTapTweak(const uint256* merkle_root) const;
273 :
274 : /** Returns a list of CKeyIDs for the CPubKeys that could have been used to create this XOnlyPubKey.
275 : * This is needed for key lookups since keys are indexed by CKeyID.
276 : */
277 : std::vector<CKeyID> GetKeyIDs() const;
278 :
279 : const unsigned char& operator[](int pos) const { return *(m_keydata.begin() + pos); }
280 0 : const unsigned char* data() const { return m_keydata.begin(); }
281 0 : static constexpr size_t size() { return decltype(m_keydata)::size(); }
282 0 : const unsigned char* begin() const { return m_keydata.begin(); }
283 0 : const unsigned char* end() const { return m_keydata.end(); }
284 0 : unsigned char* begin() { return m_keydata.begin(); }
285 : unsigned char* end() { return m_keydata.end(); }
286 0 : bool operator==(const XOnlyPubKey& other) const { return m_keydata == other.m_keydata; }
287 0 : bool operator!=(const XOnlyPubKey& other) const { return m_keydata != other.m_keydata; }
288 0 : bool operator<(const XOnlyPubKey& other) const { return m_keydata < other.m_keydata; }
289 :
290 : //! Implement serialization without length prefixes since it is a fixed length
291 0 : SERIALIZE_METHODS(XOnlyPubKey, obj) { READWRITE(obj.m_keydata); }
292 : };
293 :
294 : /** An ElligatorSwift-encoded public key. */
295 : struct EllSwiftPubKey
296 : {
297 : private:
298 : static constexpr size_t SIZE = 64;
299 : std::array<std::byte, SIZE> m_pubkey;
300 :
301 : public:
302 : /** Default constructor creates all-zero pubkey (which is valid). */
303 : EllSwiftPubKey() noexcept = default;
304 :
305 : /** Construct a new ellswift public key from a given serialization. */
306 : EllSwiftPubKey(Span<const std::byte> ellswift) noexcept;
307 :
308 : /** Decode to normal compressed CPubKey (for debugging purposes). */
309 : CPubKey Decode() const;
310 :
311 : // Read-only access for serialization.
312 0 : const std::byte* data() const { return m_pubkey.data(); }
313 0 : static constexpr size_t size() { return SIZE; }
314 0 : auto begin() const { return m_pubkey.cbegin(); }
315 0 : auto end() const { return m_pubkey.cend(); }
316 :
317 0 : bool friend operator==(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
318 : {
319 0 : return a.m_pubkey == b.m_pubkey;
320 : }
321 :
322 0 : bool friend operator!=(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
323 : {
324 0 : return a.m_pubkey != b.m_pubkey;
325 : }
326 : };
327 :
328 : struct CExtPubKey {
329 : unsigned char version[4];
330 : unsigned char nDepth;
331 : unsigned char vchFingerprint[4];
332 : unsigned int nChild;
333 : ChainCode chaincode;
334 : CPubKey pubkey;
335 :
336 0 : friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
337 : {
338 0 : return a.nDepth == b.nDepth &&
339 0 : memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
340 0 : a.nChild == b.nChild &&
341 0 : a.chaincode == b.chaincode &&
342 0 : a.pubkey == b.pubkey;
343 : }
344 :
345 0 : friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
346 : {
347 0 : return !(a == b);
348 : }
349 :
350 0 : friend bool operator<(const CExtPubKey &a, const CExtPubKey &b)
351 : {
352 0 : if (a.pubkey < b.pubkey) {
353 0 : return true;
354 0 : } else if (a.pubkey > b.pubkey) {
355 0 : return false;
356 : }
357 0 : return a.chaincode < b.chaincode;
358 0 : }
359 :
360 : void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
361 : void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
362 : void EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const;
363 : void DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]);
364 : [[nodiscard]] bool Derive(CExtPubKey& out, unsigned int nChild) const;
365 : };
366 :
367 : #endif // BITCOIN_PUBKEY_H
|