Bolstering multisig security with support for Ledger 2.0 wallet registration

Our latest open source collaboration to support the bitcoin ecosystem

First published: 03/16/2023
| Last updated: 03/16/2023
| -- min read

We at Unchained consider multisig on bitcoin an unparalleled method for safeguarding generational wealth. However, with great power comes greater complexity. And complexity can mean increased risk. This is why we continually focus on reducing the complexity of multisig without sacrificing its security. Today, we’re announcing new open-source contributions and a significant upgrade to our support for Ledger devices toward this end. 

The ‘swap attack’

One of the principles of multisig security is that a hardware wallet (or any signing device) should have some awareness of all keys involved in the wallet quorum. This is easier to solve for in singlesig setups because the device already knows all the addresses it could create for itself. In multisig, the device cannot be aware of the multisig wallet’s address in advance. Instead, it reviews the transaction it’s signing to verify that the public key held on the device was one of the keys used to generate the address. Without any external interaction, however, it cannot know that a given address can be considered “safe.” 

Consider a situation where an attacker infects your computer with clipper malware and switches out a 2-of-3 multisig receiving address. In doing so, they change the quorum from one where you have the majority of keys in the quorum to only having one. A device could confirm it recognizes that its public key was used to generate the address, even though you would no longer be able to spend those funds if at least one of the attacker’s keys is needed for a valid signature. This effectively means your key could approve a transfer of ownership of your bitcoin without your knowledge.

We refer to this kind of attack as a “swap attack”  because it involves changing out a friendly key for that of the attacker. There are two forms in which this attack can manifest: 

  • Change address: Targeted when you think you are spending to a known output destination and sending the remainder back to your own wallet, but in reality, you’re sending to a compromised address. This one is relatively simple to solve for, even in stateless signers, since you have access to the full transaction at the time of signing and can attempt to validate the change output against the inputs, verifying that the change output is returning to the same wallet as those inputs. When solved, the change address does not even need to be shown to the user for confirmation.
  • Receive address: Targeting the receive address, i.e., requesting a new address to which you want to receive funds. This kind of  “swap attack” is more complex to solve as there is no state except the address you are receiving to and, therefore, it ideally requires some sort of registration process. This allows your device to acknowledge 1) it recognizes its public key in the address and 2) it is for a wallet configuration the user has previously approved. 

Wallet registrations and policies

There are several ways to mitigate a “swap attack.” Stateful hardware wallets like Coldcard support an on-device registration where the other public keys in a multisig quorum are sent to the device and saved. This allows for pre-approval of any addresses generated from the seed on that device and those generated from that group of keys. The device then has the information necessary to verify addresses. In 2020, we collaborated with Trezor to support address verification on their stateless device to empower users to protect themselves from this attack. 

Ledger, whose devices such as the Nano S are also stateless, announced a new version of their bitcoin app in late 2021 that was the first to utilize a Bitcoin Improvement Proposal (BIP) introduced by their lead dev Salvatore Ingala. This BIP involves an extension of output descriptors that can represent a wallet configuration in a compact and human-readable way. 

Even more significant to the average user: Ledger 2.0 introduced a novel way to register multisig wallet policies with stateless devices. Without support for persisting any more data than what is in your seed, Ledger and other similar stateless devices don’t have a way to remember wallets you’ve approved. 

Instead, Ledger’s approach works by providing a cryptographically secure and compact token known as an HMAC (hashed message authentication code) as proof that a specific wallet policy has been approved by the seed on that device. This token cannot be forged or altered. Each time you need to verify an address or sign with a Ledger device, by sending both the quorum information and the HMAC, you can verify the addresses as being associated with the quorum from which the HMAC was originally generated. Additionally, this proof can be deterministically recreated, verified, and therefore reused by any other Ledger device loaded with the same seed.

Building out in the open with open source

Contributing to the larger bitcoin ecosystem through open source is a high priority for Unchained, either through projects like Caravan, our utility libraries like unchained-wallets and unchained-bitcoin, or collaborations with other development teams. The work of adding Ledger policy registration support to our platform was an opportunity to share the new tooling we built with the broader bitcoin ecosystem. 

In addition to the new interfaces in Caravan described below, we’ve released two other upgrades that should be useful to other developers: one to unchained-wallets, which serves as our HWI-like utility for JavaScript codebases, and PSBTv2 support in unchained-bitcoin. We have also updated our Caravan test suite to support the new Ledger app and test Ledger address verification and policy registration.

New interactions, broader compatibility in unchained-wallets

The unchained-wallets API creates a common interface for interacting with various hardware wallet devices, abstracting away the underlying complexity of each API. Supported “interactions” include SignMultisigTransaction, ExportExtendedPublicKey, and ConfirmMultisigAddress. There is now a new interaction: “RegisterWalletPolicy”.

The Ledger interactions now also support backward compatible fallback support for all relevant classes, such that if an application is trying to communicate with a Ledger that has not yet been upgraded, the old API will be used. It is also forward compatible, such that if you, for example, try and sign with a Ledger using version 2.0 of the bitcoin app, the Ledger interaction in unchained-wallets will recognize the need to register first and run through the requisite workflow. 

