<p>Each transaction has a certain number of "sigops", the number of signature validation script ops like OP_CHECKSIG in its scripts. These script ops are very expensive to compute. Transactions with too many sigops are considered non-standard and will not be relayed by most clients. Blocks with too many sigops in their transactions are illegal and will be rejected entirely.</p>

<p>That exploit allows you to include sigops in transactions without increasing the sigop count. It could be used to create a very slow-to-compute transaction that isn't very big size-wise. Not a huge exploit, and it could be worked around, but it demonstrates an important weakness in BIP 12: OP_EVAL scripts can't be analyzed accurately without running them first.</p>

CC BY-SA 3.0
2012-12-22T18:41:54.000Z
Thank you, I need to learn sigop count and how it's done.... I'm getting the impression the QT client counts operations in a weighted curve.. (OP_CheckSig counts as X operations, and OP_Equal counts as Y operations where X > Y)  Is this correct? Is cost per operation sometimes >1 per operation?
makerofthings7
CC BY-SA 3.0
2012-12-22T21:14:03.063Z
@makerofthings7 Only CHECKSIG and CHECKMULTISIG count. CHECKSIG counts as 1 sigop. CHECKMULTISIG always counts as 20 except inside of a P2SH transaction's hashed script where it usually counts as the number of public keys passed to CHECKMULTISIG.
theymos
CC BY-SA 3.0
2012-12-22T18:17:32.053Z
2012-12-22T18:17:32.053Z
theymos
<p>I understand that BIP12 was withdrawn, and probably because of <a href="https://gist.github.com/1546061" rel="nofollow">this exploit below</a>.  Can someone explain how this attack would have worked and the effect it would have on the network?</p>

<pre><code> for (;;) {
    RAND_bytes(nonce.b, sizeof(nonce));
    RIPEMD160(nonce.b, sizeof(nonce), digest);
    if (
      digest[0] == 174 &amp;&amp; // OP_CHECKMULTISIG
      digest[1] ==  76 &amp;&amp; // OP_PUSHDATA1
      digest[2] ==  16    // 0x16
    ) {
      // We'll print status info on partial hits, just to make things more
      // interesting.
      printf("%llx\n", nonce.i);
      print_hex(digest, 20);

      // Check for full hit
      if (digest[19] == 117) // OP_DROP
        return;
    }
</code></pre>

<script><opcodes>
Can someone explain this [outdated] BIP12 OP_EVAL exploit?
makerofthings7
# Can someone explain this [outdated] BIP12 OP_EVAL exploit?

(Asked by: username_0 on 2012-12-22)

I understand that BIP12 was withdrawn, and probably because of this exploit below.  Can someone explain how this attack would have worked and the effect it would have on the network?
 for (;;) {
    RAND_bytes(nonce.b, sizeof(nonce));
    RIPEMD160(nonce.b, sizeof(nonce), digest);
    if (
      digest[0] == 174 && // OP_CHECKMULTISIG
      digest[1] ==  76 && // OP_PUSHDATA1
      digest[2] ==  16    // 0x16
    ) {
      // We'll print status info on partial hits, just to make things more
      // interesting.
      printf("%llx\n", nonce.i);
      print_hex(digest, 20);

      // Check for full hit
      if (digest[19] == 117) // OP_DROP
        return;
    }

**Tags:** script, opcodes


---

## 1 answers

### Answer by username_1 on 2012-12-22. Score: 4 | Accepted answer

Each transaction has a certain number of "sigops", the number of signature validation script ops like OP\_CHECKSIG in its scripts. These script ops are very expensive to compute. Transactions with too many sigops are considered non-standard and will not be relayed by most clients. Blocks with too many sigops in their transactions are illegal and will be rejected entirely.

That exploit allows you to include sigops in transactions without increasing the sigop count. It could be used to create a very slow-to-compute transaction that isn't very big size-wise. Not a huge exploit, and it could be worked around, but it demonstrates an important weakness in BIP 12: OP\_EVAL scripts can't be analyzed accurately without running them first.

> **Comments:**
> **username_0**: Thank you, I need to learn sigop count and how it's done.... I'm getting the impression the QT client counts operations in a weighted curve.. (OP_CheckSig counts as X operations, and OP_Equal counts as Y operations where X > Y)  Is this correct? Is cost per operation sometimes >1 per operation?  
> **username_1**: @username_0 Only CHECKSIG and CHECKMULTISIG count. CHECKSIG counts as 1 sigop. CHECKMULTISIG always counts as 20 except inside of a P2SH transaction's hashed script where it usually counts as the number of public keys passed to CHECKMULTISIG.  

---

