Use sCrypt to implement Accumulator Multi Sig (Accumulator Multi Sig) contract

Recently, a hacker exploited a loophole in ElectrumSV’s newly launched cumulative multi-signature feature to steal a large amount of Bitcoin. We analyzed this attack and made some suggestions on how to reduce such attacks in the future.

background

In 2019, nChain introduced cumulative multi-signature to replace P2SH-based multi-signature. The P2SH function has been removed when Genesis was upgraded. It does not use P2SH to achieve the same security and privacy as multi-signature.

In ElectrumSV's cumulative multi-signature implementation, the last opcode OP_LESSTHANOREQUAL may be wrongly used as OP_GREATERTHANOREQUAL due to the negligence of the order of operation objects on the stack . This means that instead of requiring at least m of the n signatures to unlock the output, it becomes a maximum of m signatures to unlock. The attacker took advantage of this vulnerability, provided 0 valid signatures, bypassed the signature requirements, and stole 600 bitcoins .

Suggestions to reduce risk

One way to reduce risk is to use high-level languages ​​(such as sCrypt) to implement important contracts instead of the original Bitcoin script. As we have learned from this unfortunate incident, even if you are a Bitcoin script master, it is easy to make mistakes directly in script development. The cumulative multi-signature is implemented in sCrypt as follows, and the bug is more likely to be checked out, because it is easier to find whether the last line should use >= or <=.

contract AccumulatorMultiSig {
    
    
    int threshold;
    Ripemd160[3] pubKeyHashs;

    public function main(PubKey[3] pubKeys, Sig[3] sigs, bool[3] masks) {
    
    
        int total = 0;
        int i = 0;

        loop (3) {
    
    
            if (masks[i]) {
    
    
                if (hash160(pubKeys[i]) == this.pubKeyHashs[i] && checkSig(sigs[i], pubKeys[i])) {
    
    
                    total = total + 1;
                }
            }

            i = i + 1;
        }

        require(total >= this.threshold);
    }
}

sCrypt has another method to help catch these bugs, and test and run the script verification engine (also known as the Bitcoin virtual machine ) natively . Because Bitcoin smart contracts are pure functions and stateless (compared to non-pure functions and stateful smart contracts on other blockchains such as Ethereum), the effect of these tests is equivalent to the verification effect of the miner on the script, so it can Catch bugs earlier, even before contract deployment !

Guess you like

Origin blog.csdn.net/freedomhero/article/details/109715917