Bip32-Hd-Wallets

在 Python 中測試向量 1 BIP32

  • October 5, 2020

我試圖在這個 git <https://github.com/tongokongo/bitcoin-basics/blob/master/HD_wallet/bip32.py>中複製程式碼。

我不熟悉 python,但 xpub 是正確的(這是來自 BIP32 的測試向量 1),而 xpriv 是:

b’Har3K3MhV5fiuEp6ztqjoMJejPsfnrLHAzSWDpkzLGomKaoUPLkSrwPxsdKMbzgsi6eegKG5BMwPyk8RMbDEe6zpHSUnRZMNJkX2HEhDzo41ds7qJVyRkhb3jsGezXb8XB4hW12QKUuxc3pDstNHMuYwE

b’xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8'

有什麼錯誤?

程式碼下方:

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('&gt;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))

這是我影片中的程式碼。在k_priv = k_priv.get_verifying_key()它應該是大寫K中,我試圖盡可能接近原始的 biputils lib,然後你在 pubkey 相關的數據推導中使用它:

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())

很抱歉讓您感到困惑,下次我會嘗試更好地代表它:)

引用自:https://bitcoin.stackexchange.com/questions/99310