Finally, there are new utilities for creating, serializing, and validating wallet policies according to the BIP draft. These can be used in other JavaScript (or now TypeScript!) codebases that need to serialize policies for use with a Ledger or simply present the data to users. 

PSBTv2 in unchained-bitcoin

Version 2 of the PSBT standard is relatively new; as such, there aren’t many widely deployed implementations out in the open. Unfortunately for us, the new Ledger application only accepts version 2 PSBTs. While bitcoinjs-lib provided an excellent library to support PSBTv0, it has yet to be upgraded to support PSBTv2. LedgerHQ provides a basic implementation, but it only supports singlesig transactions. So, we needed a quick solution that would provide PSBTv2 support for our collaborative custody multisig wallets.

The PSBTv2 class recently released within unchained-bitcoin seeks to provide a more full-featured representation of a PSBTv2. While many of the less common features of bitcoin transactions have yet to be modeled within the class, what is present attempts to conform to BIP0174 and BIP0370 validation logic while providing helpful methods to aid in the PSBT lifecycle up through the “Signer” role. A conversion function is also provided, which supports conversion from PSBTv0 to PSBTv2 to support interoperability with unupgraded systems. 

Caravan Test Suite

One nice aspect of the Ledger system for wallet registration is that it is portable. Any upgraded Ledger that is loaded with the same seed can validate an existing registration. As a proof of concept and a tool for our product and engineering teams to test future updates, we added support for new Ledger features to unchained-bitcoin’s test fixtures and the Caravan test suite. Anyone can load up the same open-source words on their Ledger device and test the registration flow. 

These fixtures are openly available for any other codebase to use for their own tests, and the Caravan test suite directly uses the open-source unchained-wallets interactions mentioned above. 

Testing policy registrations in the Caravan test suite—can be run by anyone with a Ledger running the latest software. 

Unchained + Ledger

One small step for UX; one giant leap for multisig security

With all this tooling in place, we wanted to start giving users access to improved security and a smoother user experience. We plan on refining these interfaces over time, but with recent updates to both the Unchained platform and Caravan, you can leverage them today even if you’re not an Unchained client!

Registering your product’s wallets

Registration on Ledger requires that the device is given the wallet policy information first. This information will be replayed to the user on the device screen for approval. At this stage, the user needs to verify that the wallet policy matches the keys they expect from their backup. Since you can now back up your registration with Unchained or other similar service, doing this carefully the first time will ensure that you can safely trust your registration in the future and skip this step.

Registration flow in Ledger’s new bitcoin app

All Ledger interactions vulnerable to a swap attack require this step first. Signing and address verification will fail if the device is not given a valid HMAC during the request. Unchained can make this process smoother by allowing users to save their proof of registration. By saving the HMAC, we can present it to the device during future interactions and skip this registration step.

In this way, Ledger’s new interface allows Unchained and other bitcoin wallet coordinators to manage the state typically handled by the device.

Unchained clients now have the opportunity to register their Ledger and save that registration for future use. Transaction fees now display correctly on updated Ledgers.

Two subtle advantages to this system are not immediately obvious. The first is that by delinking the device (and seed) from the multisig wallets it can sign for, any information about those wallets remains safe if the device is compromised. A second advantage is that with the seed, device, and registration all decoupled, a seed recovery on another device won’t need to go through a re-registration process.

Portable and reusable with Caravan

Users that save their Ledger wallet policy with Unchained can also take this registration with them. Like all other relevant external spending information, the Ledger policy registration will now be stored in your wallet configuration file, which you can export anytime. 

Upon loading this configuration file inside Caravan, you will see your wallet information using the standard outlined in the Wallet Policy BIP for the keys and the wallet. Users will also be allowed to view any existing registrations for the keys in the wallet, and offer users the option to register with their device. Ledger registrations will be saved for interactions with the device (e.g. signing). The wallet configuration file should be re-downloaded by users that don’t want to re-register. 

Any other platforms that can import the Caravan wallet configuration file, like Sparrow, will also be able to support the Ledger registrations if they want, allowing their users to skip any registration done either at Unchained or with Caravan.

After a wallet has been loaded into Caravan, users can review not just the wallet details but also register the wallet with compatible devices

Most importantly, once the wallet has been loaded, users can confirm any address in their wallet with their Ledger. This process is incredibly smooth for keys that have registered the wallet already: confirm the wallet name and then the address on your device’s screen. 

Confirm address on device support now available for compatible Ledgers.

Driving multisig forward

The features released by Ledger in their new bitcoin app are a huge step forward in security for multisig users of their device. Of course, upgrades of this kind can take time to permeate the ecosystem. We’re excited to have the opportunity to bring these enhancements to Ledger users and will continue to bring improved user experiences that leverage these changes in the coming months.

We’re looking forward to seeing how other applications implement these features and hope the open-source contributions introduced above help push the industry forward!

Sign up to get notified for future blog articles.