@@ -342,13 +342,10 @@ class ConditionStack {
342
342
};
343
343
}
344
344
345
- /* * Helper for OP_CHECKSIG and OP_CHECKSIGVERIFY
346
- *
347
- * A return value of false means the script fails entirely. When true is returned, the
348
- * fSuccess variable indicates whether the signature check itself succeeded.
349
- */
350
- static bool EvalChecksig (const valtype& vchSig, const valtype& vchPubKey, CScript::const_iterator pbegincodehash, CScript::const_iterator pend, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool & fSuccess )
345
+ static bool EvalChecksigPreTapscript (const valtype& vchSig, const valtype& vchPubKey, CScript::const_iterator pbegincodehash, CScript::const_iterator pend, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool & fSuccess )
351
346
{
347
+ assert (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0);
348
+
352
349
// Subset of script starting at the most recent codeseparator
353
350
CScript scriptCode (pbegincodehash, pend);
354
351
@@ -371,6 +368,66 @@ static bool EvalChecksig(const valtype& vchSig, const valtype& vchPubKey, CScrip
371
368
return true ;
372
369
}
373
370
371
+ static bool EvalChecksigTapscript (const valtype& sig, const valtype& pubkey, ScriptExecutionData& execdata, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool & success)
372
+ {
373
+ assert (sigversion == SigVersion::TAPSCRIPT);
374
+
375
+ /*
376
+ * The following validation sequence is consensus critical. Please note how --
377
+ * upgradable public key versions precede other rules;
378
+ * the script execution fails when using empty signature with invalid public key;
379
+ * the script execution fails when using non-empty invalid signature.
380
+ */
381
+ success = !sig.empty ();
382
+ if (success) {
383
+ // Implement the sigops/witnesssize ratio test.
384
+ // Passing with an upgradable public key version is also counted.
385
+ assert (execdata.m_validation_weight_left_init );
386
+ execdata.m_validation_weight_left -= VALIDATION_WEIGHT_PER_SIGOP_PASSED;
387
+ if (execdata.m_validation_weight_left < 0 ) {
388
+ return set_error (serror, SCRIPT_ERR_TAPSCRIPT_VALIDATION_WEIGHT);
389
+ }
390
+ }
391
+ if (pubkey.size () == 0 ) {
392
+ return set_error (serror, SCRIPT_ERR_PUBKEYTYPE);
393
+ } else if (pubkey.size () == 32 ) {
394
+ if (success && !checker.CheckSchnorrSignature (sig, pubkey, sigversion, execdata)) {
395
+ return set_error (serror, SCRIPT_ERR_SIG_NULLFAIL);
396
+ }
397
+ } else {
398
+ /*
399
+ * New public key version softforks should be defined before this `else` block.
400
+ * Generally, the new code should not do anything but failing the script execution. To avoid
401
+ * consensus bugs, it should not modify any existing values (including success).
402
+ */
403
+ if ((flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE) != 0 ) {
404
+ return set_error (serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_PUBKEYTYPE);
405
+ }
406
+ }
407
+
408
+ return true ;
409
+ }
410
+
411
+ /* * Helper for OP_CHECKSIG, OP_CHECKSIGVERIFY, and (in Tapscript) OP_CHECKSIGADD.
412
+ *
413
+ * A return value of false means the script fails entirely. When true is returned, the
414
+ * fSuccess variable indicates whether the signature check itself succeeded.
415
+ */
416
+ static bool EvalChecksig (const valtype& sig, const valtype& pubkey, CScript::const_iterator pbegincodehash, CScript::const_iterator pend, ScriptExecutionData& execdata, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool & success)
417
+ {
418
+ switch (sigversion) {
419
+ case SigVersion::BASE:
420
+ case SigVersion::WITNESS_V0:
421
+ return EvalChecksigPreTapscript (sig, pubkey, pbegincodehash, pend, flags, checker, sigversion, serror, success);
422
+ case SigVersion::TAPSCRIPT:
423
+ return EvalChecksigTapscript (sig, pubkey, execdata, flags, checker, sigversion, serror, success);
424
+ case SigVersion::TAPROOT:
425
+ // Key path spending in Taproot has no script, so this is unreachable.
426
+ break ;
427
+ }
428
+ assert (false );
429
+ }
430
+
374
431
bool EvalScript (std::vector<std::vector<unsigned char > >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror)
375
432
{
376
433
static const CScriptNum bnZero (0 );
@@ -381,6 +438,9 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
381
438
// static const valtype vchZero(0);
382
439
static const valtype vchTrue (1 , 1 );
383
440
441
+ // sigversion cannot be TAPROOT here, as it admits no script execution.
442
+ assert (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0 || sigversion == SigVersion::TAPSCRIPT);
443
+
384
444
CScript::const_iterator pc = script.begin ();
385
445
CScript::const_iterator pend = script.end ();
386
446
CScript::const_iterator pbegincodehash = script.begin ();
@@ -389,15 +449,18 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
389
449
ConditionStack vfExec;
390
450
std::vector<valtype> altstack;
391
451
set_error (serror, SCRIPT_ERR_UNKNOWN_ERROR);
392
- if (script.size () > MAX_SCRIPT_SIZE)
452
+ if ((sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0) && script.size () > MAX_SCRIPT_SIZE) {
393
453
return set_error (serror, SCRIPT_ERR_SCRIPT_SIZE);
454
+ }
394
455
int nOpCount = 0 ;
395
456
bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0 ;
457
+ uint32_t opcode_pos = 0 ;
458
+ execdata.m_codeseparator_pos = 0xFFFFFFFFUL ;
459
+ execdata.m_codeseparator_pos_init = true ;
396
460
397
461
try
398
462
{
399
- while (pc < pend)
400
- {
463
+ for (; pc < pend; ++opcode_pos) {
401
464
bool fExec = vfExec.all_true ();
402
465
403
466
//
@@ -408,9 +471,12 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
408
471
if (vchPushValue.size () > MAX_SCRIPT_ELEMENT_SIZE)
409
472
return set_error (serror, SCRIPT_ERR_PUSH_SIZE);
410
473
411
- // Note how OP_RESERVED does not count towards the opcode limit.
412
- if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT)
413
- return set_error (serror, SCRIPT_ERR_OP_COUNT);
474
+ if (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0) {
475
+ // Note how OP_RESERVED does not count towards the opcode limit.
476
+ if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) {
477
+ return set_error (serror, SCRIPT_ERR_OP_COUNT);
478
+ }
479
+ }
414
480
415
481
if (opcode == OP_CAT ||
416
482
opcode == OP_SUBSTR ||
@@ -568,6 +634,15 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
568
634
if (stack.size () < 1 )
569
635
return set_error (serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
570
636
valtype& vch = stacktop (-1 );
637
+ // Tapscript requires minimal IF/NOTIF inputs as a consensus rule.
638
+ if (sigversion == SigVersion::TAPSCRIPT) {
639
+ // The input argument to the OP_IF and OP_NOTIF opcodes must be either
640
+ // exactly 0 (the empty vector) or exactly 1 (the one-byte vector with value 1).
641
+ if (vch.size () > 1 || (vch.size () == 1 && vch[0 ] != 1 )) {
642
+ return set_error (serror, SCRIPT_ERR_TAPSCRIPT_MINIMALIF);
643
+ }
644
+ }
645
+ // Under witness v0 rules it is only a policy rule, enabled through SCRIPT_VERIFY_MINIMALIF.
571
646
if (sigversion == SigVersion::WITNESS_V0 && (flags & SCRIPT_VERIFY_MINIMALIF)) {
572
647
if (vch.size () > 1 )
573
648
return set_error (serror, SCRIPT_ERR_MINIMALIF);
@@ -1001,6 +1076,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
1001
1076
1002
1077
// Hash starts after the code separator
1003
1078
pbegincodehash = pc;
1079
+ execdata.m_codeseparator_pos = opcode_pos;
1004
1080
}
1005
1081
break ;
1006
1082
@@ -1015,7 +1091,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
1015
1091
valtype& vchPubKey = stacktop (-1 );
1016
1092
1017
1093
bool fSuccess = true ;
1018
- if (!EvalChecksig (vchSig, vchPubKey, pbegincodehash, pend, flags, checker, sigversion, serror, fSuccess )) return false ;
1094
+ if (!EvalChecksig (vchSig, vchPubKey, pbegincodehash, pend, execdata, flags, checker, sigversion, serror, fSuccess )) return false ;
1019
1095
popstack (stack);
1020
1096
popstack (stack);
1021
1097
stack.push_back (fSuccess ? vchTrue : vchFalse);
@@ -1029,9 +1105,32 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
1029
1105
}
1030
1106
break ;
1031
1107
1108
+ case OP_CHECKSIGADD:
1109
+ {
1110
+ // OP_CHECKSIGADD is only available in Tapscript
1111
+ if (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0) return set_error (serror, SCRIPT_ERR_BAD_OPCODE);
1112
+
1113
+ // (sig num pubkey -- num)
1114
+ if (stack.size () < 3 ) return set_error (serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
1115
+
1116
+ const valtype& sig = stacktop (-3 );
1117
+ const CScriptNum num (stacktop (-2 ), fRequireMinimal );
1118
+ const valtype& pubkey = stacktop (-1 );
1119
+
1120
+ bool success = true ;
1121
+ if (!EvalChecksig (sig, pubkey, pbegincodehash, pend, execdata, flags, checker, sigversion, serror, success)) return false ;
1122
+ popstack (stack);
1123
+ popstack (stack);
1124
+ popstack (stack);
1125
+ stack.push_back ((num + (success ? 1 : 0 )).getvch ());
1126
+ }
1127
+ break ;
1128
+
1032
1129
case OP_CHECKMULTISIG:
1033
1130
case OP_CHECKMULTISIGVERIFY:
1034
1131
{
1132
+ if (sigversion == SigVersion::TAPSCRIPT) return set_error (serror, SCRIPT_ERR_TAPSCRIPT_CHECKMULTISIG);
1133
+
1035
1134
// ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
1036
1135
1037
1136
int i = 1 ;
@@ -1390,13 +1489,16 @@ static const CHashWriter HASHER_TAPBRANCH = TaggedHash("TapBranch");
1390
1489
static const CHashWriter HASHER_TAPTWEAK = TaggedHash(" TapTweak" );
1391
1490
1392
1491
template <typename T>
1393
- bool SignatureHashSchnorr (uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache)
1492
+ bool SignatureHashSchnorr (uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, uint8_t key_version, const PrecomputedTransactionData& cache)
1394
1493
{
1395
1494
uint8_t ext_flag;
1396
1495
switch (sigversion) {
1397
1496
case SigVersion::TAPROOT:
1398
1497
ext_flag = 0 ;
1399
1498
break ;
1499
+ case SigVersion::TAPSCRIPT:
1500
+ ext_flag = 1 ;
1501
+ break ;
1400
1502
default :
1401
1503
assert (false );
1402
1504
}
@@ -1452,6 +1554,18 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata
1452
1554
ss << sha_single_output.GetSHA256 ();
1453
1555
}
1454
1556
1557
+ // Additional data for BIP 342 signatures
1558
+ if (sigversion == SigVersion::TAPSCRIPT) {
1559
+ assert (execdata.m_tapleaf_hash_init );
1560
+ ss << execdata.m_tapleaf_hash ;
1561
+ // Key_version must be 0 for now, representing the current version of
1562
+ // public keys in the tapscript signature opcode execution.
1563
+ assert (key_version == 0 );
1564
+ ss << key_version;
1565
+ assert (execdata.m_codeseparator_pos_init );
1566
+ ss << execdata.m_codeseparator_pos ;
1567
+ }
1568
+
1455
1569
hash_out = ss.GetSHA256 ();
1456
1570
return true ;
1457
1571
}
@@ -1561,9 +1675,13 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
1561
1675
template <class T >
1562
1676
bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const unsigned char > sig, Span<const unsigned char > pubkey_in, SigVersion sigversion, const ScriptExecutionData& execdata) const
1563
1677
{
1564
- assert (sigversion == SigVersion::TAPROOT);
1678
+ assert (sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT );
1565
1679
// Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this.
1566
1680
assert (pubkey_in.size () == 32 );
1681
+ // Note that in Tapscript evaluation, empty signatures are treated specially (invalid signature that does not
1682
+ // abort script execution). This is implemented in EvalChecksigTapscript, which won't invoke
1683
+ // CheckSchnorrSignature in that case. In other contexts, they are invalid like every other signature with
1684
+ // size different from 64 or 65.
1567
1685
if (sig.size () != 64 && sig.size () != 65 ) return false ;
1568
1686
1569
1687
XOnlyPubKey pubkey{pubkey_in};
@@ -1575,7 +1693,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const uns
1575
1693
}
1576
1694
uint256 sighash;
1577
1695
assert (this ->txdata );
1578
- if (!SignatureHashSchnorr (sighash, execdata, *txTo, nIn, hashtype, sigversion, *this ->txdata )) return false ;
1696
+ if (!SignatureHashSchnorr (sighash, execdata, *txTo, nIn, hashtype, sigversion, /* key_version */ 0x00 , *this ->txdata )) return false ;
1579
1697
return VerifySchnorrSignature (sig, pubkey, sighash);
1580
1698
}
1581
1699
@@ -1671,6 +1789,30 @@ static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CS
1671
1789
{
1672
1790
std::vector<valtype> stack{stack_span.begin (), stack_span.end ()};
1673
1791
1792
+ if (sigversion == SigVersion::TAPSCRIPT) {
1793
+ // OP_SUCCESSx processing overrides everything, including stack element size limits
1794
+ CScript::const_iterator pc = scriptPubKey.begin ();
1795
+ while (pc < scriptPubKey.end ()) {
1796
+ opcodetype opcode;
1797
+ if (!scriptPubKey.GetOp (pc, opcode)) {
1798
+ // Note how this condition would not be reached if an unknown OP_SUCCESSx was found
1799
+ return set_error (serror, SCRIPT_ERR_BAD_OPCODE);
1800
+ }
1801
+ // New opcodes will be listed here. May use a different sigversion to modify existing opcodes.
1802
+ if (IsOpSuccess (opcode)) {
1803
+ if (flags & SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS) {
1804
+ return set_error (serror, SCRIPT_ERR_DISCOURAGE_OP_SUCCESS);
1805
+ }
1806
+ return set_success (serror);
1807
+ }
1808
+ }
1809
+
1810
+ // Tapscript enforces initial stack size limits (altstack is empty here)
1811
+ if (stack.size () > MAX_STACK_SIZE) {
1812
+ return set_error (serror, SCRIPT_ERR_STACK_SIZE);
1813
+ }
1814
+ }
1815
+
1674
1816
// Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack
1675
1817
for (const valtype& elem : stack) {
1676
1818
if (elem.size () > MAX_SCRIPT_ELEMENT_SIZE) return set_error (serror, SCRIPT_ERR_PUSH_SIZE);
@@ -1685,12 +1827,13 @@ static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CS
1685
1827
return true ;
1686
1828
}
1687
1829
1688
- static bool VerifyTaprootCommitment (const std::vector<unsigned char >& control, const std::vector<unsigned char >& program, const CScript& script)
1830
+ static bool VerifyTaprootCommitment (const std::vector<unsigned char >& control, const std::vector<unsigned char >& program, const CScript& script, uint256* tapleaf_hash )
1689
1831
{
1690
1832
const int path_len = (control.size () - TAPROOT_CONTROL_BASE_SIZE) / TAPROOT_CONTROL_NODE_SIZE;
1691
1833
const XOnlyPubKey p{uint256 (std::vector<unsigned char >(control.begin () + 1 , control.begin () + TAPROOT_CONTROL_BASE_SIZE))};
1692
1834
const XOnlyPubKey q{uint256 (program)};
1693
1835
uint256 k = (CHashWriter (HASHER_TAPLEAF) << uint8_t (control[0 ] & TAPROOT_LEAF_MASK) << script).GetSHA256 ();
1836
+ if (tapleaf_hash) *tapleaf_hash = k;
1694
1837
for (int i = 0 ; i < path_len; ++i) {
1695
1838
CHashWriter ss_branch{HASHER_TAPBRANCH};
1696
1839
Span<const unsigned char > node (control.data () + TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * i, TAPROOT_CONTROL_NODE_SIZE);
@@ -1762,9 +1905,16 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
1762
1905
if (control.size () < TAPROOT_CONTROL_BASE_SIZE || control.size () > TAPROOT_CONTROL_MAX_SIZE || ((control.size () - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE) != 0 ) {
1763
1906
return set_error (serror, SCRIPT_ERR_TAPROOT_WRONG_CONTROL_SIZE);
1764
1907
}
1765
- if (!VerifyTaprootCommitment (control, program, exec_script)) {
1908
+ if (!VerifyTaprootCommitment (control, program, exec_script, &execdata. m_tapleaf_hash )) {
1766
1909
return set_error (serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
1767
1910
}
1911
+ execdata.m_tapleaf_hash_init = true ;
1912
+ if ((control[0 ] & TAPROOT_LEAF_MASK) == TAPROOT_LEAF_TAPSCRIPT) {
1913
+ // Tapscript (leaf version 0xc0)
1914
+ execdata.m_validation_weight_left = ::GetSerializeSize (witness.stack , PROTOCOL_VERSION) + VALIDATION_WEIGHT_OFFSET;
1915
+ execdata.m_validation_weight_left_init = true ;
1916
+ return ExecuteWitnessScript (stack, exec_script, flags, SigVersion::TAPSCRIPT, checker, execdata, serror);
1917
+ }
1768
1918
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION) {
1769
1919
return set_error (serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION);
1770
1920
}
0 commit comments