Many in the crypto-sphere have heard of “transaction malleability” and that it’s “bad”. But, what is “transaction malleability” and why is it bad? Let’s dive into it quickly.
In a cryptocurrency such as Bitcoin, transactions are the atomic operations that transfer value between users. Users create transactions and publish them to the network. Those transactions propagate the network and are eventually mined into the blockchain. The blockchain is used by the recipients to determine if a transaction is confirmed or not.
Now, with millions of transactions flying around, how do users quickly identify them so as to be able to distinguish between them? How can a bunch of disconnected users across the globe quickly and uniquely identify transactions in the same way but without using some slow, global registry system? The answer is simple, you use the cryptographic hash of the transaction as the identifier.
A cryptographic hash allows anyone to derive a fingerprint of any data using only the data itself. The fingerprint is unique and the same every time it is calculated. Even if you change 1 bit of the data, the fingerprint hash is completely changed.
In Bitcoin, the hash of a transaction is called its TXID, and serves as the universally unique identifier for that transaction.
Great, so what is malleability?
Malleability is the ability to change the identifier of a transaction (the TXID) but without invalidating that transaction. Depending on the cryptocurrency, there are many ways this can be done. A common way across all cryptocurrencies is through signature malleability, which is the focus of this article.
Due to how the math of how ECDSA digital signatures work, it’s possible to change a signature but without invalidating it. Whilst this doesn’t permit forgeries of those signatures, it does permit an attacker to alter the TXID of a transaction containing those signatures, and this can lead to severe consequences.
Suppose Bob pays Alice some Bitcoin via a transaction with identifier X. Suppose that before being mined, X is malleated to have a new identifier X’. Alice received the payment, but Bob doesn’t know. Since Alice knows Bob doesn’t know, she tricks Bob into re-issuing the payment again. She repeats this until Bob eventually realizes what’s going on, but it could be too late. In the real-world, this attack has been performed on exchanges as follows:
In this scenario, an attacker:
1. Spins up a bunch of Sybil nodes (red)
2. Surrounds an exchange node (yellow) with his Sybil nodes.
3. Performs a withdrawal from the exchange.
4. As soon as the withdrawal X leaves the exchange, the Sybil nodes malleate the withdrawal into X’.
5. The malleated X’ is propagated to the rest of the network.
When X’ is mined into the next block, the attacker has received the withdrawal X’ but the exchanges back-end hasn’t acknowledged receipt of the withdrawal since it’s looking for X in the blockchain. Knowing this, the attacker proceeds to:
6. Ask the exchange to repeat the withdrawal, since it “hasn’t gone through”.
7. Rinse & repeat.
Depending on the size of the exchange, the attacker can employ a “parasite strategy” whereby the exchange is drained with small withdrawals and infrequently. This allows the attacker to fly under the radar to maximize their long-term heist. Alternatively, an attacker can employ a “vampire strategy” whereby the exchange is drained with high-frequency large withdrawals before system administrators can respond.
Whatever the strategy, it’s a problem and cryptocurrency designers need to address the malleability issue.
NOTE: In practice for step (2), the attacker doesn’t need to fully surround the exchange node. Only a few connections are required to perform the attack, albeit with lower probability of success. The more surrounded, the higher the probability.
Bitcoin (BTC) has “solved” malleability with the introduction of Segwit which segregates the signature from the TXID calculation and replaces it with a non-malleable hash commitment to that signature. This hash serves as a pointer to the signature which is stored in another data-structure. In order to verify the transaction signature, the verifier uses the hash to lookup the signature in the other data-structure, and then performs the usual ECDSA verification. This eliminates signatures as source of malleability from the transaction since they are stored outside of the transaction and the hash pointer to the signature cannot be malleated. Neat, but it introduces a dependency to the other data-structure that contains the signatures. A small trade-off in Bitcoin, but significant nonetheless.
Whilst Segwit in it of itself was not a bad idea, the deployment and resulting politics of the deployment caused a rift within the Bitcoin community. This led to the split of the community into Bitcoin (BTC) and Bitcoin Cash (BCH). Whilst Segwit was touted as a major reason for the split, the underlying issues were more about the deployment of Segwit than the technicals. Also, the politics of “always soft-fork never hard-fork” implied that the 1mb blocksize was essentially locked in, and this was unacceptable to many.
The technical arguments against Segwit were more to do with it’s gratuitous complexity as a soft-fork and unrelated to its soundness as a hard-fork. Segwit as a soft-fork was the straw that broke Bitcoins back, in the opinion of the author. However, Segwit as a hard-fork was (and remains) a technically sound solution-approach for malleability.
Love it or hate it, it’s done and dusted now. However, the problem of malleability remains in Bitcoin Cash.