Since the Whisper key is being decoupled from the account key and since we are introducing the hardware wallet, we need to define a new path for the Whisper key. We also should define a path for the Database key, so that the database can be encrypted using a key stored on the hardwallet without having to define an additional password.
Since our account key path is m/44’/60’/0’/0/0, I propose assigning to these keys keypaths which are siblings of this path. The reason is that this way we minimize the amount key derivation operations needed.
To allows multiple accounts, I propose using a very high index which will not conflict with possible account paths. Since every component in the path is a 32-bit number, where the most significant bit is a flag to indicate hardened/non-hardened, my idea was to reserve the second most significant bit for keys we might need internally. This way we would have
The last component, if expressed in hex, is 0xC0000000 and 0xC0000001 respectively which is admitedly easier to remember that the decimal representation.
What do you think? Do you see any problems with this?
@michele I think it’s a good idea! And we are not even using possible account addresses because they would be derived with a normal index but we are using an hardened one.
I’m unfortunately not as familiar with this domain as I wish I was, so I’ll just ask some questions instead
What do we mean by “database key”? What’s in this database exactly, does it have a more specific name?
How valuable is it to have a low HD key path?
How do other HW wallets etc solve this problem? More generally, how do people like to separate hardened keys?
How extensible is this design? As an example, let’s see we in the future use 3-5 different protocols/keys (eth/whisper/swarm/foo/bar), and for whisper and eth we want to be able to have many child keys, one for each app. How would this design accommodate that? Imagine different identities and so on. Would they be at the m/44’/60’/XXX’/0/<U+202D>0 level then?
The Status app keeps a database to store some info (I do not know exactly which, but I understand mostly chat logs). This needs to be encrypted so a key needs to be generated
What do you mean?
We are not actually separating hardened keys per-se. We are separating wallets from keys used for non-wallet purpouses
It is extensible since we have about 1 billions possible non-wallet keys following my scheme. Another billion keys is reserved for wallets. Since we have such a huge keyspace, we can keep all the keys at the same level (so far, I have defined only 2 possible values, but others can be added)
The keys we are describing are not wallets, so the BIP44 specs do not apply. The proposal was to use the mechanism described in BIP32 to derive the others keys we need and place them in the keyspace so that they do not conflict with wallets. This way, even when changing device, using your 12 (or 24) words backup you can restore all of your keys, not only wallets.
Using hardened or non-hardened in this case is actually not important, because all keys generated at this level will be leaves (won’t have further nesting).
The reason why I am using the hardened flag and the next bit to split the keyspace is for “future compatibility”, if some BIP comes out defining that the hardened flag is used for some specific wallets we will be able to support it without breaking our current keyspace, since we use a further differentiation bit.
Another key point in this process is attempting to not overlap derivation paths with ones typically used in other wallets for value storage. The “non-wallet” keys that we derive and use need to statistically never have funds in them if someone imports a wallet from another application.
Yeah, since I have used a very high index and hardened keys in my proposal, whereas the accounts are normally unhardened and use a sequential number starting from 0, the chance of someone using that index should be basically non-existant.
There is another issue regarding how we are going to implement this key export in the applet. At the moment, we have an hardcoded list of paths we allow exporting. This is great from a security standpoint, but does not allow extending the list after the applet is installed. So I see 3 possible solutions
Make the list dynamic, so it can be updated using specific commands. If we do not foresee too many paths being used, the command could even replace the entire list instead of being add/remove (for simplicity and security reasons), but then we have to fit in 255 bytes or implement segmentation. In any case there will be a maximum amount of paths that can be stored, since the array will be initialized at installation time.
Make the export command always succeed for key indexes >= 0xC0000000 (if we go with my proposal about partioning the key space). We must then be careful to never use these indexes for any wallet, although this shouldn’t be too much of a problem. This approach is the most simple both from applet and client side, as well as avoid headaches with different clients not agreeing on the list of paths that should be exportable
Keep it hardcoded, but define all possible paths/ranges we might ever need before delivering the applet. Requires see-the-future abilities
I think 0xC0000000 is a very big index, so it can be a good idea. It’s index 1073741824 plus the 2^31 hardening start, so I don’t think it would be ever used.
Unless we go back thinking about a complete different path where we have a root of exportable keys. But if I understand correctly having a completely different path means slowing a lot the derivation from the card.
To second Michele point about the risk to overlap with other wallets paths for value storage, here’s the most complete list of bip44 paths used by wallets that I found (this is MEW popup when connecting ledger)