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