I have a small Python program I'm writing to generate BIP32 keys, including child keys. I've gotten to the point where I can correctly generate a master extended key pair, but I'm not able to correctly derive a child private key and chain code. I've copied my code below:
import hmac
import struct
from hashlib import sha512
def CKDprv(chain, data):
data = data.to_bytes(33, 'big') + struct.pack('>L', 0)
return hmac.new(chain.to_bytes(32, 'big'), data, sha512).digest()
def split_key(key):
length = len(key) // 2
return key[:length], key[length:]
pub = 0x0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2
chain = 0x873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508
digest = CKDprv(chain, pub)
new_prv, new_chain = split_key(digest)
print(f'Chain code: {new_chain.hex()}')
I am using some BIP32 test vectors and trying to derive m/0' from m. I am deriving a child key with index 0, so I am hashing the parent compressed public key appended with the index represented in 4 bytes. According to the test vectors, the new chain code I should be deriving is:
47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141
but the chain code I receive from my function is:
d323f1be5af39a2d2f08f5e8f664633849653dbe329802e9847cfc85f8d7b52a
I've tried variations such as changing endianness, but nothing seems to get me the correct hash. I know I've probably made a small programming error that is throwing me off completely, and I've been staring at this problem with no progress for a few days now. If anyone can point out the flaw in my algorithm I would be greatly appreciated.