Browse Source

baseconv: set constants in initializer

The MMGen Project 3 years ago
parent
commit
67067aa7d5
8 changed files with 77 additions and 74 deletions
  1. 40 38
      mmgen/baseconv.py
  2. 7 7
      mmgen/bip39.py
  3. 1 1
      mmgen/data/version
  4. 2 2
      mmgen/mn_entry.py
  5. 3 3
      mmgen/passwdlist.py
  6. 12 11
      mmgen/wallet.py
  7. 11 11
      mmgen/xmrseed.py
  8. 1 1
      test/unit_tests_d/ut_baseconv.py

+ 40 - 38
mmgen/baseconv.py

@@ -23,82 +23,84 @@ baseconv.py:  base conversion class for the MMGen suite
 from hashlib import sha256
 from hashlib import sha256
 from .exception import *
 from .exception import *
 from .util import die
 from .util import die
+from collections import namedtuple
 
 
 def is_b58_str(s):
 def is_b58_str(s):
-	return set(list(s)) <= set(baseconv.digits['b58'])
+	return set(list(s)) <= set(baseconv('b58').digits)
 
 
 def is_b32_str(s):
 def is_b32_str(s):
-	return set(list(s)) <= set(baseconv.digits['b32'])
+	return set(list(s)) <= set(baseconv('b32').digits)
 
 
 class baseconv(object):
 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'),
