Skip to content

[New BIP 389] Multipath descriptors #1354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Pieter Wuille, Andrew Chow
| Informational
| Draft
|-
| [[bip-0389.mediawiki|389]]
| Applications
| Multipath Descriptor Key Expressions
| Andrew Chow
| Informational
| Draft
|}

<!-- IMPORTANT! See the instructions at the top of this page, do NOT JUST add BIPs here! -->
77 changes: 77 additions & 0 deletions bip-0389.mediawiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<pre>
BIP: 389
Layer: Applications
Title: Multipath Descriptor Key Expressions
Author: Andrew Chow <[email protected]>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0389
Status: Draft
Type: Informational
Created: 2022-07-26
License: BSD-2-Clause
</pre>

==Abstract==

This document specifies a modification to Key Expressions of Descriptors that are described in BIP 380.
This modification allows Key Expressions to indicate BIP 32 derivation path steps that can have multiple values.

==Copyright==

This BIP is licensed under the BSD 2-clause license.

==Motivation==

Descriptors can describe the scripts that are used in a wallet, but wallets often require at least two descriptors for all of the scripts that they watch for.
Wallets typically have one descriptor for producing receiving addresses, and the other for change addresses.
These descriptors are often extremely similar - they produce the same types of scripts, derive keys from the same master key, and use derivation paths that are almost identical.
The only differences are in the derivation path where one of the steps will be different between the descriptors.
Thus it is useful to have a notation to represent both descriptors as a single descriptor where one of the derivation steps is a pair of values.

==Specification==

For extended keys and their derivations paths in a Key Expression, BIP 380 states:

* <tt>xpub</tt> encoded extended public key or <tt>xprv</tt> encoded extended private key (as defined in BIP 32)
** Followed by zero or more <tt>/NUM</tt> or <tt>/NUMh</tt> path elements indicating BIP 32 derivation steps to be taken after the given extended key.
** Optionally followed by a single <tt>/*</tt> or <tt>/*h</tt> final step to denote all direct unhardened or hardened children.

This is modifed to state:

* <tt>xpub</tt> encoded extended public key or <tt>xprv</tt> encoded extended private key (as defined in BIP 32)
** Followed by zero or more <tt>/NUM</tt> (may be followed by <tt>h</tt>, <tt>H</tt>, or <tt>'</tt> to indicate a hardened step) path elements indicating BIP 32 derivation steps to be taken after the given extended key.
** Followed by zero or one <tt>/<NUM;NUM</tt> (each <tt>NUM</tt> may be followed by <tt>h</tt>, <tt>H</tt>, or <tt>'</tt> to indicate a hardened step) path element indicating a tuple of BIP 32 derivation steps to be taken after the given extended key.
*** Followed by zero or more <tt>;NUM</tt> (may be followed by <tt>h</tt>, <tt>H</tt>, or <tt>'</tt> to indicate a hardened step) additional tuple values of BIP 32 derivation steps
*** Followed by a single <tt>>/</tt>
** Followed by zero or more <tt>/NUM</tt> (may be followed by <tt>h</tt>, <tt>H</tt>, or <tt>'</tt> to indicate a hardened step) path elements indicating BIP 32 derivation steps to be taken after the given extended key.
** Optionally followed by a single <tt>/*</tt> (may be followed by <tt>h</tt>, <tt>H</tt>, or <tt>'</tt> to indicate a hardened step) final step to denote all direct unhardened or hardened children.

When a <tt>/<NUM;NUM;...;NUM></tt> is encountered, parsers should account for a presence of multiple descriptors where the first descriptor uses the first <tt>NUM</tt>, and a second descriptor uses the second <tt>NUM</tt>, and so on, until each <tt>NUM</tt> is accounted for in the production of public keys, scripts, and addresses, as well as descriptor import and export operations.
Descriptors that contain multiple Key Expressions that each have a <tt>/<NUM;NUM;...;NUM></tt> must have tuples of exactly the same length so that they are derived in lockstep in the same way that <tt>/*</tt> paths in multiple Key expressions are handled.

The common use case for this is to represent descriptors for producing receiving and change addresses.
When interpreting for this use case, wallets should use the first descriptor for producing receiving addresses, and the second descriptor for producing change addresses.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should comment here about what any 3rd and subsequent elements are used for, even if thats use-case dependent. This reads as though it was written before more than 2 elements were allowed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not aware of any such use cases currently, but this was a suggestion that makes sense and I don't see that it is harmful.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking something like Key expressions with multi-path tuples larger than 2 elements should not be assumed to follow the above receive/change scheme.

For this use case, the element will commonly be the value <tt>/<0;1></tt>

Note that only one <tt>/<NUM;NUM;...;NUM></tt> specifier is allowed in a Key Expression.

==Test Vectors==

TBD

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the descriptor BIPs have test vectors and this is a potential source of problems for people implementing these specs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks for reminding me to write those.


==Backwards Compatibility==

This is an addition to the Key Expressions defined in BIP 380.
Key Expressions using the format described in BIP 380 are compatible with this modification and parsers that implement this will still be able to parse such descriptors.
However as this is an addition to Key Expressions, older parsers will not be able to understand such descriptors.

This modification to Key Expressions uses two new characters: <tt><</tt> and <tt>;</tt>.
These are part of the descriptor character set and so are covered by the checksum algorithm.
As these are previously unused characters, old parsers will not accidentally mistake them for indicating something else.
Copy link

@jgriffiths jgriffiths Feb 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The biggest back compatibility change is that this allows all non-combo descriptors to produce multiple outputs instead of a simple bijection from descriptor to script/address/key, this should probably be noted. Additionally, for combo descriptors this now allows the wpkh and sh-wpkh variants to themselves produce multiple outputs.

Copy link
Member Author

@achow101 achow101 Feb 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was already the case for ranged descriptors (those with keys that have /*), so I don't think that's something that needs to be mentioned. For ranged descriptors, it's already impossible to get the real descriptor that generated a script since you don't know the parent xpub or the derivation.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change because the mapping cardinality changes. Before multi-path:

  • A non-ranged descriptor resolves to a single script (0 inputs to 1 output).
  • A ranged descriptor plus bip32 child number resolves to a single script (1-1).
  • A non-ranged combo resolves to either 2 or 4 scripts (0-[2|4]).
  • A ranged combo plus bip32 child number resolves to 4 scripts (1-4).

Note that combo is its own BIP and may not be supported by some implementations.

After Multi-path, the above all hold if multi-path aren't used. Multipath adds the following cases:

  • A non-ranged descriptor with MP resolves to N scripts (0-N).
  • A ranged descriptor plus bip32 child number with MP resolves to N scripts (1-N).
  • A non-ranged combo with MP resolves to either 2N or 4N scripts (0-[2N|4N]).
  • A ranged combo plus bip32 child number with MP resolves to 4N scripts (1-4N).

i.e. the number of required inputs to resolve to a single address has changed when MP is present.


This proposal is in contrast to similar proposals such as BIP 88 which allow for multiple derivation indexes in a single element.
This limitation exists in order to reduce the number of descriptors that are expanded, avoid confusion about how to expand the descriptor, and avoid having expanded descriptors that users are not expecting.

==Reference Implementation==

https://github.com/bitcoin/bitcoin/pull/22838