I've been working through the static test vectors provided by bitcoin core to implement an interpreter.

Some surprising behavior I found was that in the case of OP_CHECKSIGADD, if an invalid signature is found, the interpreter fails execution rather than continuing. Why is this the case?

In my (likely naive) mental model, it seems that an incorrect signature should not increment the counter on the stack and continue execution.


This is the test case that triggers the behavior i'm talking about

    "tx": "020000000342dbdd00df8ddb7968f88bd7c899d66c3007e19d1c71ddba2274f9e900c0cefa82010000006edc7db5db38e3ab6ba99b0b810400a211882152d27173c6a7945a40fe23b7924bff77cf6c0000000092d3c19742dbdd00df8ddb7968f88bd7c899d66c3007e19d1c71ddba2274f9e900c0cefa6101000000a1ea36c301b2d549000000000017a9142177f6af7e86b98028c5e4dd4a82d80f1c6492c7876f818b44",
    "prevouts": ["69cd3300000000001976a91410fa7d1c37dc119ceef9b79ec2d4abe7445c468188ac", "1d6a7600000000002251203b1c3f3adebc2e153ec7d8063cf0f2bb534171c554c0e969269a2f02dddd03f4", "1f49370000000000225120281511f00d3c3de3d36983e73a04295adb745511db699ce19d0d5331754dadf8"],
    "comment": "siglen/invalid_csa_neg",
    "final": true,
    //omit success as it isn't necessary
    "failure": {
      "scriptSig": "",
      "witness": [

2 Answers 2


Invalid signatures generally abort execution in BIP342, because of batch validation, as batch validation has no mechanism for figuring out which signature checks were invalid - only whether or not all are valid or not. Batch validation is not implemented anywhere AFAIK, but BIP340-342 are designed to support it, and thus must reject anything invalid to prevent a consensus failure once it is rolled out.

If you want a signature to not be counted (whether through OP_CHECKSIG or OP_CHECKSIGADD), the signature needs to be exactly equal to the empty string. If an empty string is provided as signature, it is treated as an intentionally missing signature, and counted as 0. But if you provide an actual signature, it must be valid.

  • Assuming batch validation wasn't a consideration it would be a trade-off between malleability (Andrew's answer) and flexibility/forgiveness (allowing a participant in the threshold sig to make a mistake and it not impact the validity of the transaction as long as there were enough valid signatures)? Just trying to understand if malleability was a serious factor in the design decision or not. Jul 12, 2022 at 12:30
  • 3
    Yeah, I think the malleability argument is also a sufficient, albeit weaker, reason to disallow invalid non-empty signatures (and one that can to some extent be addressed using standardness rules too). It's just generally a cleaner design IMO, allowing more easy reasoning about which signatures are intended to be valid. Jul 12, 2022 at 14:13

One reason is to prevent malleability, which affects the weight of the transaction, and therefore the feerate. The only valid options for OP_CHECKSIGADD are the empty vector, or a valid signature. So the signature must be valid, or intentionally empty. Otherwise, a third party could choose any of the signatures which are intentionally empty or invalid, replace it with junk, and the script could still pass. This junk could be longer than the empty vector, and depending on the possible rules in this scenario, could be variable length, longer or shorter than a valid signature, which would affect the weight, and thus affect the feerate.

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.