baseconv: tohex() -> tobytes(), fromhex() -> frombytes()

This commit is contained in:
The MMGen Project 2019-10-26 14:13:56 +00:00
commit bec3dfeed2
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
2 changed files with 25 additions and 17 deletions

View file

@ -349,7 +349,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 an integer, it refers to the minimum allowable *string length* of the output.
If an integer, the string, hex string or byte output will be padded to this length.
"""
if pad == None:
return 0
@ -364,6 +364,11 @@ class baseconv(object):
@classmethod
def tohex(cls,words_arg,wl_id,pad=None):
"convert string or list data of base 'wl_id' to hex string"
return cls.tobytes(words_arg,wl_id,pad//2 if type(pad)==int else pad).hex()
@classmethod
def tobytes(cls,words_arg,wl_id,pad=None):
"convert string or list data of base 'wl_id' to byte string"
words = words_arg if isinstance(words_arg,(list,tuple)) else tuple(words_arg.strip())
@ -376,9 +381,9 @@ class baseconv(object):
if not len(words) in d:
m = '{}: invalid length for seed-padded {} data in base conversion'
raise BaseConversionError(m.format(len(words),wl_id))
return d[len(words)] * 2
return d[len(words)]
pad_val = max(cls.get_pad(pad,get_seed_pad),2)
pad_val = max(cls.get_pad(pad,get_seed_pad),1)
wl = cls.digits[wl_id]
base = len(wl)
@ -386,38 +391,41 @@ class baseconv(object):
m = ('{w!r}:','seed data')[pad=='seed'] + ' not in {i} (base{b}) format'
raise BaseConversionError(m.format(w=words_arg,i=wl_id,b=base))
deconv = [wl.index(words[::-1][i])*(base**i) for i in range(len(words))]
ret = ('{:0{w}x}'.format(sum(deconv),w=pad_val))
return (('','0')[len(ret) % 2] + ret)
ret = sum([wl.index(words[::-1][i])*(base**i) for i in range(len(words))])
bl = ret.bit_length()
return ret.to_bytes(max(pad_val,bl//8+bool(bl%8)),'big')
@classmethod
def fromhex(cls,hexstr,wl_id,pad=None,tostr=False):
"convert hex string to list or string data of base 'wl_id'"
if wl_id in ('mmgen','tirosh','bip39'):
assert tostr == False,"'tostr' must be False for '{}'".format(wl_id)
if not is_hex_str(hexstr):
m = ('{h!r}:','seed data')[pad=='seed'] + ' not a hexadecimal string'
raise HexadecimalStringError(m.format(h=hexstr))
if not hexstr:
m = 'empty hex strings not allowed in base conversion'
raise HexadecimalStringError(m)
return cls.frombytes(bytes.fromhex(hexstr),wl_id,pad,tostr)
@classmethod
def frombytes(cls,bytestr,wl_id,pad=None,tostr=False):
"convert byte string to list or string data of base '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]
slen = len(hexstr) // 2
if not slen in d:
if not len(bytestr) in d:
m = '{}: invalid seed byte length for seed-padded base conversion'
raise SeedLengthError(m.format(slen))
return d[slen]
raise SeedLengthError(m.format(len(bytestr)))
return d[len(bytestr)]
pad = max(cls.get_pad(pad,get_seed_pad),1)
wl = cls.digits[wl_id]
base = len(wl)
num,ret = int(hexstr,16),[]
num = int.from_bytes(bytestr,'big')
ret = []
while num:
ret.append(num % base)
num //= base

View file

@ -156,7 +156,7 @@ class unit_test(object):
bad_data = (
('hexstr', 'HexadecimalStringError', ': not a hexadecimal str', lambda:fh('x','b58')),
('hexstr (seed)', 'HexadecimalStringError', 'seed data not a hexadec', lambda:fh('x','b58',pad='seed')),
('hexstr (empty)', 'HexadecimalStringError', 'empty hex strings not', lambda:fh('','b58')),
('hexstr (empty)', 'BaseConversionError', 'empty data not allowed', lambda:fh('','b58')),
('b58 data', 'BaseConversionError', ': not in b58', lambda:th('IfFzZ','b58')),
('b58 data (seed)', 'BaseConversionError', 'seed data not in b58', lambda:th(bad_b58,'b58',pad='seed')),
('b58 len (seed)', 'BaseConversionError', 'invalid length for', lambda:th(bad_b58len,'b58',pad='seed')),