mmgen-keygen: new viewkey-address file type
Generate using the --viewkeys option
Testing:
$ test/unit_tests.py --verbose addrlist.viewkeyaddr
$ test/tooltest2.py --fork --verbose --coin=xmr viewkeyaddrfile_chksum
$ test/test.py -e ref_viewkeyaddrfile_gen_xmr ref_viewkeyaddrfile_chk_xmr
This commit is contained in:
parent
50434eabb6
commit
dc685e9ced
10 changed files with 85 additions and 12 deletions
|
|
@ -117,7 +117,8 @@ class AddrFile(MMGenObject):
|
|||
if p.has_keys:
|
||||
if self.cfg.b16:
|
||||
out.append(fs.format( '', f'orig_hex: {e.sec.orig_bytes.hex()}', c ))
|
||||
out.append(fs.format( '', f'{p.al_id.mmtype.wif_label}: {e.sec.wif}', c ))
|
||||
if type(self) != ViewKeyAddrFile:
|
||||
out.append(fs.format( '', f'{p.al_id.mmtype.wif_label}: {e.sec.wif}', c ))
|
||||
for k in ('viewkey','wallet_passwd'):
|
||||
v = getattr(e,k)
|
||||
if v: out.append(fs.format( '', f'{k}: {v}', c ))
|
||||
|
|
@ -149,9 +150,10 @@ class AddrFile(MMGenObject):
|
|||
a = le(**{ 'proto': p.proto, 'idx':int(idx), p.main_attr:addr, 'comment':comment })
|
||||
|
||||
if p.has_keys: # order: wif,(orig_hex),viewkey,wallet_passwd
|
||||
d = self.get_line(lines)
|
||||
assert d[0] == p.al_id.mmtype.wif_label+':', iifs.format(d[0],p.al_id.mmtype.wif_label)
|
||||
a.sec = PrivKey(proto=p.proto,wif=d[1])
|
||||
if type(self) != ViewKeyAddrFile:
|
||||
d = self.get_line(lines)
|
||||
assert d[0] == p.al_id.mmtype.wif_label+':', iifs.format(d[0],p.al_id.mmtype.wif_label)
|
||||
a.sec = PrivKey(proto=p.proto,wif=d[1])
|
||||
for k,dtype,add_proto in (
|
||||
('viewkey',ViewKey,True),
|
||||
('wallet_passwd',WalletPassword,False) ):
|
||||
|
|
@ -162,7 +164,7 @@ class AddrFile(MMGenObject):
|
|||
|
||||
ret.append(a)
|
||||
|
||||
if p.has_keys and p.ka_validity_chk != False:
|
||||
if type(self) != ViewKeyAddrFile and p.has_keys and p.ka_validity_chk != False:
|
||||
|
||||
def verify_keys():
|
||||
from .addrgen import KeyGenerator,AddrGenerator
|
||||
|
|
@ -300,6 +302,10 @@ class KeyAddrFile(AddrFile):
|
|||
desc = 'secret keys'
|
||||
ext = 'akeys'
|
||||
|
||||
class ViewKeyAddrFile(KeyAddrFile):
|
||||
desc = 'view keys'
|
||||
ext = 'vkeys'
|
||||
|
||||
class KeyFile(KeyAddrFile):
|
||||
ext = 'keys'
|
||||
header = """
|
||||
|
|
|
|||
|
|
@ -218,6 +218,10 @@ class AddrList(MMGenObject): # Address info for a single seed ID
|
|||
if self.al_id == None:
|
||||
return
|
||||
|
||||
if type(self) == ViewKeyAddrList:
|
||||
if not 'viewkey' in self.al_id.mmtype.extra_attrs:
|
||||
die(1,f'viewkeys not supported for address type {self.al_id.mmtype.desc!r}')
|
||||
|
||||
self.id_str = AddrListIDStr(self)
|
||||
|
||||
if type(self) == KeyList:
|
||||
|
|
@ -242,8 +246,8 @@ class AddrList(MMGenObject): # Address info for a single seed ID
|
|||
|
||||
mmtype = self.al_id.mmtype
|
||||
|
||||
gen_wallet_passwd = type(self) == KeyAddrList and 'wallet_passwd' in mmtype.extra_attrs
|
||||
gen_viewkey = type(self) == KeyAddrList and 'viewkey' in mmtype.extra_attrs
|
||||
gen_wallet_passwd = type(self) in (KeyAddrList,ViewKeyAddrList) and 'wallet_passwd' in mmtype.extra_attrs
|
||||
gen_viewkey = type(self) in (KeyAddrList,ViewKeyAddrList) and 'viewkey' in mmtype.extra_attrs
|
||||
|
||||
if self.gen_addrs:
|
||||
from .addrgen import KeyGenerator,AddrGenerator
|
||||
|
|
@ -281,7 +285,8 @@ class AddrList(MMGenObject): # Address info for a single seed ID
|
|||
if gen_viewkey:
|
||||
e.viewkey = ag.to_viewkey(data)
|
||||
if gen_wallet_passwd:
|
||||
e.wallet_passwd = self.gen_wallet_passwd(e.sec)
|
||||
e.wallet_passwd = self.gen_wallet_passwd(
|
||||
e.viewkey.encode() if type(self) == ViewKeyAddrList else e.sec )
|
||||
elif self.gen_passwds:
|
||||
e.passwd = self.gen_passwd(e.sec) # TODO - own type
|
||||
|
||||
|
|
@ -406,6 +411,11 @@ class KeyAddrList(AddrList):
|
|||
has_keys = True
|
||||
chksum_rec_f = lambda foo,e: (str(e.idx), e.addr, e.sec.wif)
|
||||
|
||||
class ViewKeyAddrList(KeyAddrList):
|
||||
desc = 'viewkey-address'
|
||||
gen_desc = 'viewkey/address pair'
|
||||
chksum_rec_f = lambda foo,e: ( str(e.idx), e.addr )
|
||||
|
||||
class KeyList(KeyAddrList):
|
||||
desc = 'key'
|
||||
gen_desc = 'key'
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ opts_data = {
|
|||
(default: {dmat})
|
||||
-U, --subwallet= U Generate {what} for subwallet 'U' (see SUBWALLETS
|
||||
below)
|
||||
-V, --viewkeys Print viewkeys, omitting secret keys
|
||||
-v, --verbose Produce more verbose output
|
||||
-x, --b16 Print secret keys in hexadecimal too
|
||||
""",
|
||||
|
|
@ -156,6 +157,8 @@ ss_seed = ss.seed if cfg.subwallet is None else ss.seed.subseed(cfg.subwallet,pr
|
|||
|
||||
if cfg.no_addresses:
|
||||
gen_clsname = 'KeyList'
|
||||
elif cfg.viewkeys:
|
||||
gen_clsname = 'ViewKeyAddrList'
|
||||
|
||||
al = getattr( mmgen.addrlist, gen_clsname )(
|
||||
cfg = cfg,
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ mods = {
|
|||
'file': (
|
||||
'addrfile_chksum',
|
||||
'keyaddrfile_chksum',
|
||||
'viewkeyaddrfile_chksum',
|
||||
'passwdfile_chksum',
|
||||
'txview',
|
||||
),
|
||||
|
|
|
|||
|
|
@ -60,6 +60,11 @@ class tool_cmd(tool_cmd_base):
|
|||
from ..addrlist import KeyAddrList
|
||||
return self._file_chksum(mmgen_keyaddrfile,KeyAddrList)
|
||||
|
||||
def viewkeyaddrfile_chksum(self,mmgen_viewkeyaddrfile:str):
|
||||
"compute checksum for MMGen key-address file"
|
||||
from ..addrlist import ViewKeyAddrList
|
||||
return self._file_chksum(mmgen_viewkeyaddrfile,ViewKeyAddrList)
|
||||
|
||||
def passwdfile_chksum(self,mmgen_passwdfile:str):
|
||||
"compute checksum for MMGen password file"
|
||||
from ..passwdlist import PasswordList
|
||||
|
|
|
|||
21
test/ref/monero/98831F3A-XMR-M[1-3].vkeys
Normal file
21
test/ref/monero/98831F3A-XMR-M[1-3].vkeys
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# MMGen viewkey-address file
|
||||
#
|
||||
# This file is editable.
|
||||
# Everything following a hash symbol '#' is a comment and ignored by MMGen.
|
||||
# A text label of 80 screen cells or less may be added to the right of each
|
||||
# address, and it will be appended to the tracking wallet label upon import.
|
||||
# The label may contain any printable ASCII symbol.
|
||||
#
|
||||
# Viewkey-address data checksum for 98831F3A-XMR-M[1-3]: 40C9 0E61 B743 229C
|
||||
# Record this value to a secure location.
|
||||
98831F3A XMR:MONERO {
|
||||
1 41tmwZd2CdXEGtWqGY9fH9FVtQM8VxZASYPQ3VJQhFjtGWYzQFuidD21vJYTi2yy3tXRYXTNXBTaYVLav62rwUUpFFyicZU
|
||||
viewkey: 3fa430d35eb44ae2ac91b302b794e6b789807ca0c19757042f581e5579314503
|
||||
wallet_passwd: 4be230151aa51363af6123624ea20509
|
||||
2 45Un3DKQfZ1XP9XWKVqMrzMugrxHLU8L47Jcxyu7dNnGKd7WWDTQ6QrBjCxoxQhnL13xdgKycywfijNuuTzbZBj7UHPjBMb
|
||||
viewkey: 176fed837ea2d8ab98de50811a0869d0f2e6076fcacfa17707bfb2bca960190e
|
||||
wallet_passwd: b19f506e52c8ffd7a3b1bc1c4fb4c1bb
|
||||
3 47mWaHEPy26U4e2Xw1y3PhBuEBzMpPF1z7QzBVJ19pqe9nMmcztcHdkYs19YxrJnEWEkipSNroQxvJaoYfLX87Po39Btso4
|
||||
viewkey: be75e20cf8ae8816bade5c05cb677929c67be310fcb509fd52630735229ac20d
|
||||
wallet_passwd: 5e8e3b47a9aa28464dcc2a588e892d50
|
||||
}
|
||||
|
|
@ -41,6 +41,8 @@ class TestSuiteRef(TestSuiteBase,TestSuiteShared):
|
|||
'ref_segwitaddrfile':'98831F3A{}-S[1,31-33,500-501,1010-1011]{}.addrs',
|
||||
'ref_bech32addrfile':'98831F3A{}-B[1,31-33,500-501,1010-1011]{}.addrs',
|
||||
'ref_keyaddrfile': '98831F3A{}[1,31-33,500-501,1010-1011]{}.akeys.mmenc',
|
||||
'ref_viewkeyaddrfile': '98831F3A-XMR-M[1-3].vkeys',
|
||||
|
||||
'ref_passwdfile_b32_24': '98831F3A-фубар@crypto.org-b32-24[1,4,1100].pws',
|
||||
'ref_passwdfile_b32_12': '98831F3A-фубар@crypto.org-b32-12[1,4,1100].pws',
|
||||
'ref_passwdfile_b58_10': '98831F3A-фубар@crypto.org-b58-10[1,4,1100].pws',
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class TestSuiteRefAltcoin(TestSuiteRef,TestSuiteBase):
|
|||
'ref_keyaddrfile_chksum_zec': 'F05A 5A5C 0C8E 2617',
|
||||
'ref_keyaddrfile_chksum_zec_z': '6B87 9B2D 0D8D 8D1E',
|
||||
'ref_keyaddrfile_chksum_xmr': 'E0D7 9612 3D67 404A',
|
||||
'ref_viewkeyaddrfile_chksum_xmr': '40C9 0E61 B743 229C',
|
||||
'ref_keyaddrfile_chksum_dash': 'E83D 2C63 FEA2 4142',
|
||||
'ref_keyaddrfile_chksum_eth': 'E400 70D9 0AE3 C7C2',
|
||||
'ref_keyaddrfile_chksum_etc': 'EF49 967D BD6C FE45',
|
||||
|
|
@ -61,6 +62,7 @@ class TestSuiteRefAltcoin(TestSuiteRef,TestSuiteBase):
|
|||
('ref_keyaddrfile_gen_zec', 'generate key-address file (ZEC-T)'),
|
||||
('ref_keyaddrfile_gen_zec_z','generate key-address file (ZEC-Z)'),
|
||||
('ref_keyaddrfile_gen_xmr', 'generate key-address file (XMR)'),
|
||||
('ref_viewkeyaddrfile_gen_xmr','generate viewkey-address file (XMR)'),
|
||||
|
||||
('ref_addrfile_chk_eth', 'reference address file (ETH)'),
|
||||
('ref_addrfile_chk_etc', 'reference address file (ETC)'),
|
||||
|
|
@ -75,6 +77,7 @@ class TestSuiteRefAltcoin(TestSuiteRef,TestSuiteBase):
|
|||
('ref_keyaddrfile_chk_zec', 'reference key-address file (ZEC-T)'),
|
||||
('ref_keyaddrfile_chk_zec_z','reference key-address file (ZEC-Z)'),
|
||||
('ref_keyaddrfile_chk_xmr', 'reference key-address file (XMR)'),
|
||||
('ref_viewkeyaddrfile_chk_xmr', 'reference viewkey-address file (XMR)'),
|
||||
)
|
||||
|
||||
def ref_altcoin_tx_chk(self):
|
||||
|
|
@ -173,6 +176,13 @@ class TestSuiteRefAltcoin(TestSuiteRef,TestSuiteBase):
|
|||
def ref_keyaddrfile_gen_xmr(self):
|
||||
return self.ref_altcoin_addrgen(coin='XMR',mmtype='monero',gen_what='key')
|
||||
|
||||
def ref_viewkeyaddrfile_gen_xmr(self):
|
||||
return self.ref_altcoin_addrgen(
|
||||
coin = 'XMR',
|
||||
mmtype = 'monero',
|
||||
gen_what = 'viewkey',
|
||||
add_args = ['--viewkeys'],
|
||||
addr_idx_list = '1-3' )
|
||||
|
||||
def ref_addrfile_chk_eth(self):
|
||||
return self.ref_addrfile_chk(ftype='addr',coin='ETH',subdir='ethereum',pfx='-ETH',
|
||||
|
|
@ -222,3 +232,7 @@ class TestSuiteRefAltcoin(TestSuiteRef,TestSuiteBase):
|
|||
def ref_keyaddrfile_chk_xmr(self):
|
||||
return self.ref_addrfile_chk(ftype='keyaddr',coin='XMR',subdir='monero',pfx='-XMR-M',
|
||||
pat='XMR Mainnet.*Monero')
|
||||
|
||||
def ref_viewkeyaddrfile_chk_xmr(self):
|
||||
return self.ref_addrfile_chk(ftype='viewkeyaddr',coin='XMR',subdir='monero',pfx='-XMR-M',
|
||||
pat='XMR Mainnet.*Monero')
|
||||
|
|
|
|||
|
|
@ -681,6 +681,11 @@ tests = {
|
|||
( ['test/ref/ethereum_classic/98831F3A-ETC[1,31-33,500-501,1010-1011].addrs'],
|
||||
'E97A D796 B495 E8BC'), ],
|
||||
},
|
||||
'viewkeyaddrfile_chksum': {
|
||||
'xmr_mainnet': [
|
||||
( ['test/ref/monero/98831F3A-XMR-M[1-3].vkeys'], '40C9 0E61 B743 229C' ),
|
||||
],
|
||||
},
|
||||
'keyaddrfile_chksum': {
|
||||
'btc_mainnet': [
|
||||
( ['test/ref/98831F3A[1,31-33,500-501,1010-1011].akeys.mmenc'],
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@ test.unit_tests_d.ut_addrlist: address list unit tests for the MMGen suite
|
|||
from mmgen.common import *
|
||||
from mmgen.seed import Seed
|
||||
from mmgen.addr import MMGenAddrType
|
||||
from mmgen.addrlist import AddrIdxList,AddrList,KeyList,KeyAddrList
|
||||
from mmgen.addrlist import AddrIdxList,AddrList,KeyList,KeyAddrList,ViewKeyAddrList
|
||||
from mmgen.passwdlist import PasswordList
|
||||
from mmgen.protocol import init_proto
|
||||
from ..include.common import cfg,qmsg,vmsg
|
||||
|
||||
def do_test(list_type,chksum,idx_spec=None,pw_id_str=None,add_kwargs=None):
|
||||
def do_test(list_type,chksum,idx_spec=None,pw_id_str=None,add_kwargs=None,coin=None,addrtype=None):
|
||||
|
||||
qmsg(blue(f'Testing {list_type.__name__}'))
|
||||
proto = init_proto( cfg, 'btc' )
|
||||
proto = init_proto( cfg, coin or 'btc' )
|
||||
seed = Seed(cfg,seed_bin=bytes.fromhex('feedbead'*8))
|
||||
mmtype = MMGenAddrType(proto,'C')
|
||||
mmtype = MMGenAddrType(proto, addrtype or 'C')
|
||||
idxs = AddrIdxList(idx_spec or '1-3')
|
||||
|
||||
if cfg.verbose:
|
||||
|
|
@ -93,6 +93,12 @@ class unit_tests:
|
|||
def keyaddr(self,name,ut):
|
||||
return do_test(KeyAddrList,'4A36 AA65 8C2B 7C35')
|
||||
|
||||
def keyaddr_xmr(self,name,ut):
|
||||
return do_test(KeyAddrList,'AAA2 BA69 17FC 9A88',coin='XMR',addrtype='M')
|
||||
|
||||
def viewkeyaddr(self,name,ut):
|
||||
return do_test(ViewKeyAddrList,'C122 2E58 DC28 D6AE',coin='XMR',addrtype='M')
|
||||
|
||||
def passwd(self,name,ut):
|
||||
return do_test(PasswordList,'FF4A B716 4513 8F8F',pw_id_str='foo')
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue