New die roll (base6d) wallet format
- Permits the creation of wallets by repeated rolls of a die: 50 rolls for
128-bit, 75 for 192-bit, and 100 for 256-bit seeds. The base6d format
uses the digits from one to six, so that user doesn't have to subtract
one from each roll.
Testing:
$ test/unit_tests.py baseconv
$ test/test.py ref3 conv
Example:
NOTE: when creating a real wallet, the following steps must be performed in a
secure offline environment, and preferably with the use of a text editor and
a file written in volatile memory (e.g. /dev/shm), rather than the `echo`
command. A more private and user-friendly data input method will be provided
in a forthcoming patch.
Sample 128-bit data obtained by rolling a die 50 times and entering each roll
on the keyboard as a digit:
15146 56446 53415 45431 55141 32115 41325 16311 32553 43533
Here spaces have been added for greater readability. Newlines are also
permitted.
Save the data in a file with the extension .b6d:
$ echo 15146 56446 53415 45431 55141 32115 41325 16311 32553 43533 > myseed.b6d
Convert to MMGen's default wallet format:
$ mmgen-walletconv -o wallet myseed.b6d
Convert the wallet back to base6d:
$ mmgen-walletconv -o dieroll FE3C6545*.mmdat
Base6d die roll seed data written to file 'FE3C6545[128].b6d'
$ cat 'FE3C6545[128].b6d'
15146 56446 53415 45431 55141
32115 41325 16311 32553 43533
This commit is contained in:
parent
04a1dcaae4
commit
c778636918
8 changed files with 66 additions and 0 deletions
|
|
@ -1014,6 +1014,27 @@ class MMGenSeedFile(SeedSourceUnenc):
|
|||
|
||||
return True
|
||||
|
||||
class DieRollSeedFile(SeedSourceUnenc):
|
||||
|
||||
stdin_ok = True
|
||||
fmt_codes = 'b6d','die','dieroll',
|
||||
desc = 'base6d die roll seed data'
|
||||
ext = 'b6d'
|
||||
|
||||
def _format(self):
|
||||
d = baseconv.frombytes(self.seed.data,'b6d',pad='seed',tostr=True) + '\n'
|
||||
self.fmt_data = block_format(d,gw=5,cols=5)
|
||||
|
||||
def _deformat(self):
|
||||
d = self.fmt_data.translate(dict((ord(ws),None) for ws in '\t\n '))
|
||||
seed_bytes = baseconv.tobytes(d,'b6d',pad='seed')
|
||||
|
||||
self.seed = Seed(seed_bytes)
|
||||
self.ssdata.hexseed = seed_bytes.hex()
|
||||
|
||||
check_usr_seed_len(self.seed.bitlen)
|
||||
return True
|
||||
|
||||
class PlainHexSeedFile(SeedSourceUnenc):
|
||||
|
||||
stdin_ok = True
|
||||
|
|
|
|||
|
|
@ -287,6 +287,7 @@ class baseconv(object):
|
|||
'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'),
|
||||
'mmgen': ('MMGen native mnemonic',
|
||||
'MMGen native mnemonic seed phrase data created using old Electrum wordlist and simple base conversion'),
|
||||
}
|
||||
|
|
@ -296,6 +297,7 @@ class baseconv(object):
|
|||
'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')
|
||||
|
|
@ -306,9 +308,11 @@ class baseconv(object):
|
|||
}
|
||||
seed_pad_lens = {
|
||||
'b58': { 16:22, 24:33, 32:44 },
|
||||
'b6d': { 16:50, 24:75, 32:100 },
|
||||
}
|
||||
seed_pad_lens_rev = {
|
||||
'b58': { 22:16, 33:24, 44:32 },
|
||||
'b6d': { 50:16, 75:24, 100:32 },
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
1
test/ref/1378FC64.b6d
Normal file
1
test/ref/1378FC64.b6d
Normal file
|
|
@ -0,0 +1 @@
|
|||
135111311335561534526322511624324361264136623152556434641112356463412545532
|
||||
1
test/ref/98831F3A.b6d
Normal file
1
test/ref/98831F3A.b6d
Normal file
|
|
@ -0,0 +1 @@
|
|||
1253254513316235145146646115665463533224654453113624424263124136533542263452465156633216133232332365
|
||||
2
test/ref/FE3C6545.b6d
Normal file
2
test/ref/FE3C6545.b6d
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
15146 56446 53415 45431 55141
|
||||
32115 41325 16311 32553 43533
|
||||
|
|
@ -48,6 +48,7 @@ class TestSuiteRef3Seed(TestSuiteBase,TestSuiteShared):
|
|||
('ref_seed_chk', ([],'saved seed file')),
|
||||
('ref_hex_chk', ([],'saved mmhex file')),
|
||||
('ref_plainhex_chk',([],'saved hex file')),
|
||||
('ref_dieroll_chk', ([],'saved dieroll (b6d) file')),
|
||||
('ref_mn_chk', ([],'saved native MMGen mnemonic file')),
|
||||
('ref_bip39_chk', ([],'saved BIP39 mnemonic file')),
|
||||
('ref_hincog_chk', ([],'saved hidden incog reference wallet')),
|
||||
|
|
@ -60,6 +61,7 @@ class TestSuiteRef3Seed(TestSuiteBase,TestSuiteShared):
|
|||
('ref_walletconv_seed', ([],'wallet filename (seed)')),
|
||||
('ref_walletconv_hexseed', ([],'wallet filename (hex seed)')),
|
||||
('ref_walletconv_plainhexseed',([],'wallet filename (plain hex seed)')),
|
||||
('ref_walletconv_dieroll', ([],'wallet filename (dieroll (b6d) seed)')),
|
||||
('ref_walletconv_incog', ([],'wallet filename (incog)')),
|
||||
('ref_walletconv_xincog', ([],'wallet filename (hex incog)')),
|
||||
)
|
||||
|
|
@ -94,6 +96,10 @@ class TestSuiteRef3Seed(TestSuiteBase,TestSuiteShared):
|
|||
from mmgen.seed import PlainHexSeedFile
|
||||
return self.ref_ss_chk(ss=PlainHexSeedFile)
|
||||
|
||||
def ref_dieroll_chk(self):
|
||||
from mmgen.seed import DieRollSeedFile
|
||||
return self.ref_ss_chk(ss=DieRollSeedFile)
|
||||
|
||||
def ref_mn_chk(self):
|
||||
from mmgen.seed import MMGenMnemonic
|
||||
return self.ref_ss_chk(ss=MMGenMnemonic)
|
||||
|
|
@ -170,6 +176,7 @@ class TestSuiteRef3Seed(TestSuiteBase,TestSuiteShared):
|
|||
def ref_walletconv_seed(self): return self.ref_walletconv(ofmt='mmseed')
|
||||
def ref_walletconv_hexseed(self): return self.ref_walletconv(ofmt='mmhex')
|
||||
def ref_walletconv_plainhexseed(self): return self.ref_walletconv(ofmt='hex')
|
||||
def ref_walletconv_dieroll(self): return self.ref_walletconv(ofmt='dieroll')
|
||||
|
||||
def ref_walletconv_incog(self,ofmt='incog',ext='mmincog'):
|
||||
args = ['-r0','-p1']
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ class TestSuiteWalletConv(TestSuiteBase,TestSuiteShared):
|
|||
('ref_seed_conv', 'conversion of saved seed file'),
|
||||
('ref_hex_conv', 'conversion of saved MMGen hexadecimal seed file'),
|
||||
('ref_plainhex_conv', 'conversion of saved plain hexadecimal seed file'),
|
||||
('ref_dieroll_conv', 'conversion of saved dieroll (b6d) seed file'),
|
||||
('ref_brain_conv', 'conversion of ref brainwallet'),
|
||||
('ref_incog_conv', 'conversion of saved incog wallet'),
|
||||
('ref_incox_conv', 'conversion of saved hex incog wallet'),
|
||||
|
|
@ -76,6 +77,7 @@ class TestSuiteWalletConv(TestSuiteBase,TestSuiteShared):
|
|||
('ref_bip39_conv_out', 'ref seed conversion to BIP39 mnemonic'),
|
||||
('ref_hex_conv_out', 'ref seed conversion to MMGen hex seed'),
|
||||
('ref_plainhex_conv_out','ref seed conversion to plain hex seed'),
|
||||
('ref_dieroll_conv_out','ref seed conversion to dieroll (b6d) seed'),
|
||||
('ref_seed_conv_out', 'ref seed conversion to seed'),
|
||||
('ref_incog_conv_out', 'ref seed conversion to incog data'),
|
||||
('ref_incox_conv_out', 'ref seed conversion to hex incog data'),
|
||||
|
|
@ -101,6 +103,7 @@ class TestSuiteWalletConv(TestSuiteBase,TestSuiteShared):
|
|||
def ref_seed_conv(self): return self.ref_mn_conv(ext='mmseed')
|
||||
def ref_hex_conv(self): return self.ref_mn_conv(ext='mmhex')
|
||||
def ref_plainhex_conv(self): return self.ref_mn_conv(ext='hex')
|
||||
def ref_dieroll_conv(self): return self.ref_mn_conv(ext='b6d')
|
||||
|
||||
def ref_brain_conv(self):
|
||||
uopts = ['-i','b','-p','1','-l',str(self.seed_len)]
|
||||
|
|
@ -129,6 +132,7 @@ class TestSuiteWalletConv(TestSuiteBase,TestSuiteShared):
|
|||
def ref_seed_conv_out(self): return self.walletconv_out('seed')
|
||||
def ref_hex_conv_out(self): return self.walletconv_out('hexseed')
|
||||
def ref_plainhex_conv_out(self): return self.walletconv_out('hex')
|
||||
def ref_dieroll_conv_out(self): return self.walletconv_out('dieroll')
|
||||
def ref_incog_conv_out(self): return self.walletconv_out('i')
|
||||
def ref_incox_conv_out(self): return self.walletconv_out('xi')
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,32 @@ class unit_test(object):
|
|||
(('ffffffff',None),'37777777777'),
|
||||
(('ffffffff',20),'00000000037777777777'),
|
||||
),
|
||||
'b6d': (
|
||||
(('00',None),'1'),
|
||||
(('00',1),'1'),
|
||||
(('00',2),'11'),
|
||||
(('01',None),'2'),
|
||||
(('01',1),'2'),
|
||||
(('01',2),'12'),
|
||||
(('0f',None),'34'),
|
||||
(('0f',1),'34'),
|
||||
(('0f',2),'34'),
|
||||
(('010f',None),'2242'),
|
||||
(('010f',20),'11111111111111112242'),
|
||||
(('deadbeef',None),'2525524636426'),
|
||||
(('deadbeef',20),'11111112525524636426'),
|
||||
(('00000000',None),'1'),
|
||||
(('00000000',20),'11111111111111111111'),
|
||||
(('ffffffff',None),'2661215126614'),
|
||||
(('ffffffff',20),'11111112661215126614'),
|
||||
|
||||
(('ff'*16,'seed'),'34164464641266661652465154654653354436664555521414'),
|
||||
(('ff'*24,'seed'),'246111411433323364222465566552324652566121541623426135163525451613554313654'),
|
||||
(('ff'*32,'seed'),'2132521653312613134145131423465414636252114131225324246311141642456513416322412146151432142242565134'),
|
||||
(('00'*16,'seed'),'1'*50),
|
||||
(('00'*24,'seed'),'1'*75),
|
||||
(('00'*32,'seed'),'1'*100),
|
||||
),
|
||||
}
|
||||
|
||||
def run_test(self,name,ut):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue