aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter@wuille.net>2021-05-23 18:32:30 -0700
committerPieter Wuille <pieter@wuille.net>2021-05-24 12:14:16 -0700
commit5f6cc8daa83700d1c949d968a5cf0d935be337b7 (patch)
treea07dcd19162977dd995f9a96d66bcaa2273db343
parent2fbfb1becb3c0c109cd7c30b245b51da22039932 (diff)
downloadbitcoin-5f6cc8daa83700d1c949d968a5cf0d935be337b7.tar.xz
Add XOnlyPubKey::CreateTapTweak
-rw-r--r--src/pubkey.cpp18
-rw-r--r--src/pubkey.h4
2 files changed, 22 insertions, 0 deletions
diff --git a/src/pubkey.cpp b/src/pubkey.cpp
index f78779c182..8382897f95 100644
--- a/src/pubkey.cpp
+++ b/src/pubkey.cpp
@@ -209,6 +209,24 @@ bool XOnlyPubKey::CheckTapTweak(const XOnlyPubKey& internal, const uint256& merk
return secp256k1_xonly_pubkey_tweak_add_check(secp256k1_context_verify, m_keydata.begin(), parity, &internal_key, tweak.begin());
}
+std::optional<std::pair<XOnlyPubKey, bool>> XOnlyPubKey::CreateTapTweak(const uint256* merkle_root) const
+{
+ secp256k1_xonly_pubkey base_point;
+ if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &base_point, data())) return std::nullopt;
+ secp256k1_pubkey out;
+ uint256 tweak = ComputeTapTweakHash(merkle_root);
+ if (!secp256k1_xonly_pubkey_tweak_add(secp256k1_context_verify, &out, &base_point, tweak.data())) return std::nullopt;
+ int parity = -1;
+ std::pair<XOnlyPubKey, bool> ret;
+ secp256k1_xonly_pubkey out_xonly;
+ if (!secp256k1_xonly_pubkey_from_pubkey(secp256k1_context_verify, &out_xonly, &parity, &out)) return std::nullopt;
+ secp256k1_xonly_pubkey_serialize(secp256k1_context_verify, ret.first.begin(), &out_xonly);
+ assert(parity == 0 || parity == 1);
+ ret.second = parity;
+ return ret;
+}
+
+
bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
if (!IsValid())
return false;
diff --git a/src/pubkey.h b/src/pubkey.h
index e5d9d08b52..b9d5f5d622 100644
--- a/src/pubkey.h
+++ b/src/pubkey.h
@@ -13,6 +13,7 @@
#include <uint256.h>
#include <cstring>
+#include <optional>
#include <vector>
const unsigned int BIP32_EXTKEY_SIZE = 74;
@@ -251,6 +252,9 @@ public:
* 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(); }
static constexpr size_t size() { return decltype(m_keydata)::size(); }