Skip to content

Commit 3592e09

Browse files
jbridesucildossj
authored andcommitted
P2TSH: adding additional script verification tests that verify correct
witness program and parity bit. Credit to: https://github.com/billymcbip
1 parent a151918 commit 3592e09

File tree

5 files changed

+91
-0
lines changed

5 files changed

+91
-0
lines changed

src/script/interpreter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,6 +2406,11 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
24062406
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
24072407
}
24082408
execdata.m_tapleaf_hash_init = true;
2409+
// Check for P2TSH-specific parity requirement (must be 0xc1 for Tapscript)
2410+
if ((control[0] & TAPROOT_LEAF_MASK) == TAPROOT_LEAF_TAPSCRIPT &&
2411+
control[0] != P2TSH_LEAF_TAPSCRIPT) {
2412+
return set_error(serror, SCRIPT_ERR_P2TSH_WRONG_PARITY_BIT);
2413+
}
24092414
if (control[0] == P2TSH_LEAF_TAPSCRIPT) {
24102415
// Tapscript (leaf version 0xc1 since parity is always 1)
24112416
exec_script = CScript(script.begin(), script.end());

src/script/script_error.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ std::string ScriptErrorString(const ScriptError serror)
123123
return "Signature is found in scriptCode";
124124
case SCRIPT_ERR_P2TSH_WRONG_CONTROL_SIZE:
125125
return "Invalid P2TSH control block size";
126+
case SCRIPT_ERR_P2TSH_WRONG_PARITY_BIT:
127+
return "P2TSH leaf must use parity bit 1 (0xc1)";
126128
case SCRIPT_ERR_UNKNOWN_ERROR:
127129
case SCRIPT_ERR_ERROR_COUNT:
128130
default: break;

src/script/script_error.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ typedef enum ScriptError_t
8585

8686
/* P2TSH */
8787
SCRIPT_ERR_P2TSH_WRONG_CONTROL_SIZE,
88+
SCRIPT_ERR_P2TSH_WRONG_PARITY_BIT,
8889

8990
/* Constant scriptCode */
9091
SCRIPT_ERR_OP_CODESEPARATOR,

src/test/data/script_tests.json

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,6 +2668,87 @@
26682668
"TAPSCRIPT Test that DROP operations do not execute inside of a false IF conditional"
26692669
],
26702670

2671+
["P2TSH tests"],
2672+
[
2673+
[
2674+
"aa",
2675+
"bb",
2676+
"87",
2677+
"c1",
2678+
0.00000001
2679+
],
2680+
"",
2681+
"0x52 0x20 0x7e04991706edb31549f786fa7113bb857ceb26174f7d08e9efa91decf13324a0",
2682+
"P2SH,WITNESS,TAPROOT",
2683+
"OK",
2684+
"P2TSH: Simple negative OP_EQUAL test pre-activation"
2685+
],
2686+
[
2687+
[
2688+
"aa",
2689+
"bb",
2690+
"87",
2691+
"c1",
2692+
0.00000001
2693+
],
2694+
"",
2695+
"0x52 0x20 0x7e04991706edb31549f786fa7113bb857ceb26174f7d08e9efa91decf13324a0",
2696+
"P2SH,WITNESS,TAPROOT,P2TSH",
2697+
"EVAL_FALSE",
2698+
"P2TSH: Simple negative OP_EQUAL test post-activation"
2699+
],
2700+
[
2701+
[
2702+
"aa",
2703+
"aa",
2704+
"87",
2705+
"c1",
2706+
0.00000001
2707+
],
2708+
"",
2709+
"0x52 0x20 0x7e04991706edb31549f786fa7113bb857ceb26174f7d08e9efa91decf13324a0",
2710+
"P2SH,WITNESS,TAPROOT,P2TSH",
2711+
"OK",
2712+
"P2TSH: Simple positive OP_EQUAL test post-activation"
2713+
],
2714+
[
2715+
[
2716+
"aa",
2717+
0.00000001
2718+
],
2719+
"",
2720+
"0x52 0x20 0x7e04991706edb31549f786fa7113bb857ceb26174f7d08e9efa91decf13324a0",
2721+
"P2SH,WITNESS,TAPROOT,P2TSH",
2722+
"WITNESS_PROGRAM_MISMATCH",
2723+
"P2TSH: Key path spending not supported"
2724+
],
2725+
[
2726+
[
2727+
"aa",
2728+
"aa",
2729+
0.00000001
2730+
],
2731+
"",
2732+
"0x52 0x20 0x7e04991706edb31549f786fa7113bb857ceb26174f7d08e9efa91decf13324a0",
2733+
"P2SH,WITNESS,TAPROOT,P2TSH",
2734+
"WITNESS_PROGRAM_MISMATCH",
2735+
"P2TSH: Witness program mismatch"
2736+
],
2737+
[
2738+
[
2739+
"aa",
2740+
"aa",
2741+
"87",
2742+
"c0",
2743+
0.00000001
2744+
],
2745+
"",
2746+
"0x52 0x20 0x7e04991706edb31549f786fa7113bb857ceb26174f7d08e9efa91decf13324a0",
2747+
"P2SH,WITNESS,TAPROOT,P2TSH",
2748+
"P2TSH_WRONG_PARITY_BIT",
2749+
"P2TSH: Wrong parity bit"
2750+
],
2751+
26712752
["NULLFAIL should cover all signatures and signatures only"],
26722753
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66 and NULLFAIL-compliant"],
26732754
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"],

src/test/script_tests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ static ScriptErrorDesc script_errors[]={
9393
{SCRIPT_ERR_WITNESS_PUBKEYTYPE, "WITNESS_PUBKEYTYPE"},
9494
{SCRIPT_ERR_OP_CODESEPARATOR, "OP_CODESEPARATOR"},
9595
{SCRIPT_ERR_SIG_FINDANDDELETE, "SIG_FINDANDDELETE"},
96+
{SCRIPT_ERR_P2TSH_WRONG_CONTROL_SIZE, "P2TSH_WRONG_CONTROL_SIZE"},
97+
{SCRIPT_ERR_P2TSH_WRONG_PARITY_BIT, "P2TSH_WRONG_PARITY_BIT"},
9698
};
9799

98100
static std::string FormatScriptError(ScriptError_t err)

0 commit comments

Comments
 (0)