<p>The sighash for BIP342 script path spends is different from that of BIP341 key path spends.</p>
<p>From <a href="https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#signature-validation" rel="noreferrer">https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#signature-validation</a>:</p>
<blockquote>
<p>If the sig is 64 bytes long, return Verify(p, hash<sub>TapSighash</sub>(0x00 || SigMsg(0x00, 1) || ext), sig), where Verify is defined in BIP340.</p>
</blockquote>
<p>Note the <code>ext_flag</code> passed to <code>SigMsg</code> is 1 (unlike the 0 in the case of key path spends), and also note the <code>ext</code> appended to it, defined in the section above.</p>

CC BY-SA 4.0
2023-05-14T20:02:14.577Z
2023-05-14T20:02:14.577Z
Pieter Wuille
<p>I am trying to implement a script-path spend on taproot, where the 1 script is a 1 of 2 multisig (yes I know this isn't the most efficient way of achieving this outcome).</p>
<p>I can get the key-path to work correctly, and I have calculated all of the tagged hashes correctly, but I still get <code>error code: -26 error message: non-mandatory-script-verify-flag (Invalid Schnorr signature)</code>.</p>
<p>My Schnorr signature is correct and is validated, and corresponds to one of the keys in the multisig (when I try the other key I get same error). I suspect the problem lies in either the multisig script implementation, or the sighash construction.</p>
<p>My multisig is as follows: <code>&lt;32-byte pubkey1&gt; OP_CHECKSIG &lt;32-byte pubkey2&gt; OP_CHECKSIGADD 1 OP_NUMEQUAL</code>, a.k.a <code>&lt;20&gt; &lt;32 bytes&gt; &lt;ac&gt; &lt;20&gt; &lt;32 bytes&gt; &lt;ba&gt; &lt;51&gt; &lt;9c&gt;</code></p>
<p>My sighash is the following (with little endianness where appropriate):
<code>epoch + hash_type + version + nlocktime + #sha_prevouts + #sha_amounts +#sha_scriptpubkeys + #sha_sequences+ #sha_outputs + spend_type + input_index</code></p>
<p>Where <code>epoch = &quot;00&quot;, hash_type = &quot;00&quot;, spend_type = &quot;00&quot; and input_index = &quot;00000000&quot;</code>.
I am formatting and concatenating the SHA preimages correctly (including the script byte lengths), and this sighash format has worked for key path spends in the past. Everything hashes out correctly (there is no witness program hash mismatch).</p>
<p>My control block is: <code>c0 + internal_pubkey</code> and unlocking script is: <code>&quot;00&quot; + &quot;40&quot; + schnorr_sig + &lt;len script&gt; + &lt;script&gt; + &lt;len control block&gt; + control_block</code>. I wasn't sure if the &quot;00&quot; should go before or after the first sig, but with script execution it makes sense to put &quot;00&quot; first in case where I sign with first pubkey (although I've tried both ways unsuccessfully).</p>
<p>Given my validated signature (which does match to the 1 of 2 multisig), seemingly correct sighash etc., I'm at a loss of what I could be doing wrong. Any assistance is greatly appreciated. Below is the sighash, TapSighash, signature and final raw transaction respectively:</p>
<p>Sighash:
<code>0000010000000000000099f39068ebcfd1d34e63d3bd1159c8237d5d086343c06408cdbc79180695e8c73e1f6dbf626619317d04b24ac25799871709e0f3e35cc0e05dae4da21bc5a162e3c29eaa90352e63931c83366d585cc64019da58c9cd8dd2f43062702153d6b9bf906cd362964d265fdb27547a75d2ad2ce86cccec49cdc613764a77dc5f149d993b3cce8dcc00523357f17a52fcc5fecbe39fea83829dda4bdf453fb3d056300000000000</code></p>
<p>TapSighash:
<code>0aea7f6f399744d65b9b8077c2f1431b14a78db43bd9659f6c1afd65a912dfdc</code></p>
<p>Schnorr Sig:
<code>ef6ee4c4ec327c61b3455575f4683df36b24b993daccca3328473e1149906f1f929c2707f5f972855935f2b9320538e6999e4bd1b0ad99f86332100a190164e5</code></p>
<p>Raw Tx:
<code>01000000000101c9612f1a4436eae322feecf68ef3318f87c3ce375c09b1d257c7621e5997f5df0000000000fffffffe0218150000000000002251203ea692bfe06ac9956836045a73b0184644c9d8cdd39734236c4c101c59676ce658020000000000001976a9148059905a03a8b65b9783037490d629948898054888ac040040ef6ee4c4ec327c61b3455575f4683df36b24b993daccca3328473e1149906f1f929c2707f5f972855935f2b9320538e6999e4bd1b0ad99f86332100a190164e54620de153317307164e7c9918791c7787d9833a3a8201bdff880e631e490cf9a087cac202e936665ba37c601f91a8110d9da29caeb20b4f62c55ef3ae7868bd7a37afa84ba519c21c0b33421b257ea992bc721b71b58449ac6e529318daff80a4b7477abddf829476400000000</code></p>

