- Feature Name: Chimeric HD Wallets for Shelley
- Start Date: 2019-10-28
- RFC PR: #18
- Authors:
- Sebastien Guillemot (sebastien@emurgo.io)
- Matthias Benkort (matthias.benkort@iohk.io)
Specification of the key derivations used for chimeric wallets using BIP32 notation notably for use in the Cardano blockchain.
Cardano has two implementations - a Rust implementation (called Jormungandr) and a Haskell implementation. These vary in a few key ways so we refer to them separately.
Cardano does not use BIP32 but actually uses BIP32-Ed25519. The -Ed25519
suffix is often dropped in practice (ex: we say the Byron release of Cardano supports BIP44 but in reality this is BIP44-Ed25519).
The Byron implementation of Cardano uses purpose = 44'
(note: this was already a slight abuse of notation because Cardano implements BIP44-Ed25519 and not standard BIP44).
There are two (incompatible) implementations of BIP32-Ed25519 in Cardano:
- HD Random (notably used initially in Daedalus)
- HD Sequential (notably used initially in Icarus)
The difference is explained in more detail here and the difference in master node derivation for the two schemes is detailed in SLIP-23.
The term "account" is unfortunately an overloaded term so we clarify all its uses here
BIP44 uses the term "account" as one derivation level to mean the following
This level splits the key space into independent user identities, so the wallet never mixes the coins across different accounts.
To differentiate this from other usage, we sometimes refer to it as an account'
(uses its bip32 notation) or a BIP44 Account.
Ethereum does not use the UTXO model and instead uses the Account model for transactions.
A chimeric wallet is a wallet that supports both the UTXO model and the account model using a single mnemonic. We say a Chimeric Account is the account model component of the chimeric wallet. The relationship between the Account model and the UTXO model is explored in the Chimeric Ledger paper
Jormungandr has multiple address types. This specification relates to
- Single type: an address generated from a single UTXO derivation of a chimeric wallet. This key is sometimes called a payment key or a spending key.
- Account type: an address generated from a single chimeric account key.
- Group type: an address generated by the concatenation of a spending key and an account key
The full list can be found here.
When a Chimeric Account key is used inside a group-type address for staking purposes, it is sometimes referred to as a staking key.
Note: for Jormungandr, the concept of "staking keys" is purely semantic but for the Haskell implementation of Cardano, staking keys are a native concept separate from chimeric accounts.
We extend the derivation scheme for Cardano wallets to support Chimeric wallets. Additionally, since Jormungandr does not differentiate between chimeric accounts and staking keys at the node level, we need to specify how wallet software must handle these keys.
Recall that BIP44 specifies the following derivation path
m / purpose' / coin_type' / account' / change / address_index
Here, change
can be either
0
indicating an external chain1
indicating an internal chain
We extend this to add a new level
2
indicating a chimeric account
resulting in the following
m / purpose' / coin_type' / account' / 2 / account_index
Wallets MUST implement this new scheme using the master node derivation algorithm from Icarus with sequential addressing,
For this extension, we use purpose = 1852'
Rationale for number: The Cardano BIP44 Coin Type is 1815'
based on the year of birth of Dada Lovelace. To stay consistent in the theming, 1852 was picked as it is the year of death of Ada Lovelace.
This proposal incudes the following restrictions (which we will elaborate further below)
-
Group-type addresses SHOULD only be created using the account key
change = 2 / account_index = 0
. Other accounts may exist, but they should not be grouped. In other words, wallets SHOULD only generate one staking key peraccount'
(it cannot enforce that it is the only one due to malleability of group addresses). -
Wallets SHOULD only
account_index=0
and reserve other values for future usage. -
Wallet software SHOULD perform bip44 account detection as defined in the bip44 spec to handle wallets with multiple
account'
- This allows a wallet to have multiple stake keys by using different indices for
account'
- This allows a wallet to have multiple stake keys by using different indices for
The concept of grouped addresses already has privacy loss associated with it because anybody who looks at the blockchain can tell all transactions with the same staking key belong to the same person. This gives the same privacy as the accounting model
Creating multiple child derivations for change=2
makes the privacy loss even worse because now the payment keys are the same for each staking key which means somebody can detect these staking keys belong to the same person just by using a block explorer.
Here is an example to illustrate this
- Suppose I have a wallet currently have a single UTXO at
m / 1852' / 1815' / 0' / 0 / 0
with staking key m / 1852' / 1815' / 0' / 2 / 0
so as per sequential addressing rules, I can use any payment key up to m / 1852' / 1815' / 0' / 0 / 20
(I can have at most 20 unused external addresses)
- I send send somebody a link to my grouped address (but don’t receive anything yet)
m / 1852' / 1815' / 0' / 0 / 14 || m / 1852' / 1815' / 0' / 2 / 0
(use ||
to denote concatenation of my payment key and my staking key)
-
I switch my stake to a new staking key, I send all my funds to the staking key directly (w.l.o.g. use payment key
m / 1852' / 1815' / 0' / 0 / 0
)m / 1852' / 1815' / 0' / 0 / 0 || m / 1852' / 1815' / 0' / 2 / 1
-
In my wallet the grouped address with payment key
m / 1852' / 1815' / 0' / 0 / 14
is still unused and without noticing I sendm / 1852' / 1815' / 0' / 0 / 14 || m / 1852' / 1815' / 0' / 2 / 1
address to somebody else (who makes a transaction to this address) -
The person from step (2) finally makes a transaction to my grouped address
now we have two addresses with the same payment key (but different staking key), so the owner of both staking keys has a may be the same person (cannot be 100% sure due to address malleability)
There are two main reasons:
-
The
44'
in thepurpose
field is meant to indicate BIP44 so if we are not following BIP44, we should not use44'
. -
Shelley requires all addresses to be in bech32 format. If we reused the same purpose, then given the derivation path
m / 1852' / 1815' / 0' / 0 / 0
, wallet software would not be able to know which address should be generated (legacy address of bech32 address). By using a separate purpose, it is now clear44'
always indicates a legacy address and1852'
always indicates a bech32 address.
A competing proposal called change=3
for multiple stake keys per account'
and can be found here.
However, this requirement is not necessary for Jormungandr as Jormungandr supports having a single stake key delegate to multiple pools (called Ratio Stake).