-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
1 parent
e7aca2d
commit 6843221
Showing
1 changed file
with
326 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,326 @@ | ||
# Application of BIP 44 in Flow Wallets | ||
|
||
| Status | Accepted | | ||
:-------------- |:---------| | ||
| **FLIP #** | [200](https://github.com/onflow/flow/pull/200) | | ||
| **Author(s)** | Peter Siemens (peter@dapperlabs.com), Jeffery Doyle (jeffrey.doyle@dapperlabs.com) | | ||
| **Sponsor** | Peter Siemens (peter@dapperlabs.com) | | ||
| **Updated** | 2022-03-03 | | ||
|
||
## Objective | ||
|
||
This document aims to define a standard pattern for the application of [Bitcoin | ||
Improvement Proposal | ||
44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) (BIP 44) in | ||
Flow-compatible hardware and software wallets. | ||
|
||
## Motivation | ||
|
||
This proposal was prompted by the recent development of the first Flow hardware | ||
wallet application (Ledger) and its companion host software (FCL-Ledger-Web among | ||
others). | ||
|
||
In the near term, this proposal affects users of the Flow Ledger application. In | ||
the long term, it affects Flow wallet developers and their users. | ||
|
||
## User Benefit | ||
|
||
By following this standard, developers of existing BIP 44 crypto wallets will be | ||
able to reduce friction for users who wish to create accounts on Flow. | ||
|
||
By standardizing BIP 44 usage across wallets, users should be able to use their | ||
BIP 39 mnemonic codes across wallets to manage access to the same keys and accounts. | ||
|
||
## Design Proposal | ||
|
||
### Path Levels | ||
|
||
BIP 44 defines an implementation of [Bitcoin Improvement Proposal | ||
32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) (BIP 32) | ||
that standardizes a format for hierarchical deterministic (HD) key derivation | ||
paths that support multiple coins and multiple accounts per coin. | ||
|
||
Flow accounts support keys on two different elliptic curves (secp256k1 and NIST P-256). | ||
While BIP 32 describes the key derivation process for the secp256k1 curve, [SLIP-0010] | ||
(https://github.com/satoshilabs/slips/blob/master/slip-0010.md) generalizes the derivation | ||
process to the NIST P-256 curve. In the rest of this document, BIP 44 is applicable for | ||
both elliptic curves. | ||
|
||
The BIP 44 path format is as follows: | ||
|
||
``` | ||
m / purpose' / coin_type' / account' / change / address_index | ||
``` | ||
|
||
When using this format to construct or discover a Flow user wallet, the value(s) | ||
of each path parameter should follow the specifications below. | ||
|
||
#### Purpose | ||
|
||
Purpose is always the constant 44' (0x8000002C), as described in [BIP | ||
44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#purpose). | ||
|
||
#### Coin Type | ||
|
||
Coin type is always the constant 539' (0x8000021b), the unique identifier for | ||
the Flow protocol, as defined in [SatoshiLabs Improvement Proposal | ||
44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) (SLIP 44). | ||
|
||
#### Account | ||
|
||
Account is the index of a distinct account address owned by the wallet user. No | ||
two account indices should be used to generate child public keys that are | ||
assigned to the same Flow account address. Furthermore, a single account index | ||
should not be used to generate keys for more than one account address. | ||
|
||
The motivation for these accounts is the same set forth in BIP 44: | ||
|
||
> 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. | ||
When generating a key pair to be added on a new account, use the smallest | ||
account index that has not already been used to generate keys for an existing account. | ||
|
||
Unlike [BIP 44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#account), | ||
new accounts should be able to be created even if previously created accounts | ||
have no transaction history. | ||
|
||
#### Change | ||
|
||
Unlike Bitcoin, Flow does not utilize change addresses. Change is always the | ||
constant 0. | ||
|
||
#### Index | ||
|
||
In BIP 44, each index generates a public key that is used to derive a unique | ||
address for an account. Although Flow does not derive account addresses from | ||
public keys, index can still be used to generate multiple public keys for a | ||
single account. | ||
|
||
When applying BIP 44 to Flow, each subsequent value for index should be used to | ||
generate a new key pair for the same account, starting from 0 and incrementing | ||
by 1. | ||
|
||
This index should not be confused with the on-chain account key index. It must | ||
not be assumed that this index will reflect the on-chain account key index for | ||
any key. | ||
|
||
When generating a new key pair for an account, the key index to use in the path to | ||
generate the new key should be the smallest unused key index available which | ||
has not yet been used to generate a key on the account. | ||
|
||
### Legacy Path | ||
|
||
There exist Flow accounts with keys assigned to them which have been generated | ||
by wallets using the legacy path. | ||
|
||
The legacy path has been previously used by FCL-Ledger-Web and is what has been used to | ||
generate keys for Ledger Flow users. As far as we are aware, this is the only | ||
application which has used the legacy path. | ||
|
||
The legacy path is _deprecated_ by this FLIP, and should not be used to | ||
generate new keys. | ||
|
||
The legacy path is: | ||
|
||
``` | ||
m / 44' / 1' / 769 / 0 / 0 | ||
``` | ||
|
||
All keys generated with the legacy path as of today (Dec 2021) have been done so using the | ||
NIST P-256 elliptic curve. | ||
|
||
### Account Discovery | ||
|
||
Wallet developers should use a modified version of the original account | ||
discovery procedure [described in BIP | ||
44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#account-discovery). | ||
|
||
Modified constants from BIP 44 include: | ||
|
||
The key index gap limit should be `5`. | ||
The account index gap limit should be `2`. | ||
(The key index gap limit and account index gap limit are flexible. | ||
Developers should use their best judgement when choosing a key index gap limit | ||
or account index gap limit.) | ||
|
||
The prescribed account discovery procedure is as follows: | ||
|
||
1. Derive the key pair using the legacy path and P-256 curve, | ||
checking its use with the public key registry. If an address is found, | ||
query the Flow network to fetch the account's details. If an account | ||
is found, remember the relationship between the path used to generate | ||
this key and the account's details. | ||
2. Derive the key pair(s) (starting with account index = 0 and key index = 0) | ||
using the path specified in this FLIP and each elliptic curve that | ||
both you and Flow support (Flow currently supports keys generated on the | ||
P-256 and secp256k1 curves). | ||
Note: If you are unable to derive keys for a certain elliptic curve, | ||
you may fail to discover an account / key that the user has generated | ||
previously. | ||
3. Scan for each keys usage by querying the public key registry with the key and | ||
elliptic curve used to generate it. | ||
If the gap limit has been reached for both key index and account index, stop | ||
discovery. | ||
- 3.1. If no addresses are found in the registry | ||
- 3.1.1 If the key index gap limit has been reached without finding any | ||
addressed in the registry, then go to step 2, incrementing the account index | ||
by one and starting with key index = 0 again. | ||
- 3.1.2 If the key index gap limit has not been reached, go to step 2 and | ||
increment the key index by one. | ||
- 3.2. If one or more addresses are found, query the Flow network to fetch each | ||
account's details. | ||
- 3.2.1. If no accounts are found<sup>1</sup>, go to step 2, incrementing | ||
the account index by one. | ||
- 3.2.2. For each account found<sup>1</sup>, remember the relationship between the path | ||
used to generate this key, the curve used to generate this key, | ||
and the hash algorithm corresponding to this key and the account's details. | ||
Then go to step 2, incrementing the key index by one. | ||
|
||
<sup>1</sup>Flow supports account deletion, meaning that an address found in the | ||
registry may refer to a nonexistent account. In this case the address should be | ||
skipped but discovery should continue. | ||
|
||
#### Account Discovery Conflict Resolution | ||
|
||
It is possible for a wallet to incorrectly apply the specifications in this FLIP | ||
to generate keys. | ||
|
||
Should this scenario occur, compliant wallets may be required to work around any | ||
such previous incorrect usage. | ||
|
||
##### Conflict Resolution: Incorrect Use of Account Index | ||
|
||
If a wallet has used the account index field incorrectly to generate keys for a | ||
user, conflict resolution logic may be required when attempting to generate new | ||
keys. | ||
|
||
When generating additional keys, the correct account index to use in the path to | ||
generate the additional key should be: | ||
|
||
- If adding a key to a new account: | ||
- The smallest account index which has not yet been used to generate keys | ||
set on any account. | ||
- If adding a key to an existing account: | ||
- The largest account index that account discovery determines has been | ||
previously used to generate existing keys set on the account, which has also | ||
not been used incorrectly to generate keys set on another account. | ||
- Otherwise, the smallest account index which has not yet been used to | ||
generate keys set on any account. | ||
|
||
##### Conflict Resolution: Incorrect Use of Key Index | ||
|
||
When generating additional keys for an account, the correct key index to | ||
use in the path to generate the new key should be the smallest unused key index | ||
available which has not yet been used to generate a key on the account. | ||
|
||
##### Conflict Resolution: Multiple Signature & Hashing Algorithms Used for Keys Generated Using the Same Path | ||
|
||
The same derivation path should not be used with multiple combinations of signature and | ||
hashing algorithms to generate keys set on an account. | ||
|
||
The prescribed account discovery algorithm will find keys generated using | ||
all combinations of derivation paths, supported signature algorithms and supported hashing | ||
algorithms. However, wallets should not use the same path twice to apply | ||
it to multiple signature and hashing algorithms to generate keys. | ||
|
||
When generating a new key pair for an account, a new path, which has not yet been used in | ||
combination with any signature or hashing algorithm to generate keys set on the account, | ||
should be used. | ||
|
||
### Drawbacks | ||
|
||
#### Mapping Public Keys to Addresses | ||
|
||
A Flow account address is not derived from a public key and is instead assigned | ||
during an on-chain transaction. Flow supports a many-to-many relationship | ||
between accounts and public keys; multiple public keys can be added to a single | ||
account, and a single public key can be added to multiple accounts. | ||
|
||
The Flow protocol maintains an index from `address => [publicKey]`, but there is | ||
currently no on-chain reverse mapping from `publicKey => [address]`. | ||
|
||
Implementers of this standard will require a separate source of truth, the | ||
public key registry, to return the associated user address for a given public | ||
key. This requirement is mentioned in the [related issues](#related-issues) | ||
section below. | ||
|
||
#### Account Key Index Alignment | ||
|
||
The Flow protocol assigns an index to each account key that is registered on | ||
chain. When discussing this proposal, Flow contributors considered a variation | ||
that would require the path index to always align with the on-chain index for | ||
the corresponding account. | ||
|
||
For example, a user may create an account from a seed phrase and generate public | ||
keys at indices 0, 1 and 2. If added to the account in order, their on-chain | ||
indices would also be 0, 1, 2, resulting in a clear mapping from each on-chain | ||
key to its corresponding derivation path. | ||
|
||
The authors of this proposal chose to omit this restriction after considering | ||
that, in many cases, a user may add additional public keys from other sources, | ||
thus breaking the perfect alignment between on-chain and key path indices. Even | ||
without outside keys, it is still possible for keys to be added out of order. | ||
|
||
Wallet developers or users should therefore not rely on the false assumption | ||
that the path index of a public key always matches its on-chain account key | ||
index, as doing so will cause confusion and errors. | ||
|
||
#### Potential Misuse of BIP 44 | ||
|
||
One could argue that this is a misuse of the original BIP 44, BIP 43 and BIP 32 | ||
standards based on the fact that Flow does not derive addresses directly from | ||
cryptographic public keys. | ||
|
||
#### Overdependence on BIP 44 | ||
|
||
This proposal may also promote an overdependence on the BIP 44 standard, | ||
especially for wallets that do not already implement it. In some cases it may be | ||
better to use a new implementation or adaptation of BIP 32 that is better suited | ||
to the Flow account model. | ||
|
||
### Dependencies | ||
|
||
* Dependent projects: Flow Ledger application, Flow Port, FCL-Ledger-Web | ||
|
||
### Tutorials and Examples | ||
|
||
TODO: add examples | ||
|
||
### Compatibility | ||
|
||
This proposal does not change any existing APIs. The chosen path structure is | ||
meant to maximize forward compatibility in a variety of use cases. | ||
|
||
The convention proposed in this document is intended for use by any wallet that | ||
supports the BIP 44 standard. | ||
|
||
In particular, this proposal impacts wallet software that is compatible with the | ||
Flow Ledger application, such as FCL-Ledger-Web. | ||
|
||
## Related Issues | ||
|
||
### Mapping Public Keys to Addresses | ||
|
||
As mentioned in the [drawbacks](#drawbacks) section, this proposal necessitates | ||
a public key registry that maps public keys to account addresses. | ||
|
||
## Prior Art | ||
|
||
This document outlines a specific application of the standard described by [BIP | ||
44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki). This | ||
standard has been widely adopted by Bitcoin, Ethereum and many other | ||
cryptocurrency projects and communities. | ||
|
||
[SLIP-0010](https://github.com/satoshilabs/slips/blob/master/slip-0010.md) | ||
is a document that generalizes the BIP 32 key derivation process | ||
to other curves, in particular the NIST P-256 curve supported by Flow accounts. | ||
|
||
[SLIP 48](https://github.com/satoshilabs/slips/blob/master/slip-0048.md) | ||
describes an alternative to BIP 44 for Graphene-based networks which, similar to | ||
Flow, do not derive account addresses directly from cryptographic public keys. | ||
|
||
## Questions and Discussion Topics | ||
|
||
Should the index path parameter be used? |
6843221
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
flow-docs – ./
flow-docs-onflow.vercel.app
flow-docs.vercel.app
docs.onflow.org
flow-docs-git-master-onflow.vercel.app