From 69e7fcd0fcf5ff644d419d71a15819506549074d Mon Sep 17 00:00:00 2001 From: philemon Date: Wed, 16 Jul 2014 08:11:16 +0400 Subject: [PATCH] Bugfixes; incognito hex format added --- mmgen-addrgen | 19 +++++++++++-------- mmgen-txcreate | 4 ++-- mmgen-txsign | 14 +++++++++++--- mmgen-walletchk | 33 +++++++++++++++++++++------------ mmgen-walletgen | 10 +++++----- mmgen/Opts.py | 8 ++++---- mmgen/config.py | 1 + mmgen/tx.py | 4 ++-- mmgen/util.py | 37 +++++++++++++++++++++++-------------- 9 files changed, 80 insertions(+), 50 deletions(-) diff --git a/mmgen-addrgen b/mmgen-addrgen index 92970255..78694460 100755 --- a/mmgen-addrgen +++ b/mmgen-addrgen @@ -66,9 +66,10 @@ help_data = { -b, --from-brain l,p Generate {W} from a user-created password, i.e. a "brainwallet", using seed length 'l' and hash preset 'p' (comma-separated) --g, --from-incognito Generate {W} from an incognito-format wallet --G, --hidden-incog-data f,o,l Generate {W} from incognito data in file - 'f' at offset 'o', with seed length of 'l' +-g, --from-incog Generate {W} from an incognito wallet +-X, --from-incog-hex Generate {W} from an incognito hexadecimal wallet +-G, --from-incog-hidden f,o,l Generate {W} from incognito data in file + 'f' at offset 'o', with seed length of 'l' -m, --from-mnemonic Generate {W} from an electrum-like mnemonic -s, --from-seed Generate {W} from a seed in .{S} format @@ -113,11 +114,12 @@ in all future invocations with that passphrase short_opts = ["h","A","d:","e", "H","K","l:","p:", "P:","q","S","v","x","b:", - "g","G:","m","s"] + "g","X","G:","m","s"] long_opts = ["help","no_addresses","outdir=","echo_passphrase", "show_hash_presets","no_keyconv","seed_len=","hash_preset=", "passwd_file=","quiet","stdout","verbose","b16","from_brain=", - "from_incognito","hidden_incog_data=","from_mnemonic","from_seed"] + "from_incog","from_incog_hex","from_incog_hidden=", + "from_mnemonic","from_seed"] if invoked_as == "addrgen": for i in "A","x": short_opts.remove(i) @@ -126,9 +128,10 @@ if invoked_as == "addrgen": opts,cmd_args = process_opts(sys.argv,help_data,"".join(short_opts),long_opts) if 'show_hash_presets' in opts: show_hash_presets() -if 'quiet' in opts: g.quiet = True if 'verbose' in opts: g.verbose = True -if 'hidden_incog_data' in opts: opts['from_incognito'] = True +if 'quiet' in opts: g.quiet = True +if 'from_incog_hex' in opts or 'from_incog_hidden' in opts: + opts['from_incog'] = True opts['gen_what'] = gen_what @@ -140,7 +143,7 @@ if len(cmd_args) == 1 and ( 'from_mnemonic' in opts or 'from_brain' in opts or 'from_seed' in opts - or 'from_incognito' in opts + or 'from_incog_hidden' in opts ): infile,addr_list_arg = "",cmd_args[0] elif len(cmd_args) == 2: diff --git a/mmgen-txcreate b/mmgen-txcreate index 56b98318..df9b5dfd 100755 --- a/mmgen-txcreate +++ b/mmgen-txcreate @@ -90,8 +90,8 @@ if not 'info' in opts: if "," in a: a1,a2 = a.split(",") if is_mmgen_addr(a1) or is_btc_addr(a1): - if is_mmgen_addr(a1): - btaddr = mm2btc_addr_proc(c,a1,acct_data,addr_data,b2m_map) + btaddr = mm2btc_addr_proc(c,a1,acct_data,addr_data,b2m_map) \ + if is_mmgen_addr(a1) else a1 if is_btc_amt(a2): tx_out[btaddr] = check_btc_amt(a2) else: diff --git a/mmgen-txsign b/mmgen-txsign index 9635307d..5d4ad520 100755 --- a/mmgen-txsign +++ b/mmgen-txsign @@ -47,7 +47,10 @@ help_data = { i.e. a "brainwallet", using seed length 'l' and hash preset 'p' -w, --use-wallet-dat Get keys from a running bitcoind --g, --from-incognito Generate keys from an incognito-format wallet +-g, --from-incog Generate keys from an incognito wallet +-X, --from-incog-hex Generate keys from an incognito hexadecimal wallet +-G, --from-incog-hidden f,o,l Generate keys from incognito data in file + 'f' at offset 'o', with seed length of 'l' -m, --from-mnemonic Generate keys from an electrum-like mnemonic -s, --from-seed Generate keys from a seed in .{} format @@ -78,14 +81,19 @@ Seed data supplied in files must have the following extensions: """.format(g.seed_ext,g.wallet_ext,g.seed_ext,g.mn_ext,g.brain_ext) } -short_opts = "hd:eiIk:P:qVb:wgms" +short_opts = "hd:eiIk:P:qVb:wgXG:ms" long_opts = "help","outdir=","echo_passphrase","info","tx_id",\ "keys_from_file=","passwd_file=","quiet","skip_key_preverify",\ "from_brain=","use_wallet_dat",\ - "from_incognito","from_mnemonic","from_seed" + "from_incog","from_incog_hex","from_incog_hidden=",\ + "from_mnemonic","from_seed" opts,infiles = process_opts(sys.argv,help_data,short_opts,long_opts) + if "quiet" in opts: g.quiet = True +if 'from_incog_hex' in opts or 'from_incog_hidden' in opts: + opts['from_incog'] = True + check_opts(opts,long_opts) if not infiles: usage(help_data) diff --git a/mmgen-walletchk b/mmgen-walletchk index 8ac55dcb..819fd205 100755 --- a/mmgen-walletchk +++ b/mmgen-walletchk @@ -39,23 +39,26 @@ help_data = { -q, --quiet Suppress warnings; overwrite files without prompting -S, --stdout Print seed or mnemonic data to standard output -v, --verbose Produce more verbose output --g, --export-incognito Export wallet to incognito format --G, --hide-incog-data f,o Hide incognito data in existing file 'f' - at offset 'o' (comma-separated) +-g, --export-incog Export wallet to incognito format +-X, --export-incog-hex Export wallet to incognito hexadecimal format +-G, --export-incog-hidden f,o Hide incognito data in existing file 'f' + at offset 'o' (comma-separated) -m, --export-mnemonic Export the wallet's mnemonic to file -s, --export-seed Export the wallet's seed to file """ } -short_opts = "hd:eP:qSvgG:ms" +short_opts = "hd:eP:qSvgXG:ms" long_opts = "help","outdir=","echo_passphrase","passwd_file=","quiet",\ "stdout","verbose",\ - "export_incognito","hide_incog_data=","export_mnemonic","export_seed" + "export_incog","export_incog_hex","export_incog_hidden=",\ + "export_mnemonic","export_seed" opts,cmd_args = process_opts(sys.argv,help_data,short_opts,long_opts) if 'quiet' in opts: g.quiet = True if 'verbose' in opts: g.verbose = True -if 'hide_incog_data' in opts: opts['export_incognito'] = True +if 'export_incog_hidden' in opts or 'export_incog_hex' in opts: + opts['export_incog'] = True # Argument sanity checks and processing: check_opts(opts,long_opts) @@ -68,7 +71,7 @@ if 'export_mnemonic' in opts: qmsg("Exporting mnemonic data to file by user request") elif 'export_seed' in opts: qmsg("Exporting seed data to file by user request") -elif 'export_incognito' in opts: +elif 'export_incog' in opts: qmsg("Exporting wallet to incognito format by user request") d = get_data_from_wallet(cmd_args[0],silent=True) @@ -92,8 +95,8 @@ elif 'export_incognito' in opts: key = make_key(passwd, iv, preset, "wrapper key") incog_enc = encrypt_seed(salt + enc_seed, key, iv=int(hexlify(iv),16)) - if "hide_incog_data" in opts: - fname,offset = opts['hide_incog_data'].split(",") # Already sanity-checked + if "export_incog_hidden" in opts: + fname,offset = opts['export_incog_hidden'].split(",") #Already sanity-checked offset = int(offset) check_data_fits_file_at_offset(fname,offset,len(iv + incog_enc),"write") @@ -106,9 +109,15 @@ elif 'export_incognito' in opts: qmsg("Data written to file '%s' at offset %s" % (fname,offset), "Data written to file") else: - fn = "%s-%s-%s[%s,%s].%s" % (seed_id, key_id, iv_id, - len(enc_seed)*8, preset, g.incog_ext) - export_to_file(fn, iv + incog_enc, "incognito wallet data", opts) + fn = "%s-%s-%s[%s,%s].%s" % ( + seed_id, key_id, iv_id, len(enc_seed)*8, preset, + g.incog_hex_ext if "export_incog_hex" in opts else g.incog_ext + ) + data = iv + incog_enc + if "export_incog_hex" in opts: + data = "".join([hexlify(data[i*2:i*2+2]) + (" " if (i+1)%8 else "\n") + for i in range(len(data)/2)]) + export_to_file(fn, data, "incognito wallet data", opts) sys.exit() diff --git a/mmgen-walletgen b/mmgen-walletgen index 58efb972..d0c93088 100755 --- a/mmgen-walletgen +++ b/mmgen-walletgen @@ -54,7 +54,7 @@ help_data = { -b, --from-brain l,p Generate wallet from a user-created passphrase, i.e. a "brainwallet", using seed length 'l' and hash preset 'p' (comma-separated) --g, --from-incognito Generate wallet from an incognito-format wallet +-g, --from-incog Generate wallet from an incognito-format wallet -m, --from-mnemonic Generate wallet from an Electrum-like mnemonic -s, --from-seed Generate wallet from a seed in .{S} format @@ -97,7 +97,7 @@ in all future invocations with that passphrase. short_opts = "hd:eHl:L:p:P:qu:vb:gms" long_opts = "help","outdir=","echo_passphrase","show_hash_presets","seed_len=",\ "label=","hash_preset=","passwd_file=","quiet","usr_randlen=","verbose",\ - "from_brain=","from_incognito","from_mnemonic","from_seed" + "from_brain=","from_incog","from_mnemonic","from_seed" opts,cmd_args = process_opts(sys.argv,help_data,short_opts,long_opts) if 'quiet' in opts: g.quiet = True @@ -152,11 +152,11 @@ if g.debug: display_user_random_data(usr_keys,key_timings) usr_rand_data = sha256(usr_keys).digest() + \ sha256("".join(key_timings)).digest() -for i in 'from_mnemonic','from_brain','from_seed','from_incognito': +for i in 'from_mnemonic','from_brain','from_seed','from_incog': if infile or (i in opts): seed = get_seed_retry(infile,opts) - if "from_incognito" in opts or get_extension(infile) == g.incog_ext: - qmsg(cmessages['incognito'] % make_chksum_8(seed)) + if "from_incog" in opts or get_extension(infile) == g.incog_ext: + qmsg(cmessages['incog'] % make_chksum_8(seed)) else: qmsg("") break else: diff --git a/mmgen/Opts.py b/mmgen/Opts.py index 25b65ce6..4722f1a6 100755 --- a/mmgen/Opts.py +++ b/mmgen/Opts.py @@ -130,9 +130,9 @@ def check_opts(opts,long_opts): "%s": illegal character in label. Only ASCII characters are permitted. """.strip() % ch) sys.exit(1) - elif opt == 'hide_incog_data' or opt == 'hidden_incog_data': + elif opt == 'export_incog_hidden' or opt == 'from_incog_hidden': try: - if opt == 'hide_incog_data': + if opt == 'export_incog_hidden': outfile,offset = val.split(",") else: outfile,offset,seed_len = val.split(",") @@ -150,7 +150,7 @@ def check_opts(opts,long_opts): msg("'%s': invalid 'o' %s (less than zero)" % (offset,what)) sys.exit(1) - if opt == 'hidden_incog_data': + if opt == 'from_incog_hidden': try: sl = int(seed_len) except: @@ -174,7 +174,7 @@ def check_opts(opts,long_opts): sys.exit(1) ac,m = (os.W_OK,"writ") \ - if "hide_incog_data" in opts else (os.R_OK,"read") + if "export_incog_hidden" in opts else (os.R_OK,"read") if not os.access(outfile, ac): msg("Requested %s '%s' is un%sable by you" % (what,outfile,m)) sys.exit(1) diff --git a/mmgen/config.py b/mmgen/config.py index 850dec20..3e0e3365 100755 --- a/mmgen/config.py +++ b/mmgen/config.py @@ -33,6 +33,7 @@ seed_ext = "mmseed" mn_ext = "mmwords" brain_ext = "mmbrain" incog_ext = "mmincog" +incog_hex_ext = "mmincox" seedfile_exts = wallet_ext, seed_ext, mn_ext, brain_ext, incog_ext diff --git a/mmgen/tx.py b/mmgen/tx.py index d188bb73..4c2ad228 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -677,7 +677,7 @@ def get_keys_for_mmgen_addrs(mmgen_addrs,infiles,seeds,opts,gen_pairs=False): infile = infiles.pop(0) seed = get_seed_retry(infile,opts) elif "from_brain" in opts or "from_mnemonic" in opts \ - or "from_seed" in opts or "from_incognito" in opts: + or "from_seed" in opts or "from_incog" in opts: msg("Need data for seed ID %s" % seed_ids[0]) seed = get_seed_retry("",opts) else: @@ -706,7 +706,7 @@ def get_keys_for_mmgen_addrs(mmgen_addrs,infiles,seeds,opts,gen_pairs=False): else: msg(" for ID %s" % seed_id) else: msg("Seed source produced an invalid seed ID (%s)" % seed_id) - if "from_incognito" in opts or infile.split(".")[-1] == g.incog_ext: + if "from_incog" in opts or infile.split(".")[-1] == g.incog_ext: msg( """Incorrect hash preset, password or incognito wallet data diff --git a/mmgen/util.py b/mmgen/util.py index c58a8b3f..10f36650 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -102,20 +102,20 @@ def show_hash_presets(): cmessages = { 'null': "", - 'incognito_iv_id': """ + 'incog_iv_id': """ If you know your IV ID, check it against the value above. If it's incorrect, then your incognito data is invalid. """, - 'incognito_iv_id_hidden': """ + 'incog_iv_id_hidden': """ If you know your IV ID, check it against the value above. If it's incorrect, then your incognito data is invalid or you've supplied an incorrect offset. """, - 'incognito_key_id': """ + 'incog_key_id': """ Check that the generated seed ID is correct. If it's not, then your password or hash preset is incorrect or incognito data is corrupted. """, - 'incognito_key_id_hidden': """ + 'incog_key_id_hidden': """ Check that the generated seed ID is correct. If it's not, then your password or hash preset is incorrect or incognito data is corrupted. If the key ID is correct but the seed ID is not, then you might have @@ -750,7 +750,7 @@ def check_data_fits_file_at_offset(fname,offset,dlen,action): def get_hidden_incog_data(opts): # Already sanity-checked: - fname,offset,seed_len = opts['hidden_incog_data'].split(",") + fname,offset,seed_len = opts['from_incog_hidden'].split(",") qmsg("Getting hidden incog data from file '%s'" % fname) dlen = g.aesctr_iv_len + g.salt_len + (int(seed_len)/8) @@ -769,15 +769,22 @@ def get_seed_from_incog_wallet( infile, opts, prompt="Enter %s wallet passphrase: " % g.proj_name_cap, - silent=False - ): + silent=False, + hex_input=False + ): what = "incognito wallet data" - if "hidden_incog_data" in opts: + if "from_incog_hidden" in opts: d = get_hidden_incog_data(opts) else: d = get_data_from_file(infile,what) + if hex_input: + try: + d = unhexlify("".join(d.split()).strip()) + except: + msg("Data in file '%s' is not in hexadecimal format" % infile) + sys.exit(2) # File could be of invalid length, so check: valid_dlens = [i/8 + g.aesctr_iv_len + g.salt_len for i in g.seed_lens] if len(d) not in valid_dlens: @@ -789,8 +796,8 @@ def get_seed_from_incog_wallet( iv, enc_incog_data = d[0:g.aesctr_iv_len], d[g.aesctr_iv_len:] qmsg("IV ID: %s. Check this value if possible." % make_chksum_8(iv)) - vmsg(cmessages['incognito_iv_id_hidden' if "hidden_incog_data" in opts - else 'incognito_iv_id']) + vmsg(cmessages['incog_iv_id_hidden' if "from_incog_hidden" in opts + else 'incog_iv_id']) passwd = get_mmgen_passphrase(prompt,opts) @@ -817,8 +824,8 @@ def get_seed_from_incog_wallet( seed = decrypt_seed(enc_seed, key, "", "") qmsg("Seed ID: %s. Check that this value is correct." % make_chksum_8(seed)) - vmsg(cmessages['incognito_key_id_hidden' if "hidden_incog_data" in opts - else 'incognito_key_id']) + vmsg(cmessages['incog_key_id_hidden' if "from_incog_hidden" in opts + else 'incog_key_id']) return seed @@ -888,10 +895,11 @@ def get_seed(infile,opts,silent=False): elif ext == g.seed_ext: source = "seed" elif ext == g.wallet_ext: source = "wallet" elif ext == g.incog_ext: source = "incognito wallet" + elif ext == g.incog_hex_ext: source = "incognito wallet" elif 'from_mnemonic' in opts: source = "mnemonic" elif 'from_brain' in opts: source = "brainwallet" elif 'from_seed' in opts: source = "seed" - elif 'from_incognito' in opts: source = "incognito wallet" + elif 'from_incog' in opts: source = "incognito wallet" else: if infile: msg( "Invalid file extension for file: %s\nValid extensions: '.%s'" % @@ -924,7 +932,8 @@ def get_seed(infile,opts,silent=False): elif source == "wallet": seed = get_seed_from_wallet(infile, opts, silent=silent) elif source == "incognito wallet": - seed = get_seed_from_incog_wallet(infile, opts, silent=silent) + h = True if ext == g.incog_hex_ext or 'from_incog_hex' in opts else False + seed = get_seed_from_incog_wallet(infile, opts, silent=silent, hex_input=h) if infile and not seed and (