Key derivation in HD wallets utilizing the prolonged personal key vs hardened derivation

0
4
Key derivation in HD wallets utilizing the prolonged personal key vs hardened derivation


There’s plenty of confusion right here, largely bits and items of the entire scheme that’s Hierarchical Deterministic derivation, and eventually two questions that appear to point lacking some level about it.
The reply to the primary query is No. The second query is extra fascinating :

Let’s begin from prolonged keys, particularly BIP32 keys.
Like personal keys and public keys, prolonged keys may be both “personal” or “public”. I put each in quotes becaus each sorts of prolonged keys do include personal info.
At the least sufficient to trace key use. This mechanism is utilized by {hardware} wallets and “watchonly” software program wallets on a PC.

An prolonged key’s only a base58 encoded serialization of some items of information :

[ magic ][ depth ][ parent fingerprint ][ key index ][ chain code ][ key ]

The place key may be both a public key or a non-public key. Non-public keys are prepended with a single 0x00 byte, so the size of this blob stays the identical.
An prolonged key’s often derived by “traversing” some path, that means you’ll begin your derivation at some mum or dad prolonged key, and consecutively derive little one keys with particular indexes till you lastly derive the ultimate prolonged key within the path.
I will cease utilizing “prolonged” on this reply. Any more I will discuss with an prolonged personal key as xprv and to an prolonged public key as xpub, and simply “keys” generally. Non-extended are simply “personal key” or “public key”.

An xprv or xpub’s magic are 4 bytes to point the community it belongs to: testnet or mainnet (t or x respectively), and the kind of key it’s (pub and prv respectively).
The depth is a byte that indecates how deep an xpriv or xpout is in a path, ranging from 00 because the depth of the grasp key, and incremented by one because the derivation of extra little one keys is finished alongside the trail.
Be aware that up till now, the one distinction between xprv and xpub keys that I discussed is the prv or pub half within the magic.
It additionally ought to be clear that an xprv and xpub may be in the identical path, and in the identical depth. Which means for such pair of xprv and xpub, the [ key ] a part of the could have a 32 byte personal key (prepended with one 00 byte) within the xprv, and a 33 byte public key which is the general public key which which you get from the personal key within the xprv.

A mum or dad’s fingerprint are the primary 4 bytes of the hash160 of the public key of the mum or dad. Which means even when a mum or dad xprv was used to derive a baby xprv, it could have the identical mum or dad fingerprint as if a mum or dad xpub was used to derive a baby xpub.
A parent-child relationship between keys implies that they’re adjoining in a path.

A path is an n-tuple of indexes, often in base 10, separated by /. The vary of an index may be between zero and and 4294967295 (or 2^32-1), the place something in [0,2147483647] follows non-hardnened derivation, and indexes in [2147483648,4294967295] comply with hardened derivation.
You possibly can see that every half of the vary of indexes is used for a special technique. We will say that there are two ranges. [0,2147483647] for non-hardened keys, and [0h,2147483647h] for hardened keys. The h signifies that the index (we’ll name it i) ought to be handled as i + 2147483648.
You are most likely extra prone to see the h notation as a caret ' as a substitute, so 1' == 1h, however I do not assume it is very fairly so I will follow h for now.

An instance of what a path appears to be like like is :

m/0h/1/2h/2/1000000000

The m implies that the important thing at this index is a grasp xprv or grasp xpub. A small m implies that this prolonged key’s a grasp xprv, and massive M a grasp xpub. Following the earlier definitions, you’ll be able to inform that m is the mum or dad of the important thing at 0h, and the important thing at 2h is the kid of the important thing earlier than it at index 1.
To make this simpler to comply with, we’ll annote the completely different keys within the path with letters {a..e} if we imply that these are xprvs and {A..B} if xpubs.

m / 0h / 1 / 2h / 2 / 1000000000
m   a    b   c    d   e

A path is often given with indexes in base10, however in the important thing itself they’re encoded in hex (base16), so a [ key index ] is all the time 4 bytes with zeros prepended if wanted. The depth and index of a grasp key are each alwasy zero, so 00 and 00000000, and so they can get to a most of FF and FFFFFFFF respectively.
So m and a are mum or dad and little one, and so are d and e. The depth of b is 02 and its index is 00000001, and the depth of c is 03 whereas its index is 80000002 (80000000 + 2).
The final little one key to be derived is e. We will say that we adopted a path beginning at m, from it we derived the important thing a at index 0h, then from a we derived the important thing b at index 1.. and so forth. However what does it imply to derive a brand new key?

