Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save 0xBEEFCAF3/f6b451c171d7c3087098b85956bed316 to your computer and use it in GitHub Desktop.
Save 0xBEEFCAF3/f6b451c171d7c3087098b85956bed316 to your computer and use it in GitHub Desktop.

BIP: BIP-unhardened-multisig Title: Unhardened Derivation Paths for Multisignature Coordination Author: Armin Sabouri [email protected] Jameson Lopp [email protected] Justin Moore [email protected] Status: Draft Type: Informational Created: 2023-01-03 License: BSD-2-Clause

==Abstract==

This BIP introduces a hierarchical deterministic wallet structure intended for multisignature wallets based on the algorithm described in BIP-0032(BIP32 from now on). This BIP is a particular application of BIP-0043(BIP43 from now on).

==Motivation==

BIP32 notes why the use of key hardening is recommended:

“One weakness that may not be immediately obvious, is that knowledge of a parent extended public key plus any non-hardened private key descending from it is equivalent to knowing the parent extended private key (and thus every private and public key descending from it). This means that extended public keys must be treated more carefully than regular public keys. It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of account-specific (or below) private key never risks compromising the master or other accounts.”

However, BIP32 was written before the popularization of multisignature locking scripts and the existence of dedicated key management hardware devices. In the decade since publication of BIP32 there have been no known incidents in which loss of funds occurred due to a single private key leaking from a hierarchical deterministic wallet as opposed to the extended private key / seed phrase leaking. In short, the weakness that key hardening protects against appears to be highly theoretical rather than practical.

Multisignature wallet developers have learned that use of extensive key hardening causes usability issues. This is due to additional complexities that arise from having to coordinate the use of multiple geographically distributed keys. The degradation of user experience is not offset by any security improvements because the primary security of a multisignature wallet comes from preventing any given key from being a single point of failure.

Over the past several years, hardware manufacturers have added further restrictions on the derivation paths that their devices will support for signing operations. Per trezor/trezor-firmware#1044:

This change is to provide better sandboxing of our apps. In 2.3.1 we are giving the apps (such as bitcoin etc.) only a subset of the keys. That means the bitcoin app now receives only 44'/0' subtree (or similar for segwit etc.) and is not allowed to manipulate the other keys.

We propose that the hardware vendors should not be restricting the ability for others to innovate at the software layer. They certainly should not prevent clients from signing paths that have been previously used or exported.

==Specification==

We define the following 5 levels in BIP32 path: m / purpose' / coin_type / account / change / address_index

Apostrophe in the path indicates that BIP32 hardened derivation is used. Further explanation for each path is provided below.

This BIP does not prescribe any specific derivation paths for script types. It is expected that wallets will use output descriptors per BIP-0380 in order to define this aspect of any given wallet. ​​The descriptor or descriptor template should contain the key origin information for maximum compatibility with BIP-0174

===Purpose===

Purpose is a constant set to 45’ (or 0x8000002D), following the BIP43 recommendation. It indicates that the subtree of this node is used according to this specification.

m / 45' / *

Hardened derivation is used at this level.

===Coin Type===

This level creates a separate subtree for each coin; thus, preventing address re-use and improving on-chain privacy. Coin types are constants as defined in SLIP-0044. Hardened derivation is not used at this level. A multisignature coordinator should be able to re-use devices across multiple coin types without needing the user to physically access the device. A more thorough example is provided below under “Rationale.”

=== Account Index === This level splits the key space into independent user identities, following the BIP44 pattern, so the wallet never mixes the coins across different accounts. Users can use these accounts to organize the funds in the same fashion as bank accounts; for donation purposes (where all addresses are considered public), for saving purposes, for common expenses, etc. Accounts are numbered from index 0 in sequentially increasing manner. This number is used as child index in BIP32 derivation. Hardened derivation is not used at this level === Change === Constant 0 is used for external chain and constant 1 for internal chain (also known as change addresses). External chain is used for addresses that are meant to be visible outside of the wallet (e.g. for receiving payments). Internal chain is used for addresses which are not meant to be visible outside of the wallet and is used for return transaction change. Hardened derivation is not used at this level === Address Index === Addresses are numbered from index 0 in sequentially increasing manner. This number is used as child index in BIP32 derivation. Hardened derivation is not used at this level

===Rationale===

If the only hardened key is the purpose field then multisignature wallet developers only need to export the extended public key for a given signing device one time and this device can be used for an unlimited number of coin types and accounts without the need for access to private keys in order to generate new logically distinct wallets.

Take the standard BIP-0044 path structure, for example:

m / purpose' / coin_type’ / account’ / change / address_index

Imagine we create an M-of-N multisignature wallet with N different dedicated hardware devices that are geographically distributed for security and redundancy. What is required if we later wish to perform one of the following actions?

Add a new account in order to have a logically separated bucket of funds Replace one of the devices because it was lost or compromised Add support for a new coin type

Adding a new account will require the user to access all N devices in order to generate new account-level xpubs from hardened keys. The complexity for replacing a device or adding a new coin type can then require as much as M * N operations in order to derive as many account-level xpubs as are needed to match the number of accounts desired by the user.

Since there is no standard for indicating to a hardware device that it is being used in a multisignature wallet, the best signal that device manufacturers can use in their firmware is the derivation path being used at the time of a request to sign a message or transaction. As such, we recommend that device manufacturers allow signing for arbitrary derivation paths (without depth restrictions) that start with m/45’.

The purpose field value of 45 has been chosen solely due to the fact that it is already in use by other multisignature wallets that need to perform unhardened derivation.

The derivation path depth should be used to differentiate between the proposed BIP32 path and BIP-0045 (BIP45 from now on) paths. If the derivation path is up to four fields deep, this should indicate BIP-45 is being used. The significant difference between BIP45 and this BIP is that BIP45 lacks a coin type and uses a cosigner_index rather than an account_index.

=== Address Discovery === The multisig descriptors or descriptor template that is generated from the cosigners' combined key records should be used to generate and discover addresses.

To discover addresses, import both the receiving and change descriptors; respect the gap limit described below. === Address Gap Limit === Address gap limit is currently set to 20. If the software hits 20 unused addresses in a row, it expects there are no used addresses beyond this point and stops searching the address chain. Wallet software should warn or prevent when the user is trying to exceed the gap limit on an external descriptor by generating multiple unused addresses.

===Examples===

{| !coin !account !chain !address

!path
Bitcoin
first
external
first
m / 45' / 0 / 0 / 0 / 0
-
Bitcoin
second
change
fifth
m / 45' / 0 / 1 / 1 / 4
-
Bitcoin Testnet
tenth
change
first
m / 45' / 1 / 9 / 1 / 0
-
Litecoin
fifth
external
seventh
m / 45' / 2 / 4 / 0 / 6
-
Ethereum
second
external
first
m / 45' / 60 / 1 / 0 / 0
-
Liquid BTC
eleventh
change
ninth
m / 45' / 1776 / 10 / 1 / 8
}

===Compatible Wallets=== Casa Electrum Specter Unchained Capital

===References=== BIP-0032 - Hierarchical Deterministic Wallets BIP-0045 - Structure for Deterministic P2SH Multisignature Wallets BIP-0043 - Purpose Field for Deterministic Wallets BIP-0044 - Multi-Account Hierarchy for Deterministic Wallets BIP-0380 - Output Script Descriptors General Operation SLIP-0044 - Registered coin types for BIP-0044 Output Descriptors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment