Made bip32 extended key serialization functions more generic and allow passing params, with default params for master keys. Simplified some of the main.py test code.
This commit is contained in:
parent
fc0bb21e7f
commit
f41b566576
32
bip32.py
32
bip32.py
|
@ -21,25 +21,21 @@ PRV_VER = bytes.fromhex( '02fac398' if DOGE_MODE else '0488ADE4' )
|
||||||
# 0488B21E - bitcoin pub
|
# 0488B21E - bitcoin pub
|
||||||
# 02facafd - dogecoin pub
|
# 02facafd - dogecoin pub
|
||||||
PUB_VER = bytes.fromhex( '02facafd' if DOGE_MODE else '0488B21E' )
|
PUB_VER = bytes.fromhex( '02facafd' if DOGE_MODE else '0488B21E' )
|
||||||
# return serialized master private key string from master private (key, chain) bytes pair
|
|
||||||
def serializeMasterPrvKey( master ):
|
|
||||||
depth = 0
|
|
||||||
parFP = intBytes( 0, 4 ) # parent fingerprint
|
|
||||||
childNum = 0
|
|
||||||
prvroot = base58.encodeCheck( PRV_VER, intBytes( depth, 1 ) +
|
|
||||||
parFP + intBytes( childNum, 4 ) + master[1] +
|
|
||||||
b'\x00' + master[0] )
|
|
||||||
return prvroot
|
|
||||||
|
|
||||||
# return serialized master public key string from master private (key, chain) bytes pair
|
# serialize an extended private key (key, chain)
|
||||||
def serializeMasterPubKey( master ):
|
# parfp is the 4byte parent fingerprint
|
||||||
depth = 0
|
# default parameters assume master key
|
||||||
parFP = intBytes( 0, 4 ) # parent fingerprint
|
def serializeExtPrvKey( key, depth=0, parfp=b'\x00\x00\x00\x00', child=0 ):
|
||||||
childNum = 0
|
return base58.encodeCheck( PRV_VER, intBytes( depth, 1 ) +
|
||||||
pubroot = base58.encodeCheck( PUB_VER, intBytes( depth, 1 ) +
|
parfp + intBytes( child, 4 ) + key[1] + b'\x00' + key[0] )
|
||||||
parFP + intBytes( childNum, 4 ) + master[1] +
|
|
||||||
keys.getPubKey( master[0] ) )
|
# serialize an extended public key (key, chain)
|
||||||
return pubroot
|
# key is compressed public point bytes
|
||||||
|
# parfp is the 4byte parent fingerprint
|
||||||
|
# default parameters assume master key
|
||||||
|
def serializeExtPubKey( key, depth=0, parfp=b'\x00\x00\x00\x00', child=0 ):
|
||||||
|
return base58.encodeCheck( PUB_VER, intBytes( depth, 1 ) +
|
||||||
|
parfp + intBytes( child, 4 ) + key[1] + key[0] )
|
||||||
|
|
||||||
# public parent -> public child.
|
# public parent -> public child.
|
||||||
# pub is (key, chain) where key is the compressed pubkey bytes
|
# pub is (key, chain) where key is the compressed pubkey bytes
|
||||||
|
|
13
keys.py
13
keys.py
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
from hashlib import new as newhash
|
from hashlib import new as newhash
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
from random import getrandbits
|
from os import urandom
|
||||||
|
|
||||||
import base58
|
import base58
|
||||||
import ecdsa
|
import ecdsa
|
||||||
|
@ -20,15 +20,12 @@ WIF_VER = b'\x9e' if DOGE_MODE else b'\x80'
|
||||||
# 0x1e - dogecoin
|
# 0x1e - dogecoin
|
||||||
ADDR_VER = b'\x1e' if DOGE_MODE else b'\x00'
|
ADDR_VER = b'\x1e' if DOGE_MODE else b'\x00'
|
||||||
|
|
||||||
# gen random 256bit privkey as bytes
|
# gen random 256bit prvkey bytes
|
||||||
def genRandPrvKey():
|
def genRandPrvKey(): return urandom( 32 )
|
||||||
# replace with os.urandom for the real deal
|
|
||||||
rawpk = intBytes( getrandbits( 256 ) )
|
|
||||||
return rawpk
|
|
||||||
|
|
||||||
# get base58 wif privkey from raw privkey bytes
|
# get base58 wif privkey from raw privkey bytes
|
||||||
def getPrvKeyWIF( rawpk ):
|
def getPrvKeyWIF( prv ):
|
||||||
return base58.encodeCheck( WIF_VER, rawpk + b'\x01' )
|
return base58.encodeCheck( WIF_VER, prv + b'\x01' )
|
||||||
|
|
||||||
# get hash160 bytes of pubkey bytes. base58Check this for addr
|
# get hash160 bytes of pubkey bytes. base58Check this for addr
|
||||||
# also used for bip32 ext key identifier. first 32bits of id is the fingerprint
|
# also used for bip32 ext key identifier. first 32bits of id is the fingerprint
|
||||||
|
|
24
main.py
24
main.py
|
@ -18,20 +18,28 @@ if __name__ == '__main__':
|
||||||
b39seed = bip39.genSeed( b39phrase )
|
b39seed = bip39.genSeed( b39phrase )
|
||||||
|
|
||||||
# test bip32
|
# test bip32
|
||||||
# master (key, chain) bytes
|
# master private (key, chain) bytes
|
||||||
b32master = bip32.getMaster( b39seed )
|
b32master = bip32.getMaster( b39seed )
|
||||||
# serialize root master prv and pub key
|
# serialize master ext prv and pub key
|
||||||
b32masterxprv = bip32.serializeMasterPrvKey( b32master )
|
b32masterxprv = bip32.serializeExtPrvKey( b32master )
|
||||||
b32masterxpub = bip32.serializeMasterPubKey( b32master )
|
b32masterxpub = bip32.serializeExtPubKey( (keys.getPubKey( b32master[0] ), b32master[1]) )
|
||||||
|
|
||||||
print( 'BIP39\n', b39phrase + '\n', b39seed.hex() + '\nBIP32\n' +
|
print( 'BIP39 phrase, seed\n\t', b39phrase + '\n\t', b39seed.hex() +
|
||||||
f'{b32masterxprv}\n{b32masterxpub}\n{base58.decodeCheck( b32masterxprv ).hex()}\n{base58.decodeCheck( b32masterxpub ).hex()}' )
|
'\nBIP32 master\n' + f'\t{b32masterxprv}\n\t{b32masterxpub}' )
|
||||||
print()
|
print()
|
||||||
|
|
||||||
prvmaster = (b32master[0], b32master[1])
|
prvmaster = (b32master[0], b32master[1])
|
||||||
prvroot0 = bip32.ckdPrv( prvmaster, 0 ) # m/0
|
prvroot0 = bip32.ckdPrv( prvmaster, 0 ) # m/0
|
||||||
|
|
||||||
|
parfp = keys.getPubKeyHash( keys.getPubKey( prvmaster[0] ) )[:4] # parent fingerprint
|
||||||
|
prvroot0ext = bip32.serializeExtPrvKey(
|
||||||
|
prvroot0, 1, parfp, 0 )
|
||||||
|
pubroot0ext = bip32.serializeExtPubKey(
|
||||||
|
(keys.getPubKey( prvroot0[0] ), prvroot0[1]), 1, parfp, 0 )
|
||||||
|
print( f'm/0 derived ext keys:\n\t{prvroot0ext}\n\t{pubroot0ext}' )
|
||||||
|
|
||||||
for i in range( 20 ):
|
for i in range( 20 ):
|
||||||
# pubkeys
|
# pubkey - prvkey
|
||||||
pk = bip32.ckdPrv( prvroot0, i )[0]
|
pk = bip32.ckdPrv( prvroot0, i )[0]
|
||||||
print( 'm/0/{}: {} - {}'.format( i, keys.getPubKey( pk ).hex(), keys.getPrvKeyWIF( pk ) ) )
|
print( 'm/0/{}: {} - {}'.format( i, keys.getPubKey( pk ).hex(), keys.getPrvKeyWIF( pk ) ) )
|
||||||
|
|
||||||
|
@ -42,6 +50,6 @@ if __name__ == '__main__':
|
||||||
pubaddr = keys.getPubKeyAddr( pubkey )
|
pubaddr = keys.getPubKeyAddr( pubkey )
|
||||||
print( f'prvkey hex: {prvkey.hex()}' )
|
print( f'prvkey hex: {prvkey.hex()}' )
|
||||||
print( f'b58 wif pk: {keys.getPrvKeyWIF( prvkey )}' )
|
print( f'b58 wif pk: {keys.getPrvKeyWIF( prvkey )}' )
|
||||||
print( f'pubkey: {pubkey.hex()}\n\thash: {keys.getPubKeyHash( pubkey ).hex()}\n\taddr: {pubaddr}\n\tdecoded: {base58.decodeCheck( pubaddr ).hex()}' )
|
print( f'pubkey: {pubkey.hex()}\n\thash: {keys.getPubKeyHash( pubkey ).hex()}\n\taddr: {pubaddr}' )
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue