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
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: