summaryrefslogtreecommitdiff
path: root/Modern Hierarchy for Deterministic Multisignature Wallets.mediawiki
blob: 8748762f73ff9236dec7a16ae64ec69e7abf7978 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
<pre>
  BIP: Number not assigned
  Layer: Applications
  Title: Modern Hierarchy for Deterministic Multisignature Wallets
  Author: Robert Spigler <RobertSpigler@ProtonMail.ch>
  Comments-Summary: No comments
  Comments-URI:
  Status: Proposed
  Type: Standards Track
  Created: 2020-03-11
  License: BSD-2-Clause
</pre>

==Abstract==

This BIP defines a sane hierarchy for deterministic multisig wallets based on an algorithm described in BIP-0032 (BIP32 from now on), purpose scheme described in BIP-0043 (BIP43 from now on), and multi-account hierarchy described in BIP-0044 (BIP44 from now on).

This BIP is a particular application of BIP43.

==Copyright==

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

==Motivation==

With the increase of more user friendly (offline) multisignature wallets, and adoption of new technologies such as [https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the descriptor language] and [https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174 (Partially Signed Bitcoin Transactions)] it is necessary to create a common derivation scheme that makes use of all new technologies.

As background, BIP 44/49/84 specifies:

<pre>
m / purpose' / coin_type' / account' / change / address_index
</pre>

where the BIP43 <code>purpose'</code> path is separate for each script (P2PKH, P2WPKH-in-P2SH, and P2WPKH respectively).  Having a script-per-derivation for single sig wallets allows for easy backup and restore, with just the private key information.

Multisignature wallets need more information to backup and restore, and these per-script derivations are made redundant with descriptors, which describe a collection of output scripts.
A modern standardization is needed for multisig derivation paths.  There are some in existence, but all have issues.  For example, BIP45 specifies:

<pre>
m / purpose' / cosigner_index / change / address_index
</pre>

Like BIP44/49/84, BIP45 unecessarily demands a single script type (here, P2SH).  In addition, BIP45 sets <code>cosigner_index</code> in order to sort the <code>purpose'</code> public keys of each cosigner.  This too is redundant, as descriptors can set the order of the public keys with <code>multi</code> or have them sorted lexicographically (as described in [https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki BIP67]) with <code>sortedmulti</code>.  Sorting public keys between cosigners in order to create the full derivation path, prior to sending the key record to the coordinator to create the descriptor, merely adds additional unnecessary communication rounds.

The second multisignature "standard" in use is m/48', which specifies:

<pre>
m / purpose' / coin_type' / account' / script_type' / change / address_index
</pre>

Rather than following in BIP 44/49/84's path and having a separate BIP per script after P2SH (BIP45), vendors decided to insert <code>script_type'</code> into the derivation path (where P2SH-P2WSH=1, P2WSH=2, Future_Script=3, etc). As described previously, this is unnecessary, as the descriptor sets the script.  While it attempts to reduce maintainence work by getting rid of new BIPs-per-script, it still requires maintaining an updated, redundant, <code>script_type</code> list.

The structure proposed later in this paper solves these issues and is quite comprehensive. It allows the handling of multiple accounts, external and internal chains per account, and millions of addresses per chain, in a multi-party multisignature hierarchical deterministic wallet regardless of the script type <ref>**Why propose this structure only for multisignature wallets?** Currently, single-sig wallets are able to restore funds using just the master private key data (in the format of BIP39 usually).  Even if the user doesn't recall the derivation used, the wallet implementation can iterate through common schemes (BIP44/49/84).  With this proposed hierarchy, the user would either have to now backup additional data (the descriptor), or the wallet would have to attempt all script types for every account level when restoring.  Because of this, even though the descriptor language handles the signature type just like it does the script type, it is best to restrict this script-agnostic hierarchy to multisignature wallets only. Co-signers in multisignature wallets need to backup all other cosigner public keys anyway in order to restore, so the descriptor provides this information with the benefit of key origin information and error detection.</ref>.

Any script that is supported by descriptors (and the specific wallet implementation) is compatible with this BIP.

This paper was inspired from BIP44.

==Specification==

===Key sorting===

Any wallet that supports descriptors inherently supports deterministic key sorting as per BIP67 (through the <code>sortedmulti</code> function) so that all possible multisignature addresses/scripts are derived from deterministically sorted public keys.

===Path levels===

We should not be mixing keys and scripts in the same layer. The wallet should create extended private/public keys independent of the script type, whereas the descriptor language tells wallets to watch the multisig outputs with the specified public keys.

We define the following 5 levels in the BIP32 path:

<pre>
m / purpose' / coin_type' / account' / change / address_index
</pre>

<code>h</code> or <code>'</code> in the path indicates that BIP32 hardened derivation is used.

Each level has a special meaning, described in the chapters below.

