<p>You've correctly described three of the benefits:</p>
<ul>
<li>OP_CHECKMULTISIG is inefficient, since it performs up to as many signature checks as there are public keys. OP_CHECKSIGADD always performs one check per signature, since unused public keys are required to be paired with an empty witness item and are skipped.</li>
<li>Fixing the dummy stack item bug. This was partially addressed in <a href="https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki" rel="nofollow noreferrer">BIP147</a> by requiring it to be an empty vector, which removed malleability, but since OP_CHECKSIGADD is a new opcode it can just not reimplement the bug.</li>
<li>Schnorr signatures, whose benefits are too many to describe here.</li>
</ul>
<p>There are other benefits:</p>
<ul>
<li>One other weakness of OP_CHECKMULTISIG is that it only allows up to 20 public keys. OP_CHECKSIGADD is limited to 999 public keys, as that runs into the stack limit. See for example <a href="https://mempool.space/tx/7393096d97bfee8660f4100ffd61874d62f9a65de9fb6acf740c4c386990ef73" rel="nofollow noreferrer">this</a> transaction whose input has a 998-of-999 multisig script.</li>
<li>OP_CHECKMULTISIG is incompatible with batch verification, which was the primary motivation for introducing OP_CHECKSIGADD (and disabling OP_CHECKMULTISIG[VERIFY] in Tapscript).</li>
<li>Tapscript doesn't contribute to the global sigop limit, instead allocating a sigop budget per script based on its size. This makes blocks easier to construct for miners, as optimizing for both weight and sigops is a hard optimization problem (specifically the multidimensional knapsack problem).</li>
</ul>

CC BY-SA 4.0
2023-11-24T18:25:52.530Z
All of these benefits are correct, but the direct motivation is something else: the "retrying" behavior of needing to figure out which signature corresponds to which key is incompatible with batch validation - a design goal of BIP341/342. That's why BIP342 didn't just add `OP_CHECKSIGADD` but also **disable** `OP_CHECKMULTISIG[VERIFY]`.
Pieter Wuille
CC BY-SA 4.0
2023-11-24T18:32:01.400Z
@PieterWuille Thanks, I've updated the answer.
Vojtěch Strnad
CC BY-SA 4.0
2023-11-24T18:32:27.613Z
Thanks, just have a question.  You wrote that for `OP_CHECKMULTISIG` it is necessary to perform as many signature checks as there are public keys. So for my example it means that 30 signature check must be performed? Is there any optimization? Like, for example: if you don't find a corresponding public key for the first signature, fail (don't try with others), or (since signatures must be in order) to continue from the public key for which you last found a match and not to always start check from the beggining?
Cosmos
CC BY-SA 4.0
2023-11-24T18:35:10.450Z
@MudjaAdjum No, at most one check will be performed for every public key. If the check fails, the next public key is checked for the same signature, and the previous public key is never checked again.
Vojtěch Strnad
CC BY-SA 4.0
2023-11-24T18:36:53.853Z
@VojtěchStrnad And for the next signature it continues from the public key it previously stopped (from the public key it found matching signature)?
Cosmos
CC BY-SA 4.0
2023-11-24T18:37:22.630Z
The keys and the signatures must be in the same order, so it's only n checks, not k*n.
Pieter Wuille
CC BY-SA 4.0
2023-11-24T18:39:09.247Z
@PieterWuille So when it finds a matching between some signature and public key, for the next signature it continues from that public key?
Cosmos
CC BY-SA 4.0
2023-11-24T18:40:29.557Z
When a signature check succeeds, it continues with both the next key and the next signature. If a signature check fails, verification with the next key, but stays on the same signature.
Pieter Wuille
CC BY-SA 4.0
2023-11-24T18:11:29.303Z
2023-11-24T18:31:34.397Z
2023-11-24T18:31:34.397Z
Vojtěch Strnad
<p>What are all the benefits of introducing <code>OP_CHECKSIGADD</code> in Taproot instead of <code>OP_CHECKMULTISIG</code>?</p>
<p>I assume the first benefit is the following.</p>
<p>For example, in pre-taproot approach, if we have 3-of-10 multisig with the scriptPubKey:</p>
<pre><code>3 &lt;pub_key1&gt; &lt;pub_key2&gt; &lt;pub_key3&gt; ... &lt;pub_key9&gt; &lt;pub_key10&gt; 10 OP_CHECKMULTISIG
</code></pre>
<p>and the scriptSig (or witness stack for segWit 1):</p>
<pre><code>0 &lt;signature 5&gt; &lt;signature 8&gt; &lt;signature 10&gt;
</code></pre>
<p>the problem is that for every signature in witness data check must be done over all public keys in scriptPubKey (e.g. <code>&lt;signature 5&gt;</code> must be checked for all public keys up to 5th public key where they match; same for &lt;signature 8&gt; and &lt;signature 10&gt;). <strong>Therefore, there are a lot of unnecessary checks.</strong></p>
<p>This does not exist with <code>OP_CHECKSIGADD</code> because there is a direct check between the signature and the public key and if they match, OP_CHECKSIGAD increments the counter on the stack by 1.</p>
<p>That is the first benefit.</p>
<p>Second benefit is that a bug with one additional element that must be passed to <code>OP_CHECKMULTISIG</code> in order to it work has been removed.</p>
<p>Third is that <code>OP_CHECKSIG</code>/<code>OP_CHECKSIGVERITY</code> and <code>OP_CHECKSIGADD</code> now work with Schnorr instead of ECDSA.</p>
<ol>
<li>Am I right for these three benefits?</li>
<li>Are there any other benefits?</li>
</ol>

