Branch data 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 : 458680 : CKeyID() : uint160() {}
# 27 : 5894800 : 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 : : unsigned int static GetLen(unsigned char chHeader)
# 61 : 21552658 : {
# 62 [ + + ][ + + ]: 21552658 : if (chHeader == 2 || chHeader == 3)
# 63 : 21494548 : return COMPRESSED_SIZE;
# 64 [ + + ][ + + ]: 58110 : if (chHeader == 4 || chHeader == 6 || chHeader == 7)
# [ + + ]
# 65 : 18992 : return SIZE;
# 66 : 39118 : return 0;
# 67 : 58110 : }
# 68 : :
# 69 : : //! Set this key data to be invalid
# 70 : : void Invalidate()
# 71 : 4220810 : {
# 72 : 4220810 : vch[0] = 0xFF;
# 73 : 4220810 : }
# 74 : :
# 75 : : public:
# 76 : :
# 77 : 26924 : bool static ValidSize(const std::vector<unsigned char> &vch) {
# 78 [ + + ][ + + ]: 26924 : return vch.size() > 0 && GetLen(vch[0]) == vch.size();
# 79 : 26924 : }
# 80 : :
# 81 : : //! Construct an invalid public key.
# 82 : : CPubKey()
# 83 : 4201588 : {
# 84 : 4201588 : Invalidate();
# 85 : 4201588 : }
# 86 : :
# 87 : : //! Initialize a public key using begin/end iterators to byte data.
# 88 : : template <typename T>
# 89 : : void Set(const T pbegin, const T pend)
# 90 : 1689852 : {
# 91 [ - + ][ - + ]: 1689852 : int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
# [ + + ][ - + ]
# 92 [ + - ][ + + ]: 1689852 : if (len && len == (pend - pbegin))
# [ + + ][ + - ]
# [ + - ][ + - ]
# [ + + ][ + - ]
# 93 : 1670737 : memcpy(vch, (unsigned char*)&pbegin[0], len);
# 94 : 19115 : else
# 95 : 19115 : Invalidate();
# 96 : 1689852 : }
# 97 : :
# 98 : : //! Construct a public key using begin/end iterators to byte data.
# 99 : : template <typename T>
# 100 : : CPubKey(const T pbegin, const T pend)
# 101 : 2134 : {
# 102 : 2134 : Set(pbegin, pend);
# 103 : 2134 : }
# 104 : :
# 105 : : //! Construct a public key from a byte vector.
# 106 : : explicit CPubKey(Span<const uint8_t> _vch)
# 107 : 386380 : {
# 108 : 386380 : Set(_vch.begin(), _vch.end());
# 109 : 386380 : }
# 110 : :
# 111 : : //! Simple read-only vector-like interface to the pubkey data.
# 112 : 19838311 : unsigned int size() const { return GetLen(vch[0]); }
# 113 : 1736618 : const unsigned char* data() const { return vch; }
# 114 : 1897350 : const unsigned char* begin() const { return vch; }
# 115 : 165078 : const unsigned char* end() const { return vch + size(); }
# 116 : 42080 : const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
# 117 : :
# 118 : : //! Comparator implementation.
# 119 : : friend bool operator==(const CPubKey& a, const CPubKey& b)
# 120 : 6519 : {
# 121 [ + - ]: 6519 : return a.vch[0] == b.vch[0] &&
# 122 [ + - ]: 6519 : memcmp(a.vch, b.vch, a.size()) == 0;
# 123 : 6519 : }
# 124 : : friend bool operator!=(const CPubKey& a, const CPubKey& b)
# 125 : 0 : {
# 126 : 0 : return !(a == b);
# 127 : 0 : }
# 128 : : friend bool operator<(const CPubKey& a, const CPubKey& b)
# 129 : 10028787 : {
# 130 [ + + ]: 10028787 : return a.vch[0] < b.vch[0] ||
# 131 [ + + ][ + + ]: 10028787 : (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
# 132 : 10028787 : }
# 133 : : friend bool operator>(const CPubKey& a, const CPubKey& b)
# 134 : 2 : {
# 135 [ - + ]: 2 : return a.vch[0] > b.vch[0] ||
# 136 [ + - ][ + - ]: 2 : (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) > 0);
# 137 : 2 : }
# 138 : :
# 139 : : //! Implement serialization, as if this was a byte vector.
# 140 : : template <typename Stream>
# 141 : : void Serialize(Stream& s) const
# 142 : 19000 : {
# 143 : 19000 : unsigned int len = size();
# 144 : 19000 : ::WriteCompactSize(s, len);
# 145 : 19000 : s << Span{vch, len};
# 146 : 19000 : }
# 147 : : template <typename Stream>
# 148 : : void Unserialize(Stream& s)
# 149 : 21760 : {
# 150 : 21760 : const unsigned int len(::ReadCompactSize(s));
# 151 [ + - ][ + - ]: 21760 : if (len <= SIZE) {
# 152 : 21760 : s >> Span{vch, len};
# 153 [ + + ][ - + ]: 21760 : if (len != size()) {
# 154 : 12 : Invalidate();
# 155 : 12 : }
# 156 : 21760 : } else {
# 157 : : // invalid pubkey, skip available data
# 158 : 0 : s.ignore(len);
# 159 : 0 : Invalidate();
# 160 : 0 : }
# 161 : 21760 : }
# 162 : :
# 163 : : //! Get the KeyID of this public key (hash of its serialization)
# 164 : : CKeyID GetID() const
# 165 : 5547867 : {
# 166 : 5547867 : return CKeyID(Hash160(Span{vch}.first(size())));
# 167 : 5547867 : }
# 168 : :
# 169 : : //! Get the 256-bit hash of this public key.
# 170 : : uint256 GetHash() const
# 171 : 8202 : {
# 172 : 8202 : return Hash(Span{vch}.first(size()));
# 173 : 8202 : }
# 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 : : bool IsValid() const
# 190 : 1233655 : {
# 191 : 1233655 : return size() > 0;
# 192 : 1233655 : }
# 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 : 47310 : {
# 200 : 47310 : return size() == COMPRESSED_SIZE;
# 201 : 47310 : }
# 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 : 1219938 : 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 : 31400 : 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 : 1130479 : 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 : 0 : const unsigned char& operator[](int pos) const { return *(m_keydata.begin() + pos); }
# 280 : 189735 : const unsigned char* data() const { return m_keydata.begin(); }
# 281 : 14148 : static constexpr size_t size() { return decltype(m_keydata)::size(); }
# 282 : 1291740 : const unsigned char* begin() const { return m_keydata.begin(); }
# 283 : 1291740 : const unsigned char* end() const { return m_keydata.end(); }
# 284 : 149829 : unsigned char* begin() { return m_keydata.begin(); }
# 285 : 8 : unsigned char* end() { return m_keydata.end(); }
# 286 : 0 : bool operator==(const XOnlyPubKey& other) const { return m_keydata == other.m_keydata; }
# 287 : 3897 : bool operator!=(const XOnlyPubKey& other) const { return m_keydata != other.m_keydata; }
# 288 : 376131 : 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 : 6865 : 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 : 493694 : const std::byte* data() const { return m_pubkey.data(); }
# 313 : 2416370 : static constexpr size_t size() { return SIZE; }
# 314 : 340200 : auto begin() const { return m_pubkey.cbegin(); }
# 315 : 340200 : auto end() const { return m_pubkey.cend(); }
# 316 : :
# 317 : : bool friend operator==(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
# 318 : 196 : {
# 319 : 196 : return a.m_pubkey == b.m_pubkey;
# 320 : 196 : }
# 321 : :
# 322 : : bool friend operator!=(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
# 323 : 0 : {
# 324 : 0 : return a.m_pubkey != b.m_pubkey;
# 325 : 0 : }
# 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 : : friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
# 337 : 60 : {
# 338 [ + - ]: 60 : return a.nDepth == b.nDepth &&
# 339 [ + - ]: 60 : memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
# 340 [ + - ]: 60 : a.nChild == b.nChild &&
# 341 [ + - ]: 60 : a.chaincode == b.chaincode &&
# 342 [ + - ]: 60 : a.pubkey == b.pubkey;
# 343 : 60 : }
# 344 : :
# 345 : : friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
# 346 : 6 : {
# 347 : 6 : return !(a == b);
# 348 : 6 : }
# 349 : :
# 350 : : friend bool operator<(const CExtPubKey &a, const CExtPubKey &b)
# 351 : 4 : {
# 352 [ + + ]: 4 : if (a.pubkey < b.pubkey) {
# 353 : 2 : return true;
# 354 [ + - ]: 2 : } else if (a.pubkey > b.pubkey) {
# 355 : 2 : return false;
# 356 : 2 : }
# 357 : 0 : return a.chaincode < b.chaincode;
# 358 : 4 : }
# 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
|