Casa Blog - Bitcoin Security Made Easy

Today Casa is excited to announce that we’re releasing support for bitcoin wallet descriptors. Only a handful of wallets currently support descriptors, thus I’d like to explain our reasoning behind becoming an early adopter of this technology.

Let’s start with some wallet basics.

What is a bitcoin wallet?

To define and recreate a bitcoin wallet, you need several components:

Public keys: bitcoin wallets generate public keys from private keys via asymmetric cryptography. Public keys (or more complex scripts containing public keys) are then hashed and encoded to create bitcoin addresses. Each address represents a destination for receiving bitcoin transactions. A wallet must be able to generate new addresses as needed for receiving funds and for scanning the blockchain to find the history of deposits and withdrawals.

Derivation paths: hierarchical deterministic wallets use an extended public key to generate a tree of many keys. This structure allows for the creation of an unlimited number of addresses from a single seed, making backups far simpler. Since a single seed phrase and its accompanying extended public key can create a limitless amount of keys, it’s crucial to know the specific path(s) of the tree your wallet is using.

Spending conditions: it’s necessary to know exactly what type of data structure and signatures are required when using your private keys to create a valid transaction to spend funds from the wallet. This is because the entire set of spending conditions get hashed in order to create your deposit addresses. Even a single byte of difference in the spending conditions results in completely different addresses being generated.

In short, there are multiple variables required in order to define the characteristics of a specific bitcoin wallet.

What is a wallet descriptor?

A wallet descriptor is also known as an “output descriptor” because it’s technically defining the conditions for creating and spending transaction outputs within a wallet.

A descriptor is a structured format used to describe the aforementioned characteristics of a given bitcoin wallet. It provides a concise and standardized way to specify the addresses that a wallet can generate, import, and spend from.

Output descriptors typically include the following components:

Keys / Hashes: Specifies the key material involved in the redeem script. For example, in a P2PKH script, the output descriptor could include the private key or the public key hash corresponding to the recipient's address. Sometimes there are multiple different ways to describe the same output; for example the 6 following descriptors all resolve to the same spending conditions:

pkh([deadbeef/1/2'/3/4']L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)

pkh([deadbeef/1/2'/3/4']03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)

pkh(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)

pkh(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)

pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0)

pkh([bd16bee5/2147483647h]xpub69H7F5dQzmVd3vPuLKtcXJziMEQByuDidnX3YdwgtNsecY5HRGtAAQC5mXTt4dsv9RzyjgDjAQs9VGVV6ydYCHnprc9vvaA5YtqWyL6hyds/0)

You can see the first 4 examples provide single specific keys and hashes while the last 2 examples provide an extended private or public key + a derivation path. For Casa’s purposes we’ll be using extended public keys plus derivation paths.

Script Expression: Describes the type of script being used, such as Pay-to-Public-Key-Hash (P2PKH), Pay-to-Script-Hash (P2SH), Pay-to-Witness-Public-Key-Hash (P2WPKH), etc.

Script Operations: Defines the specific conditions required to spend funds locked in the script. Basic descriptors generally only include keys and (number of) signatures, but miniscript descriptors can also define hash pre-images, time locks, and boolean AND/OR logic to define far more complex spending conditions.

Casa’s wallet descriptors

So…what does a full wallet descriptor actually look like? Well, a 3-key Casa vault descriptor would look something like this:

