_b58chk_encode(), _b58chk_decode(): reimplement using bytes
This commit is contained in:
parent
f63b35469c
commit
3e0caf7beb
4 changed files with 34 additions and 25 deletions
|
|
@ -123,7 +123,8 @@ class AddrGeneratorZcashZ(AddrGenerator):
|
|||
from nacl.bindings import crypto_scalarmult_base
|
||||
p2 = crypto_scalarmult_base(self.zhash256(key,1))
|
||||
from mmgen.protocol import _b58chk_encode
|
||||
ret = _b58chk_encode(g.proto.addr_ver_num['zcash_z'][0] + (self.zhash256(key,0)+p2).hex())
|
||||
ver_bytes = bytes.fromhex(g.proto.addr_ver_num['zcash_z'][0])
|
||||
ret = _b58chk_encode(ver_bytes + self.zhash256(key,0) + p2)
|
||||
assert len(ret) == self.addr_width,'Invalid Zcash z-address length'
|
||||
return CoinAddr(ret)
|
||||
|
||||
|
|
@ -135,7 +136,8 @@ class AddrGeneratorZcashZ(AddrGenerator):
|
|||
vk[63] &= 0x7f
|
||||
vk[63] |= 0x40
|
||||
from mmgen.protocol import _b58chk_encode
|
||||
ret = _b58chk_encode(g.proto.addr_ver_num['viewkey'][0] + vk.hex())
|
||||
ver_bytes = bytes.fromhex(g.proto.addr_ver_num['viewkey'][0])
|
||||
ret = _b58chk_encode(ver_bytes + vk)
|
||||
assert len(ret) == self.vk_width,'Invalid Zcash view key length'
|
||||
return ZcashViewKey(ret)
|
||||
|
||||
|
|
|
|||
|
|
@ -458,10 +458,12 @@ class CoinInfo(object):
|
|||
|
||||
def phash2addr(ver_num,pk_hash):
|
||||
from mmgen.protocol import _b58chk_encode
|
||||
return _b58chk_encode('{:0{}x}'.format(ver_num,2 if ver_num < 256 else 4) + pk_hash)
|
||||
bl = ver_num.bit_length()
|
||||
ver_bytes = int.to_bytes(ver_num,bl//8 + bool(bl%8),'big')
|
||||
return _b58chk_encode(ver_bytes + pk_hash)
|
||||
|
||||
low = phash2addr(ver_num,'00'*20)
|
||||
high = phash2addr(ver_num,'ff'*20)
|
||||
low = phash2addr(ver_num,b'\x00'*20)
|
||||
high = phash2addr(ver_num,b'\xff'*20)
|
||||
|
||||
if verbose:
|
||||
print('low address: ' + low)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ def hash160(hexnum): # take hex, return hex - OP_HASH160
|
|||
def hash256(hexnum): # take hex, return hex - OP_HASH256
|
||||
return hashlib.sha256(hashlib.sha256(bytes.fromhex(hexnum)).digest()).hexdigest()
|
||||
|
||||
def hash256bytes(bstr): # bytes in, bytes out - OP_HASH256
|
||||
return hashlib.sha256(hashlib.sha256(bstr).digest()).digest()
|
||||
|
||||
_b58a='123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
|
||||
# From en.bitcoin.it:
|
||||
|
|
@ -46,24 +49,22 @@ _b58a='123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
|||
# The 'zero address':
|
||||
# 1111111111111111111114oLvT2 (pubkeyhash = '\0'*20)
|
||||
|
||||
def _b58chk_encode(hexstr):
|
||||
lzeroes = (len(hexstr) - len(hexstr.lstrip('0'))) // 2
|
||||
def b58enc(n):
|
||||
def _b58chk_encode(bstr):
|
||||
lzeroes = len(bstr) - len(bstr.lstrip(b'\x00'))
|
||||
def do_enc(n):
|
||||
while n:
|
||||
yield _b58a[n % 58]
|
||||
n //= 58
|
||||
return ('1' * lzeroes) + ''.join(b58enc(int(hexstr+hash256(hexstr)[:8],16)))[::-1]
|
||||
return ('1' * lzeroes) + ''.join(do_enc(int.from_bytes(bstr+hash256bytes(bstr)[:4],'big')))[::-1]
|
||||
|
||||
def _b58chk_decode(s):
|
||||
lzeroes = len(s) - len(s.lstrip('1'))
|
||||
hexstr = '{}{:x}'.format(
|
||||
'00' * lzeroes,
|
||||
sum(_b58a.index(ch) * 58**n for n,ch in enumerate(s[::-1])) )
|
||||
if len(hexstr) % 2: hexstr = '0' + hexstr
|
||||
if hexstr[-8:] != hash256(hexstr[:-8])[:8]:
|
||||
fs = '_b58chk_decode(): {}: incorrect checksum for {!r}, expected {}'
|
||||
raise ValueError(fs.format(hexstr[-8:],hexstr[:-8],hash256(hexstr[:-8])[:8]))
|
||||
return hexstr[:-8]
|
||||
res = sum(_b58a.index(ch) * 58**n for n,ch in enumerate(s[::-1]))
|
||||
bl = res.bit_length()
|
||||
out = b'\x00' * lzeroes + res.to_bytes(bl//8 + bool(bl%8),'big')
|
||||
if out[-4:] != hash256bytes(out[:-4])[:4]:
|
||||
raise ValueError('_b58chk_decode(): incorrect checksum')
|
||||
return out[:-4]
|
||||
|
||||
# chainparams.cpp
|
||||
class BitcoinProtocol(MMGenObject):
|
||||
|
|
@ -129,14 +130,18 @@ class BitcoinProtocol(MMGenObject):
|
|||
return (pk % cls.secp256k1_ge).to_bytes(cls.privkey_len,'big')
|
||||
|
||||
@classmethod
|
||||
def hex2wif(cls,hexpriv,pubkey_type,compressed): # PrivKey
|
||||
assert len(hexpriv) == cls.privkey_len*2, '{} bytes: incorrect private key length!'.format(len(hexpriv)//2)
|
||||
def hex2wif(cls,hexpriv,pubkey_type,compressed): # input is preprocessed hex
|
||||
sec = bytes.fromhex(hexpriv)
|
||||
assert len(sec) == cls.privkey_len, '{} bytes: incorrect private key length!'.format(len(sec))
|
||||
assert pubkey_type in cls.wif_ver_num, '{!r}: invalid pubkey_type'.format(pubkey_type)
|
||||
return _b58chk_encode(cls.wif_ver_num[pubkey_type] + hexpriv + ('','01')[bool(compressed)])
|
||||
return _b58chk_encode(
|
||||
bytes.fromhex(cls.wif_ver_num[pubkey_type])
|
||||
+ sec
|
||||
+ (b'',b'\x01')[bool(compressed)])
|
||||
|
||||
@classmethod
|
||||
def parse_wif(cls,wif):
|
||||
key = bytes.fromhex(_b58chk_decode(wif))
|
||||
key = _b58chk_decode(wif)
|
||||
|
||||
for k,v in cls.wif_ver_num.items():
|
||||
v = bytes.fromhex(v)
|
||||
|
|
@ -176,7 +181,7 @@ class BitcoinProtocol(MMGenObject):
|
|||
if type(pfx) == tuple:
|
||||
if addr[0] not in pfx: continue
|
||||
elif addr[:len(pfx)] != pfx: continue
|
||||
addr_hex = _b58chk_decode(addr)
|
||||
addr_hex = _b58chk_decode(addr).hex()
|
||||
if addr_hex[:len(ver_num)] != ver_num: continue
|
||||
return {
|
||||
'hex': addr_hex[len(ver_num):],
|
||||
|
|
@ -193,7 +198,7 @@ class BitcoinProtocol(MMGenObject):
|
|||
def pubhash2addr(cls,pubkey_hash,p2sh):
|
||||
assert len(pubkey_hash) == 40,'{}: invalid length for pubkey hash'.format(len(pubkey_hash))
|
||||
s = cls.addr_ver_num[('p2pkh','p2sh')[p2sh]][0] + pubkey_hash
|
||||
return _b58chk_encode(s)
|
||||
return _b58chk_encode(bytes.fromhex(s))
|
||||
|
||||
# Segwit:
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -340,12 +340,12 @@ class MMGenToolCmdUtil(MMGenToolCmdBase):
|
|||
def hextob58chk(self,hexstr:'sstr'):
|
||||
"convert a hexadecimal number to base58-check encoding"
|
||||
from mmgen.protocol import _b58chk_encode
|
||||
return _b58chk_encode(hexstr)
|
||||
return _b58chk_encode(bytes.fromhex(hexstr))
|
||||
|
||||
def b58chktohex(self,b58chk_num:'sstr'):
|
||||
"convert a base58-check encoded number to hexadecimal"
|
||||
from mmgen.protocol import _b58chk_decode
|
||||
return _b58chk_decode(b58chk_num)
|
||||
return _b58chk_decode(b58chk_num).hex()
|
||||
|
||||
def hextob32(self,hexstr:'sstr',pad=0):
|
||||
"convert a hexadecimal number to MMGen's flavor of base 32"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue