Added 'mmgen-tool' utility with following commands:

General operations:
  hexdump      - encode binary data in formatted hexadecimal form
  unhexdump    - decode formatted hexadecimal data

  Bitcoin operations:
  strtob58     - convert a string to base 58
  hextob58     - convert a hexadecimal number to base 58
  b58tohex     - convert a base 58 number to hexadecimal
  b58randenc   - generate a random 32-byte number and convert it to base 58
  randwif      - generate a random private key in WIF format
  randpair     - generate a random private key/address pair
  wif2addr     - generate a Bitcoin address from a key in WIF format

  Mnemonic operations (choose "electrum" (default), "tirosh" or "all" wordlists):
  mn_rand128   - generate random 128-bit mnemonic
  mn_rand192   - generate random 192-bit mnemonic
  mn_rand256   - generate random 256-bit mnemonic
  mn_stats     - show stats for mnemonic wordlist
  mn_printlist - print mnemonic wordlist
This commit is contained in:
The MMGen Project 2014-07-17 21:50:52 +04:00
commit 0894985bfa
26 changed files with 426 additions and 85 deletions

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

68
mmgen-tool Executable file
View file

@ -0,0 +1,68 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
mmgen-tool: Perform various Bitcoin-related operations - part of the MMGen suite
"""
import sys, os
from hashlib import sha256
from mmgen.Opts import *
import mmgen.config as g
from mmgen.util import pretty_hexdump
from mmgen.tool import *
prog_name = sys.argv[0].split("/")[-1]
help_data = {
'prog_name': prog_name,
'desc': "Perform various BTC-related operations",
'usage': "[opts] <command> <args>",
'options': """
-h, --help Print this help message
-q, --quiet Produce quieter output
-v, --verbose Produce more verbose output
COMMANDS:{}
Type '{} <command> --help for usage information on a particular command
""".format(command_help,prog_name)
}
short_opts = "hqv"
long_opts = "help","quiet","verbose"
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 len(cmd_args) < 1:
usage(help_data)
sys.exit(1)
else: command = cmd_args.pop(0)
if command not in commands.keys():
msg("'%s': No such command" % command)
sys.exit(1)
if cmd_args and cmd_args[0] == '--help':
tool_usage(prog_name, command)
sys.exit(0)
args = process_args(prog_name, command, cmd_args) if cmd_args else []
#print command + "(" + ", ".join(args) + ")"
eval(command + "(" + ", ".join(args) + ")")

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -79,36 +79,36 @@ if not 'info' in opts:
check_infile(a)
addr_data.append(parse_addrs_file(a))
def mm2btc_addr_proc(c,mmadr,acct_data,addr_data,b2m_map):
btaddr,label = mmgen_addr_to_walletd(c,mmadr,acct_data)
if not btaddr:
btaddr,label = mmgen_addr_to_addr_data(mmadr,addr_data)
b2m_map[btaddr] = mmadr,label
return btaddr
def mm_addr2btc_addr(c,mmadr,acct_data,addr_data,b2m_map):
btcaddr,label = mmgen_addr_to_walletd(c,mmadr,acct_data)
if not btcaddr:
btcaddr,label = mmgen_addr_to_addr_data(mmadr,addr_data)
b2m_map[btcaddr] = mmadr,label
return btcaddr
for a in [i for i in cmd_args if not match_ext(i,g.addrfile_ext)]:
if "," in a:
a1,a2 = a.split(",")
if is_mmgen_addr(a1) or is_btc_addr(a1):
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:
msg("%s: invalid amount in argument '%s'" % (a2,a))
sys.exit(2)
if is_btc_addr(a1):
btcaddr = a1
elif is_mmgen_addr(a1):
btcaddr = mm_addr2btc_addr(c,a1,acct_data,addr_data,b2m_map)
else:
msg("%s: unrecognized subargument in argument '%s'" % (a1,a))
sys.exit(2)
if is_btc_amt(a2):
tx_out[btcaddr] = check_btc_amt(a2)
else:
msg("%s: invalid amount in argument '%s'" % (a2,a))
sys.exit(2)
elif is_mmgen_addr(a) or is_btc_addr(a):
if change_addr:
msg("More than one change address specified: %s, %s" %
msg("ERROR: More than one change address specified: %s, %s" %
(change_addr, a))
sys.exit(2)
if is_mmgen_addr(a):
change_addr = mm2btc_addr_proc(c,a,acct_data,addr_data,b2m_map)
else:
change_addr = a
change_addr = a if is_btc_addr(a) else \
mm_addr2btc_addr(c,a,acct_data,addr_data,b2m_map)
tx_out[change_addr] = 0
else:
msg("%s: unrecognized argument" % a)
@ -157,7 +157,9 @@ msg("Total amount to spend: %s%s" % (
while True:
sel_nums = select_outputs(unspent,
"Enter a range or space-separated list of outputs to spend: ")
msg("Selected outputs: %s" % " ".join(str(i) for i in sel_nums))
msg("Selected output%s: %s" %
(("" if len(sel_nums) == 1 else "s"), " ".join(str(i) for i in sel_nums))
)
sel_unspent = [unspent[i-1] for i in sel_nums]
mmaddrs = set([parse_mmgen_label(i.account)[0] for i in sel_unspent])

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -73,50 +73,19 @@ elif 'export_seed' in opts:
qmsg("Exporting seed data to file by user request")
elif 'export_incog' in opts:
qmsg("Exporting wallet to incognito format by user request")
d = get_data_from_wallet(cmd_args[0],silent=True)
seed_id,key_id,preset,salt,enc_seed = \
d[1][0], d[1][1], d[2].split(":")[0], d[3], d[4]
passwd = get_mmgen_passphrase("Enter mmgen passphrase: ",opts)
key = make_key(passwd, salt, preset, "main key")
# We don't need the seed; just do this to verify password.
if decrypt_seed(enc_seed, key, seed_id, key_id) == False:
sys.exit(2)
from Crypto import Random
iv = Random.new().read(g.aesctr_iv_len)
iv_id = make_chksum_8(iv)
qmsg("IV ID: %s" % iv_id)
from binascii import hexlify
from hashlib import sha256
# IV is used BOTH to initialize counter and to salt password!
key = make_key(passwd, iv, preset, "wrapper key")
incog_enc = encrypt_seed(salt + enc_seed, key, iv=int(hexlify(iv),16))
incog_enc,seed_id,key_id,iv_id,preset = \
wallet_to_incog_data(cmd_args[0],opts)
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")
if not g.quiet: confirm_or_exit("","alter file '%s'" % fname)
f = os.open(fname,os.O_RDWR)
os.lseek(f, offset, os.SEEK_SET)
os.write(f, iv + incog_enc)
os.close(f)
qmsg("Data written to file '%s' at offset %s" % (fname,offset),
"Data written to file")
export_to_hidden_incog(incog_enc,opts)
else:
seed_len = (len(incog_enc)-g.salt_len-g.aesctr_iv_len)*8
fn = "%s-%s-%s[%s,%s].%s" % (
seed_id, key_id, iv_id, len(enc_seed)*8, preset,
seed_id, key_id, iv_id, seed_len, 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)])
data = pretty_hexdump(incog_enc,2,8,line_nums=False) \
if "export_incog_hex" in opts else incog_enc
export_to_file(fn, data, "incognito wallet data", opts)
sys.exit()

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# MMGen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -24,9 +24,9 @@ from mmgen.util import msg, msg_r, get_char
gpl = {
'warning': """
MMGen Copyright (C) 2013 by Philemon <mmgen-py@yandex.com>. This
program comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
MMGen Copyright (C) 2013-2014 by Philemon <mmgen-py@yandex.com>. This
program comes with ABSOLUTELY NO WARRANTY. This is free software, and
you are welcome to redistribute it under certain conditions.
""",
'prompt': """
Press 'w' for conditions and warranty info, or 'c' to continue:

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -95,7 +95,7 @@ def check_wordlist(wl_str,label):
from hashlib import sha256
print "Length: %i" % len(wl)
print "Length: %i words" % len(wl)
new_chksum = sha256(" ".join(wl)).hexdigest()[:8]
if new_chksum != wl_checksums[label]:

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -218,6 +218,5 @@ tests = {
"wiftoaddr_comp": ['wif [str]'],
}
args = process_test_args(sys.argv, tests)
eval(sys.argv[1])(*args)