CC BY-SA 4.0
2023-05-14T18:48:53.613Z
The sighash computation is different for key path and script path spends. Is this what you're missing?
Pieter Wuille
CC BY-SA 4.0
2023-05-14T19:18:08.390Z
@PieterWuille Yes that would be it. Where can I find the sighash computation specification for script path spends? I don't see in the BIPs.
Peter
<taproot><sighash>
Taproot Script Path - Multisig Invalid Schnorr Signature
Peter
# Taproot Script Path - Multisig Invalid Schnorr Signature

(Asked by: username_0 on 2023-05-14)

I am trying to implement a script-path spend on taproot, where the 1 script is a 1 of 2 multisig (yes I know this isn't the most efficient way of achieving this outcome).

I can get the key-path to work correctly, and I have calculated all of the tagged hashes correctly, but I still get `error code: -26 error message: non-mandatory-script-verify-flag (Invalid Schnorr signature)`.

My Schnorr signature is correct and is validated, and corresponds to one of the keys in the multisig (when I try the other key I get same error). I suspect the problem lies in either the multisig script implementation, or the sighash construction.

My multisig is as follows: `<32-byte pubkey1> OP_CHECKSIG <32-byte pubkey2> OP_CHECKSIGADD 1 OP_NUMEQUAL`, a.k.a `<20> <32 bytes> <ac> <20> <32 bytes> <ba> <51> <9c>`

My sighash is the following (with little endianness where appropriate):
`epoch + hash_type + version + nlocktime + #sha_prevouts + #sha_amounts +#sha_scriptpubkeys + #sha_sequences+ #sha_outputs + spend_type + input_index`

Where `epoch = "00", hash_type = "00", spend_type = "00" and input_index = "00000000"`.
I am formatting and concatenating the SHA preimages correctly (including the script byte lengths), and this sighash format has worked for key path spends in the past. Everything hashes out correctly (there is no witness program hash mismatch).

My control block is: `c0 + internal_pubkey` and unlocking script is: `"00" + "40" + schnorr_sig + <len script> + <script> + <len control block> + control_block`. I wasn't sure if the "00" should go before or after the first sig, but with script execution it makes sense to put "00" first in case where I sign with first pubkey (although I've tried both ways unsuccessfully).

Given my validated signature (which does match to the 1 of 2 multisig), seemingly correct sighash etc., I'm at a loss of what I could be doing wrong. Any assistance is greatly appreciated. Below is the sighash, TapSighash, signature and final raw transaction respectively:

Sighash:
`0000010000000000000099f39068ebcfd1d34e63d3bd1159c8237d5d086343c06408cdbc79180695e8c73e1f6dbf626619317d04b24ac25799871709e0f3e35cc0e05dae4da21bc5a162e3c29eaa90352e63931c83366d585cc64019da58c9cd8dd2f43062702153d6b9bf906cd362964d265fdb27547a75d2ad2ce86cccec49cdc613764a77dc5f149d993b3cce8dcc00523357f17a52fcc5fecbe39fea83829dda4bdf453fb3d056300000000000`

TapSighash:
`0aea7f6f399744d65b9b8077c2f1431b14a78db43bd9659f6c1afd65a912dfdc`

Schnorr Sig:
`ef6ee4c4ec327c61b3455575f4683df36b24b993daccca3328473e1149906f1f929c2707f5f972855935f2b9320538e6999e4bd1b0ad99f86332100a190164e5`

Raw Tx:
`01000000000101c9612f1a4436eae322feecf68ef3318f87c3ce375c09b1d257c7621e5997f5df0000000000fffffffe0218150000000000002251203ea692bfe06ac9956836045a73b0184644c9d8cdd39734236c4c101c59676ce658020000000000001976a9148059905a03a8b65b9783037490d629948898054888ac040040ef6ee4c4ec327c61b3455575f4683df36b24b993daccca3328473e1149906f1f929c2707f5f972855935f2b9320538e6999e4bd1b0ad99f86332100a190164e54620de153317307164e7c9918791c7787d9833a3a8201bdff880e631e490cf9a087cac202e936665ba37c601f91a8110d9da29caeb20b4f62c55ef3ae7868bd7a37afa84ba519c21c0b33421b257ea992bc721b71b58449ac6e529318daff80a4b7477abddf829476400000000`

**Tags:** taproot, sighash

> **Comments:**
> **username_1**: The sighash computation is different for key path and script path spends. Is this what you're missing?  
> **username_0**: @username_1 Yes that would be it. Where can I find the sighash computation specification for script path spends? I don't see in the BIPs.  

---

## 1 answers

### Answer by username_1 on 2023-05-14. Score: 5 | Accepted answer

The sighash for BIP342 script path spends is different from that of BIP341 key path spends.

From <https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#signature-validation>:

> If the sig is 64 bytes long, return Verify(p, hashTapSighash(0x00 || SigMsg(0x00, 1) || ext), sig), where Verify is defined in BIP340.

Note the `ext_flag` passed to `SigMsg` is 1 (unlike the 0 in the case of key path spends), and also note the `ext` appended to it, defined in the section above.


---