The remaining two parts within the prolonged key format, the mum or dad’s [ chain code ] and [ key ] are used along with what could be the kid key’s index to derive it.
That implies that to derive c from b, we might feed some operate with b‘s chain code and key, and c‘s index.
A selected instance of our b and c could be :

b :

0488ADE4
02
5C1BD648
00000001
2A7857631386BA23DACAC34180DD1983734E444FDBF774041578E9B6ADB37C19
003C6CB8D0F6A264C91EA8B5030FADAA8E538B020F0A387421A12DE9319DC93368

c :

0488ADE4
03
BEF5A2F9
80000002
04466B9CC8E161E966409CA52986C584F07E9DC81F735DB683C3FF6EC7B1503F
00CBCE0D719ECF7431D88E6A89FA1483E02E35092AF60C042B1DF2FF59FA424DCA

The fields are ordered as within the construction above. On each, the magic says xprv, the depth is incremented between the mum or dad and little one, the fingerprint at c is the hash160 of the general public key that you’d get from the personal key at b, and b‘s index is within the first, non-hardened half of the vary whereas c‘s is the second, hardned half. Lastly the chain code and keys of every of the xprvs are encoded.

Deriving the chain code and key for c from b is finished with a course of referred to as CKDpriv, which suggests deriving a baby xprv from a mum or dad xprv. On this course of we used the chain code and key from b, and the index from c.
The necessary level to make: We solely encoded c after deriving its chain code and key from what could be its index.

Any xprv can be utilized with CKDpriv to derive a baby xprv at any index. The precise manner CKDpriv will act on the enter depends upon the kid’s index being within the hardened vary, or the non-hardned vary. Mainly, a CKDpriv operate runs an HMAC-SHA512 on the mum or dad’s chain code and key, and the kid’s index. This hmac operate takes two values a key* (to not be confused with our occurences of key, shall be refered to as hkey), and textual content.
The mum or dad’s chain code is used because the hkey, whereas the textual content is made up of the mum or dad’s key within the personal key kind if the the kid’s index is within the hardened vary, [0h,2147483647h], and within the public key kind if the index is within the non-hardened vary. It’s then concatenated with the kid’s index.

c‘s index is within the hardened vary, so CKDpriv‘s hmac-sha512 runs with the inputs:

HMAC-SHA512( 2A7857631386BA23DACAC34180DD1983734E444FDBF774041578E9B6ADB37C19,
             003C6CB8D0F6A264C91EA8B5030FADAA8E538B020F0A387421A12DE9319DC9336880000002 )

Which returns a 64 byte hash :

8F6154A0A82D0F68B9E5B586EA66D951DAAA071BEBD390097CC516285C791A6204466B9CC8E161E966409CA52986C584F07E9DC81F735DB683C3FF6EC7B1503F

The 32 bytes on the correct half of this hash, 04466B9C...C7B1503F turn out to be the kid’s (c right here) chain code, and the 32 bytes on the left are used to “tweak”, that means simply “addition mod n” to the mum or dad’s key, on this instance :

  8F6154A0A82D0F68B9E5B586EA66D951DAAA071BEBD390097CC516285C791A62
+
  3C6CB8D0F6A264C91EA8B5030FADAA8E538B020F0A387421A12DE9319DC93368
=
  CBCE0D719ECF7431D88E6A89FA1483E02E35092AF60C042B1DF2FF59FA424DCA   mod n
  • I did not write the 00 prepended bytes within the keys right here as a result of that is simply including numbers, however these zero bytes are crucial for the hash operate, so I purposely included them there.

Now that we have got c‘s chain code and key (in personal key kind), we might wish to really encode c for it to be a usable xprv.
To get the fingerprint from b, we have to know the general public key of the key from b. Because it’s in personal key kind, we’ll should do multiplication:

