Skip to content

Commit 6843221

Browse files
psiemensRob MyersJeffreyDoyletarakbyTarak Ben Youssef
authored
FLIP-0200: Application of BIP 44 in Flow Wallets (#200)
* First draft of FLIP: "Application of BIP 44 in Flow Wallets" * Update 20201125-bip-44-multi-account.md * Update FLIP 200 based on discussion feedback * Update account discovery to cover deleted accounts * Update 20201125-bip-44-multi-account.md * Update 20201125-bip-44-multi-account.md * Update prior art * Update flips/20201125-bip-44-multi-account.md Co-authored-by: Rob Myers <rob@robmyers.org> * Updates FLIP 200 with new proposal updates (#727) * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Updates FLIP 200 with new proposal updates * Update 20201125-bip-44-multi-account.md * mention SLIP-10 * Specify that Key & Account index gap limits are flexible (#832) * Update 20201125-bip-44-multi-account.md Co-authored-by: Rob Myers <rob@robmyers.org> Co-authored-by: Jeff Doyle <jeffrey.doyle@dapperlabs.com> Co-authored-by: Tarak Ben Youssef <50252200+tarakby@users.noreply.github.com> Co-authored-by: Tarak Ben Youssef <tarak.benyoussef@dapperlabs.com>
1 parent e7aca2d commit 6843221

File tree

1 file changed

+326
-0
lines changed

1 file changed

+326
-0
lines changed
+326
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
# Application of BIP 44 in Flow Wallets
2+
3+
| Status | Accepted |
4+
:-------------- |:---------|
5+
| **FLIP #** | [200](https://github.com/onflow/flow/pull/200) |
6+
| **Author(s)** | Peter Siemens (peter@dapperlabs.com), Jeffery Doyle (jeffrey.doyle@dapperlabs.com) |
7+
| **Sponsor** | Peter Siemens (peter@dapperlabs.com) |
8+
| **Updated** | 2022-03-03 |
9+
10+
## Objective
11+
12+
This document aims to define a standard pattern for the application of [Bitcoin
13+
Improvement Proposal
14+
44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) (BIP 44) in
15+
Flow-compatible hardware and software wallets.
16+
17+
## Motivation
18+
19+
This proposal was prompted by the recent development of the first Flow hardware
20+
wallet application (Ledger) and its companion host software (FCL-Ledger-Web among
21+
others).
22+
23+
In the near term, this proposal affects users of the Flow Ledger application. In
24+
the long term, it affects Flow wallet developers and their users.
25+
26+
## User Benefit
27+
28+
By following this standard, developers of existing BIP 44 crypto wallets will be
29+
able to reduce friction for users who wish to create accounts on Flow.
30+
31+
By standardizing BIP 44 usage across wallets, users should be able to use their
32+
BIP 39 mnemonic codes across wallets to manage access to the same keys and accounts.
33+
34+
## Design Proposal
35+
36+
### Path Levels
37+
38+
BIP 44 defines an implementation of [Bitcoin Improvement Proposal
39+
32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) (BIP 32)
40+
that standardizes a format for hierarchical deterministic (HD) key derivation
41+
paths that support multiple coins and multiple accounts per coin.
42+
43+
Flow accounts support keys on two different elliptic curves (secp256k1 and NIST P-256).
44+
While BIP 32 describes the key derivation process for the secp256k1 curve, [SLIP-0010]
45+
(https://github.com/satoshilabs/slips/blob/master/slip-0010.md) generalizes the derivation
46+
process to the NIST P-256 curve. In the rest of this document, BIP 44 is applicable for
47+
both elliptic curves.
48+
49+
The BIP 44 path format is as follows:
50+
51+
```
52+
m / purpose' / coin_type' / account' / change / address_index
53+
```
54+
55+
When using this format to construct or discover a Flow user wallet, the value(s)
56+
of each path parameter should follow the specifications below.
57+
58+
#### Purpose
59+
60+
Purpose is always the constant 44' (0x8000002C), as described in [BIP
61+
44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#purpose).
62+
63+
#### Coin Type
64+
65+
Coin type is always the constant 539' (0x8000021b), the unique identifier for
66+
the Flow protocol, as defined in [SatoshiLabs Improvement Proposal
67+
44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) (SLIP 44).
68+
69+
#### Account
70+
71+
Account is the index of a distinct account address owned by the wallet user. No
72+
two account indices should be used to generate child public keys that are
73+
assigned to the same Flow account address. Furthermore, a single account index
74+
should not be used to generate keys for more than one account address.
75+
76+
The motivation for these accounts is the same set forth in BIP 44:
77+
78+
> Users can use these accounts to organize the funds in the same fashion as bank
79+
> accounts; for donation purposes (where all addresses are considered public),
80+
> for saving purposes, for common expenses etc.
81+
82+
When generating a key pair to be added on a new account, use the smallest
83+
account index that has not already been used to generate keys for an existing account.
84+
85+
Unlike [BIP 44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#account),
86+
new accounts should be able to be created even if previously created accounts
87+
have no transaction history.
88+
89+
#### Change
90+
91+
Unlike Bitcoin, Flow does not utilize change addresses. Change is always the
92+
constant 0.
93+
94+
#### Index
95+
96+
In BIP 44, each index generates a public key that is used to derive a unique
97+
address for an account. Although Flow does not derive account addresses from
98+
public keys, index can still be used to generate multiple public keys for a
99+
single account.
100+
101+
When applying BIP 44 to Flow, each subsequent value for index should be used to
102+
generate a new key pair for the same account, starting from 0 and incrementing
103+
by 1.
104+
105+
This index should not be confused with the on-chain account key index. It must
106+
not be assumed that this index will reflect the on-chain account key index for
107+
any key.
108+
109+
When generating a new key pair for an account, the key index to use in the path to
110+
generate the new key should be the smallest unused key index available which
111+
has not yet been used to generate a key on the account.
112+
113+
### Legacy Path
114+
115+
There exist Flow accounts with keys assigned to them which have been generated
116+
by wallets using the legacy path.
117+
118+
The legacy path has been previously used by FCL-Ledger-Web and is what has been used to
119+
generate keys for Ledger Flow users. As far as we are aware, this is the only
120+
application which has used the legacy path.
121+
122+
The legacy path is _deprecated_ by this FLIP, and should not be used to
123+
generate new keys.
124+
125+
The legacy path is:
126+
127+
```
128+
m / 44' / 1' / 769 / 0 / 0
129+
```
130+
131+
All keys generated with the legacy path as of today (Dec 2021) have been done so using the
132+
NIST P-256 elliptic curve.
133+
134+
### Account Discovery
135+
136+
Wallet developers should use a modified version of the original account
137+
discovery procedure [described in BIP
138+
44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#account-discovery).
139+
140+
Modified constants from BIP 44 include:
141+
142+
The key index gap limit should be `5`.
143+
The account index gap limit should be `2`.
144+
(The key index gap limit and account index gap limit are flexible.
145+
Developers should use their best judgement when choosing a key index gap limit
146+
or account index gap limit.)
147+
148+
The prescribed account discovery procedure is as follows:
149+
150+
1. Derive the key pair using the legacy path and P-256 curve,
151+
checking its use with the public key registry. If an address is found,
152+
query the Flow network to fetch the account's details. If an account
153+
is found, remember the relationship between the path used to generate
154+
this key and the account's details.
155+
2. Derive the key pair(s) (starting with account index = 0 and key index = 0)
156+
using the path specified in this FLIP and each elliptic curve that
157+
both you and Flow support (Flow currently supports keys generated on the
158+
P-256 and secp256k1 curves).
159+
Note: If you are unable to derive keys for a certain elliptic curve,
160+
you may fail to discover an account / key that the user has generated
161+
previously.
162+
3. Scan for each keys usage by querying the public key registry with the key and
163+
elliptic curve used to generate it.
164+
If the gap limit has been reached for both key index and account index, stop
165+
discovery.
166+
- 3.1. If no addresses are found in the registry
167+
- 3.1.1 If the key index gap limit has been reached without finding any
168+
addressed in the registry, then go to step 2, incrementing the account index
169+
by one and starting with key index = 0 again.
170+
- 3.1.2 If the key index gap limit has not been reached, go to step 2 and
171+
increment the key index by one.
172+
- 3.2. If one or more addresses are found, query the Flow network to fetch each
173+
account's details.
174+
- 3.2.1. If no accounts are found<sup>1</sup>, go to step 2, incrementing
175+
the account index by one.
176+
- 3.2.2. For each account found<sup>1</sup>, remember the relationship between the path
177+
used to generate this key, the curve used to generate this key,
178+
and the hash algorithm corresponding to this key and the account's details.
179+
Then go to step 2, incrementing the key index by one.
180+
181+
<sup>1</sup>Flow supports account deletion, meaning that an address found in the
182+
registry may refer to a nonexistent account. In this case the address should be
183+
skipped but discovery should continue.
184+
185+
#### Account Discovery Conflict Resolution
186+
187+
It is possible for a wallet to incorrectly apply the specifications in this FLIP
188+
to generate keys.
189+
190+
Should this scenario occur, compliant wallets may be required to work around any
191+
such previous incorrect usage.
192+
193+
##### Conflict Resolution: Incorrect Use of Account Index
194+
195+
If a wallet has used the account index field incorrectly to generate keys for a
196+
user, conflict resolution logic may be required when attempting to generate new
197+
keys.
198+
199+
When generating additional keys, the correct account index to use in the path to
200+
generate the additional key should be:
201+
202+
- If adding a key to a new account:
203+
- The smallest account index which has not yet been used to generate keys
204+
set on any account.
205+
- If adding a key to an existing account:
206+
- The largest account index that account discovery determines has been
207+
previously used to generate existing keys set on the account, which has also
208+
not been used incorrectly to generate keys set on another account.
209+
- Otherwise, the smallest account index which has not yet been used to
210+
generate keys set on any account.
211+
212+
##### Conflict Resolution: Incorrect Use of Key Index
213+
214+
When generating additional keys for an account, the correct key index to
215+
use in the path to generate the new key should be the smallest unused key index
216+
available which has not yet been used to generate a key on the account.
217+
218+
##### Conflict Resolution: Multiple Signature & Hashing Algorithms Used for Keys Generated Using the Same Path
219+
220+
The same derivation path should not be used with multiple combinations of signature and
221+
hashing algorithms to generate keys set on an account.
222+
223+
The prescribed account discovery algorithm will find keys generated using
224+
all combinations of derivation paths, supported signature algorithms and supported hashing
225+
algorithms. However, wallets should not use the same path twice to apply
226+
it to multiple signature and hashing algorithms to generate keys.
227+
228+
When generating a new key pair for an account, a new path, which has not yet been used in
229+
combination with any signature or hashing algorithm to generate keys set on the account,
230+
should be used.
231+
232+
### Drawbacks
233+
234+
#### Mapping Public Keys to Addresses
235+
236+
A Flow account address is not derived from a public key and is instead assigned
237+
during an on-chain transaction. Flow supports a many-to-many relationship
238+
between accounts and public keys; multiple public keys can be added to a single
239+
account, and a single public key can be added to multiple accounts.
240+
241+
The Flow protocol maintains an index from `address => [publicKey]`, but there is
242+
currently no on-chain reverse mapping from `publicKey => [address]`.
243+
244+
Implementers of this standard will require a separate source of truth, the
245+
public key registry, to return the associated user address for a given public
246+
key. This requirement is mentioned in the [related issues](#related-issues)
247+
section below.
248+
249+
#### Account Key Index Alignment
250+
251+
The Flow protocol assigns an index to each account key that is registered on
252+
chain. When discussing this proposal, Flow contributors considered a variation
253+
that would require the path index to always align with the on-chain index for
254+
the corresponding account.
255+
256+
For example, a user may create an account from a seed phrase and generate public
257+
keys at indices 0, 1 and 2. If added to the account in order, their on-chain
258+
indices would also be 0, 1, 2, resulting in a clear mapping from each on-chain
259+
key to its corresponding derivation path.
260+
261+
The authors of this proposal chose to omit this restriction after considering
262+
that, in many cases, a user may add additional public keys from other sources,
263+
thus breaking the perfect alignment between on-chain and key path indices. Even
264+
without outside keys, it is still possible for keys to be added out of order.
265+
266+
Wallet developers or users should therefore not rely on the false assumption
267+
that the path index of a public key always matches its on-chain account key
268+
index, as doing so will cause confusion and errors.
269+
270+
#### Potential Misuse of BIP 44
271+
272+
One could argue that this is a misuse of the original BIP 44, BIP 43 and BIP 32
273+
standards based on the fact that Flow does not derive addresses directly from
274+
cryptographic public keys.
275+
276+
#### Overdependence on BIP 44
277+
278+
This proposal may also promote an overdependence on the BIP 44 standard,
279+
especially for wallets that do not already implement it. In some cases it may be
280+
better to use a new implementation or adaptation of BIP 32 that is better suited
281+
to the Flow account model.
282+
283+
### Dependencies
284+
285+
* Dependent projects: Flow Ledger application, Flow Port, FCL-Ledger-Web
286+
287+
### Tutorials and Examples
288+
289+
TODO: add examples
290+
291+
### Compatibility
292+
293+
This proposal does not change any existing APIs. The chosen path structure is
294+
meant to maximize forward compatibility in a variety of use cases.
295+
296+
The convention proposed in this document is intended for use by any wallet that
297+
supports the BIP 44 standard.
298+
299+
In particular, this proposal impacts wallet software that is compatible with the
300+
Flow Ledger application, such as FCL-Ledger-Web.
301+
302+
## Related Issues
303+
304+
### Mapping Public Keys to Addresses
305+
306+
As mentioned in the [drawbacks](#drawbacks) section, this proposal necessitates
307+
a public key registry that maps public keys to account addresses.
308+
309+
## Prior Art
310+
311+
This document outlines a specific application of the standard described by [BIP
312+
44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki). This
313+
standard has been widely adopted by Bitcoin, Ethereum and many other
314+
cryptocurrency projects and communities.
315+
316+
[SLIP-0010](https://github.com/satoshilabs/slips/blob/master/slip-0010.md)
317+
is a document that generalizes the BIP 32 key derivation process
318+
to other curves, in particular the NIST P-256 curve supported by Flow accounts.
319+
320+
[SLIP 48](https://github.com/satoshilabs/slips/blob/master/slip-0048.md)
321+
describes an alternative to BIP 44 for Graphene-based networks which, similar to
322+
Flow, do not derive account addresses directly from cryptographic public keys.
323+
324+
## Questions and Discussion Topics
325+
326+
Should the index path parameter be used?

0 commit comments

Comments
 (0)