diff options
Diffstat (limited to 'src/pubkey.h')
-rw-r--r-- | src/pubkey.h | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/src/pubkey.h b/src/pubkey.h index 12514fc3c9..eec34a89c2 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -12,7 +12,8 @@ #include <span.h> #include <uint256.h> -#include <stdexcept> +#include <cstring> +#include <optional> #include <vector> const unsigned int BIP32_EXTKEY_SIZE = 74; @@ -101,7 +102,7 @@ public: } //! Construct a public key from a byte vector. - explicit CPubKey(const std::vector<unsigned char>& _vch) + explicit CPubKey(Span<const uint8_t> _vch) { Set(_vch.begin(), _vch.end()); } @@ -222,19 +223,60 @@ private: uint256 m_keydata; public: + /** Construct an empty x-only pubkey. */ + XOnlyPubKey() = default; + + XOnlyPubKey(const XOnlyPubKey&) = default; + XOnlyPubKey& operator=(const XOnlyPubKey&) = default; + + /** Determine if this pubkey is fully valid. This is true for approximately 50% of all + * possible 32-byte arrays. If false, VerifySchnorr and CreatePayToContract will always + * fail. */ + bool IsFullyValid() const; + + /** Test whether this is the 0 key (the result of default construction). This implies + * !IsFullyValid(). */ + bool IsNull() const { return m_keydata.IsNull(); } + /** Construct an x-only pubkey from exactly 32 bytes. */ explicit XOnlyPubKey(Span<const unsigned char> bytes); + /** Construct an x-only pubkey from a normal pubkey. */ + explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span<const unsigned char>(pubkey.begin() + 1, pubkey.begin() + 33)) {} + /** Verify a Schnorr signature against this public key. * * sigbytes must be exactly 64 bytes. */ bool VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const; - bool CheckPayToContract(const XOnlyPubKey& base, const uint256& hash, bool parity) const; + + /** Compute the Taproot tweak as specified in BIP341, with *this as internal + * key: + * - if merkle_root == nullptr: H_TapTweak(xonly_pubkey) + * - otherwise: H_TapTweak(xonly_pubkey || *merkle_root) + * + * Note that the behavior of this function with merkle_root != nullptr is + * consensus critical. + */ + uint256 ComputeTapTweakHash(const uint256* merkle_root) const; + + /** Verify that this is a Taproot tweaked output point, against a specified internal key, + * Merkle root, and parity. */ + bool CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const; + + /** Construct a Taproot tweaked output point with this point as internal key. */ + std::optional<std::pair<XOnlyPubKey, bool>> CreateTapTweak(const uint256* merkle_root) const; const unsigned char& operator[](int pos) const { return *(m_keydata.begin() + pos); } const unsigned char* data() const { return m_keydata.begin(); } - size_t size() const { return m_keydata.size(); } + static constexpr size_t size() { return decltype(m_keydata)::size(); } + const unsigned char* begin() const { return m_keydata.begin(); } + const unsigned char* end() const { return m_keydata.end(); } + unsigned char* begin() { return m_keydata.begin(); } + unsigned char* end() { return m_keydata.end(); } + bool operator==(const XOnlyPubKey& other) const { return m_keydata == other.m_keydata; } + bool operator!=(const XOnlyPubKey& other) const { return m_keydata != other.m_keydata; } + bool operator<(const XOnlyPubKey& other) const { return m_keydata < other.m_keydata; } }; struct CExtPubKey { @@ -247,7 +289,7 @@ struct CExtPubKey { friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) { return a.nDepth == b.nDepth && - memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], sizeof(vchFingerprint)) == 0 && + memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 && a.nChild == b.nChild && a.chaincode == b.chaincode && a.pubkey == b.pubkey; @@ -274,4 +316,10 @@ public: ~ECCVerifyHandle(); }; +typedef struct secp256k1_context_struct secp256k1_context; + +/** Access to the internal secp256k1 context used for verification. Only intended to be used + * by key.cpp. */ +const secp256k1_context* GetVerifyContext(); + #endif // BITCOIN_PUBKEY_H |