CBCE0D719ECF7431D88E6A89FA1483E02E35092AF60C042B1DF2FF59FA424DCA * G
= 03501E454BF00751F24B1B489AA925215D66AF2234E3891C3B21A52BEDB3CD711C

Take the hash160 of this public key, and the returned hash is BEF5A2F9A56A94AAB12459F72AD9CF8CF19C7BBE.
The primary 4 bytes are b‘s fingerprint : BEF5A2F9.
Encoding the remainder of c is simple. Begin with the magic xprv since we derived a baby xprv, increment the depth of b by one, then the fingerprint.
Subsequent c‘s index is encoded. We derived index 2h, so this could be 80000002, after which the brand new chain code and key that we acquired from CKDpriv.

That is principally what hardened derivation is. The mum or dad’s personal key and chain code are used to derive the kid key at some hardened index.
What if we wish to derive d? It is at index 2, so a non-hardened index. That is the second case of CKDpriv.

The distinction is in what’s used for the textual content parameter of the HMAC-SHA512 operate. As a substitute of utilizing the mum or dad’s key in personal key kind, we use the general public key kind, so to derive d at index 2 from c, we first discover the general public key of c :

CBCE0D719ECF7431D88E6A89FA1483E02E35092AF60C042B1DF2FF59FA424DCA * G
= 0357BFE1E341D01C69FE5654309956CBEA516822FBA8A601743A012A7896EE8DC2

Then proceed following the identical steps because the above:

HMAC-SHA512( 04466B9CC8E161E966409CA52986C584F07E9DC81F735DB683C3FF6EC7B1503F,
             0357BFE1E341D01C69FE5654309956CBEA516822FBA8A601743A012A7896EE8DC200000002 )

                            tweak                                                            chain code
437984D45C4A2F5840C65B3DC6D7274E2859AD25D092DB032C49AA4D006A426B|CFB71883F01676F587D023CC53A35BC7F88F724B1F8C2892AC1275AC822A3EDD

* observe that 00 is just not prepended to the textual content, since it is a public key.

  437984D45C4A2F5840C65B3DC6D7274E2859AD25D092DB032C49AA4D006A426B
+
  CBCE0D719ECF7431D88E6A89FA1483E02E35092AF60C042B1DF2FF59FA424DCA
=
  0F479245FB19A38A1954C5C7C0EBAB2F9BDFD96A17563EF28A6A4B1A2A764EF4   mod n

hash160( 0357BFE1E341D01C69FE5654309956CBEA516822FBA8A601743A012A7896EE8DC2 )

finger
   print
EE7AB90C|DE56A8C0E2BB086AC49748B8DB9DCE72

The remainder is simple, and we are able to encode :

d :

0488ADE4
04
EE7AB90C
00000002
CFB71883F01676F587D023CC53A35BC7F88F724B1F8C2892AC1275AC822A3EDD
000F479245FB19A38A1954C5C7C0EBAB2F9BDFD96A17563EF28A6A4B1A2A764EF4

The distinction between these two strategies of deriving little one xprvs is refined however necessary. It allows CKDpub, which is a operate to derive little one xpubs from a mum or dad xpub. CKDpub works virtually the identical as CKDpriv‘s non-hardened derivation, however it does the derivation utilizing level addition, so moderately than including up integers to make little one personal keys, we’re including up factors to make little one public keys.
Discover how within the non-hardened derivation we used the mum or dad’s public level for the HMAC-SHA512, we used the tweak because the added worth to the mum or dad personal key to derive the kid personal key, particularly, we derived d‘s personal key.

