HD Wallets

In Cardano, hierarchical deterministic (HD) wallets are similar to those described in BIP-0032.

Deterministic wallets and elliptic curve mathematics permit schemes where one can calculate a wallet public keys without revealing its private keys. This permits for example a webshop business to let its webserver generate fresh addresses (public key hashes) for each order or for each customer, without giving the webserver access to the corresponding private keys (which are required for spending the received funds). However, deterministic wallets typically consist of a single “chain” of keypairs. The fact that there is only one chain means that sharing a wallet happens on an all-or-nothing basis.

However, in some cases one only wants some (public) keys to be shared and recoverable. In the example of a webshop, the webserver does not need access to all public keys of the merchant’s wallet; only to those addresses which are used to receive customer’s payments, and not for example the change addresses that are generated when the merchant spends money. Hierarchical deterministic wallets allow such selective sharing by supporting multiple keypair chains, derived from a single root.

Notation

Conceptually, HD derivation can be seen as a tree with many branches, where keys live at each node and leaf such that an entire sub-tree can be recovered from only a parent key (and seemingly, the whole tree can be recovered from the root master key).

For deriving new keys from parent keys, we use the same approach as defined in BIP32-Ed25519: Hierarchical Deterministic Keys over a Non-linear Keyspace.

We note \(CKD_{priv}\) the derivation of a private child key from a parent private key such that:

$$ CKD_{prv}((k^P, c^P), i) → (k_i, c_i) $$

We note \(CKD_{pub}\) the derivation of a public child key from a parent public key such that:

$$ i < 2^{31}: CKD_{pub}((A^P, c^P), i) → (A_i, c_i) $$

Note

This is only possible for so-called “soft” derivation indexes, smaller than \(2^{31}\).

We note \(N\) the public key corresponding to a private key such that:

$$ N(k, c) → (A, c) $$

To shorten notation, we will borrow the same notation as described in BIP-0032 and write \(CKD_{priv}(CKD_{priv}(CKD_{priv}(m,3H),2),5)\) as m/3H/2/5. Equivalently for public keys, we write \(CKD_{pub}(CKD_{pub}(CKD_{pub}(M,3),2),5)\) as M/3/2/5.

Path Levels

Cardano wallet defines the following path levels:

$$ m / purpose_H / coin\_type_H / account_H / account\_type / address\_index $$

  • \(purpose_H\) is set to \(1852_H\)
  • \(coin\_type_H\) is set to \(1815_H\)
  • \(account_H\) is set for now to \(0_H\)
  • \(account\_type\) is either:
    • 0 to indicate an address on the external chain, that is, an address that is meant to be public and communicated to other users.
    • 1 to indicate an address on the internal chain, that is, an address that is meant for change, generated by a wallet software.
    • 2 to indicate a reward account address, used for delegation.
  • \(address\_index\) is either:
    • 0 if the \(account\_type\) is 2
    • Anything between \(0\) and \(2^{31}\) otherwise

In the Byron era, sequential wallets used in Yoroi (a.k.a Icarus wallets) have been using \(purpose = 44_H\) according to standard BIP-44 wallets. The Shelley era introduces however an extension to BIP-44, and therefore, uses a different \(purpose\) number.

Account Discovery

What follows is taken from the “Account Discovery” section from BIP-0044

When the master seed is imported from an external source the software should start to discover the accounts in the following manner:

  • derive the first account’s node (index = 0)
  • derive the external chain node of this account
  • scan addresses of the external chain; respect the gap limit described below
  • if no transactions are found on the external chain, stop discovery
  • if there are some transactions, increase the account index and go to step 1

For the algorithm to be successful, software should disallow creation of new accounts if previous one has no transaction history.

Please note that the algorithm works with the transaction history, not account balances, so you can have an account with 0 total coins and the algorithm will still continue with discovery.

Address gap limit

Address gap limit is currently set to 20. If the software hits 20 unused addresses in a row, it expects there are no used addresses beyond this point and stops searching the address chain. We scan just the external chains, because internal chains receive only coins that come from the associated external chains.

Wallet software should warn when the user is trying to exceed the gap limit on an external chain by generating a new address.

Links to this page