baseconv: minor cleanups & fixes (import, init_mn)
This commit is contained in:
parent
ca994bdd74
commit
f1e7cbb7a0
6 changed files with 38 additions and 28 deletions
|
|
@ -29,50 +29,53 @@ def is_b32_str(s): return set(list(s)) <= set(baseconv.digits['b32'])
|
|||
class baseconv(object):
|
||||
|
||||
desc = {
|
||||
'b58': ('base58', 'base58-encoded data'),
|
||||
'b32': ('MMGen base32', 'MMGen base32-encoded data created using simple base conversion'),
|
||||
'b16': ('hexadecimal string', 'base16 (hexadecimal) string data'),
|
||||
'b10': ('base10 string', 'base10 (decimal) string data'),
|
||||
'b8': ('base8 string', 'base8 (octal) string data'),
|
||||
'b6d': ('base6d (die roll)', 'base6 data using the digits from one to six'),
|
||||
'b58': ('base58', 'base58-encoded data'),
|
||||
'b32': ('MMGen base32', 'MMGen base32-encoded data created using simple base conversion'),
|
||||
'b16': ('hexadecimal string','base16 (hexadecimal) string data'),
|
||||
'b10': ('base10 string', 'base10 (decimal) string data'),
|
||||
'b8': ('base8 string', 'base8 (octal) string data'),
|
||||
'b6d': ('base6d (die roll)', 'base6 data using the digits from one to six'),
|
||||
'tirosh':('Tirosh mnemonic', 'base1626 mnemonic using truncated Tirosh wordlist'), # not used by wallet
|
||||
'mmgen': ('MMGen native mnemonic',
|
||||
'MMGen native mnemonic seed phrase data created using old Electrum wordlist and simple base conversion'),
|
||||
}
|
||||
# https://en.wikipedia.org/wiki/Base32#RFC_4648_Base32_alphabet
|
||||
# https://tools.ietf.org/html/rfc4648
|
||||
digits = {
|
||||
'b58': tuple('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'),
|
||||
'b32': tuple('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'),
|
||||
'b32': tuple('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), # RFC 4648 alphabet
|
||||
'b16': tuple('0123456789abcdef'),
|
||||
'b10': tuple('0123456789'),
|
||||
'b8': tuple('01234567'),
|
||||
'b6d': tuple('123456'),
|
||||
}
|
||||
mn_base = 1626 # tirosh list is 1633 words long!
|
||||
mn_ids = ('mmgen','tirosh')
|
||||
wl_chksums = {
|
||||
'mmgen': '5ca31424',
|
||||
'tirosh': '48f05e1f', # tirosh truncated to mn_base (1626)
|
||||
# 'tirosh1633': '1a5faeff'
|
||||
}
|
||||
seed_pad_lens = {
|
||||
seedlen_map = {
|
||||
'b58': { 16:22, 24:33, 32:44 },
|
||||
'b6d': { 16:50, 24:75, 32:100 },
|
||||
}
|
||||
seed_pad_lens_rev = {
|
||||
seedlen_map_rev = {
|
||||
'b58': { 22:16, 33:24, 44:32 },
|
||||
'b6d': { 50:16, 75:24, 100:32 },
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def init_mn(cls,mn_id):
|
||||
assert mn_id in cls.mn_ids
|
||||
if mn_id in cls.digits:
|
||||
return
|
||||
if mn_id == 'mmgen':
|
||||
from mmgen.mn_electrum import words
|
||||
cls.digits[mn_id] = words
|
||||
elif mn_id == 'tirosh':
|
||||
from mmgen.mn_tirosh import words
|
||||
cls.digits[mn_id] = words[:cls.mn_base]
|
||||
else: # bip39
|
||||
cls.digits[mn_id] = cls.words
|
||||
else:
|
||||
raise ValueError('{}: unrecognized mnemonic ID'.format(mn_id))
|
||||
|
||||
@classmethod
|
||||
def get_wordlist(cls,wl_id):
|
||||
|
|
@ -109,7 +112,7 @@ class baseconv(object):
|
|||
"""
|
||||
'pad' argument to baseconv conversion methods must be either None, 'seed' or an integer.
|
||||
If None, output of minimum (but never zero) length will be produced.
|
||||
If 'seed', output length will be mapped from input length using data in seed_pad_lens.
|
||||
If 'seed', output length will be mapped from input length using data in seedlen_map.
|
||||
If an integer, the string, hex string or byte output will be padded to this length.
|
||||
"""
|
||||
if pad == None:
|
||||
|
|
@ -131,6 +134,9 @@ class baseconv(object):
|
|||
def tobytes(cls,words_arg,wl_id,pad=None):
|
||||
"convert string or list data of base 'wl_id' to byte string"
|
||||
|
||||
if wl_id not in cls.digits:
|
||||
cls.init_mn(wl_id)
|
||||
|
||||
words = words_arg if isinstance(words_arg,(list,tuple)) else tuple(words_arg.strip())
|
||||
desc = cls.desc[wl_id][0]
|
||||
|
||||
|
|
@ -138,8 +144,8 @@ class baseconv(object):
|
|||
raise BaseConversionError('empty {} data'.format(desc))
|
||||
|
||||
def get_seed_pad():
|
||||
assert wl_id in cls.seed_pad_lens_rev,'seed padding not supported for base {!r}'.format(wl_id)
|
||||
d = cls.seed_pad_lens_rev[wl_id]
|
||||
assert wl_id in cls.seedlen_map_rev,'seed padding not supported for base {!r}'.format(wl_id)
|
||||
d = cls.seedlen_map_rev[wl_id]
|
||||
if not len(words) in d:
|
||||
m = '{}: invalid length for seed-padded {} data in base conversion'
|
||||
raise BaseConversionError(m.format(len(words),desc))
|
||||
|
|
@ -172,12 +178,15 @@ class baseconv(object):
|
|||
def frombytes(cls,bytestr,wl_id,pad=None,tostr=False):
|
||||
"convert byte string to list or string data of base 'wl_id'"
|
||||
|
||||
if wl_id not in cls.digits:
|
||||
cls.init_mn(wl_id)
|
||||
|
||||
if not bytestr:
|
||||
raise BaseConversionError('empty data not allowed in base conversion')
|
||||
|
||||
def get_seed_pad():
|
||||
assert wl_id in cls.seed_pad_lens,'seed padding not supported for base {!r}'.format(wl_id)
|
||||
d = cls.seed_pad_lens[wl_id]
|
||||
assert wl_id in cls.seedlen_map,'seed padding not supported for base {!r}'.format(wl_id)
|
||||
d = cls.seedlen_map[wl_id]
|
||||
if not len(bytestr) in d:
|
||||
m = '{}: invalid byte length for seed data in seed-padded base conversion'
|
||||
raise SeedLengthError(m.format(len(bytestr)))
|
||||
|
|
|
|||
|
|
@ -2081,7 +2081,6 @@ zoo
|
|||
""".split())
|
||||
|
||||
mn_base = 2048
|
||||
mn_ids = ('bip39',)
|
||||
wl_chksums = { 'bip39': 'f18b9a84' }
|
||||
# ENT CS MS
|
||||
constants = {
|
||||
|
|
@ -2170,3 +2169,7 @@ zoo
|
|||
res = seed_bin + chk_bin
|
||||
|
||||
return tuple(wl[int(res[i*11:(i+1)*11],2)] for i in range(mn_len))
|
||||
|
||||
@classmethod
|
||||
def init_mn(cls,mn_id):
|
||||
assert mn_id == 'bip39', "'mn_id' must be 'bip39'"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ from mmgen.util import msg,ymsg,Msg,ydie
|
|||
from mmgen.obj import MMGenObject,BTCAmt,LTCAmt,BCHAmt,B2XAmt,ETHAmt
|
||||
from mmgen.globalvars import g
|
||||
import mmgen.bech32 as bech32
|
||||
from mmgen.baseconv import baseconv,is_b58_str
|
||||
|
||||
def hash160(hexnum): # take hex, return hex - OP_HASH160
|
||||
return hashlib.new('ripemd160',hashlib.sha256(bytes.fromhex(hexnum)).digest()).hexdigest()
|
||||
|
|
@ -407,6 +406,8 @@ class MoneroProtocol(DummyWIF,BitcoinProtocolAddrgen):
|
|||
@classmethod
|
||||
def verify_addr(cls,addr,hex_width,return_dict=False):
|
||||
|
||||
from mmgen.baseconv import baseconv,is_b58_str
|
||||
|
||||
def b58dec(addr_str):
|
||||
l = len(addr_str)
|
||||
a = ''.join([baseconv.tohex(addr_str[i*11:i*11+11],'b58',pad=16) for i in range(l//11)])
|
||||
|
|
|
|||
|
|
@ -825,10 +825,6 @@ class MMGenMnemonic(SeedSourceUnenc):
|
|||
wl_id = 'mmgen'
|
||||
conv_cls = baseconv
|
||||
|
||||
def __init__(self,*args,**kwargs):
|
||||
self.conv_cls.init_mn(self.wl_id)
|
||||
super().__init__(*args,**kwargs)
|
||||
|
||||
def _get_data_from_user(self,desc):
|
||||
|
||||
if not g.stdin_tty:
|
||||
|
|
@ -853,6 +849,7 @@ class MMGenMnemonic(SeedSourceUnenc):
|
|||
if keypress_confirm(prompt,default_yes=True,no_nl=not g.test_suite):
|
||||
break
|
||||
|
||||
self.conv_cls.init_mn(self.wl_id)
|
||||
wl = self.conv_cls.digits[self.wl_id]
|
||||
longest_word = max(len(w) for w in wl)
|
||||
from string import ascii_lowercase
|
||||
|
|
@ -923,6 +920,7 @@ class MMGenMnemonic(SeedSourceUnenc):
|
|||
|
||||
def _deformat(self):
|
||||
|
||||
self.conv_cls.init_mn(self.wl_id)
|
||||
mn = self.fmt_data.split()
|
||||
|
||||
if len(mn) not in self.mn_lens:
|
||||
|
|
@ -1227,7 +1225,7 @@ class Wallet (SeedSourceEnc):
|
|||
msg("Hash parameters '{}' don't match hash preset '{}'".format(' '.join(hash_params),d.hash_preset))
|
||||
return False
|
||||
|
||||
lmin,foo,lmax = sorted(baseconv.seed_pad_lens_rev['b58']) # 22,33,44
|
||||
lmin,foo,lmax = sorted(baseconv.seedlen_map_rev['b58']) # 22,33,44
|
||||
for i,key in (4,'salt'),(5,'enc_seed'):
|
||||
l = lines[i].split(' ')
|
||||
chk = l.pop(0)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import sys,os,json
|
|||
from stat import *
|
||||
from mmgen.common import *
|
||||
from mmgen.obj import *
|
||||
from mmgen.baseconv import *
|
||||
|
||||
wmsg = lambda k: {
|
||||
'addr_in_addrfile_only': """
|
||||
|
|
@ -699,6 +698,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam
|
|||
repr([amt_to_str(e.__dict__) for e in self.outputs])
|
||||
]
|
||||
if self.label:
|
||||
from mmgen.baseconv import baseconv
|
||||
lines.append(baseconv.frombytes(self.label.encode(),'b58',tostr=True))
|
||||
if self.coin_txid:
|
||||
if not self.label: lines.append('-') # keep old tx files backwards compatible
|
||||
|
|
@ -1215,6 +1215,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam
|
|||
c = tx_data.pop(-1)
|
||||
if c != '-':
|
||||
desc = 'encoded comment (not base58)'
|
||||
from mmgen.baseconv import baseconv
|
||||
comment = baseconv.tobytes(c,'b58').decode()
|
||||
assert comment != False,'invalid comment'
|
||||
desc = 'comment'
|
||||
|
|
|
|||
|
|
@ -264,8 +264,6 @@ def is_int(s):
|
|||
except:
|
||||
return False
|
||||
|
||||
# https://en.wikipedia.org/wiki/Base32#RFC_4648_Base32_alphabet
|
||||
# https://tools.ietf.org/html/rfc4648
|
||||
def is_hex_str(s): return set(list(s.lower())) <= set(list(hexdigits.lower()))
|
||||
def is_hex_str_lc(s): return set(list(s)) <= set(list(hexdigits.lower()))
|
||||
def is_hex_str_uc(s): return set(list(s)) <= set(list(hexdigits.upper()))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue