| 225 | }; |
| 226 | |
| 227 | class XOnlyPubKey |
| 228 | { |
| 229 | private: |
| 230 | uint256 m_keydata; |
| 231 | |
| 232 | public: |
| 233 | /** Construct an empty x-only pubkey. */ |
| 234 | XOnlyPubKey() = default; |
| 235 | |
| 236 | XOnlyPubKey(const XOnlyPubKey&) = default; |
| 237 | XOnlyPubKey& operator=(const XOnlyPubKey&) = default; |
| 238 | |
| 239 | /** Determine if this pubkey is fully valid. This is true for approximately 50% of all |
| 240 | * possible 32-byte arrays. If false, VerifySchnorr, CheckTapTweak and CreateTapTweak |
| 241 | * will always fail. */ |
| 242 | bool IsFullyValid() const; |
| 243 | |
| 244 | /** Test whether this is the 0 key (the result of default construction). This implies |
| 245 | * !IsFullyValid(). */ |
| 246 | bool IsNull() const { return m_keydata.IsNull(); } |
| 247 | |
| 248 | /** Construct an x-only pubkey from exactly 32 bytes. */ |
| 249 | explicit XOnlyPubKey(Span<const unsigned char> bytes); |
| 250 | |
| 251 | /** Construct an x-only pubkey from a normal pubkey. */ |
| 252 | explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span{pubkey}.subspan(1, 32)) {} |
| 253 | |
| 254 | /** Verify a Schnorr signature against this public key. |
| 255 | * |
| 256 | * sigbytes must be exactly 64 bytes. |
| 257 | */ |
| 258 | bool VerifySchnorr(const Span<const unsigned char> msg, Span<const unsigned char> sigbytes) const; |
| 259 | |
| 260 | // ELEMENTS: this is preserved from an old version of the Taproot code for use in OP_TWEAKVERIFY |
| 261 | bool CheckPayToContract(const XOnlyPubKey& base, const uint256& hash, bool parity) const; |
| 262 | |
| 263 | /** Compute the Taproot tweak as specified in BIP341, with *this as internal |
| 264 | * key: |
| 265 | * - if merkle_root == nullptr: H_TapTweak(xonly_pubkey) |
| 266 | * - otherwise: H_TapTweak(xonly_pubkey || *merkle_root) |
| 267 | * |
| 268 | * Note that the behavior of this function with merkle_root != nullptr is |
| 269 | * consensus critical. |
| 270 | */ |
| 271 | uint256 ComputeTapTweakHash(const uint256* merkle_root) const; |
| 272 | |
| 273 | /** Verify that this is a Taproot tweaked output point, against a specified internal key, |
| 274 | * Merkle root, and parity. */ |
| 275 | bool CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const; |
| 276 | |
| 277 | /** Construct a Taproot tweaked output point with this point as internal key. */ |
| 278 | std::optional<std::pair<XOnlyPubKey, bool>> CreateTapTweak(const uint256* merkle_root) const; |
| 279 | |
| 280 | /** Returns a list of CKeyIDs for the CPubKeys that could have been used to create this XOnlyPubKey. |
| 281 | * This is needed for key lookups since keys are indexed by CKeyID. |
| 282 | */ |
| 283 | std::vector<CKeyID> GetKeyIDs() const; |
| 284 | |