子の秘密鍵は、親のchaincdeと[親の公開鍵+index]をhmac_sha512でハッシュ化して作成している。
### マスター秘密鍵、公開鍵
import os import binascii import hmac import hashlib import ecdsa seed = os.urandom(32) root_key = b"Bitcoin seed" def hmac_sha512(data, key_message): hash = hmac.new(data, key_message, hashlib.sha512).digest() return hash def create_pubkey(private_key): publickey = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1).verifying_key.to_string() return publickey master = hmac_sha512(seed, root_key) master_secretkey = master[:32] master_chaincode = master[32:] master_publickey = create_pubkey(master_secretkey) master_publickey_integer = int.from_bytes(master_publickey[32:], byteorder="big") if master_publickey_integer %2 == 0: master_publickey_x = b"\x02" + master_publickey[:32] else: master_publickey_x = b"\x03" + master_publickey[:32] print(binascii.hexlify(master_secretkey)) print(binascii.hexlify(master_chaincode)) print(binascii.hexlify(master_publickey_x))
$ python3 master_key.py
b’8a6dbaaff700682778dcbae2bc8718452fe5ed80fc9026a9b564420f8d5b0d80′
b’4ce8b10cc0c0874467d8f438c412fdbf21fba51517e668dbc4bd105af6861dec’
b’03cb15210804ca8f0d45b620832be935e2f90c3830f13f04c4bd6e8b4648f27817′
(secretkey, chaincode, pubkey)
### 子秘密鍵、子公開鍵
index = 0 index_bytes = index.to_bytes(8, "big") data = master_publickey_x + index_bytes result_hmac512 = hmac_sha512(data, master_chaincode) sum_integer = int.from_bytes(master_secretkey,"big") + int.from_bytes(result_hmac512[:32],"big") p = 2 ** 256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1 child_secretkey = (sum_integer % p).to_bytes(32,"big") child_chaincode = result_hmac512[32:] child_publickey = create_pubkey(child_secretkey) child_publickey_integer = int.from_bytes(child_publickey[32:], byteorder="big") if child_publickey_integer %2 == 0: child_publickey_x = b"\x02" + child_publickey[:32] else: child_publickey_x = b"\x03" + child_publickey[:32] print(binascii.hexlify(child_secretkey)) print(binascii.hexlify(child_chaincode)) print(binascii.hexlify(child_publickey_x))
b’5ff011a3e9cd672aaf0dc9fd52cb3172ac2815cb270f919135e6b0f0e6e03d54′
b’15f4d148b2d7730076d5e670249649ea8f0fd8572dad3818680e347196149dda’
b’03480a1dbb4a87d867bee3d364b608e21d685af271876707b9f9d5b75c6df6fde7′
—
b’23faf6fad81cd93e12c003c944ba3ef215dae714c638756386b6b9404da5aac9′
b’e3563dc6891e238cd0d8ebf99e65ebfc67cecf42364de9756b89859bbd049b62′
b’02039253af3e828bfbf1e560fe0e923a144fc4496ded3b6bbfa0d568cf7177d1c3′
なるほど、一見複雑そうに見えるが、なかなか面白いね