def _walletconv_export(self, wf, uargs=[], out_fmt='w', pf=None): opts = ['-d',self.tmpdir,'-o',out_fmt] + uargs + \ ([],[wf])[bool(wf)] + ([],['-P',pf])[bool(pf)] t = self.spawn('mmgen-walletconv', opts) t.license() if not pf: icls = Wallet.ext_to_type(get_extension(wf)) t.passphrase(icls.desc, self.wpasswd) ocls = Wallet.fmt_code_to_type(out_fmt) out_pw = issubclass(ocls, WalletEnc) and ocls != Brainwallet if out_pw: t.passphrase_new('new ' + ocls.desc, self.wpasswd) t.usr_rand(self.usr_rand_chars) if ocls.__name__.startswith('Incog'): m = 'Encrypting OS random data with key' t.expect(m) t.expect(m) incog_id = t.expect_getend('New Incog Wallet ID: ') t.expect(m) if ocls == IncogWalletHidden: self.write_to_tmpfile(incog_id_fn, incog_id) t.hincog_create(hincog_bytes) elif ocls == MMGenWallet: t.label() return t.written_to_file(capfirst(ocls.desc), oo=True), t
def txsign(self, wf, txfile, pf='', bumpf='', save=True, has_label=False, extra_opts=[], extra_desc='', view='n', dfl_wallet=False): opts = extra_opts + ['-d', self.tmpdir, txfile] + ([wf] if wf else []) t = self.spawn('mmgen-txsign', opts, extra_desc) t.license() t.view_tx(view) wcls = MMGenWallet if dfl_wallet else Wallet.ext_to_type( get_extension(wf)) pw = issubclass(wcls, WalletEnc) and wcls != Brainwallet if pw: t.passphrase(wcls.desc, self.wpasswd) if save: self.txsign_end(t, has_label=has_label) else: t.do_comment(False, has_label=has_label) t.expect('Save signed transaction? (Y/n): ', 'n') t.req_exit_val = 1 return t
def ss_splt(self, tdir, ofmt, spec, add_args=[], wf=None, master=None): try: os.mkdir(self.get_tmp_subdir(tdir)) except: pass t = self.spawn( 'mmgen-seedsplit', ['-q', '-d', self.get_tmp_subdir(tdir), '-r0', '-o', ofmt] + (['-L', (spec or 'label')] if ofmt == 'w' else []) + add_args + (['--master-share={}'.format(master)] if master else []) + ([wf] if wf else []) + ([spec] if spec else [])) if not wf: t.passphrase(dfl_wcls.desc, wpasswd) if spec: from mmgen.obj import SeedSplitSpecifier sss = SeedSplitSpecifier(spec) pat = r"Processing .*\b{}\b of \b{}\b of .* id .*'{}'".format( sss.idx, sss.count, sss.id) else: pat = "master share #{}".format(master) t.expect(pat, regex=True) ocls = Wallet.fmt_code_to_type(ofmt) pw = issubclass(ocls, WalletEnc) if pw: t.hash_preset('new ' + ocls.desc, '1') t.passphrase_new('new ' + ocls.desc, sh1_passwd) if ocls == IncogWalletHidden: t.hincog_create(1234) t.written_to_file(capfirst(ocls.desc)) return t
def export_seed(self, wf, out_fmt='seed', pf=None): f, t = self._walletconv_export(wf, out_fmt=out_fmt, pf=pf) silence() wcls = Wallet.fmt_code_to_type(out_fmt) msg('{}: {}'.format(capfirst(wcls.desc), cyan(get_data_from_file(f, wcls.desc)))) end_silence() return t
def txsign3(self, wf1, wf2, txf2): t = self.spawn('mmgen-txsign', ['-d', self.tmpdir, wf1, wf2, txf2]) t.license() t.view_tx('n') for cnum, wf in (('1', wf1), ('3', wf2)): wcls = Wallet.ext_to_type(get_extension(wf)) t.passphrase(wcls.desc, self.cfgs[cnum]['wpasswd']) self.txsign_end(t) return t
def seed(): for n in range(1, 3): msg(f'------- NEW WALLET {n} -------\n') w1 = Wallet() msg(f'\n==> got pw,preset,lbl: [{w1.ssdata.passwd}][{w1.ssdata.hash_preset}][{w1.ssdata.label}]\n' ) for n in range(1, 3): msg(f'------- PASSCHG {n} -------\n') w2 = Wallet(ss=w1, passchg=True) msg(f'\n==> got pw,preset,lbl: [{w2.ssdata.passwd}][{w2.ssdata.hash_preset}][{w2.ssdata.label}]\n' ) msg(f'------- WALLET FROM FILE -------\n') w3 = Wallet(fn='test/ref/FE3C6545-D782B529[128,1].mmdat' ) # passphrase: 'reference password' msg(f'\n==> got pw,preset,lbl: [{w3.ssdata.passwd}][{w3.ssdata.hash_preset}][{w3.ssdata.label}]\n' )
def _user_seed_entry(self, fmt, usr_rand=False, out_fmt=None, entry_mode='full', mn=None): wcls = Wallet.fmt_code_to_type(fmt) wf = os.path.join(ref_dir, 'FE3C6545.{}'.format(wcls.ext)) if wcls.wclass == 'mnemonic': mn = mn or read_from_file(wf).strip().split() elif wcls.wclass == 'dieroll': mn = mn or list( read_from_file(wf).strip().translate( dict((ord(ws), None) for ws in '\t\n '))) for idx, val in ((5, 'x'), (18, '0'), (30, '7'), (44, '9')): mn.insert(idx, val) t = self.spawn('mmgen-walletconv', ['-r10', '-S', '-i', fmt, '-o', out_fmt or fmt]) t.expect('{} type:.*{}'.format(capfirst(wcls.wclass), wcls.mn_type), regex=True) t.expect(wcls.choose_seedlen_prompt, '1') t.expect('(Y/n): ', 'y') if wcls.wclass == 'mnemonic': t.expect('Type a number.*: ', '6', regex=True) t.expect('invalid') from mmgen.mn_entry import mn_entry mne = mn_entry(fmt, entry_mode) t.expect('Type a number.*: ', str(mne.entry_modes.index(entry_mode) + 1), regex=True) t.expect('Using (.+) entry mode', regex=True) mode = strip_ansi_escapes(t.p.match.group(1)).lower() assert mode == mne.em.name.lower(), '{} != {}'.format( mode, mne.em.name.lower()) stealth_mnemonic_entry(t, mne, mn, entry_mode=entry_mode) elif wcls.wclass == 'dieroll': user_dieroll_entry(t, mn) if usr_rand: t.expect(wcls.user_entropy_prompt, 'y') t.usr_rand(10) else: t.expect(wcls.user_entropy_prompt, 'n') if not usr_rand: sid_chk = 'FE3C6545' sid = t.expect_getend('Valid {} for Seed ID '.format(wcls.desc)) sid = strip_ansi_escapes(sid.split(',')[0]) assert sid == sid_chk, 'Seed ID mismatch! {} != {}'.format( sid, sid_chk) t.expect('to confirm: ', 'YES\n') t.read() return t
def subwalletgen_mnemonic(self, wf): icls = Wallet.ext_to_type(get_extension(wf)) ocls = MMGenMnemonic args = [ self.usr_rand_arg, '-p1', '-d', self.tr.trash_dir, '-o', ocls.fmt_codes[0], wf, '3L' ] t = self.spawn('mmgen-subwalletgen', args) t.license() t.passphrase(icls.desc, self.cfgs['1']['wpasswd']) t.expect('Generating subseed 3L') fn = t.written_to_file(capfirst(ocls.desc)) ext = get_extension(fn) assert ext == ocls.ext, 'incorrect file extension: {}'.format(ext) return t
def addrgen_incog(self, wf=[], foo='', in_fmt='i', args=[]): t = self.spawn( 'mmgen-addrgen', args + self.segwit_arg + ['-i' + in_fmt, '-d', self.tmpdir] + ([], [wf])[bool(wf)] + [self.addr_idx_list]) t.license() t.expect_getend('Incog Wallet ID: ') wcls = Wallet.fmt_code_to_type(in_fmt) t.hash_preset(wcls.desc, '1') t.passphrase('{} \w{{8}}'.format(wcls.desc), self.wpasswd) vmsg('Comparing generated checksum with checksum from address file') chk = t.expect_getend(r'Checksum for address data .*?: ', regex=True) verify_checksum_or_exit(self._get_addrfile_checksum(), chk) t.no_overwrite() t.req_exit_val = 1 return t
def ss_join(self, tdir, ofmt, in_exts, add_args=[], sid=None, bad_invocation=False, master=None, id_str=None): td = self.get_tmp_subdir(tdir) shares = [get_file_with_ext(td, f) for f in in_exts] if not sid: sid = self.read_from_tmpfile('dfl.sid') t = self.spawn( 'mmgen-seedjoin', add_args + (['--master-share={}'.format(master)] if master else []) + (['--id-str={}'.format(id_str)] if id_str else []) + ['-d', td, '-o', ofmt] + (['--label', 'Joined Wallet Label', '-r0'] if ofmt == 'w' else []) + shares) if bad_invocation: t.read() return t icls = (MMGenWallet if 'mmdat' in in_exts else IncogWallet if 'mmincog' in in_exts else IncogWalletHex if 'mmincox' in in_exts else IncogWalletHidden if '-H' in add_args else None) if icls in (IncogWallet, IncogWalletHex, IncogWalletHidden): t.hash_preset(icls.desc, '1') if icls: t.passphrase(icls.desc, sh1_passwd) if master: fs = "master share #{}, split id.*'{}'.*, share count {}" pat = fs.format(master, id_str or 'default', len(shares) + (icls == IncogWalletHidden)) t.expect(pat, regex=True) sid_cmp = strip_ansi_escapes(t.expect_getend('Joined Seed ID: ')) cmp_or_die(sid, sid_cmp) ocls = Wallet.fmt_code_to_type(ofmt) if ocls == MMGenWallet: t.hash_preset('new ' + ocls.desc, '1') t.passphrase_new('new ' + ocls.desc, wpasswd) t.written_to_file(capfirst(ocls.desc)) return t
def addrgen_seed(self, wf, foo, in_fmt='seed'): wcls = Wallet.fmt_code_to_type(in_fmt) stdout = wcls == MMGenSeedFile # capture output to screen once add_args = ([], ['-S'])[bool(stdout)] + self.segwit_arg t = self.spawn( 'mmgen-addrgen', add_args + ['-i' + in_fmt, '-d', self.tmpdir, wf, self.addr_idx_list]) t.license() t.expect_getend('Valid {} for Seed ID '.format(wcls.desc)) vmsg( 'Comparing generated checksum with checksum from previous address file' ) chk = t.expect_getend(r'Checksum for address data .*?: ', regex=True) if stdout: t.read() verify_checksum_or_exit(self._get_addrfile_checksum(), chk) if in_fmt != 'seed': t.no_overwrite() t.req_exit_val = 1 return t
def txsign5(self, wf, txf, bad_vsize=True, add_args=[]): non_mm_file = joinpath(self.tmpdir, non_mmgen_fn) t = self.spawn( 'mmgen-txsign', add_args + ['-d', self.tmpdir, '-k', non_mm_file, txf, wf]) t.license() t.view_tx('n') wcls = Wallet.ext_to_type(get_extension(wf)) t.passphrase(wcls.desc, self.cfgs['20']['wpasswd']) if bad_vsize: t.expect('Estimated transaction vsize') t.expect('1 transaction could not be signed') exit_val = 2 else: t.do_comment(False) t.expect('Save signed transaction? (Y/n): ', 'y') exit_val = 0 t.read() t.req_exit_val = exit_val return t
def addrgen(self, wf, pf=None, check_ref=False, ftype='addr', id_str=None, extra_args=[], mmtype=None, stdout=False, dfl_wallet=False): passgen = ftype[:4] == 'pass' if not mmtype and not passgen: mmtype = self.segwit_mmtype cmd_pfx = (ftype, 'pass')[passgen] t = self.spawn( 'mmgen-{}gen'.format(cmd_pfx), ['-d', self.tmpdir] + extra_args + ([], ['--type=' + str(mmtype)])[bool(mmtype)] + ([], ['--stdout'])[stdout] + ([], [wf])[bool(wf)] + ([], [id_str])[bool(id_str)] + [getattr(self, '{}_idx_list'.format(cmd_pfx))], extra_desc='({})'.format(mmtype) if mmtype in ('segwit', 'bech32') else '') t.license() wcls = MMGenWallet if dfl_wallet else Wallet.ext_to_type( get_extension(wf)) t.passphrase(wcls.desc, self.wpasswd) t.expect('Passphrase is OK') desc = ('address', 'password')[passgen] chk = t.expect_getend(r'Checksum for {} data .*?: '.format(desc), regex=True) if passgen: t.expect('Encrypt password list? (y/N): ', 'N') t.read() if stdout else t.written_to_file( ('Addresses', 'Password list')[passgen]) if check_ref: chk_ref = ( self.chk_data[self.test_name] if passgen else self.chk_data[self.test_name][self.fork][self.proto.testnet]) cmp_or_die(chk, chk_ref, desc='{}list data checksum'.format(ftype)) return t
def keyaddrgen(self, wf, pf=None, check_ref=False, mmtype=None): if not mmtype: mmtype = self.segwit_mmtype args = ['-d', self.tmpdir, self.usr_rand_arg, wf, self.addr_idx_list] t = self.spawn( 'mmgen-keygen', ([], ['--type=' + str(mmtype)])[bool(mmtype)] + args, extra_desc='({})'.format(mmtype) if mmtype in ('segwit', 'bech32') else '') t.license() wcls = Wallet.ext_to_type(get_extension(wf)) t.passphrase(wcls.desc, self.wpasswd) chk = t.expect_getend(r'Checksum for key-address data .*?: ', regex=True) if check_ref: chk_ref = self.chk_data[self.test_name][self.fork][g.proto.testnet] cmp_or_die(chk, chk_ref, desc='key-address list data checksum') t.expect('Encrypt key list? (y/N): ', 'y') t.usr_rand(self.usr_rand_chars) t.hash_preset('new key list', '1') t.passphrase_new('new key list', self.kapasswd) t.written_to_file('Encrypted secret keys', oo=True) return t
def walletchk(self, wf, pf, wcls=None, add_args=[], sid=None, extra_desc='', dfl_wallet=False): hp = self.hash_preset if hasattr(self, 'hash_preset') else '1' wcls = wcls or Wallet.ext_to_type(get_extension(wf)) t = self.spawn('mmgen-walletchk', ([] if dfl_wallet else ['-i', wcls.fmt_codes[0]]) + add_args + ['-p', hp] + ([wf] if wf else []), extra_desc=extra_desc) if wcls != IncogWalletHidden: t.expect("Getting {} from file '".format(wcls.desc)) pw = issubclass(wcls, WalletEnc) and wcls != Brainwallet if pw: t.passphrase(wcls.desc, self.wpasswd) t.expect(['Passphrase is OK', 'Passphrase.* are correct'], regex=True) chk = t.expect_getend('Valid {} for Seed ID '.format(wcls.desc))[:8] if sid: cmp_or_die(chk, sid) return t