Skip to content
This repository has been archived by the owner on Aug 21, 2020. It is now read-only.

HD Chimeric Wallet #18

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions text/1852-hd-chimeric.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
- 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)

# Summary
[summary]: #summary

Specification of the key derivations used for chimeric wallets using BIP32 notation notably for use in the Cardano blockchain.

# Terminology

## Cardano Implementations

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.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be specific about which implementation is targeted by this document?


## Derivation style

Cardano does not use [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) but actually uses [BIP32-Ed25519](https://cardanolaunch.com/assets/Ed25519_BIP.pdf). The `-Ed25519` suffix is often dropped in practice (ex: we say the Byron release of Cardano supports [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) 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:

1) HD Random (notably used initially in Daedalus)
2) HD Sequential (notably used initially in Icarus)

The difference is explained in more detail [here](https://github.com/input-output-hk/cardano-wallet/wiki/About-Address-Derivation) and the difference in master node derivation for the two schemes is detailed in [SLIP-23](https://github.com/satoshilabs/slips/blob/andrewkozlik/slip-0023/slip-0023.md).

## Meaning of *account*

The term "account" is unfortunately an overloaded term so we clarify all its uses here
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌


#### 1) "Account" as a BIP44 derivation level

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.

#### 2) "Account" as a transaction model

Ethereum does not use the UTXO model and instead uses the [*Account model*](https://github.com/ethereum/wiki/wiki/Design-Rationale#accounts-and-not-utxos) for transactions.

#### 3) "Chimeric Account" as a wallet component

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](https://eprint.iacr.org/2018/262.pdf)

## Address Types

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*
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels somewhat wrong to speak about chimeric wallet and chimeric account for Jörmungandr (or for a node in general). Nodes don't have this concept and for them, it's really just about keys. Hence in practice, a "Single" address is an address generated from a single key which references a UTxO, and so forth.


The full list can be found [here](https://github.com/input-output-hk/chain-libs/blob/master/chain-impl-mockchain/doc/address.md#known-type-of-payloads).

## "Staking key" as a usage of a "Chimeric Account"

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.

# Motivation
[motivation]: #motivation

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.

# Decision
[Decision]: #decision

### Decision #1: Extension the Icarus BIP44 model

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 chain*
- `1` 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,

### Decision #2: A new purpose value

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.

# Drawbacks/Implications
[drawbacks]: #drawbacksimplications
[implications]: #drawbacksimplications

This proposal incudes the following restrictions (which we will elaborate further below)

1) 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 per `account'` (it cannot enforce that it is the only one due to malleability of group addresses).

2) Wallets **SHOULD** only `account_index=0` and reserve other values for future usage.

3) 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'`

# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

### Why only allow `account_index=0` for group keys

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

1) 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)

2) 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)

3) 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`

4) In my wallet the grouped address with payment key `m / 1852' / 1815' / 0' / 0 / 14` is still unused and without noticing I send `m / 1852' / 1815' / 0' / 0 / 14 || m / 1852' / 1815' / 0' / 2 / 1` address to somebody else  (who makes a transaction to this address)

5) 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)

### Why use a separate purpose

There are two main reasons:

1) The `44'` in the `purpose` field is meant to indicate BIP44 so if we are not following BIP44, we should not use `44'`.

2) 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 clear `44'` always indicates a legacy address and `1852'` always indicates a bech32 address.

### Alternative that allows multiple staking keys for a single `account'`

A competing proposal called `change=3` for multiple stake keys per `account'` and can be found [here](https://gist.github.com/SebastienGllmt/14cd2a892674bd993061c32f771a8f58).

However, this requirement is not necessary for Jormungandr as Jormungandr supports having a single stake key delegate to multiple pools (called Ratio Stake).