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 derivationTo 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:
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:
(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?