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
|
||||
# 02facafd - dogecoin pub
|
||||
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
|
||||
def serializeMasterPubKey( master ):
|
||||
depth = 0
|
||||
parFP = intBytes( 0, 4 ) # parent fingerprint
|
||||
childNum = 0
|
||||
pubroot = base58.encodeCheck( PUB_VER, intBytes( depth, 1 ) +
|
||||
parFP + intBytes( childNum, 4 ) + master[1] +
|
||||
keys.getPubKey( master[0] ) )
|
||||
return pubroot
|
||||
# serialize an extended private key (key, chain)
|
||||
# parfp is the 4byte parent fingerprint
|
||||
# default parameters assume master key
|
||||
def serializeExtPrvKey( key, depth=0, parfp=b'\x00\x00\x00\x00', child=0 ):
|
||||
return base58.encodeCheck( PRV_VER, intBytes( depth, 1 ) +
|
||||
parfp + intBytes( child, 4 ) + key[1] + b'\x00' + key[0] )
|
||||
|
||||
# serialize an extended public key (key, chain)
|
||||
# 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.
|
||||
# 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 sha256
|
||||
from random import getrandbits
|
||||
from os import urandom
|
||||
|
||||
import base58
|
||||
import ecdsa
|
||||
|
@ -20,15 +20,12 @@ WIF_VER = b'\x9e' if DOGE_MODE else b'\x80'
|
|||
# 0x1e - dogecoin
|
||||
ADDR_VER = b'\x1e' if DOGE_MODE else b'\x00'
|
||||
|
||||
# gen random 256bit privkey as bytes
|
||||
def genRandPrvKey():
|
||||
# replace with os.urandom for the real deal
|
||||
rawpk = intBytes( getrandbits( 256 ) )
|
||||
return rawpk
|
||||
# gen random 256bit prvkey bytes
|
||||
def genRandPrvKey(): return urandom( 32 )
|
||||
|
||||
# get base58 wif privkey from raw privkey bytes
|
||||
def getPrvKeyWIF( rawpk ):
|
||||
return base58.encodeCheck( WIF_VER, rawpk + b'\x01' )
|
||||
def getPrvKeyWIF( prv ):
|
||||
return base58.encodeCheck( WIF_VER, prv + b'\x01' )
|
||||
|
||||
# get hash160 bytes of pubkey bytes. base58Check this for addr
|
||||
# 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 )
|
||||
|
||||
# test bip32
|
||||
# master (key, chain) bytes
|
||||
# master private (key, chain) bytes
|
||||
b32master = bip32.getMaster( b39seed )
|
||||
# serialize root master prv and pub key
|
||||
b32masterxprv = bip32.serializeMasterPrvKey( b32master )
|
||||
b32masterxpub = bip32.serializeMasterPubKey( b32master )
|
||||
# serialize master ext prv and pub key
|
||||
b32masterxprv = bip32.serializeExtPrvKey( b32master )
|
||||
b32masterxpub = bip32.serializeExtPubKey( (keys.getPubKey( b32master[0] ), b32master[1]) )
|
||||
|
||||
print( 'BIP39\n', b39phrase + '\n', b39seed.hex() + '\nBIP32\n' +
|
||||
f'{b32masterxprv}\n{b32masterxpub}\n{base58.decodeCheck( b32masterxprv ).hex()}\n{base58.decodeCheck( b32masterxpub ).hex()}' )
|
||||
print( 'BIP39 phrase, seed\n\t', b39phrase + '\n\t', b39seed.hex() +
|
||||
'\nBIP32 master\n' + f'\t{b32masterxprv}\n\t{b32masterxpub}' )
|
||||
print()
|
||||
|
||||
prvmaster = (b32master[0], b32master[1])
|
||||
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 ):
|
||||
# pubkeys
|
||||
# pubkey - prvkey
|
||||
pk = bip32.ckdPrv( prvroot0, i )[0]
|
||||
print( 'm/0/{}: {} - {}'.format( i, keys.getPubKey( pk ).hex(), keys.getPrvKeyWIF( pk ) ) )
|
||||
|
||||
|
@ -42,6 +50,6 @@ if __name__ == '__main__':
|
|||
pubaddr = keys.getPubKeyAddr( pubkey )
|
||||
print( f'prvkey hex: {prvkey.hex()}' )
|
||||
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