To know CKDpub, it helps to first learn about yet one more BIP32 operate referred to as Neuter. It is goal is to transform an xprv to an xpub.
Let’s “run” Neuter on our xprv d. We’ll name the ensuing xpub D. Neuter does two issues to an xprv:
1. Substitute the magic from 0488ADE4 to 0488B21E (replaces xprv with xpub)
2. Replaces the personal key within the key area` with the general public level of the identical personal key

for our xprv d, the general public level is:

0F479245FB19A38A1954C5C7C0EBAB2F9BDFD96A17563EF28A6A4B1A2A764EF4 * G
= 02E8445082A72F29B75CA48748A914DF60622A609CACFCE8ED0E35804560741D29

(that is simply regular course of of personal key -> public key)

so the result’s:

D:

0488B21E
04
EE7AB90C
00000002
CFB71883F01676F587D023CC53A35BC7F88F724B1F8C2892AC1275AC822A3EDD
02E8445082A72F29B75CA48748A914DF60622A609CACFCE8ED0E35804560741D29

Now d is “neutered”, D has the general public key encoded, however see how the chain code, depth, fingerprint and index continued. The xpub D is on the identical place within the path because the xprv d. We shall be utilizing the chain code and key (public key) for CKDpub, identical as CKDpriv with non-hardened derivation, however as for CKDpriv, we derived the kid personal key utilizing:

tweak + (mum or dad personal key) = little one personal key

for CKDpub we shall be utilizing:

tweak*G + (mum or dad public key) = little one public key

This works as a result of mum or dad public key is basically simply (mum or dad personal key)*G, and little one public key is simply (little one personal key)*G. That’s, if we take the CKDpriv tweak equation and multiply all parts by G, we get precisely the CKDpub tweak equation.
CKDpub can solely derive little one xpub keys within the non-hardened index vary. It is because the knowledge current within the mum or dad xpub, particularly the general public key within the [ key ], solely applies to the non-hardened vary.
The place in CKDpriv we may use the personal key to know the general public key, we will not go the opposite manner. the HMAC-SHA512 spherical that makes use of public keys in CKDpriv applies to the non-hardened index vary.

Now that we’ve got neutered d to create the xpub D, subsequent within the path is e‘s with index 1000000000 (or 3B9ACA00), which is within the non-hardened vary, so we must always be capable to derive E the kid xpub from D utilizing CKDpub. We begin with hmac-sha512 of the mum or dad chain code as hkey and mum or dad key (public key) concatenated with the kid E‘s index :

HMAC-SHA512( CFB71883F01676F587D023CC53A35BC7F88F724B1F8C2892AC1275AC822A3EDD,
             02E8445082A72F29B75CA48748A914DF60622A609CACFCE8ED0E35804560741D293B9ACA00 )

                            tweak                                                            chain code
37D3E49D8ECB854CC518BBA096F46795A9707860BF0FC95E5B19278C997098D4|C783E67B921D2BEB8F6B389CC646D7263B4145701DADD2161548A8B078E65E9E

Multiply the tweak by the generator G so we are able to tweak the mum or dad’s public key utilizing level addition :

37D3E49D8ECB854CC518BBA096F46795A9707860BF0FC95E5B19278C997098D4 * G
= 0327E992F68217BC3E88CFFC3FEAB475880145413CBE008DB22B496DF4E1C3F864  <- tweak*G

Add the tweak to the mum or dad level. The result’s the kid’s public key :

  0327E992F68217BC3E88CFFC3FEAB475880145413CBE008DB22B496DF4E1C3F864
+
  02E8445082A72F29B75CA48748A914DF60622A609CACFCE8ED0E35804560741D29
=
  022A471424DA5E657499D1FF51CB43C47481A03B1E77F951FE64CEC9F5A48F7011

Get the paren’ts fingerprint :

hash160(02E8445082A72F29B75CA48748A914DF60622A609CACFCE8ED0E35804560741D29) = D880D7D8....

Lastly we are able to encode E :

0488B21E
05
D880D7D8
3B9ACA00
C783E67B921D2BEB8F6B389CC646D7263B4145701DADD2161548A8B078E65E9E
022A471424DA5E657499D1FF51CB43C47481A03B1E77F951FE64CEC9F5A48F7011

Neutering d to make D then deriving E, we are able to say that our path now appears to be like like :

m / 0h / 1 / 2h / 2 / 1000000000
m / a  / b / c  / D / E

Or we are able to use the N() notation (for Neuter) to point out the place CKDpub was used, however I feel it is much less fairly.
m / a / b / c / N(d / e)

So to recap in your query, there are 3 completely different derivation strategies, two utilizing personal keys and one utilizing public keys :

  1. CKDpriv to derive a baby xprv at a hardened index
  2. CKDpriv to derive a baby xprv at a non-hardend index
  3. CKDpub to derive a baby xpub at a non-hardened index

LEAVE A REPLY

Please enter your comment!
Please enter your name here