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

  • 2
    The sighash computation is different for key path and script path spends. Is this what you're missing? Commented May 14, 2023 at 18:48
  • 1
    @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
    Commented May 14, 2023 at 19:18

1 Answer 1


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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.