1111#include < script/signingprovider.h>
1212#include < script/standard.h>
1313#include < uint256.h>
14+ #include < util/vector.h>
1415
1516typedef std::vector<unsigned char > valtype;
1617
@@ -30,6 +31,8 @@ MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMu
3031
3132bool MutableTransactionSignatureCreator::CreateSig (const SigningProvider& provider, std::vector<unsigned char >& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
3233{
34+ assert (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0);
35+
3336 CKey key;
3437 if (!provider.GetKey (address, key))
3538 return false ;
@@ -48,6 +51,51 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid
4851 return true ;
4952}
5053
54+ bool MutableTransactionSignatureCreator::CreateSchnorrSig (const SigningProvider& provider, std::vector<unsigned char >& sig, const XOnlyPubKey& pubkey, const uint256* leaf_hash, const uint256* merkle_root, SigVersion sigversion) const
55+ {
56+ assert (sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT);
57+
58+ CKey key;
59+ {
60+ // For now, use the old full pubkey-based key derivation logic. As it indexed by
61+ // Hash160(full pubkey), we need to try both a version prefixed with 0x02, and one
62+ // with 0x03.
63+ unsigned char b[33 ] = {0x02 };
64+ std::copy (pubkey.begin (), pubkey.end (), b + 1 );
65+ CPubKey fullpubkey;
66+ fullpubkey.Set (b, b + 33 );
67+ CKeyID keyid = fullpubkey.GetID ();
68+ if (!provider.GetKey (keyid, key)) {
69+ b[0 ] = 0x03 ;
70+ fullpubkey.Set (b, b + 33 );
71+ CKeyID keyid = fullpubkey.GetID ();
72+ if (!provider.GetKey (keyid, key)) return false ;
73+ }
74+ }
75+
76+ // BIP341/BIP342 signing needs lots of precomputed transaction data. While some
77+ // (non-SIGHASH_DEFAULT) sighash modes exist that can work with just some subset
78+ // of data present, for now, only support signing when everything is provided.
79+ if (!m_txdata || !m_txdata->m_bip341_taproot_ready || !m_txdata->m_spent_outputs_ready ) return false ;
80+
81+ ScriptExecutionData execdata;
82+ execdata.m_annex_init = true ;
83+ execdata.m_annex_present = false ; // Only support annex-less signing for now.
84+ if (sigversion == SigVersion::TAPSCRIPT) {
85+ execdata.m_codeseparator_pos_init = true ;
86+ execdata.m_codeseparator_pos = 0xFFFFFFFF ; // Only support non-OP_CODESEPARATOR BIP342 signing for now.
87+ if (!leaf_hash) return false ; // BIP342 signing needs leaf hash.
88+ execdata.m_tapleaf_hash_init = true ;
89+ execdata.m_tapleaf_hash = *leaf_hash;
90+ }
91+ uint256 hash;
92+ if (!SignatureHashSchnorr (hash, execdata, *txTo, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false ;
93+ sig.resize (64 );
94+ if (!key.SignSchnorr (hash, sig, merkle_root, nullptr )) return false ;
95+ if (nHashType) sig.push_back (nHashType);
96+ return true ;
97+ }
98+
5199static bool GetCScript (const SigningProvider& provider, const SignatureData& sigdata, const CScriptID& scriptid, CScript& script)
52100{
53101 if (provider.GetCScript (scriptid, script)) {
@@ -104,6 +152,86 @@ static bool CreateSig(const BaseSignatureCreator& creator, SignatureData& sigdat
104152 return false ;
105153}
106154
155+ static bool CreateTaprootScriptSig (const BaseSignatureCreator& creator, SignatureData& sigdata, const SigningProvider& provider, std::vector<unsigned char >& sig_out, const XOnlyPubKey& pubkey, const uint256& leaf_hash, SigVersion sigversion)
156+ {
157+ auto lookup_key = std::make_pair (pubkey, leaf_hash);
158+ auto it = sigdata.taproot_script_sigs .find (lookup_key);
159+ if (it != sigdata.taproot_script_sigs .end ()) {
160+ sig_out = it->second ;
161+ }
162+ if (creator.CreateSchnorrSig (provider, sig_out, pubkey, &leaf_hash, nullptr , sigversion)) {
163+ sigdata.taproot_script_sigs [lookup_key] = sig_out;
164+ return true ;
165+ }
166+ return false ;
167+ }
168+
169+ static bool SignTaprootScript (const SigningProvider& provider, const BaseSignatureCreator& creator, SignatureData& sigdata, int leaf_version, const CScript& script, std::vector<valtype>& result)
170+ {
171+ // Only BIP342 tapscript signing is supported for now.
172+ if (leaf_version != TAPROOT_LEAF_TAPSCRIPT) return false ;
173+ SigVersion sigversion = SigVersion::TAPSCRIPT;
174+
175+ uint256 leaf_hash = (CHashWriter (HASHER_TAPLEAF) << uint8_t (leaf_version) << script).GetSHA256 ();
176+
177+ // <xonly pubkey> OP_CHECKSIG
178+ if (script.size () == 34 && script[33 ] == OP_CHECKSIG && script[0 ] == 0x20 ) {
179+ XOnlyPubKey pubkey (MakeSpan (script).subspan (1 , 32 ));
180+ std::vector<unsigned char > sig;
181+ if (CreateTaprootScriptSig (creator, sigdata, provider, sig, pubkey, leaf_hash, sigversion)) {
182+ result = Vector (std::move (sig));
183+ return true ;
184+ }
185+ }
186+
187+ return false ;
188+ }
189+
190+ static bool SignTaproot (const SigningProvider& provider, const BaseSignatureCreator& creator, const WitnessV1Taproot& output, SignatureData& sigdata, std::vector<valtype>& result)
191+ {
192+ TaprootSpendData spenddata;
193+
194+ // Gather information about this output.
195+ if (provider.GetTaprootSpendData (output, spenddata)) {
196+ sigdata.tr_spenddata .Merge (spenddata);
197+ }
198+
199+ // Try key path spending.
200+ {
201+ std::vector<unsigned char > sig;
202+ if (sigdata.taproot_key_path_sig .size () == 0 ) {
203+ if (creator.CreateSchnorrSig (provider, sig, spenddata.internal_key , nullptr , &spenddata.merkle_root , SigVersion::TAPROOT)) {
204+ sigdata.taproot_key_path_sig = sig;
205+ }
206+ }
207+ if (sigdata.taproot_key_path_sig .size ()) {
208+ result = Vector (sigdata.taproot_key_path_sig );
209+ return true ;
210+ }
211+ }
212+
213+ // Try script path spending.
214+ std::vector<std::vector<unsigned char >> smallest_result_stack;
215+ for (const auto & [key, control_blocks] : sigdata.tr_spenddata .scripts ) {
216+ const auto & [script, leaf_ver] = key;
217+ std::vector<std::vector<unsigned char >> result_stack;
218+ if (SignTaprootScript (provider, creator, sigdata, leaf_ver, script, result_stack)) {
219+ result_stack.emplace_back (std::begin (script), std::end (script)); // Push the script
220+ result_stack.push_back (*control_blocks.begin ()); // Push the smallest control block
221+ if (smallest_result_stack.size () == 0 ||
222+ GetSerializeSize (result_stack, PROTOCOL_VERSION) < GetSerializeSize (smallest_result_stack, PROTOCOL_VERSION)) {
223+ smallest_result_stack = std::move (result_stack);
224+ }
225+ }
226+ }
227+ if (smallest_result_stack.size () != 0 ) {
228+ result = std::move (smallest_result_stack);
229+ return true ;
230+ }
231+
232+ return false ;
233+ }
234+
107235/* *
108236 * Sign scriptPubKey using signature made with creator.
109237 * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
@@ -125,7 +253,6 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
125253 case TxoutType::NONSTANDARD:
126254 case TxoutType::NULL_DATA:
127255 case TxoutType::WITNESS_UNKNOWN:
128- case TxoutType::WITNESS_V1_TAPROOT:
129256 return false ;
130257 case TxoutType::PUBKEY:
131258 if (!CreateSig (creator, sigdata, provider, sig, CPubKey (vSolutions[0 ]), scriptPubKey, sigversion)) return false ;
@@ -187,6 +314,9 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
187314 // Could not find witnessScript, add to missing
188315 sigdata.missing_witness_script = uint256 (vSolutions[0 ]);
189316 return false ;
317+
318+ case TxoutType::WITNESS_V1_TAPROOT:
319+ return SignTaproot (provider, creator, WitnessV1Taproot (XOnlyPubKey{vSolutions[0 ]}), sigdata, ret);
190320 } // no default case, so the compiler can warn about missing cases
191321 assert (false );
192322}
@@ -249,6 +379,12 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
249379 sigdata.scriptWitness .stack = result;
250380 sigdata.witness = true ;
251381 result.clear ();
382+ } else if (whichType == TxoutType::WITNESS_V1_TAPROOT && !P2SH) {
383+ sigdata.witness = true ;
384+ if (solved) {
385+ sigdata.scriptWitness .stack = std::move (result);
386+ }
387+ result.clear ();
252388 } else if (solved && whichType == TxoutType::WITNESS_UNKNOWN) {
253389 sigdata.witness = true ;
254390 }
@@ -414,6 +550,7 @@ class DummySignatureChecker final : public BaseSignatureChecker
414550public:
415551 DummySignatureChecker () {}
416552 bool CheckECDSASignature (const std::vector<unsigned char >& scriptSig, const std::vector<unsigned char >& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true ; }
553+ bool CheckSchnorrSignature (Span<const unsigned char > sig, Span<const unsigned char > pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror) const override { return true ; }
417554};
418555const DummySignatureChecker DUMMY_CHECKER;
419556
@@ -439,6 +576,11 @@ class DummySignatureCreator final : public BaseSignatureCreator {
439576 vchSig[6 + m_r_len + m_s_len] = SIGHASH_ALL;
440577 return true ;
441578 }
579+ bool CreateSchnorrSig (const SigningProvider& provider, std::vector<unsigned char >& sig, const XOnlyPubKey& pubkey, const uint256* leaf_hash, const uint256* tweak, SigVersion sigversion) const override
580+ {
581+ sig.assign (64 , ' \000 ' );
582+ return true ;
583+ }
442584};
443585
444586}
0 commit comments