===Purpose===

Purpose is a constant set to XY' following the BIP43 recommendation.
It indicates that the subtree of this node is used according to this specification.

Hardened derivation is used at this level.

===Coin type===

One master node (seed) can be used for multiple Bitcoin networks.
Sharing the same space for various networks has some disadvantages.

This level creates a separate subtree for every network, avoiding reusing addresses across networks and improving privacy issues.

Coin type <code>0</code> for mainnet and <code>1</code> for testnets (testnet, regtest, and signet).

Hardened derivation is used at this level.

===Account===

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 used at this level.

It is crucial that this level is increased for each new wallet joined or private/public keys created; for both privacy and cryptographic purposes.
For example, before sending a new key record to a coordinator, the wallet must increment the <code>account'</code> level.
This prevents key reuse - across ECDSA and Schnorr signatures, across different script types, and inbetween the same wallet types.

===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.

Public derivation is used at this level.

===Index===

Addresses are numbered from index 0 in sequentially increasing manner.
This number is used as child index in BIP32 derivation.

Public derivation is used at this level.

==Address Discovery==

The multisig descriptor that is generated from the cosigners combined key records should be used to generate and discover addresses. For example:
<code>wsh(sortedmulti(2,[xfpForA/XY'/0'/0']XpubA/*,[xfpForB/XY'/0'/0']XpubB/*))#Checksum</code>

# Derive the wallet's first account's node (index = 0)
# Derive the external chain node of this account (index = 0)
# Scan addresses of the external chain; respect the gap limit described below
# If there are some transactions, increase the account index and go to step 2
# If no transactions are found on the external chain, continue to search the following account indexes in compliance with the account gap limit described below.

Please note that the algorithm works with the transaction history, not account
balances, so you can have an account with 0 total coins and the algorithm will
still continue with discovery.

The wallet implementation should scan the accounts and addresses following the parent descriptor string.

===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. We scan just the external chains, because internal chains receive only coins that come from the associated external chains.

Wallet software should warn when the user is trying to exceed the gap limit on an external chain by generating a new address.

===Account Gap Limit===

Account gap limit is currently set to 5.  When the software hits an account that contains 20 unused addresses in a row, it will search the the next 4 accounts (while obeying the address gap limit), before stoping discovery.  If any transactions are found during this process, discovery is restarted (after finding 20 unused addresses) on the next account index, and the account gap limit is reset.  Only when the address gap limit is found consecutively for the account gap limit is discovery stopped.

==Rationale==

<references/>

==Examples==

{|
|network
|account
|chain
|address
|path
|-
|mainnet
|first
|external
|first
|m / XY' / 0' / 0' / 0 / 0
|-
|mainnet
|first
|external
|second
|m / XY' / 0' / 0' / 0 / 1
|-
|mainnet
|first
|change
|first
|m / XY' / 0' / 0' / 1 / 0
|-
|mainnet
|first
|change
|second
|m / XY' / 0' / 0' / 1 / 1
|-
|mainnet
|second
|external
|first
|m / XY' / 0' / 1' / 0 / 0
|-
|mainnet
|second
|external
|second
|m / XY' / 0' / 1' / 0 / 1
|-
|testnet
|first
|external
|first
|m / XY' / 1' / 0' / 0 / 0
|-
|testnet
|first
|external
|second
|m / XY' / 1' / 0' / 0 / 1
|-
|testnet
|first
|change
|first
|m / XY' / 1' / 0' / 1 / 0
|-
|testnet
|first
|change
|second
|m / XY' / 1' / 0' / 1 / 1
|-
|testnet
|second
|external
|first
|m / XY' / 1' / 1' / 0 / 0
|-
|testnet
|second
|external
|second
|m / XY' / 1' / 1' / 0 / 1
|-
|testnet
|second
|change
|first
|m / XY' / 1' / 1' / 1 / 0
|-
|testnet
|second
|change
|second
|m / XY' / 1' / 1' / 1 / 1
|}

==Reference Implementation==

None at the moment.

==Acknowledgement==

Special thanks to SomberNight, Craig Raw, David Harding, Jochen Hoenicke, and others for their feedback on the specification.

==References==

Original mailing list thread: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-March/018630.html

* [[bip-0032.mediawiki|BIP32 - Hierarchical Deterministic Wallets]]
* [[bip-0043.mediawiki|BIP43 - Purpose Field for Deterministic Wallets]]
* [[bip-0044.mediawiki|BIP44 - Multi-Account Hierarchy for Deterministic Wallets]]
* [https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md Output Descriptors]
* [[bip-0174.mediawiki|BIP174 - Partially Signed Bitcoin Transaction Format]]
* [[bip-0067.mediawiki|BIP67 - Deterministic Pay-to-script-hash multi-signature addresses through public key sorting]]