# BIP-44 derivation paths

Each coin uses [BIP-44] derivation path scheme. If the coin is UTXO-based the path
should have all five parts, precisely as defined in [BIP-32]. If it is account-based we
follow Stellar's [SEP-0005] - paths have only three parts `44'/c'/a'`. Unfortunately,
lot of exceptions occur due to compatibility reasons.

Keys are derived according to [SLIP-10], which is a superset of the BIP-32 derivation
algorithm, extended to work on other curves.

[bip-44]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
[bip-32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
[sep-0005]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md
[slip-10]: https://github.com/satoshilabs/slips/blob/master/slip-0010.md

## List of used derivation paths

| coin     | curve     | path               | public node | note           |
| -------- | --------- | ------------------ | ----------- | -------------- |
| Bitcoin  | secp256k1 | `44'/c'/a'/y/i`    | yes         | [1](#Bitcoin)  |
| Ethereum | secp256k1 | `44'/c'/0'/0/a`    | yes         | [2](#Ethereum) |
| Ripple   | secp256k1 | `44'/144'/a'/0/0`  |             | [3](#Ripple)   |
| EOS      | secp256k1 | `44'/194'/a'/0/0`  |             | [3](#Ripple)   |
| Binance  | secp256k1 | `44'/714'/a'/0/0`  |             | [3](#Ripple)   |
| Tron     | secp256k1 | TODO               |             | TODO           |
| Ontology | nist256p1 | TODO               |             | TODO           |
| Cardano  | ed25519   | `44'/1815'/a'/y/i` | yes         | [4](#Cardano)  |
| Stellar  | ed25519   | `44'/148'/a'`      |             |                |
| Lisk     | ed25519   | `44'/134'/a'`      |             |                |
| NEM      | ed25519   | `44'/43'/a'`       |             | [5](#NEM)      |
| Monero   | ed25519   | `44'/128'/a'`      |             |                |
| Tezos    | ed25519   | `44'/1729'/a'`     |             | [6](#Tezos)    |

`c` stands for the [SLIP-44 id] of the currency, when multiple currencies are handled
by the same code. `a` is an account number, `y` is change address indicator (must be
0 or 1), and `i` is address index.

[slip-44 id]: https://github.com/satoshilabs/slips/blob/master/slip-0044.md

Paths that do not conform to this table are allowed, but user needs to confirm a warning
on Trezor.

### Public nodes

Some currencies allow exporting a _public node_, which lets the client derive all
non-hardened paths below it. In that case, the conforming path is equal to the
hardened prefix.

I.e., for Bitcoin's path `44'/c'/a'/y/i`, the allowed public node path is `44'/c'/a'`.

Trezor does not check if the path is followed by other non-hardened items (anyone can
derive those anyway). This is beneficial for Ethereum and its MEW compatibility, which
sends `44'/60'/0'/0` for getPublicKey.

### Notes

1. <a name="Bitcoin"></a> For Bitcoin and its derivatives it is a little bit more
   complicated. `p` is decided based on the following table:

   | p   | type            | input script type |
   | --- | --------------- | ----------------- |
   | 44  | legacy          | SPENDADDRESS      |
   | 48  | legacy multisig | SPENDMULTISIG     |
   | 49  | p2sh segwit     | SPENDP2SHWITNESS  |
   | 84  | native segwit   | SPENDWITNESS      |

   Other `p` are disallowed.

2. <a name="Ethereum"></a> We believe this should be `44'/c'/a'`, because Ethereum is
   account-based, rather than UTXO-based. Unfortunately, lot of Ethereum tools (MEW,
   Metamask) do not use such scheme and set `a = 0` and then iterate the address index
   `i`. Therefore for compatibility reasons we use the same scheme.

3. <a name="Ripple"></a> Similar to Ethereum this should be `44'/c'/a'`. But for
   compatibility with other HW vendors we use `44'/c'/a'/0/0`.

4. <a name="Cardano"></a> Cardano has a [custom derivation] algorithm that allows
   non-hardened derivation on ed25519.

[custom derivation]: https://cardanolaunch.com/assets/Ed25519_BIP.pdf

5. <a name="NEM"></a> NEM's path should be `44'/43'/a'` as per SEP-0005, but we allow
   `44'/43'/a'/0'/0'` as well for compatibility reasons with NanoWallet.

6. <a name="Tezos"></a> Tezos supports multiple curves, but Trezor currently supports
   ed25519 only.

Sign message paths are validated in the same way as the sign tx paths are.

## Allowed values

For UTXO-based currencies, account number `a` needs to be in the interval \[0, 20]
and address index `i` in the interval \[0, 1 000 000].

For account-based currencies (i.e., those that do not use address indexes), account
number `a` needs to be in the interval \[0, 1 000 000]