+	mn_base = 1626
+	dt = namedtuple('desc_tuple',['short','long'])
+	constants = {
+	'desc': {
+		'b58':   dt('base58',            'base58-encoded data'),
+		'b32':   dt('MMGen base32',      'MMGen base32-encoded data created using simple base conversion'),
+		'b16':   dt('hexadecimal string','base16 (hexadecimal) string data'),
+		'b10':   dt('base10 string',     'base10 (decimal) string data'),
+		'b8':    dt('base8 string',      'base8 (octal) string data'),
+		'b6d':   dt('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
 #		'tirosh':('Tirosh mnemonic',   'base1626 mnemonic using truncated Tirosh wordlist'), # not used by wallet
-		'mmgen': ('MMGen native mnemonic',
+		'mmgen': dt('MMGen native mnemonic',
 		'MMGen native mnemonic seed phrase created using old Electrum wordlist and simple base conversion'),
 		'MMGen native mnemonic seed phrase created using old Electrum wordlist and simple base conversion'),
-	}
+	},
 	# https://en.wikipedia.org/wiki/Base32#RFC_4648_Base32_alphabet
 	# https://en.wikipedia.org/wiki/Base32#RFC_4648_Base32_alphabet
 	# https://tools.ietf.org/html/rfc4648
 	# https://tools.ietf.org/html/rfc4648
-	digits = {
+	'digits': {
 		'b58': tuple('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'),
 		'b58': tuple('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'),
 		'b32': tuple('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), # RFC 4648 alphabet
 		'b32': tuple('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), # RFC 4648 alphabet
 		'b16': tuple('0123456789abcdef'),
 		'b16': tuple('0123456789abcdef'),
 		'b10': tuple('0123456789'),
 		'b10': tuple('0123456789'),
 		'b8':  tuple('01234567'),
 		'b8':  tuple('01234567'),
 		'b6d': tuple('123456'),
 		'b6d': tuple('123456'),
-	}
-	mn_base = 1626
-	wl_chksums = {
+	},
+	'wl_chksum': {
 		'mmgen':  '5ca31424',
 		'mmgen':  '5ca31424',
 #		'tirosh': '48f05e1f', # tirosh truncated to mn_base
 #		'tirosh': '48f05e1f', # tirosh truncated to mn_base
 #		'tirosh1633': '1a5faeff' # tirosh list is 1633 words long!
 #		'tirosh1633': '1a5faeff' # tirosh list is 1633 words long!
-	}
-	seedlen_map = {
+	},
+	'seedlen_map': {
 		'b58': { 16:22, 24:33, 32:44 },
 		'b58': { 16:22, 24:33, 32:44 },
 		'b6d': { 16:50, 24:75, 32:100 },
 		'b6d': { 16:50, 24:75, 32:100 },
 		'mmgen': { 16:12, 24:18, 32:24 },
 		'mmgen': { 16:12, 24:18, 32:24 },
-	}
-	seedlen_map_rev = {
+	},
+	'seedlen_map_rev': {
 		'b58': { 22:16, 33:24, 44:32 },
 		'b58': { 22:16, 33:24, 44:32 },
 		'b6d': { 50:16, 75:24, 100:32 },
 		'b6d': { 50:16, 75:24, 100:32 },
 		'mmgen': { 12:16, 18:24, 24:32 },
 		'mmgen': { 12:16, 18:24, 24:32 },
 	}
 	}
+	}
 
 
 	def __init__(self,wl_id):
 	def __init__(self,wl_id):
 
 
 		if wl_id == 'mmgen':
 		if wl_id == 'mmgen':
 			from .mn_electrum import words
 			from .mn_electrum import words
-			self.digits[wl_id] = words
-		elif wl_id not in self.digits:
+			self.constants['digits'][wl_id] = words
+		elif wl_id not in self.constants['digits']:
 			raise ValueError(f'{wl_id}: unrecognized mnemonic ID')
 			raise ValueError(f'{wl_id}: unrecognized mnemonic ID')
 
 
+		for k,v in self.constants.items():
+			if wl_id in v:
+				setattr(self,k,v[wl_id])
+
 		self.wl_id = wl_id
 		self.wl_id = wl_id
 
 
 	def get_wordlist(self):
 	def get_wordlist(self):
-		return self.digits[self.wl_id]
+		return self.digits
 
 
 	def get_wordlist_chksum(self):
 	def get_wordlist_chksum(self):
-		return sha256(' '.join(self.digits[self.wl_id]).encode()).hexdigest()[:8]
+		return sha256( ' '.join(self.digits).encode() ).hexdigest()[:8]
 
 
 	def check_wordlist(self):
 	def check_wordlist(self):
 
 
-		wl = self.digits[self.wl_id]
+		wl = self.digits
 		from .util import qmsg,compare_chksums
 		from .util import qmsg,compare_chksums
 		ret = f'Wordlist: {self.wl_id}\nLength: {len(wl)} words'
 		ret = f'Wordlist: {self.wl_id}\nLength: {len(wl)} words'
 		new_chksum = self.get_wordlist_chksum()
 		new_chksum = self.get_wordlist_chksum()
 
 
-		compare_chksums(
-			new_chksum,
-			'generated',
-			self.wl_chksums[self.wl_id],
-			'saved',
-			die_on_fail = True )
+		compare_chksums( new_chksum, 'generated', self.wl_chksum, 'saved', die_on_fail=True )
 
 
 		if tuple(sorted(wl)) == wl:
 		if tuple(sorted(wl)) == wl:
 			return ret + '\nList is sorted'
 			return ret + '\nList is sorted'
@@ -130,21 +132,21 @@ class baseconv(object):
 		"convert string or list data of instance base to byte string"
 		"convert string or list data of instance base to byte string"
 
 
 		words = words_arg if isinstance(words_arg,(list,tuple)) else tuple(words_arg.strip())
 		words = words_arg if isinstance(words_arg,(list,tuple)) else tuple(words_arg.strip())
-		desc = self.desc[self.wl_id][0]
+		desc = self.desc.short
 
 
 		if len(words) == 0:
 		if len(words) == 0:
 			raise BaseConversionError(f'empty {desc} data')
 			raise BaseConversionError(f'empty {desc} data')
 
 
 		def get_seed_pad():
 		def get_seed_pad():
-			assert self.wl_id in self.seedlen_map_rev, f'seed padding not supported for base {self.wl_id!r}'
-			d = self.seedlen_map_rev[self.wl_id]
+			assert hasattr(self,'seedlen_map_rev'), f'seed padding not supported for base {self.wl_id!r}'
+			d = self.seedlen_map_rev
 			if not len(words) in d:
 			if not len(words) in d:
 				raise BaseConversionError(
 				raise BaseConversionError(
 					f'{len(words)}: invalid length for seed-padded {desc} data in base conversion' )
 					f'{len(words)}: invalid length for seed-padded {desc} data in base conversion' )
 			return d[len(words)]
 			return d[len(words)]
 
 
 		pad_val = max(self.get_pad(pad,get_seed_pad),1)
 		pad_val = max(self.get_pad(pad,get_seed_pad),1)
-		wl = self.digits[self.wl_id]
+		wl = self.digits
 		base = len(wl)
 		base = len(wl)
 
 
 		if not set(words) <= set(wl):
 		if not set(words) <= set(wl):
@@ -174,15 +176,15 @@ class baseconv(object):
 			raise BaseConversionError('empty data not allowed in base conversion')
 			raise BaseConversionError('empty data not allowed in base conversion')
 
 
 		def get_seed_pad():
 		def get_seed_pad():
-			assert self.wl_id in self.seedlen_map, f'seed padding not supported for base {self.wl_id!r}'
-			d = self.seedlen_map[self.wl_id]
+			assert hasattr(self,'seedlen_map'), f'seed padding not supported for base {self.wl_id!r}'
+			d = self.seedlen_map
 			if not len(bytestr) in d:
 			if not len(bytestr) in d:
 				raise SeedLengthError(
 				raise SeedLengthError(
 					f'{len(bytestr)}: invalid byte length for seed data in seed-padded base conversion' )
 					f'{len(bytestr)}: invalid byte length for seed data in seed-padded base conversion' )
 			return d[len(bytestr)]
 			return d[len(bytestr)]
 
 
 		pad = max(self.get_pad(pad,get_seed_pad),1)
 		pad = max(self.get_pad(pad,get_seed_pad),1)
-		wl = self.digits[self.wl_id]
+		wl = self.digits
 
 
 		def gen():
 		def gen():
 			num = int.from_bytes(bytestr,'big')
 			num = int.from_bytes(bytestr,'big')

+ 7 - 7
mmgen/bip39.py

@@ -32,10 +32,10 @@ def is_bip39_str(s):
 # implements a subset of the baseconv API
 # implements a subset of the baseconv API
 class bip39(baseconv):
 class bip39(baseconv):
 
 
-	desc            = { 'bip39': ('BIP39 mnemonic', 'BIP39 mnemonic seed phrase') }
-	wl_chksums      = { 'bip39': 'f18b9a84' }
-	seedlen_map     = { 'bip39': { 16:12, 24:18, 32:24 } }
-	seedlen_map_rev = { 'bip39': { 12:16, 18:24, 24:32 } }
+	desc            = baseconv.dt('BIP39 mnemonic', 'BIP39 mnemonic seed phrase')
+	wl_chksum       = 'f18b9a84'
+	seedlen_map     = { 16:12, 24:18, 32:24 }
+	seedlen_map_rev = { 12:16, 18:24, 24:32 }
 
 
 	from collections import namedtuple
 	from collections import namedtuple
 	bc = namedtuple('bip39_constants',['chk_len','mn_len'])
 	bc = namedtuple('bip39_constants',['chk_len','mn_len'])
@@ -51,7 +51,7 @@ class bip39(baseconv):
 	def __init__(self,wl_id='bip39'):
 	def __init__(self,wl_id='bip39'):
 		assert wl_id == 'bip39', "initialize with 'bip39' for compatibility with baseconv API"
 		assert wl_id == 'bip39', "initialize with 'bip39' for compatibility with baseconv API"
 		from .mn_bip39 import words
 		from .mn_bip39 import words
-		self.digits = { 'bip39': words }
+		self.digits = words
 		self.wl_id = 'bip39'
 		self.wl_id = 'bip39'
 
 
 	@classmethod
 	@classmethod
@@ -79,7 +79,7 @@ class bip39(baseconv):
 		assert isinstance(words,(list,tuple)),'words must be list or tuple'
 		assert isinstance(words,(list,tuple)),'words must be list or tuple'
 		assert pad in (None,'seed'), f"{pad}: invalid 'pad' argument (must be None or 'seed')"
 		assert pad in (None,'seed'), f"{pad}: invalid 'pad' argument (must be None or 'seed')"
 
 
-		wl = self.digits['bip39']
+		wl = self.digits
 
 
 		for n,w in enumerate(words):
 		for n,w in enumerate(words):
 			if w not in wl:
 			if w not in wl:
@@ -114,7 +114,7 @@ class bip39(baseconv):
 		assert tostr == False,"'tostr' must be False for 'bip39'"
 		assert tostr == False,"'tostr' must be False for 'bip39'"
 		assert pad in (None,'seed'), f"{pad}: invalid 'pad' argument (must be None or 'seed')"
 		assert pad in (None,'seed'), f"{pad}: invalid 'pad' argument (must be None or 'seed')"
 
 
-		wl = self.digits['bip39']
+		wl = self.digits
 		seed_bytes = bytes.fromhex(seed_hex)
 		seed_bytes = bytes.fromhex(seed_hex)
 		bitlen = len(seed_bytes) * 8
 		bitlen = len(seed_bytes) * 8
 
 

+ 1 - 1
mmgen/data/version

@@ -1 +1 @@
-13.1.dev003
+13.1.dev004

+ 2 - 2
mmgen/mn_entry.py

@@ -220,7 +220,7 @@ def mn_entry(wl_id,entry_mode=None):
 	me = MnemonicEntry.get_cls_by_wordlist(wl_id)
 	me = MnemonicEntry.get_cls_by_wordlist(wl_id)
 	import importlib
 	import importlib
 	me.bconv = getattr(importlib.import_module(f'mmgen.{me.modname}'),me.modname)(wl_id)
 	me.bconv = getattr(importlib.import_module(f'mmgen.{me.modname}'),me.modname)(wl_id)
-	me.wl = me.bconv.digits[wl_id]
+	me.wl = me.bconv.digits
 	obj = me()
 	obj = me()
 	if entry_mode:
 	if entry_mode:
 		obj.em = globals()['MnEntryMode'+capfirst(entry_mode)](obj)
 		obj.em = globals()['MnEntryMode'+capfirst(entry_mode)](obj)
@@ -334,7 +334,7 @@ class MnemonicEntry(object):
 				msg_r(erase)
 				msg_r(erase)
 
 
 	def get_mnemonic_from_user(self,mn_len,validate=True):
 	def get_mnemonic_from_user(self,mn_len,validate=True):
-		mll = list(self.bconv.seedlen_map_rev[self.wl_id])
+		mll = list(self.bconv.seedlen_map_rev)
 		assert mn_len in mll, f'{mn_len}: invalid mnemonic length (must be one of {mll})'
 		assert mn_len in mll, f'{mn_len}: invalid mnemonic length (must be one of {mll})'
 
 
 		if self.usr_dfl_entry_mode:
 		if self.usr_dfl_entry_mode:

+ 3 - 3
mmgen/passwdlist.py

@@ -160,9 +160,9 @@ class PasswordList(AddrList):
 			good_pw_len = bip39.seedlen2nwords(seed.byte_len,in_bytes=True)
 			good_pw_len = bip39.seedlen2nwords(seed.byte_len,in_bytes=True)
 		elif pf == 'xmrseed':
 		elif pf == 'xmrseed':
 			from .xmrseed import xmrseed
 			from .xmrseed import xmrseed
-			pw_bytes = xmrseed.seedlen_map_rev['xmrseed'][self.pw_len]
+			pw_bytes = xmrseed().seedlen_map_rev[self.pw_len]
 			try:
 			try:
-				good_pw_len = xmrseed.seedlen_map['xmrseed'][seed.byte_len]
+				good_pw_len = xmrseed().seedlen_map[seed.byte_len]
 			except:
 			except:
 				die(1,f'{seed.byte_len*8}: unsupported seed length for Monero new-style mnemonic')
 				die(1,f'{seed.byte_len*8}: unsupported seed length for Monero new-style mnemonic')
 		elif pf in ('b32','b58'):
 		elif pf in ('b32','b58'):
@@ -199,7 +199,7 @@ class PasswordList(AddrList):
 			return ' '.join( bip39().fromhex(secbytes[:pw_len_bytes].hex()) )
 			return ' '.join( bip39().fromhex(secbytes[:pw_len_bytes].hex()) )
 		elif self.pw_fmt == 'xmrseed':
 		elif self.pw_fmt == 'xmrseed':
 			from .xmrseed import xmrseed
 			from .xmrseed import xmrseed
-			pw_len_bytes = xmrseed.seedlen_map_rev['xmrseed'][self.pw_len]
+			pw_len_bytes = xmrseed().seedlen_map_rev[self.pw_len]
 			from .protocol import init_proto
 			from .protocol import init_proto
 			bytes_preproc = init_proto('xmr').preprocess_key(
 			bytes_preproc = init_proto('xmr').preprocess_key(
 				secbytes[:pw_len_bytes], # take most significant part
 				secbytes[:pw_len_bytes], # take most significant part

+ 12 - 11
mmgen/wallet.py

@@ -402,7 +402,7 @@ class Mnemonic(WalletUnenc):
 
 
 	@property
 	@property
 	def mn_lens(self):
 	def mn_lens(self):
-		return sorted(self.conv_cls.seedlen_map_rev[self.wl_id])
+		return sorted(self.conv_cls(self.wl_id).seedlen_map_rev)
 
 
 	def _get_data_from_user(self,desc):
 	def _get_data_from_user(self,desc):
 
 
@@ -439,7 +439,7 @@ class Mnemonic(WalletUnenc):
 			return False
 			return False
 
 
 		for n,w in enumerate(mn,1):
 		for n,w in enumerate(mn,1):
-			if w not in bc.digits[self.wl_id]:
+			if w not in bc.digits:
 				msg(f'Invalid mnemonic: word #{n} is not in the {self.wl_id.upper()} wordlist')
 				msg(f'Invalid mnemonic: word #{n} is not in the {self.wl_id.upper()} wordlist')
 				return False
 				return False
 
 
@@ -555,8 +555,9 @@ class DieRollSeedFile(WalletUnenc):
 	def _deformat(self):
 	def _deformat(self):
 
 
 		d = remove_whitespace(self.fmt_data)
 		d = remove_whitespace(self.fmt_data)
+		bc = baseconv('b6d')
+		rmap = bc.seedlen_map_rev
 
 
-		rmap = self.conv_cls.seedlen_map_rev['b6d']
 		if not len(d) in rmap:
 		if not len(d) in rmap:
 			raise SeedLengthError('{!r}: invalid length for {} (must be one of {})'.format(
 			raise SeedLengthError('{!r}: invalid length for {} (must be one of {})'.format(
 				len(d),
 				len(d),
@@ -565,7 +566,7 @@ class DieRollSeedFile(WalletUnenc):
 
 
 		# truncate seed to correct length, discarding high bits
 		# truncate seed to correct length, discarding high bits
 		seed_len = rmap[len(d)]
 		seed_len = rmap[len(d)]
-		seed_bytes = baseconv('b6d').tobytes(d,pad='seed')[-seed_len:]
+		seed_bytes = bc.tobytes( d, pad='seed' )[-seed_len:]
 
 
 		if self.interactive_input and opt.usr_randchars:
 		if self.interactive_input and opt.usr_randchars:
 			if keypress_confirm(self.user_entropy_prompt):
 			if keypress_confirm(self.user_entropy_prompt):
@@ -585,9 +586,11 @@ class DieRollSeedFile(WalletUnenc):
 		if not g.stdin_tty:
 		if not g.stdin_tty:
 			return get_data_from_user(desc)
 			return get_data_from_user(desc)
 
 
-		seed_bitlens = [n*8 for n in sorted(self.conv_cls.seedlen_map['b6d'])]
-		seed_bitlen = self._choose_seedlen(self.wclass,seed_bitlens,self.mn_type)
-		nDierolls = self.conv_cls.seedlen_map['b6d'][seed_bitlen // 8]
+		bc = baseconv('b6d')
+
+		seed_bitlens = [ n*8 for n in sorted(bc.seedlen_map) ]
+		seed_bitlen = self._choose_seedlen( self.wclass, seed_bitlens, self.mn_type )
+		nDierolls = bc.seedlen_map[seed_bitlen // 8]
 
 
 		m = """
 		m = """
 			For a {sb}-bit seed you must roll the die {nd} times.  After each die roll,
 			For a {sb}-bit seed you must roll the die {nd} times.  After each die roll,
@@ -596,8 +599,6 @@ class DieRollSeedFile(WalletUnenc):
 		"""
 		"""
 		msg('\n'+fmt(m.strip()).format(sb=seed_bitlen,nd=nDierolls)+'\n')
 		msg('\n'+fmt(m.strip()).format(sb=seed_bitlen,nd=nDierolls)+'\n')
 
 
-		b6d_digits = self.conv_cls.digits['b6d']
-
 		cr = '\n' if g.test_suite else '\r'
 		cr = '\n' if g.test_suite else '\r'
 		prompt_fs = f'\b\b\b   {cr}Enter die roll #{{}}: {CUR_SHOW}'
 		prompt_fs = f'\b\b\b   {cr}Enter die roll #{{}}: {CUR_SHOW}'
 		clear_line = '' if g.test_suite else '\r' + ' ' * 25
 		clear_line = '' if g.test_suite else '\r' + ' ' * 25
@@ -609,7 +610,7 @@ class DieRollSeedFile(WalletUnenc):
 			sleep = g.short_disp_timeout
 			sleep = g.short_disp_timeout
 			while True:
 			while True:
 				ch = get_char(p.format(n),num_chars=1,sleep=sleep)
 				ch = get_char(p.format(n),num_chars=1,sleep=sleep)
-				if ch in b6d_digits:
+				if ch in bc.digits:
 					msg_r(CUR_HIDE + ' OK')
 					msg_r(CUR_HIDE + ' OK')
 					return ch
 					return ch
 				else:
 				else:
@@ -826,7 +827,7 @@ class MMGenWallet(WalletEnc):
 			msg(f'Hash parameters {" ".join(hash_params)!r} don’t match hash preset {d.hash_preset!r}')
 			msg(f'Hash parameters {" ".join(hash_params)!r} don’t match hash preset {d.hash_preset!r}')
 			return False
 			return False
 
 
-		lmin,foo,lmax = sorted(baseconv.seedlen_map_rev['b58']) # 22,33,44
+		lmin,foo,lmax = sorted(baseconv('b58').seedlen_map_rev) # 22,33,44
 		for i,key in (4,'salt'),(5,'enc_seed'):
 		for i,key in (4,'salt'),(5,'enc_seed'):
 			l = lines[i].split(' ')
 			l = lines[i].split(' ')
 			chk = l.pop(0)
 			chk = l.pop(0)

+ 11 - 11
mmgen/xmrseed.py

@@ -30,15 +30,15 @@ def is_xmrseed(s):
 # implements a subset of the baseconv API
 # implements a subset of the baseconv API
 class xmrseed(baseconv):
 class xmrseed(baseconv):
 
 
-	desc            = { 'xmrseed': ('Monero mnemonic', 'Monero new-style mnemonic seed phrase') }
-	wl_chksums      = { 'xmrseed': '3c381ebb' }
-	seedlen_map     = { 'xmrseed': { 32:25 } }
-	seedlen_map_rev = { 'xmrseed': { 25:32 } }
+	desc            = baseconv.dt('Monero mnemonic', 'Monero new-style mnemonic seed phrase')
+	wl_chksum       = '3c381ebb'
+	seedlen_map     = { 32:25 }
+	seedlen_map_rev = { 25:32 }
 
 
 	def __init__(self,wl_id='xmrseed'):
 	def __init__(self,wl_id='xmrseed'):
 		assert wl_id == 'xmrseed', "initialize with 'xmrseed' for compatibility with baseconv API"
 		assert wl_id == 'xmrseed', "initialize with 'xmrseed' for compatibility with baseconv API"
 		from .mn_monero import words
 		from .mn_monero import words
-		self.digits = { 'xmrseed': words }
+		self.digits = words
 		self.wl_id = 'xmrseed'
 		self.wl_id = 'xmrseed'
 
 
 	@staticmethod
 	@staticmethod
@@ -51,14 +51,14 @@ class xmrseed(baseconv):
 		assert isinstance(words,(list,tuple)),'words must be list or tuple'
 		assert isinstance(words,(list,tuple)),'words must be list or tuple'
 		assert pad == None, f"{pad}: invalid 'pad' argument (must be None)"
 		assert pad == None, f"{pad}: invalid 'pad' argument (must be None)"
 
 
-		desc = self.desc[self.wl_id][0]
-		wl = self.digits[self.wl_id]
+		desc = self.desc.short
+		wl = self.digits
 		base = len(wl)
 		base = len(wl)
 
 
 		if not set(words) <= set(wl):
 		if not set(words) <= set(wl):
 			raise MnemonicError( f'{words!r}: not in {desc} format' )
 			raise MnemonicError( f'{words!r}: not in {desc} format' )
 
 
-		if len(words) not in self.seedlen_map_rev['xmrseed']:
+		if len(words) not in self.seedlen_map_rev:
 			raise MnemonicError( f'{len(words)}: invalid seed phrase length for {desc}' )
 			raise MnemonicError( f'{len(words)}: invalid seed phrase length for {desc}' )
 
 
 		z = self.monero_mn_checksum(words[:-1])
 		z = self.monero_mn_checksum(words[:-1])
@@ -77,11 +77,11 @@ class xmrseed(baseconv):
 	def frombytes(self,bytestr,pad=None,tostr=False):
 	def frombytes(self,bytestr,pad=None,tostr=False):
 		assert pad == None, f"{pad}: invalid 'pad' argument (must be None)"
 		assert pad == None, f"{pad}: invalid 'pad' argument (must be None)"
 
 
-		desc = self.desc[self.wl_id][0]
-		wl = self.digits[self.wl_id]
+		desc = self.desc.short
+		wl = self.digits
 		base = len(wl)
 		base = len(wl)
 
 
-		if len(bytestr) not in self.seedlen_map['xmrseed']:
+		if len(bytestr) not in self.seedlen_map:
 			raise SeedLengthError(f'{len(bytestr)}: invalid seed byte length for {desc}')
 			raise SeedLengthError(f'{len(bytestr)}: invalid seed byte length for {desc}')
 
 
 		def num2base_monero(num):
 		def num2base_monero(num):

+ 1 - 1
test/unit_tests_d/ut_baseconv.py

@@ -198,7 +198,7 @@ class unit_test(object):
 		qmsg_r('\nChecking wordlist checksums:')
 		qmsg_r('\nChecking wordlist checksums:')
 		vmsg('')
 		vmsg('')
 
 
-		for wl_id in baseconv.wl_chksums:
+		for wl_id in baseconv.constants['wl_chksum']:
 			vmsg_r(f'  {wl_id+":":9}')
 			vmsg_r(f'  {wl_id+":":9}')
 			baseconv(wl_id).check_wordlist()
 			baseconv(wl_id).check_wordlist()