seed.py: minor fixes and cleanups

This commit is contained in:
The MMGen Project 2019-06-14 17:10:50 +00:00
commit 310ce2d05e
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
3 changed files with 30 additions and 36 deletions

View file

@ -167,7 +167,7 @@ class SubSeedList(MMGenObject):
last_sid = SeedID(sid=last_sid)
def add_subseed(idx,length):
for nonce in range(self.nonce_start,self.member_type.max_nonce): # use nonce to handle SeedID collisions
for nonce in range(self.nonce_start,self.member_type.max_nonce+1): # handle SeedID collisions
sid = make_chksum_8(self.member_type.make_subseed_bin(self,idx,nonce,length))
if not (sid in self.data['long'] or sid in self.data['short'] or sid == self.parent_seed.sid):
self.data[length][sid] = (idx,nonce)
@ -214,24 +214,22 @@ class Seed(SeedBase):
def subseed_by_seed_id(self,sid,last_idx=None,print_msg=False):
return self.subseeds.get_subseed_by_seed_id(sid,last_idx=last_idx,print_msg=print_msg)
def split(self,count,id_str=None,use_master=False,master_idx=1):
def split(self,count,id_str=None,use_master=False,master_idx=MasterShareIdx.min_val):
return SeedShareList(self,count,id_str,master_idx if use_master else None)
@staticmethod
def join_shares(seed_list,use_master=False,master_idx=1,id_str=None):
def join_shares(seed_list,use_master=False,master_idx=MasterShareIdx.min_val,id_str=None):
if not hasattr(seed_list,'__next__'): # seed_list can be iterator or iterable
seed_list = iter(seed_list)
class d(object):
slen = None
ret = 0
count = 0
byte_len,ret,count = None,0,0
def add_share(ss):
if d.slen:
assert ss.bitlen == d.slen,'Seed length mismatch! {} != {}'.format(ss.bitlen,d.slen)
if d.byte_len:
assert ss.byte_len == d.byte_len,'Seed length mismatch! {} != {}'.format(ss.byte_len,d.byte_len)
else:
d.slen = ss.bitlen
d.byte_len = ss.byte_len
d.ret ^= int(ss.data.hex(),16)
d.count += 1
@ -245,7 +243,7 @@ class Seed(SeedBase):
add_share(SeedShareMasterJoining(master_idx,master_share,id_str,d.count+1).derived_seed)
SeedShareCount(d.count)
return Seed(seed_bin=d.ret.to_bytes(d.slen // 8,'big'))
return Seed(seed_bin=d.ret.to_bytes(d.byte_len,'big'))
class SubSeed(SeedBase):
@ -266,9 +264,7 @@ class SubSeed(SeedBase):
seed = parent_list.parent_seed
short = { 'short': True, 'long': False }[length]
# field maximums: idx: 4294967295 (1000000), nonce: 65535 (1000), short: 255 (1)
scramble_key = idx.to_bytes(4,'big',signed=False) + \
nonce.to_bytes(2,'big',signed=False) + \
short.to_bytes(1,'big',signed=False)
scramble_key = idx.to_bytes(4,'big') + nonce.to_bytes(2,'big') + short.to_bytes(1,'big')
return scramble_seed(seed.data,scramble_key)[:16 if short else seed.byte_len]
class SeedShareList(SubSeedList):
@ -359,11 +355,9 @@ class SeedShare(SubSeed):
assert length == 'long'
# field maximums: id_str: none (256 chars), count: 65535 (1024), idx: 65535 (1024), nonce: 65535 (1000)
scramble_key = '{}:{}:'.format(parent_list.split_type,parent_list.id_str).encode() + \
parent_list.count.to_bytes(2,'big',signed=False) + \
idx.to_bytes(2,'big',signed=False) + \
nonce.to_bytes(2,'big',signed=False)
parent_list.count.to_bytes(2,'big') + idx.to_bytes(2,'big') + nonce.to_bytes(2,'big')
if parent_list.master_share:
scramble_key += b':master:' + parent_list.master_share.idx.to_bytes(2,'big',signed=False)
scramble_key += b':master:' + parent_list.master_share.idx.to_bytes(2,'big')
return scramble_seed(seed.data,scramble_key)[:seed.byte_len]
class SeedShareLast(SeedBase):
@ -402,12 +396,12 @@ class SeedShareMaster(SeedBase):
def make_base_seed_bin(self):
seed = self.parent_list.parent_seed
# field maximums: idx: 65535 (1024)
scramble_key = b'master:' + self.idx.to_bytes(2,'big',signed=False)
scramble_key = b'master:' + self.idx.to_bytes(2,'big')
return scramble_seed(seed.data,scramble_key)[:seed.byte_len]
def make_derived_seed_bin(self,id_str,count):
# field maximums: id_str: none (256 chars), count: 65535 (1024)
scramble_key = id_str.encode() + b':' + count.to_bytes(2,'big',signed=False)
scramble_key = id_str.encode() + b':' + count.to_bytes(2,'big')
return scramble_seed(self.data,scramble_key)[:self.byte_len]
class SeedShareMasterJoining(SeedShareMaster):

View file

@ -680,4 +680,4 @@ class TwGetBalance(MMGenObject):
if key == 'TOTAL': continue
if vals[3]:
o += red('Warning: this wallet contains PRIVATE KEYS for {} outputs!\n'.format(key))
return o
return o.rstrip()

View file

@ -14,34 +14,34 @@ class unit_test(object):
def basic_ops(master_idx):
test_data = {
'default': (
(8,'4710FBF0','B3D9411B','2670E83D','D1FC57ED','AE49CABE','63FFBA62',256),
(6,'9D07ABBD','AF5DC2F6','1A3BBDAC','2548AEE9','B94F7450','1F4E5A12',192),
(4,'43670520','1F72C066','E5AA8DA1','A33966A0','D2BCE0A5','A568C315',128),
(8,'4710FBF0','B3D9411B','2670E83D','D1FC57ED','AE49CABE','63FFBA62',0,0),
(6,'9D07ABBD','AF5DC2F6','1A3BBDAC','2548AEE9','B94F7450','1F4E5A12',0,0),
(4,'43670520','1F72C066','E5AA8DA1','A33966A0','D2BCE0A5','A568C315',0,0),
),
'φυβαρ': (
(8,'4710FBF0','269D658C','9D25889E','6D730ECB','C61A963F','9FE99C05',256),
(6,'9D07ABBD','4998B33E','F00CE041','C612BEE5','35CD3675','41B3BE61',192),
(4,'43670520','77140076','EA82CB30','80F7AEDE','D168D768','77BE57AA',128),
(8,'4710FBF0','269D658C','9D25889E','6D730ECB','C61A963F','9FE99C05',0,0),
(6,'9D07ABBD','4998B33E','F00CE041','C612BEE5','35CD3675','41B3BE61',0,0),
(4,'43670520','77140076','EA82CB30','80F7AEDE','D168D768','77BE57AA',0,0),
)
}
test_data_master = {
'1': {
'default': (
(8,'4710FBF0','B512A312','3588E156','9374255D','3E87A907','752A2E4E',256),
(4,'43670520','05880E2B','C6B438D4','5FF9B5DF','778E9C60','2C01F046',128) ),
(8,'4710FBF0','B512A312','3588E156','9374255D','3E87A907','752A2E4E',0,0),
(4,'43670520','05880E2B','C6B438D4','5FF9B5DF','778E9C60','2C01F046',0,0) ),
'φυβαρ': (
(8,'4710FBF0','5FA963B0','69A1F56A','25789CC4','9777A750','E17B9B8B',256),
(4,'43670520','AF8BFDF8','66F319BE','A5E40978','927549D2','93B2418B',128),
(8,'4710FBF0','5FA963B0','69A1F56A','25789CC4','9777A750','E17B9B8B',0,0),
(4,'43670520','AF8BFDF8','66F319BE','A5E40978','927549D2','93B2418B',0,0),
)
},
'5': {
'default': (
(8,'4710FBF0','A8A34BC0','F69B6CF8','234B5DCD','BB004DC5','08DC9776',256),
(4,'43670520','C887A2D6','86AE9445','3188AD3D','07339882','BE3FE72A',128) ),
(8,'4710FBF0','A8A34BC0','F69B6CF8','234B5DCD','BB004DC5','08DC9776',0,0),
(4,'43670520','C887A2D6','86AE9445','3188AD3D','07339882','BE3FE72A',0,0) ),
'φυβαρ': (
(8,'4710FBF0','89C35D99','B1CD5854','8414652C','32C24668','17CA1E19',256),
(4,'43670520','06929789','32E8E375','C6AC3C9D','4BEA2AB2','15AFC7F2',128)
(8,'4710FBF0','89C35D99','B1CD5854','8414652C','32C24668','17CA1E19',0,0),
(4,'43670520','06929789','32E8E375','C6AC3C9D','4BEA2AB2','15AFC7F2',0,0)
)
}
}
@ -52,12 +52,12 @@ class unit_test(object):
msg_r('Testing basic ops (id_str={!r}, master_idx={})...'.format(id_str,master_idx))
vmsg('')
for a,b,c,d,e,f,h,i in test_data[id_str if id_str is not None else 'default']:
for a,b,c,d,e,f,h,i,p in test_data[id_str if id_str is not None else 'default']:
seed_bin = bytes.fromhex('deadbeef' * a)
seed = Seed(seed_bin)
assert seed.sid == b, seed.sid
for share_count,j,k,l in ((2,c,c,d),(5,e,f,h)):
for share_count,j,k,l,m in ((2,c,c,d,i),(5,e,f,h,p)):
shares = seed.split(share_count,id_str,bool(master_idx),master_idx)
A = len(shares)