i tried to replicate code in this git https://github.com/tongokongo/bitcoin-basics/blob/master/HD_wallet/bip32.py .
I'm not familiar with python but the xpub is correct (this is the Test Vector 1 from BIP32) while the xpriv is:
b'Har3K3MhV5fiuEp6ztqjoMJejPsfnrLHAzSWDpkzLGomKaoUPLkSrwPxsdKMbzgsi6eegKG5BMwPyk8RMbDEe6zpHSUnRZMNJkX2HEhDzo41ds7qJVyRkhb3jsGezXb8XB4hW12QKUuxc3pDstNHMuYwEyV'
b'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8'
what's the mistake?
Below the code:
import binascii
import hmac
import hashlib
import struct
import ecdsa
import base58
from ecdsa.curves import SECP256k1
from ecdsa.ecdsa import int_to_string, string_to_int
#chain m
seed = binascii.unhexlify("000102030405060708090a0b0c0d0e0f") #generiamo il seed, importiamo la stringa del test vector
#calcolaiamo ora I come HMAC-SHA512 (seed key="Bitcoin seed" Data = seed) - occorre importare hmac e hashlib
I = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest()
#il risultato ottenuto va diviso in 2 stringhe da 32bytes (Il & Ir)
Il, Ir= I[:32], I[32:]
#il risultato va serializzato come descritto dal BIP32
#priv=xpriv+depth(1byte)+fingerprint(4bytes)+chaincode(32bytes)+chiave(33bytes)
#pub=xpub+depth(1byte)+fingerprint(4bytes)+chaincode(32bytes)+chiave(33bytes)
secret = Il #parte sinistra ottenuta dal HMAC
chain = Ir #parte destra
xprv = binascii.unhexlify("0488ade4") #è la version di default per la mainnet di Bicoin
xpub = binascii.unhexlify("0488b21e") #è la version di default per la mainnet di Bicoin
depth = b"\x00" #come da guida a livello della master "0x00 for master nodes"
fingerp= b"\0\0\0\0" #come da guida a livello dalla master "(0x00000000 if master key)"
index = 0 #index del child al livello della master
child = struct.pack('>L', index) # L = big endian, the way of storing values starting from most significant value in sequence
#importare ECDSA dopo averlo installato. Occorreranno inoltre le librerie:
#from ecdsa.curves import SECP256k1
#from ecdsa.ecdsa import int_to_string, string_to_int
k_priv = ecdsa.SigningKey.from_string(secret, curve=SECP256k1)
k_priv = k_priv.get_verifying_key()
#bisogna ora serializzare la chiave privata come 32bytes con 00 davanti
data_priv = b'\x00' + (k_priv.to_string())
# serialization the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form
if k_priv.pubkey.point.y() & 1:
data_pub = b'\3' + int_to_string(k_priv.pubkey.point.x())
else:
data_pub = b'\2' + int_to_string(k_priv.pubkey.point.x())
raw_priv = xprv + depth + fingerp + child + chain + data_priv
raw_pub = xpub + depth + fingerp + child + chain + data_pub
#print(raw_priv)
#print(raw_pub)
#a questo punto abbiamo ottenuto due strutture da 78 byte che possono essere Codificate base58. Occore però prima trovare e concatenare
#il cheksum da 32 bits (4 bytes). Il Checksum si ottiene con un doppio SHA256
hashed_xprv = hashlib.sha256(raw_priv).digest()
hashed_xprv = hashlib.sha256(hashed_xprv).digest()
hashed_xpub = hashlib.sha256(raw_pub).digest()
hashed_xpub = hashlib.sha256(hashed_xpub).digest()
#vogliamo aggiungere a raw_priv e raw_pub gli ultimi 4 bytes dei digest ottenuti
raw_priv += hashed_xprv[:4]
raw_pub += hashed_xpub[:4]
#codifichiamo ora base58 - importare prima il pacchetto
print(base58.b58encode(raw_priv))
print(base58.b58encode(raw_pub))