sh(wsh(sortedmulti(2,[af29b904/]Ypub6ihJP1GWiGzh4wgcmx1n8azoWxa8rsvDjmXLEz9Mk1z64xPFj1cyqBiwtTtvUaiWQJnkuEra7Mo9iZVbgxj8be6M9vmGwwbKixUW9C6GoFD/<0;1>/*,[a6713122/49/0/9]Ypub6iPSKFEXk26Jdhwbahm7fXQRws41PLG7hUaeCRCJQZmU7cdraZ5mBFgSbJUwfBJ6jTKuRvjdACAnU4ufr1h6vwiYyFFngkGgfiCaTPv2eME/<0;1>/*,[e699b76c/49/0/9]Ypub6igtCKM336QNjeE57irwVReUTogipbtuX9pEk2a8Vhz838D7YrXBFiwR9QGrMhD2xqLHrf7yZNRwbAf1Hrijym7oaxj6CqRckGRG3xuseqe/<0;1>/*)))

How is this descriptor interpreted?

  • sh(wsh()) - outputs are created as P2SH wrapped Segregated Witness script hashes
  • sortedmulti(2, [list of extended public keys]) - outputs must be signed with private keys corresponding to 2 of the 3 public keys derived from these extended keys at the specified derivation paths

To view and save the wallet descriptor for your vault in the Casa app, on the "Receive BTC" screen just tap on the "..." options button in the upper right and you'll see the toggle between viewing a single address and the full wallet descriptor, like so:

casa-app-wallet-descriptor-export

While you can copy / paste the raw wallet descriptor text, we recommend saving the QR encoded version of it, which has built-in error correction and is thus far less likely to be corrupted.

Wallet recreation & recovery nightmares

You’re probably familiar with the phrase “not your keys, not your coins” and understand that having a robust seed phrase backup system is crucial to ensuring that you don’t lose your self custodied bitcoin.

But what if I told you that you can lose access to your bitcoin even while still having the seed phrase(s) and keys that can spend the funds?

As mentioned earlier, in order to construct the appropriate spending conditions for a wallet and in order to be able to derive the appropriate deposit addresses in order to look up the transaction history and balance, wallet software actually needs to have several critical pieces of information in addition to the seed phrase or extended public key.

Further complicating matters are BIP 32 derivation paths. Although BIPs 44, 49, and 84 have specified standard BIP 32 derivation paths for different output scripts and addresses, not all wallets support them nor use those derivation paths. The lack of derivation path information in these backups and exports leads to further incompatibilities between wallets that don't support descriptors and simply make assumptions about which paths to use.

A common issue for users of multisig wallets is that while you may only need M of N seed phrases to spend from the wallet, if you don’t have all N public keys, you won’t be able to create the appropriate redeem script that you can sign! As such, if you don’t have backups of ALL of your public keys, you could lose access to your funds despite having a spending quorum of seed phrases. Since wallet descriptors include ALL of the extended public keys, it makes backing up this critical information far simpler since it’s all contained in one data blob.

While great advances have been made in interoperability and recoverability, developers across the industry continue to build wallets that either:

  • Don’t implement BIP standard(s).
  • Implement a BIP standard, but inconsistently when compared with other wallets.
  • Implement a BIP standard, but one that has not been widely adopted.
  • Don’t have clear documentation about their derivation paths, backup and recovery processes.

You can see the great effort put forth to document 80+ software wallets and their default script types and derivation paths at https://walletsrecovery.org/

Why should every wallet support descriptors?

We believe that all bitcoin wallets should support descriptors for several reasons:

  1. Removal of ambiguity. Descriptors are unambiguous as to which public keys and which spending conditions to use. This makes them suitable for importing to other wallets without confusion. In contrast, traditional import mechanisms only support extended public keys with special versioning to indicate the scripts to produce, and don't provide the derivation paths. Versioning of extended public keys also causes so much confusion that I wrote this converter tool several years ago. It’s problematic because users may import an extended key into a wallet but then be unable to see their addresses because that wallet uses a different derivation path than the original wallet. Descriptors avoid this issue entirely by specifying the derivation paths and the script type.
  2. Interoperability. Descriptors ensure interoperability between different wallet implementations and services. Wallets that support descriptors can more easily exchange information about which addresses belong to a given wallet, enabling smoother integration with other bitcoin-related software and platforms. This helps prevent single points of failure due to vendor lock-in and also makes it easier to coordinate multisignature wallets for which different signers use different wallet software.
  3. Simplicity and consistency. Descriptors simplify the process of backing up and recreating wallets by providing a consistent and unified interface. Wallet developers can use descriptors to handle various address types and script templates without needing to implement custom solutions for each one. Take, for example, Casa’s Sovereign Recovery guide for how to recreate your wallet in non-Casa software. This guide would be about 80% simpler if all that was required was copy/pasting your descriptor into other wallets.
  4. Complex script support. With the addition of miniscript, descriptors are particularly useful for managing multisignature addresses and more complex script types. They allow wallets to generate, import, and track addresses associated with custom script templates, including those used in multisignature setups and other advanced smart contracts.
  5. Future compatibility. Supporting wallet descriptors means that we don’t have to worry about further fracturing of backup schemes across the ecosystem as improvements to the bitcoin protocol continue to increase the complexity of potential spending condition definitions. As the bitcoin ecosystem evolves, new address types and scripting capabilities may be introduced, and descriptors provide a standardized way to accommodate these changes.

Overall, by incorporating support for descriptors, bitcoin wallets can offer users a more versatile, secure, and future-proof way to manage their funds and interact with the rest of the ecosystem.

Which wallets support descriptors?

Casa recommends that every bitcoin wallet adds support for descriptors in order to increase interoperability across the ecosystem. However, at time of writing, only a handful of wallets have adopted this framework.

You can find a list of supported wallets at https://outputdescriptors.org/ 

Stay tuned

This is only the first step — descriptors open up avenues to several improvements we have added to Casa’s roadmap.

Since Casa’s primary goal is the elimination of single points of failure, making backups and Sovereign Recovery even easier for our members is of utmost importance.

Descriptors also combine well with miniscript in allowing a wallet to handle tracking and signing for a larger variety of complex spending conditions. We’re excited to explore the possibilities that tapscript enabled a few years ago; only a handful of organizations have begun to scratch the surface of this design space.

Further reading & resources

If you want to dig deeper into the technical minutiae of wallet descriptors, check out: