Over the summer, we identified several critical issues in the implementations of some widely used MPC wallets. An attacker compromising one of the signers could have recovered the full private key. One of the affected providers is Vultisig, whose wallets protect more than 500M USD in assets across dozens of chains. After our disclosure, Vultisig made changes to the affected code and has agreed to let us talk about the issue for educational purposes.
MPC and Crypto Wallets: A Match Made in Heaven?
The popularity of MPC-powered crypto wallets has skyrocketed over the last 5 years, and for good reason. MPC wallets provide the benefits of traditional multisig wallets without many of the drawbacks. For example, a signature generated by an MPC wallet is indistinguishable from one produced by a regular wallet. This exact property makes estimating the total value of assets secured by MPC wallets tricky, but available estimates place the figure in the hundreds of billions (with a B!) of dollars.
We looked at MPC wallets that produce ECDSA signatures, which are used to sign transactions on both the Bitcoin and Ethereum networks. The promise of MPC wallets is that the private key for an account never exists in a single place, but can still be used to sign transactions efficiently. In practice, a few different devices (which could be servers, laptops, or even mobile phones) are each given a specially crafted piece of a private key, called a secret share. A single secret share looks random but, given a certain threshold of shares, anyone can run a simple algorithm to obtain the full private key.
The simplest case is two devices with a threshold of two, meaning both shares are needed to reconstruct the key. Because no single device holds the private key, the two devices need to collaborate if they want to sign a transaction. They talk back and forth, and after a few iterations they are able to produce a valid signature for the required transaction, without ever reconstructing the private key. Why go through this trouble? Because MPC wallets promise very strong security guarantees: an attacker who obtains one share is unable to recover the full key, even if they can (maliciously!) participate in signing interactions. Therefore, if the wallet is implemented well, such an attacker can only sign transactions also approved by whoever holds the other key share.
The Attack: From One Share to the Full Key, Bit by Bit
The issues we identified violate exactly this promise: they allow an attacker who compromises one device to obtain the other key share by sending malicious messages during signing interactions. Once the attacker has both shares, they obtain the full signing key, can sign any transaction, and can steal the wallet’s funds.
How is this possible? Unfortunately, ECDSA is not the most MPC-friendly signature scheme. Producing a signature requires exchanging large messages and performing expensive computation. This is bad if you want to generate signatures very fast. To speed up signing, the implementations we investigated use a well-known optimization. They run an expensive setup step that produces an additional secret value per device, which we will call a seed. Each device therefore holds a key share and a seed. By reusing these seeds, parties can perform subsequent signing operations much more efficiently. This second secret is as sensitive as the key share: an attacker who controls one device and learns the other device’s seed can use it to recover the other device’s key share.
In Vultisig’s ECDSA implementation, an attacker could have performed what is known as a “selective abort” attack. During the signing interaction, the attacker could have sent specially crafted messages and observed whether the other device returned an error. These messages would be crafted so that the other device’s response (an error or not) would depend on a particular bit of its seed, allowing the attacker to learn that bit. With many such malicious messages, the attacker could have recovered the full seed of the other device one bit at a time, and from this its key share and finally the full private key.
The Challenge: Using Secure Libraries Securely
What was the root cause? Vultisig (like most wallets) relies on libraries for the MPC protocol’s cryptographic core. The library developers know that this protocol design allows selective abort attacks. That’s not a problem in itself, since the error that leaks secret seed bits should never occur if the other device behaves honestly. So the library assumes that if the critical error appears, the device will refuse further signing until the seed is rotated. Do that, and keys stay safe. But the library can’t enforce this itself. It delegates that responsibility to the calling application. The error it returns reads “abort protocol and ban party”. Other libraries, like the archived Coinbase Kryptology, return even more intimidating errors: “this may be an attempted attack; do NOT re-run the protocol”. But ultimately, the responsibility lies with the library caller. In Vultisig’s case, that library error was captured at the application layer and returned to the user with an innocent-looking message. No further action was taken, allowing the attack to continue.
This issue exemplifies a more general challenge of MPC implementations. Initially, an academic paper describes an MPC protocol in pseudocode and proves its security in an abstract model. This is good! Secure products should be rooted in sound scientific research. Developers with cryptographic expertise then translate the protocol into a library, handling its mathematical and cryptographic details. The library is commonly audited by independent experts. This is also good! Implementing advanced cryptography securely requires serious expertise. Finally, the library becomes the foundation for a product. This is where things get tricky: the library’s interfaces can be complicated, and the product’s security depends on satisfying the assumptions made when the library was developed. These assumptions are usually (somewhat) documented, but the developers integrating the library, however knowledgeable, are not always cryptography specialists. A single violated assumption can have consequences that are just as severe as a bug in the implementation of the underlying cryptography.
As MPC wallets become more widely adopted, a few cryptographic libraries will become standard, and their security will be under intense scrutiny. The orchestration layer around them will then be the weak link, as it has historically been for other, less complex, cryptographic primitives (like encryption or signature schemes) with far simpler interfaces.
Are you building an MPC-powered application and wondering whether you’re affected by similar issues? Our engineers are happy to chat!
We have not reviewed Vultisig’s fixes for the reported issue or audited other parts of their protocol. This post is not an endorsement of Vultisig or their products.
