Post
Topic
Board Development & Technical Discussion
Topic OP
BIP0032 HD Wallet private key derivation incorrect?
by
Wink
on 04/09/2013, 18:09:23 UTC
I have been implementing the BIP0032 HD Wallet protocol, and ran into an issue in the documentation at https://en.bitcoin.it/wiki/BIP_0032 which slowed me down for an entire day. Here is the documentation on private child key derivation.

Private child key derivation
To define CKD((kpar, cpar), i) → (ki, ci):
Check whether the highest bit (0x80000000) of i is set:
If 1, private derivation is used: let I = HMAC-SHA512(Key = cpar, Data = 0x00 || kpar || i) [Note: The 0x00 pads the private key to make it 33 bytes long.]
If 0, public derivation is used: let I = HMAC-SHA512(Key = cpar, Data = χ(kpar*G) || i)
Split I = IL || IR into two 32-byte sequences, IL and IR.
ki = IL + kpar (mod n).
ci = IR.

It says you should add IL to kpar(mod n).
In pseudo code, this would be:
Code:
i_left + (kpar % n)

Adding these two values together should always create a new number that is 32 bytes long. However, for some values of IL and kpar(mod n), adding them together can create a number that is greater than 32 bytes long, and is therefore no longer a valid 256bit private key.

It appears the parenthesis are in the wrong place in the documentation. It should read:

ki = (IL + kpar) mod n.

or in pseudo code:
Code:
(i_left + kpar) % n

Changing the parenthesis finally made all of my test vectors pass. I'm posting this to hopefully save someone else a world of trouble. Can we change the documentation?