CC BY-SA 4.0
2023-11-27T18:55:33.783Z
The signatures for a `OP_CHECKMULTISIG` must be provided in the same order as the public keys, and each key may only sign once. So in your example, the validation process would check `<signature 5>` against pub_key1 through pub_key5, then `<signature 8>` against pub_key6–pub_key8, and finally `<signature 10>` against pub_key9 and pub_key10, rather than needing to start over with pub_key1 for the latter two.
Murch
<script><multi-signature><taproot>
What are the all benefits/advantages of OP_CHECKSIGADD over OP_CHECKMULTISIG?
Cosmos
# What are the all benefits/advantages of OP_CHECKSIGADD over OP_CHECKMULTISIG?

(Asked by: username_0 on 2023-11-24)

What are all the benefits of introducing `OP_CHECKSIGADD` in Taproot instead of `OP_CHECKMULTISIG`?

I assume the first benefit is the following.

For example, in pre-taproot approach, if we have 3-of-10 multisig with the scriptPubKey:

```
3 <pub_key1> <pub_key2> <pub_key3> ... <pub_key9> <pub_key10> 10 OP_CHECKMULTISIG

```

and the scriptSig (or witness stack for segWit 1):

```
0 <signature 5> <signature 8> <signature 10>

```

the problem is that for every signature in witness data check must be done over all public keys in scriptPubKey (e.g. `<signature 5>` must be checked for all public keys up to 5th public key where they match; same for <signature 8> and <signature 10>). **Therefore, there are a lot of unnecessary checks.**

This does not exist with `OP_CHECKSIGADD` because there is a direct check between the signature and the public key and if they match, OP\_CHECKSIGAD increments the counter on the stack by 1.

That is the first benefit.

Second benefit is that a bug with one additional element that must be passed to `OP_CHECKMULTISIG` in order to it work has been removed.

Third is that `OP_CHECKSIG`/`OP_CHECKSIGVERITY` and `OP_CHECKSIGADD` now work with Schnorr instead of ECDSA.

1. Am I right for these three benefits?
2. Are there any other benefits?

**Tags:** script, multi-signature, taproot

> **Comments:**
> **username_1**: The signatures for a `OP_CHECKMULTISIG` must be provided in the same order as the public keys, and each key may only sign once. So in your example, the validation process would check `<signature 5>` against pub_key1 through pub_key5, then `<signature 8>` against pub_key6–pub_key8, and finally `<signature 10>` against pub_key9 and pub_key10, rather than needing to start over with pub_key1 for the latter two.  

---

## 1 answers

### Answer by username_2 on 2023-11-24. Score: 1 | Accepted answer

You've correctly described three of the benefits:

* OP\_CHECKMULTISIG is inefficient, since it performs up to as many signature checks as there are public keys. OP\_CHECKSIGADD always performs one check per signature, since unused public keys are required to be paired with an empty witness item and are skipped.
* Fixing the dummy stack item bug. This was partially addressed in [BIP147](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki) by requiring it to be an empty vector, which removed malleability, but since OP\_CHECKSIGADD is a new opcode it can just not reimplement the bug.
* Schnorr signatures, whose benefits are too many to describe here.

There are other benefits:

* One other weakness of OP\_CHECKMULTISIG is that it only allows up to 20 public keys. OP\_CHECKSIGADD is limited to 999 public keys, as that runs into the stack limit. See for example [this](https://mempool.space/tx/7393096d97bfee8660f4100ffd61874d62f9a65de9fb6acf740c4c386990ef73) transaction whose input has a 998-of-999 multisig script.
* OP\_CHECKMULTISIG is incompatible with batch verification, which was the primary motivation for introducing OP\_CHECKSIGADD (and disabling OP\_CHECKMULTISIG[VERIFY] in Tapscript).
* Tapscript doesn't contribute to the global sigop limit, instead allocating a sigop budget per script based on its size. This makes blocks easier to construct for miners, as optimizing for both weight and sigops is a hard optimization problem (specifically the multidimensional knapsack problem).

> **Comments:**
> **username_3**: All of these benefits are correct, but the direct motivation is something else: the "retrying" behavior of needing to figure out which signature corresponds to which key is incompatible with batch validation - a design goal of BIP341/342. That's why BIP342 didn't just add `OP_CHECKSIGADD` but also **disable** `OP_CHECKMULTISIG[VERIFY]`.  
> **username_2**: @username_3 Thanks, I've updated the answer.  
> **username_0**: Thanks, just have a question.  You wrote that for `OP_CHECKMULTISIG` it is necessary to perform as many signature checks as there are public keys. So for my example it means that 30 signature check must be performed? Is there any optimization? Like, for example: if you don't find a corresponding public key for the first signature, fail (don't try with others), or (since signatures must be in order) to continue from the public key for which you last found a match and not to always start check from the beggining?  
> **username_2**: @MudjaAdjum No, at most one check will be performed for every public key. If the check fails, the next public key is checked for the same signature, and the previous public key is never checked again.  
> **username_0**: @username_2 And for the next signature it continues from the public key it previously stopped (from the public key it found matching signature)?  
> **username_3**: The keys and the signatures must be in the same order, so it's only n checks, not k*n.  
> **username_0**: @username_3 So when it finds a matching between some signature and public key, for the next signature it continues from that public key?  
> **username_3**: When a signature check succeeds, it continues with both the next key and the next signature. If a signature check fails, verification with the next key, but stays on the same signature.  

---