View file

@ -19,11 +19,12 @@
mnemonic.py: Test suite for mmgen.mnemonic module
"""
from mmgen.mnemonic import *
from test import *
import sys
from binascii import hexlify
from mmgen.mnemonic import *
from mmgen.mn_electrum import electrum_words as el
from mmgen.mn_tirosh import tirosh_words as tl

244
mmgen/tool.py Executable file
View file

@ -0,0 +1,244 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
tool.py: Routines and data for the mmgen-tool utility
"""
import sys
import mmgen.bitcoin as bitcoin
from mmgen.util import *
commands = {
# "keyconv_compare": ['wif [str]'],
# "keyconv_compare_randloop": ['iterations [int]'],
# "hextob58_pad": ['hexnum [str]],
# "b58tohex_pad": ['b58num [str]'],
# "hextob58_pad_randloop": ['iterations [int]'],
# "test_wiftohex": ['wif [str]'],
# "hextosha256": ['hexnum [str]'],
# "hextowiftopubkey": ['hexnum [str]'],
# "pubhextoaddr": ['hexnum [str]'],
# "hextowif_comp": ['hexnum [str]'],
# "wiftohex_comp": ['wif [str]'],
# "privhextoaddr_comp": ['hexnum [str]'],
# "wiftoaddr_comp": ['wif [str]'],
"strtob58": ['<string> [str]'],
"hextob58": ['<hex number> [str]'],
"b58tohex": ['<b58 number> [str]'],
"b58randenc": [],
"randwif": ['compressed [bool=False]'],
"randpair": ['compressed [bool=False]'],
"wif2addr": ['<wif> [str]', 'compressed [bool=False]'],
"hexdump": ['<infile> [str]', 'cols [int=8]', 'line_nums [bool=True]'],
"unhexdump": ['<infile> [str]'],
"mn_rand128": ['wordlist [str="electrum"]'],
"mn_rand192": ['wordlist [str="electrum"]'],
"mn_rand256": ['wordlist [str="electrum"]'],
"mn_stats": ['wordlist [str="electrum"]'],
"mn_printlist": ['wordlist [str="electrum"]']
}
command_help = """
General operations:
hexdump - encode binary data in formatted hexadecimal form
unhexdump - decode formatted hexadecimal data
Bitcoin operations:
strtob58 - convert a string to base 58
hextob58 - convert a hexadecimal number to base 58
b58tohex - convert a base 58 number to hexadecimal
b58randenc - generate a random 32-byte number and convert it to base 58
randwif - generate a random private key in WIF format
randpair - generate a random private key/address pair
wif2addr - generate a Bitcoin address from a key in WIF format
Mnemonic operations (choose "electrum" (default), "tirosh" or "all" wordlists):
mn_rand128 - generate random 128-bit mnemonic
mn_rand192 - generate random 192-bit mnemonic
mn_rand256 - generate random 256-bit mnemonic
mn_stats - show stats for mnemonic wordlist
mn_printlist - print mnemonic wordlist
IMPORTANT NOTE: Though MMGen mnemonics use the Electrum wordlist, they're
computed using a different algorithm and are NOT Electrum-compatible!
"""
def tool_usage(prog_name, command):
print "USAGE: '%s %s%s'" % (prog_name, command,
(" "+" ".join(commands[command]) if commands[command] else ""))
def process_args(prog_name, command, uargs):
cargs = commands[command]
cargs_req = [[i.split(" [")[0],i.split(" [")[1][:-1]]
for i in cargs if "=" not in i]
cargs_nam = dict([[
i.split(" [")[0],
[i.split(" [")[1].split("=")[0], i.split(" [")[1].split("=")[1][:-1]]
] for i in cargs if "=" in i])
uargs_req = [i for i in uargs if "=" not in i]
uargs_nam = dict([i.split("=") for i in uargs if "=" in i])
# print cargs_req; print cargs_nam; print uargs_req; print uargs_nam; sys.exit()
n = len(cargs_req)
if len(uargs_req) != n:
print "ERROR: %s argument%s required" % (n, " is" if n==1 else "s are")
tool_usage(prog_name, command)
sys.exit(1)
for a in uargs_nam.keys():
if a not in cargs_nam.keys():
print "'%s' invalid named argument" % a
sys.exit(1)
def test_type(arg_type,arg,name=""):
try:
t = type(eval(arg))
assert(t == eval(arg_type))
except:
print "'%s': Invalid argument for argument %s ('%s' required)" % \
(arg, name, arg_type)
sys.exit(1)
return True
ret = []
for i in range(len(cargs_req)):
arg,arg_type = uargs_req[i], cargs_req[i][1]
if arg == "true" or arg == "false": arg = arg.capitalize()
if arg_type == "str":
ret.append('"%s"' % (arg))
elif test_type(arg_type, arg, "#"+str(i+1)):
ret.append('%s' % (arg))
for k in uargs_nam.keys():
arg,arg_type = uargs_nam[k], cargs_nam[k][0]
if arg == "true" or arg == "false": arg = arg.capitalize()
if arg_type == "str":
ret.append('%s="%s"' % (k, arg))
elif test_type(arg_type, arg, "'"+k+"'"):
ret.append('%s=%s' % (k, arg))
return ret
# Individual commands
def print_convert_results(indata,enc,dec,no_recode=False):
vmsg("Input: [%s]" % indata)
vmsg_r("Encoded data: ["); msg_r(enc); vmsg_r("]"); msg("")
if not no_recode:
vmsg("Recoded data: [%s]" % dec)
if indata != dec:
msg("WARNING! Recoded number doesn't match input stringwise!")
def hexdump(infile, cols=8, line_nums=True):
data = get_data_from_file(infile)
o = pretty_hexdump(data, 2, cols, line_nums)
print o
def unhexdump(infile):
data = get_data_from_file(infile)
o = decode_pretty_hexdump(data)
sys.stdout.write(o)
def strtob58(s):
enc = bitcoin.b58encode(s)
dec = bitcoin.b58decode(enc)
print_convert_results(s,enc,dec)
def hextob58(s,f_enc=bitcoin.b58encode, f_dec=bitcoin.b58decode):
enc = f_enc(unhexlify(s))
dec = hexlify(f_dec(enc))
print_convert_results(s,enc,dec)
def b58tohex(s,f_enc=bitcoin.b58decode, f_dec=bitcoin.b58encode):
tmp = f_enc(s)
if tmp == False: sys.exit(1)
enc = hexlify(tmp)
dec = f_dec(unhexlify(enc))
print_convert_results(s,enc,dec)
def get_random(length):
from Crypto import Random
return Random.new().read(length)
def b58randenc():
r = get_random(32)
enc = bitcoin.b58encode(r)
dec = bitcoin.b58decode(enc)
print_convert_results(hexlify(r),enc,hexlify(dec))
def randwif(compressed=False):
r_hex = hexlify(get_random(32))
enc = bitcoin.hextowif(r_hex,compressed)
print_convert_results(r_hex,enc,"",no_recode=True)
def randpair(compressed=False):
r_hex = hexlify(get_random(32))
wif = bitcoin.hextowif(r_hex,compressed)
addr = bitcoin.privnum2addr(int(r_hex,16),compressed)
vmsg("Key (hex): %s" % r_hex)
vmsg_r("Key (WIF): "); msg(wif)
vmsg_r("Addr: "); msg(addr)
def wif2addr(s_in,compressed=False):
s_enc = bitcoin.wiftohex(s_in,compressed)
if s_enc == False:
msg("Invalid address")
sys.exit(1)
addr = bitcoin.privnum2addr(int(s_enc,16),compressed)
vmsg_r("Addr: "); msg(addr)
from mmgen.mnemonic import *
from mmgen.mn_electrum import electrum_words as el
from mmgen.mn_tirosh import tirosh_words as tl
wordlists = sorted(wl_checksums.keys())
def get_wordlist(wordlist):
wordlist = wordlist.lower()
if wordlist not in wordlists:
msg('"%s": invalid wordlist. Valid choices: %s' %
(wordlist,'"'+'" "'.join(wordlists)+'"'))
sys.exit(1)
return el if wordlist == "electrum" else tl
def do_random_mn(nbytes,wordlist):
r = get_random(nbytes)
wlists = wordlists if wordlist == "all" else [wordlist]
for wl in wlists:
l = get_wordlist(wl)
if wl == wlists[0]: vmsg("Seed: %s" % hexlify(r))
mn = get_mnemonic_from_seed(r,l.strip().split("\n"),
wordlist,print_info=False)
vmsg("%s wordlist mnemonic:" % (wl.capitalize()))
print " ".join(mn)
def mn_rand128(wordlist="electrum"): do_random_mn(16,wordlist)
def mn_rand192(wordlist="electrum"): do_random_mn(24,wordlist)
def mn_rand256(wordlist="electrum"): do_random_mn(32,wordlist)
def mn_stats(wordlist="electrum"):
l = get_wordlist(wordlist)
check_wordlist(l,wordlist)
def mn_printlist(wordlist="electrum"):
l = get_wordlist(wordlist)
print "%s" % l.strip()

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -994,5 +994,61 @@ def do_pager(text):
else: print text+end
def export_to_hidden_incog(incog_enc,opts):
fname,offset = opts['export_incog_hidden'].split(",") #Already sanity-checked
check_data_fits_file_at_offset(fname,int(offset),len(incog_enc),"write")
if not g.quiet: confirm_or_exit("","alter file '%s'" % fname)
f = os.open(fname,os.O_RDWR)
os.lseek(f, int(offset), os.SEEK_SET)
os.write(f, incog_enc)
os.close(f)
qmsg("Data written to file '%s' at offset %s" % (fname,offset),
"Data written to file")
def pretty_hexdump(data,gw,cols,line_nums=False):
r = 1 if len(data) % gw else 0
return "".join(
[
("" if (line_nums == False or i % cols) else "%03i: " % (i/cols)) +
hexlify(data[i*gw:i*gw+gw]) +
(" " if (i+1) % cols else "\n")
for i in range(len(data)/gw + r)
]
).rstrip()
def decode_pretty_hexdump(data):
import re
lines = [re.sub('^\d+:\s+','',l) for l in data.split("\n")]
return unhexlify("".join(("".join(lines).split())))
def wallet_to_incog_data(infile,opts):
d = get_data_from_wallet(infile,silent=True)
seed_id,key_id,preset,salt,enc_seed = \
d[1][0], d[1][1], d[2].split(":")[0], d[3], d[4]
passwd = get_mmgen_passphrase("Enter mmgen passphrase: ",opts)
key = make_key(passwd, salt, preset, "main key")
# We don't need the seed; just do this to verify password.
if decrypt_seed(enc_seed, key, seed_id, key_id) == False:
sys.exit(2)
from Crypto import Random
iv = Random.new().read(g.aesctr_iv_len)
iv_id = make_chksum_8(iv)
qmsg("IV ID: %s" % iv_id)
from binascii import hexlify
from hashlib import sha256
# IV is used BOTH to initialize counter and to salt password!
key = make_key(passwd, iv, preset, "wrapper key")
wrap_enc = encrypt_seed(salt + enc_seed, key, iv=int(hexlify(iv),16))
return iv+wrap_enc,seed_id,key_id,iv_id,preset
if __name__ == "__main__":
print "util.py"

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
#
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
# Copyright (C) 2013-2014 by philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -20,6 +20,7 @@ setup(
'mmgen.mn_tirosh',
'mmgen.Opts',
'mmgen.term',
'mmgen.tool',
'mmgen.tx',
'mmgen.util',
'mmgen.walletgen',
@ -52,5 +53,6 @@ setup(
'mmgen-txsign',
'mmgen-txsend',
'mmgen-pywallet'
'mmgen-tool',
]
)