electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 4dcdcbc068d0d42ac7edc27c7d618b53cb6f706d
parent 94a5d26013c74601e3b4749df1bf92a5c8a2cd5b
Author: ThomasV <thomasv@gitorious>
Date:   Thu, 28 Aug 2014 15:37:42 +0200

move mnemonic to separate class and use slush's wordlist. new commands: make_seed and check_seed

Diffstat:
Melectrum | 7+++++++
Mlib/__init__.py | 2--
Mlib/bitcoin.py | 10+---------
Mlib/commands.py | 11+++++++++++
Mlib/mnemonic.py | 1725+++----------------------------------------------------------------------------
Alib/old_mnemonic.py | 1691+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/wallet.py | 94++++++++++++++++++++++++++++++-------------------------------------------------
Alib/wordlist/english.txt | 2048+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 3856 insertions(+), 1732 deletions(-)

diff --git a/electrum b/electrum @@ -90,6 +90,8 @@ def arg_parser(): parser.add_option("--2of3", action="store_true", dest="2of3", default=False, help="create 2of3 wallet") parser.add_option("--mpk", dest="mpk", default=False, help="restore from master public key") parser.add_option("-m", action="store_true", dest="hide_gui", default=False, help="hide GUI on startup") + parser.add_option("--nbits", dest="nbits", default="128", help="number of bits for make_seed") + parser.add_option("--entropy", dest="entropy", default="1", help="custom entropy for make_seed") return parser @@ -385,6 +387,9 @@ if __name__ == '__main__': elif cmd.name == 'listaddresses': args = [cmd, options.show_all, options.show_labels] + elif cmd.name == 'make_seed': + args = [cmd, int(options.nbits), long(options.entropy)] + elif cmd.name in ['payto', 'mktx']: domain = [options.from_addr] if options.from_addr else None args = ['mktx', args[1], Decimal(args[2]), Decimal(options.tx_fee) if options.tx_fee else None, options.change_addr, domain] @@ -421,6 +426,8 @@ if __name__ == '__main__': print_msg("Warning: Final argument was reconstructed from several arguments:", repr(message)) args = args[0:cmd.min_args] + [message] + if cmd.name == 'check_seed': + args.append(long(options.entropy)) # run the command diff --git a/lib/__init__.py b/lib/__init__.py @@ -11,8 +11,6 @@ import account import transaction from transaction import Transaction from plugins import BasePlugin -from mnemonic import mn_encode as mnemonic_encode -from mnemonic import mn_decode as mnemonic_decode from commands import Commands, known_commands from daemon import NetworkServer from network_proxy import NetworkProxy diff --git a/lib/bitcoin.py b/lib/bitcoin.py @@ -111,17 +111,9 @@ def Hash(x): hash_encode = lambda x: x[::-1].encode('hex') hash_decode = lambda x: x.decode('hex')[::-1] hmac_sha_512 = lambda x,y: hmac.new(x, y, hashlib.sha512).digest() - - -def mnemonic_to_seed(mnemonic, passphrase): - from pbkdf2 import PBKDF2 - import hmac - PBKDF2_ROUNDS = 2048 - return PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations = PBKDF2_ROUNDS, macmodule = hmac, digestmodule = hashlib.sha512).read(64) - - is_new_seed = lambda x: hmac_sha_512("Seed version", x.encode('utf8')).encode('hex')[0:2].startswith(SEED_PREFIX) + def is_old_seed(seed): import mnemonic words = seed.strip().split() diff --git a/lib/commands.py b/lib/commands.py @@ -108,6 +108,8 @@ register_command('decrypt', 2,-1, False, True, True, 'decrypt a m register_command('getproof', 1, 1, True, False, False, 'get merkle proof', 'getproof <address>') register_command('getutxoaddress', 2, 2, True, False, False, 'get the address of an unspent transaction output','getutxoaddress <txid> <pos>') register_command('sweep', 2, 3, True, False, False, 'Sweep a private key.', 'sweep privkey addr [fee]') +register_command('make_seed', 2, 2, False, False, False, 'Create a seed.','options: --nbits --entropy') +register_command('check_seed', 1,-1, False, False, False, 'Check that a seed was generated with external entropy. Option: --entropy') class Commands: @@ -129,6 +131,15 @@ class Commands: apply(self._callback, ()) return result + def make_seed(self, nbits, custom_entropy): + from mnemonic import Mnemonic + s = Mnemonic('english').make_seed(nbits, custom_entropy) + return s + + def check_seed(self, seed, custom_entropy): + from mnemonic import Mnemonic + return Mnemonic('english').check_seed(seed, custom_entropy) + def getaddresshistory(self, addr): return self.network.synchronous_get([ ('blockchain.address.get_history',[addr]) ])[0] diff --git a/lib/mnemonic.py b/lib/mnemonic.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Electrum - lightweight Bitcoin client -# Copyright (C) 2011 thomasv@gitorious +# Copyright (C) 2014 Thomas Voegtlin # # 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 @@ -16,1675 +16,76 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import os +import hmac +import math +import hashlib +import ecdsa +import pbkdf2 -# list of words from http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists/Contemporary_poetry +from util import print_error +from bitcoin import is_old_seed, is_new_seed -words = [ -"like", -"just", -"love", -"know", -"never", -"want", -"time", -"out", -"there", -"make", -"look", -"eye", -"down", -"only", -"think", -"heart", -"back", -"then", -"into", -"about", -"more", -"away", -"still", -"them", -"take", -"thing", -"even", -"through", -"long", -"always", -"world", -"too", -"friend", -"tell", -"try", -"hand", -"thought", -"over", -"here", -"other", -"need", -"smile", -"again", -"much", -"cry", -"been", -"night", -"ever", -"little", -"said", -"end", -"some", -"those", -"around", -"mind", -"people", -"girl", -"leave", -"dream", -"left", -"turn", -"myself", -"give", -"nothing", -"really", -"off", -"before", -"something", -"find", -"walk", -"wish", -"good", -"once", -"place", -"ask", -"stop", -"keep", -"watch", -"seem", -"everything", -"wait", -"got", -"yet", -"made", -"remember", -"start", -"alone", -"run", -"hope", -"maybe", -"believe", -"body", -"hate", -"after", -"close", -"talk", -"stand", -"own", -"each", -"hurt", -"help", -"home", -"god", -"soul", -"new", -"many", -"two", -"inside", -"should", -"true", -"first", -"fear", -"mean", -"better", -"play", -"another", -"gone", -"change", -"use", -"wonder", -"someone", -"hair", -"cold", -"open", -"best", -"any", -"behind", -"happen", -"water", -"dark", -"laugh", -"stay", -"forever", -"name", -"work", -"show", -"sky", -"break", -"came", -"deep", -"door", -"put", -"black", -"together", -"upon", -"happy", -"such", -"great", -"white", -"matter", -"fill", -"past", -"please", -"burn", -"cause", -"enough", -"touch", -"moment", -"soon", -"voice", -"scream", -"anything", -"stare", -"sound", -"red", -"everyone", -"hide", -"kiss", -"truth", -"death", -"beautiful", -"mine", -"blood", -"broken", -"very", -"pass", -"next", -"forget", -"tree", -"wrong", -"air", -"mother", -"understand", -"lip", -"hit", -"wall", -"memory", -"sleep", -"free", -"high", -"realize", -"school", -"might", -"skin", -"sweet", -"perfect", -"blue", -"kill", -"breath", -"dance", -"against", -"fly", -"between", -"grow", -"strong", -"under", -"listen", -"bring", -"sometimes", -"speak", -"pull", -"person", -"become", -"family", -"begin", -"ground", -"real", -"small", -"father", -"sure", -"feet", -"rest", -"young", -"finally", -"land", -"across", -"today", -"different", -"guy", -"line", -"fire", -"reason", -"reach", -"second", -"slowly", -"write", -"eat", -"smell", -"mouth", -"step", -"learn", -"three", -"floor", -"promise", -"breathe", -"darkness", -"push", -"earth", -"guess", -"save", -"song", -"above", -"along", -"both", -"color", -"house", -"almost", -"sorry", -"anymore", -"brother", -"okay", -"dear", -"game", -"fade", -"already", -"apart", -"warm", -"beauty", -"heard", -"notice", -"question", -"shine", -"began", -"piece", -"whole", -"shadow", -"secret", -"street", -"within", -"finger", -"point", -"morning", -"whisper", -"child", -"moon", -"green", -"story", -"glass", -"kid", -"silence", -"since", -"soft", -"yourself", -"empty", -"shall", -"angel", -"answer", -"baby", -"bright", -"dad", -"path", -"worry", -"hour", -"drop", -"follow", -"power", -"war", -"half", -"flow", -"heaven", -"act", -"chance", -"fact", -"least", -"tired", -"children", -"near", -"quite", -"afraid", -"rise", -"sea", -"taste", -"window", -"cover", -"nice", -"trust", -"lot", -"sad", -"cool", -"force", -"peace", -"return", -"blind", -"easy", -"ready", -"roll", -"rose", -"drive", -"held", -"music", -"beneath", -"hang", -"mom", -"paint", -"emotion", -"quiet", -"clear", -"cloud", -"few", -"pretty", -"bird", -"outside", -"paper", -"picture", -"front", -"rock", -"simple", -"anyone", -"meant", -"reality", -"road", -"sense", -"waste", -"bit", -"leaf", -"thank", -"happiness", -"meet", -"men", -"smoke", -"truly", -"decide", -"self", -"age", -"book", -"form", -"alive", -"carry", -"escape", -"damn", -"instead", -"able", -"ice", -"minute", -"throw", -"catch", -"leg", -"ring", -"course", -"goodbye", -"lead", -"poem", -"sick", -"corner", -"desire", -"known", -"problem", -"remind", -"shoulder", -"suppose", -"toward", -"wave", -"drink", -"jump", -"woman", -"pretend", -"sister", -"week", -"human", -"joy", -"crack", -"grey", -"pray", -"surprise", -"dry", -"knee", -"less", -"search", -"bleed", -"caught", -"clean", -"embrace", -"future", -"king", -"son", -"sorrow", -"chest", -"hug", -"remain", -"sat", -"worth", -"blow", -"daddy", -"final", -"parent", -"tight", -"also", -"create", -"lonely", -"safe", -"cross", -"dress", -"evil", -"silent", -"bone", -"fate", -"perhaps", -"anger", -"class", -"scar", -"snow", -"tiny", -"tonight", -"continue", -"control", -"dog", -"edge", -"mirror", -"month", -"suddenly", -"comfort", -"given", -"loud", -"quickly", -"gaze", -"plan", -"rush", -"stone", -"town", -"battle", -"ignore", -"spirit", -"stood", -"stupid", -"yours", -"brown", -"build", -"dust", -"hey", -"kept", -"pay", -"phone", -"twist", -"although", -"ball", -"beyond", -"hidden", -"nose", -"taken", -"fail", -"float", -"pure", -"somehow", -"wash", -"wrap", -"angry", -"cheek", -"creature", -"forgotten", -"heat", -"rip", -"single", -"space", -"special", -"weak", -"whatever", -"yell", -"anyway", -"blame", -"job", -"choose", -"country", -"curse", -"drift", -"echo", -"figure", -"grew", -"laughter", -"neck", -"suffer", -"worse", -"yeah", -"disappear", -"foot", -"forward", -"knife", -"mess", -"somewhere", -"stomach", -"storm", -"beg", -"idea", -"lift", -"offer", -"breeze", -"field", -"five", -"often", -"simply", -"stuck", -"win", -"allow", -"confuse", -"enjoy", -"except", -"flower", -"seek", -"strength", -"calm", -"grin", -"gun", -"heavy", -"hill", -"large", -"ocean", -"shoe", -"sigh", -"straight", -"summer", -"tongue", -"accept", -"crazy", -"everyday", -"exist", -"grass", -"mistake", -"sent", -"shut", -"surround", -"table", -"ache", -"brain", -"destroy", -"heal", -"nature", -"shout", -"sign", -"stain", -"choice", -"doubt", -"glance", -"glow", -"mountain", -"queen", -"stranger", -"throat", -"tomorrow", -"city", -"either", -"fish", -"flame", -"rather", -"shape", -"spin", -"spread", -"ash", -"distance", -"finish", -"image", -"imagine", -"important", -"nobody", -"shatter", -"warmth", -"became", -"feed", -"flesh", -"funny", -"lust", -"shirt", -"trouble", -"yellow", -"attention", -"bare", -"bite", -"money", -"protect", -"amaze", -"appear", -"born", -"choke", -"completely", -"daughter", -"fresh", -"friendship", -"gentle", -"probably", -"six", -"deserve", -"expect", -"grab", -"middle", -"nightmare", -"river", -"thousand", -"weight", -"worst", -"wound", -"barely", -"bottle", -"cream", -"regret", -"relationship", -"stick", -"test", -"crush", -"endless", -"fault", -"itself", -"rule", -"spill", -"art", -"circle", -"join", -"kick", -"mask", -"master", -"passion", -"quick", -"raise", -"smooth", -"unless", -"wander", -"actually", -"broke", -"chair", -"deal", -"favorite", -"gift", -"note", -"number", -"sweat", -"box", -"chill", -"clothes", -"lady", -"mark", -"park", -"poor", -"sadness", -"tie", -"animal", -"belong", -"brush", -"consume", -"dawn", -"forest", -"innocent", -"pen", -"pride", -"stream", -"thick", -"clay", -"complete", -"count", -"draw", -"faith", -"press", -"silver", -"struggle", -"surface", -"taught", -"teach", -"wet", -"bless", -"chase", -"climb", -"enter", -"letter", -"melt", -"metal", -"movie", -"stretch", -"swing", -"vision", -"wife", -"beside", -"crash", -"forgot", -"guide", -"haunt", -"joke", -"knock", -"plant", -"pour", -"prove", -"reveal", -"steal", -"stuff", -"trip", -"wood", -"wrist", -"bother", -"bottom", -"crawl", -"crowd", -"fix", -"forgive", -"frown", -"grace", -"loose", -"lucky", -"party", -"release", -"surely", -"survive", -"teacher", -"gently", -"grip", -"speed", -"suicide", -"travel", -"treat", -"vein", -"written", -"cage", -"chain", -"conversation", -"date", -"enemy", -"however", -"interest", -"million", -"page", -"pink", -"proud", -"sway", -"themselves", -"winter", -"church", -"cruel", -"cup", -"demon", -"experience", -"freedom", -"pair", -"pop", -"purpose", -"respect", -"shoot", -"softly", -"state", -"strange", -"bar", -"birth", -"curl", -"dirt", -"excuse", -"lord", -"lovely", -"monster", -"order", -"pack", -"pants", -"pool", -"scene", -"seven", -"shame", -"slide", -"ugly", -"among", -"blade", -"blonde", -"closet", -"creek", -"deny", -"drug", -"eternity", -"gain", -"grade", -"handle", -"key", -"linger", -"pale", -"prepare", -"swallow", -"swim", -"tremble", -"wheel", -"won", -"cast", -"cigarette", -"claim", -"college", -"direction", -"dirty", -"gather", -"ghost", -"hundred", -"loss", -"lung", -"orange", -"present", -"swear", -"swirl", -"twice", -"wild", -"bitter", -"blanket", -"doctor", -"everywhere", -"flash", -"grown", -"knowledge", -"numb", -"pressure", -"radio", -"repeat", -"ruin", -"spend", -"unknown", -"buy", -"clock", -"devil", -"early", -"false", -"fantasy", -"pound", -"precious", -"refuse", -"sheet", -"teeth", -"welcome", -"add", -"ahead", -"block", -"bury", -"caress", -"content", -"depth", -"despite", -"distant", -"marry", -"purple", -"threw", -"whenever", -"bomb", -"dull", -"easily", -"grasp", -"hospital", -"innocence", -"normal", -"receive", -"reply", -"rhyme", -"shade", -"someday", -"sword", -"toe", -"visit", -"asleep", -"bought", -"center", -"consider", -"flat", -"hero", -"history", -"ink", -"insane", -"muscle", -"mystery", -"pocket", -"reflection", -"shove", -"silently", -"smart", -"soldier", -"spot", -"stress", -"train", -"type", -"view", -"whether", -"bus", -"energy", -"explain", -"holy", -"hunger", -"inch", -"magic", -"mix", -"noise", -"nowhere", -"prayer", -"presence", -"shock", -"snap", -"spider", -"study", -"thunder", -"trail", -"admit", -"agree", -"bag", -"bang", -"bound", -"butterfly", -"cute", -"exactly", -"explode", -"familiar", -"fold", -"further", -"pierce", -"reflect", -"scent", -"selfish", -"sharp", -"sink", -"spring", -"stumble", -"universe", -"weep", -"women", -"wonderful", -"action", -"ancient", -"attempt", -"avoid", -"birthday", -"branch", -"chocolate", -"core", -"depress", -"drunk", -"especially", -"focus", -"fruit", -"honest", -"match", -"palm", -"perfectly", -"pillow", -"pity", -"poison", -"roar", -"shift", -"slightly", -"thump", -"truck", -"tune", -"twenty", -"unable", -"wipe", -"wrote", -"coat", -"constant", -"dinner", -"drove", -"egg", -"eternal", -"flight", -"flood", -"frame", -"freak", -"gasp", -"glad", -"hollow", -"motion", -"peer", -"plastic", -"root", -"screen", -"season", -"sting", -"strike", -"team", -"unlike", -"victim", -"volume", -"warn", -"weird", -"attack", -"await", -"awake", -"built", -"charm", -"crave", -"despair", -"fought", -"grant", -"grief", -"horse", -"limit", -"message", -"ripple", -"sanity", -"scatter", -"serve", -"split", -"string", -"trick", -"annoy", -"blur", -"boat", -"brave", -"clearly", -"cling", -"connect", -"fist", -"forth", -"imagination", -"iron", -"jock", -"judge", -"lesson", -"milk", -"misery", -"nail", -"naked", -"ourselves", -"poet", -"possible", -"princess", -"sail", -"size", -"snake", -"society", -"stroke", -"torture", -"toss", -"trace", -"wise", -"bloom", -"bullet", -"cell", -"check", -"cost", -"darling", -"during", -"footstep", -"fragile", -"hallway", -"hardly", -"horizon", -"invisible", -"journey", -"midnight", -"mud", -"nod", -"pause", -"relax", -"shiver", -"sudden", -"value", -"youth", -"abuse", -"admire", -"blink", -"breast", -"bruise", -"constantly", -"couple", -"creep", -"curve", -"difference", -"dumb", -"emptiness", -"gotta", -"honor", -"plain", -"planet", -"recall", -"rub", -"ship", -"slam", -"soar", -"somebody", -"tightly", -"weather", -"adore", -"approach", -"bond", -"bread", -"burst", -"candle", -"coffee", -"cousin", -"crime", -"desert", -"flutter", -"frozen", -"grand", -"heel", -"hello", -"language", -"level", -"movement", -"pleasure", -"powerful", -"random", -"rhythm", -"settle", -"silly", -"slap", -"sort", -"spoken", -"steel", -"threaten", -"tumble", -"upset", -"aside", -"awkward", -"bee", -"blank", -"board", -"button", -"card", -"carefully", -"complain", -"crap", -"deeply", -"discover", -"drag", -"dread", -"effort", -"entire", -"fairy", -"giant", -"gotten", -"greet", -"illusion", -"jeans", -"leap", -"liquid", -"march", -"mend", -"nervous", -"nine", -"replace", -"rope", -"spine", -"stole", -"terror", -"accident", -"apple", -"balance", -"boom", -"childhood", -"collect", -"demand", -"depression", -"eventually", -"faint", -"glare", -"goal", -"group", -"honey", -"kitchen", -"laid", -"limb", -"machine", -"mere", -"mold", -"murder", -"nerve", -"painful", -"poetry", -"prince", -"rabbit", -"shelter", -"shore", -"shower", -"soothe", -"stair", -"steady", -"sunlight", -"tangle", -"tease", -"treasure", -"uncle", -"begun", -"bliss", -"canvas", -"cheer", -"claw", -"clutch", -"commit", -"crimson", -"crystal", -"delight", -"doll", -"existence", -"express", -"fog", -"football", -"gay", -"goose", -"guard", -"hatred", -"illuminate", -"mass", -"math", -"mourn", -"rich", -"rough", -"skip", -"stir", -"student", -"style", -"support", -"thorn", -"tough", -"yard", -"yearn", -"yesterday", -"advice", -"appreciate", -"autumn", -"bank", -"beam", -"bowl", -"capture", -"carve", -"collapse", -"confusion", -"creation", -"dove", -"feather", -"girlfriend", -"glory", -"government", -"harsh", -"hop", -"inner", -"loser", -"moonlight", -"neighbor", -"neither", -"peach", -"pig", -"praise", -"screw", -"shield", -"shimmer", -"sneak", -"stab", -"subject", -"throughout", -"thrown", -"tower", -"twirl", -"wow", -"army", -"arrive", -"bathroom", -"bump", -"cease", -"cookie", -"couch", -"courage", -"dim", -"guilt", -"howl", -"hum", -"husband", -"insult", -"led", -"lunch", -"mock", -"mostly", -"natural", -"nearly", -"needle", -"nerd", -"peaceful", -"perfection", -"pile", -"price", -"remove", -"roam", -"sanctuary", -"serious", -"shiny", -"shook", -"sob", -"stolen", -"tap", -"vain", -"void", -"warrior", -"wrinkle", -"affection", -"apologize", -"blossom", -"bounce", -"bridge", -"cheap", -"crumble", -"decision", -"descend", -"desperately", -"dig", -"dot", -"flip", -"frighten", -"heartbeat", -"huge", -"lazy", -"lick", -"odd", -"opinion", -"process", -"puzzle", -"quietly", -"retreat", -"score", -"sentence", -"separate", -"situation", -"skill", -"soak", -"square", -"stray", -"taint", -"task", -"tide", -"underneath", -"veil", -"whistle", -"anywhere", -"bedroom", -"bid", -"bloody", -"burden", -"careful", -"compare", -"concern", -"curtain", -"decay", -"defeat", -"describe", -"double", -"dreamer", -"driver", -"dwell", -"evening", -"flare", -"flicker", -"grandma", -"guitar", -"harm", -"horrible", -"hungry", -"indeed", -"lace", -"melody", -"monkey", -"nation", -"object", -"obviously", -"rainbow", -"salt", -"scratch", -"shown", -"shy", -"stage", -"stun", -"third", -"tickle", -"useless", -"weakness", -"worship", -"worthless", -"afternoon", -"beard", -"boyfriend", -"bubble", -"busy", -"certain", -"chin", -"concrete", -"desk", -"diamond", -"doom", -"drawn", -"due", -"felicity", -"freeze", -"frost", -"garden", -"glide", -"harmony", -"hopefully", -"hunt", -"jealous", -"lightning", -"mama", -"mercy", -"peel", -"physical", -"position", -"pulse", -"punch", -"quit", -"rant", -"respond", -"salty", -"sane", -"satisfy", -"savior", -"sheep", -"slept", -"social", -"sport", -"tuck", -"utter", -"valley", -"wolf", -"aim", -"alas", -"alter", -"arrow", -"awaken", -"beaten", -"belief", -"brand", -"ceiling", -"cheese", -"clue", -"confidence", -"connection", -"daily", -"disguise", -"eager", -"erase", -"essence", -"everytime", -"expression", -"fan", -"flag", -"flirt", -"foul", -"fur", -"giggle", -"glorious", -"ignorance", -"law", -"lifeless", -"measure", -"mighty", -"muse", -"north", -"opposite", -"paradise", -"patience", -"patient", -"pencil", -"petal", -"plate", -"ponder", -"possibly", -"practice", -"slice", -"spell", -"stock", -"strife", -"strip", -"suffocate", -"suit", -"tender", -"tool", -"trade", -"velvet", -"verse", -"waist", -"witch", -"aunt", -"bench", -"bold", -"cap", -"certainly", -"click", -"companion", -"creator", -"dart", -"delicate", -"determine", -"dish", -"dragon", -"drama", -"drum", -"dude", -"everybody", -"feast", -"forehead", -"former", -"fright", -"fully", -"gas", -"hook", -"hurl", -"invite", -"juice", -"manage", -"moral", -"possess", -"raw", -"rebel", -"royal", -"scale", -"scary", -"several", -"slight", -"stubborn", -"swell", -"talent", -"tea", -"terrible", -"thread", -"torment", -"trickle", -"usually", -"vast", -"violence", -"weave", -"acid", -"agony", -"ashamed", -"awe", -"belly", -"blend", -"blush", -"character", -"cheat", -"common", -"company", -"coward", -"creak", -"danger", -"deadly", -"defense", -"define", -"depend", -"desperate", -"destination", -"dew", -"duck", -"dusty", -"embarrass", -"engine", -"example", -"explore", -"foe", -"freely", -"frustrate", -"generation", -"glove", -"guilty", -"health", -"hurry", -"idiot", -"impossible", -"inhale", -"jaw", -"kingdom", -"mention", -"mist", -"moan", -"mumble", -"mutter", -"observe", -"ode", -"pathetic", -"pattern", -"pie", -"prefer", -"puff", -"rape", -"rare", -"revenge", -"rude", -"scrape", -"spiral", -"squeeze", -"strain", -"sunset", -"suspend", -"sympathy", -"thigh", -"throne", -"total", -"unseen", -"weapon", -"weary" -] +class Mnemonic(object): + # Seed derivation follows BIP39 + # Mnemonic phrase uses a hash based checksum, instead of a wordlist-dependent checksum + def __init__(self, lang='english'): + path = os.path.join(os.path.dirname(__file__), 'wordlist', lang + '.txt') + self.wordlist = open(path,'r').read().strip().split('\n') -n = 1626 + @classmethod + def mnemonic_to_seed(self, mnemonic, passphrase): + PBKDF2_ROUNDS = 2048 + return pbkdf2.PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations = PBKDF2_ROUNDS, macmodule = hmac, digestmodule = hashlib.sha512).read(64) -# Note about US patent no 5892470: Here each word does not represent a given digit. -# Instead, the digit represented by a word is variable, it depends on the previous word. + @classmethod + def prepare_seed(self, seed): + import unicodedata + return unicodedata.normalize('NFC', unicode(seed.strip())) -def mn_encode( message ): - assert len(message) % 8 == 0 - out = [] - for i in range(len(message)/8): - word = message[8*i:8*i+8] - x = int(word, 16) - w1 = (x%n) - w2 = ((x/n) + w1)%n - w3 = ((x/n/n) + w2)%n - out += [ words[w1], words[w2], words[w3] ] - return out + def mnemonic_encode(self, i): + n = len(self.wordlist) + words = [] + while i: + x = i%n + i = i/n + words.append(self.wordlist[x]) + return ' '.join(words) -def mn_decode( wlist ): - out = '' - for i in range(len(wlist)/3): - word1, word2, word3 = wlist[3*i:3*i+3] - w1 = words.index(word1) - w2 = (words.index(word2))%n - w3 = (words.index(word3))%n - x = w1 +n*((w2-w1)%n) +n*n*((w3-w2)%n) - out += '%08x'%x - return out + def mnemonic_decode(self, seed): + n = len(self.wordlist) + words = seed.split() + i = 0 + while words: + w = words.pop() + k = self.wordlist.index(w) + i = i*n + k + return i + def check_seed(self, seed, custom_entropy): + assert is_new_seed(seed) + i = self.mnemonic_decode(seed) + return i % custom_entropy == 0 + + def make_seed(self, num_bits=128, custom_entropy=1): + n = int(math.ceil(math.log(custom_entropy,2))) + # we add at least 16 bits + n_added = max(16, num_bits-n) + print_error("make_seed: adding %d bits"%n_added) + my_entropy = ecdsa.util.randrange( pow(2, n_added) ) + nonce = 0 + while True: + nonce += 1 + i = custom_entropy * (my_entropy + nonce) + seed = self.mnemonic_encode(i) + assert i == self.mnemonic_decode(seed) + if is_old_seed(seed): + continue + # this removes 8 bits of entropy + if is_new_seed(seed): + break + return seed -if __name__ == '__main__': - import sys - if len( sys.argv ) == 1: - print 'I need arguments: a hex string to encode, or a list of words to decode' - elif len( sys.argv ) == 2: - print ' '.join(mn_encode(sys.argv[1])) - else: - print mn_decode(sys.argv[1:]) diff --git a/lib/old_mnemonic.py b/lib/old_mnemonic.py @@ -0,0 +1,1691 @@ + +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# 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/>. + + + +# list of words from http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists/Contemporary_poetry + +words = [ +"like", +"just", +"love", +"know", +"never", +"want", +"time", +"out", +"there", +"make", +"look", +"eye", +"down", +"only", +"think", +"heart", +"back", +"then", +"into", +"about", +"more", +"away", +"still", +"them", +"take", +"thing", +"even", +"through", +"long", +"always", +"world", +"too", +"friend", +"tell", +"try", +"hand", +"thought", +"over", +"here", +"other", +"need", +"smile", +"again", +"much", +"cry", +"been", +"night", +"ever", +"little", +"said", +"end", +"some", +"those", +"around", +"mind", +"people", +"girl", +"leave", +"dream", +"left", +"turn", +"myself", +"give", +"nothing", +"really", +"off", +"before", +"something", +"find", +"walk", +"wish", +"good", +"once", +"place", +"ask", +"stop", +"keep", +"watch", +"seem", +"everything", +"wait", +"got", +"yet", +"made", +"remember", +"start", +"alone", +"run", +"hope", +"maybe", +"believe", +"body", +"hate", +"after", +"close", +"talk", +"stand", +"own", +"each", +"hurt", +"help", +"home", +"god", +"soul", +"new", +"many", +"two", +"inside", +"should", +"true", +"first", +"fear", +"mean", +"better", +"play", +"another", +"gone", +"change", +"use", +"wonder", +"someone", +"hair", +"cold", +"open", +"best", +"any", +"behind", +"happen", +"water", +"dark", +"laugh", +"stay", +"forever", +"name", +"work", +"show", +"sky", +"break", +"came", +"deep", +"door", +"put", +"black", +"together", +"upon", +"happy", +"such", +"great", +"white", +"matter", +"fill", +"past", +"please", +"burn", +"cause", +"enough", +"touch", +"moment", +"soon", +"voice", +"scream", +"anything", +"stare", +"sound", +"red", +"everyone", +"hide", +"kiss", +"truth", +"death", +"beautiful", +"mine", +"blood", +"broken", +"very", +"pass", +"next", +"forget", +"tree", +"wrong", +"air", +"mother", +"understand", +"lip", +"hit", +"wall", +"memory", +"sleep", +"free", +"high", +"realize", +"school", +"might", +"skin", +"sweet", +"perfect", +"blue", +"kill", +"breath", +"dance", +"against", +"fly", +"between", +"grow", +"strong", +"under", +"listen", +"bring", +"sometimes", +"speak", +"pull", +"person", +"become", +"family", +"begin", +"ground", +"real", +"small", +"father", +"sure", +"feet", +"rest", +"young", +"finally", +"land", +"across", +"today", +"different", +"guy", +"line", +"fire", +"reason", +"reach", +"second", +"slowly", +"write", +"eat", +"smell", +"mouth", +"step", +"learn", +"three", +"floor", +"promise", +"breathe", +"darkness", +"push", +"earth", +"guess", +"save", +"song", +"above", +"along", +"both", +"color", +"house", +"almost", +"sorry", +"anymore", +"brother", +"okay", +"dear", +"game", +"fade", +"already", +"apart", +"warm", +"beauty", +"heard", +"notice", +"question", +"shine", +"began", +"piece", +"whole", +"shadow", +"secret", +"street", +"within", +"finger", +"point", +"morning", +"whisper", +"child", +"moon", +"green", +"story", +"glass", +"kid", +"silence", +"since", +"soft", +"yourself", +"empty", +"shall", +"angel", +"answer", +"baby", +"bright", +"dad", +"path", +"worry", +"hour", +"drop", +"follow", +"power", +"war", +"half", +"flow", +"heaven", +"act", +"chance", +"fact", +"least", +"tired", +"children", +"near", +"quite", +"afraid", +"rise", +"sea", +"taste", +"window", +"cover", +"nice", +"trust", +"lot", +"sad", +"cool", +"force", +"peace", +"return", +"blind", +"easy", +"ready", +"roll", +"rose", +"drive", +"held", +"music", +"beneath", +"hang", +"mom", +"paint", +"emotion", +"quiet", +"clear", +"cloud", +"few", +"pretty", +"bird", +"outside", +"paper", +"picture", +"front", +"rock", +"simple", +"anyone", +"meant", +"reality", +"road", +"sense", +"waste", +"bit", +"leaf", +"thank", +"happiness", +"meet", +"men", +"smoke", +"truly", +"decide", +"self", +"age", +"book", +"form", +"alive", +"carry", +"escape", +"damn", +"instead", +"able", +"ice", +"minute", +"throw", +"catch", +"leg", +"ring", +"course", +"goodbye", +"lead", +"poem", +"sick", +"corner", +"desire", +"known", +"problem", +"remind", +"shoulder", +"suppose", +"toward", +"wave", +"drink", +"jump", +"woman", +"pretend", +"sister", +"week", +"human", +"joy", +"crack", +"grey", +"pray", +"surprise", +"dry", +"knee", +"less", +"search", +"bleed", +"caught", +"clean", +"embrace", +"future", +"king", +"son", +"sorrow", +"chest", +"hug", +"remain", +"sat", +"worth", +"blow", +"daddy", +"final", +"parent", +"tight", +"also", +"create", +"lonely", +"safe", +"cross", +"dress", +"evil", +"silent", +"bone", +"fate", +"perhaps", +"anger", +"class", +"scar", +"snow", +"tiny", +"tonight", +"continue", +"control", +"dog", +"edge", +"mirror", +"month", +"suddenly", +"comfort", +"given", +"loud", +"quickly", +"gaze", +"plan", +"rush", +"stone", +"town", +"battle", +"ignore", +"spirit", +"stood", +"stupid", +"yours", +"brown", +"build", +"dust", +"hey", +"kept", +"pay", +"phone", +"twist", +"although", +"ball", +"beyond", +"hidden", +"nose", +"taken", +"fail", +"float", +"pure", +"somehow", +"wash", +"wrap", +"angry", +"cheek", +"creature", +"forgotten", +"heat", +"rip", +"single", +"space", +"special", +"weak", +"whatever", +"yell", +"anyway", +"blame", +"job", +"choose", +"country", +"curse", +"drift", +"echo", +"figure", +"grew", +"laughter", +"neck", +"suffer", +"worse", +"yeah", +"disappear", +"foot", +"forward", +"knife", +"mess", +"somewhere", +"stomach", +"storm", +"beg", +"idea", +"lift", +"offer", +"breeze", +"field", +"five", +"often", +"simply", +"stuck", +"win", +"allow", +"confuse", +"enjoy", +"except", +"flower", +"seek", +"strength", +"calm", +"grin", +"gun", +"heavy", +"hill", +"large", +"ocean", +"shoe", +"sigh", +"straight", +"summer", +"tongue", +"accept", +"crazy", +"everyday", +"exist", +"grass", +"mistake", +"sent", +"shut", +"surround", +"table", +"ache", +"brain", +"destroy", +"heal", +"nature", +"shout", +"sign", +"stain", +"choice", +"doubt", +"glance", +"glow", +"mountain", +"queen", +"stranger", +"throat", +"tomorrow", +"city", +"either", +"fish", +"flame", +"rather", +"shape", +"spin", +"spread", +"ash", +"distance", +"finish", +"image", +"imagine", +"important", +"nobody", +"shatter", +"warmth", +"became", +"feed", +"flesh", +"funny", +"lust", +"shirt", +"trouble", +"yellow", +"attention", +"bare", +"bite", +"money", +"protect", +"amaze", +"appear", +"born", +"choke", +"completely", +"daughter", +"fresh", +"friendship", +"gentle", +"probably", +"six", +"deserve", +"expect", +"grab", +"middle", +"nightmare", +"river", +"thousand", +"weight", +"worst", +"wound", +"barely", +"bottle", +"cream", +"regret", +"relationship", +"stick", +"test", +"crush", +"endless", +"fault", +"itself", +"rule", +"spill", +"art", +"circle", +"join", +"kick", +"mask", +"master", +"passion", +"quick", +"raise", +"smooth", +"unless", +"wander", +"actually", +"broke", +"chair", +"deal", +"favorite", +"gift", +"note", +"number", +"sweat", +"box", +"chill", +"clothes", +"lady", +"mark", +"park", +"poor", +"sadness", +"tie", +"animal", +"belong", +"brush", +"consume", +"dawn", +"forest", +"innocent", +"pen", +"pride", +"stream", +"thick", +"clay", +"complete", +"count", +"draw", +"faith", +"press", +"silver", +"struggle", +"surface", +"taught", +"teach", +"wet", +"bless", +"chase", +"climb", +"enter", +"letter", +"melt", +"metal", +"movie", +"stretch", +"swing", +"vision", +"wife", +"beside", +"crash", +"forgot", +"guide", +"haunt", +"joke", +"knock", +"plant", +"pour", +"prove", +"reveal", +"steal", +"stuff", +"trip", +"wood", +"wrist", +"bother", +"bottom", +"crawl", +"crowd", +"fix", +"forgive", +"frown", +"grace", +"loose", +"lucky", +"party", +"release", +"surely", +"survive", +"teacher", +"gently", +"grip", +"speed", +"suicide", +"travel", +"treat", +"vein", +"written", +"cage", +"chain", +"conversation", +"date", +"enemy", +"however", +"interest", +"million", +"page", +"pink", +"proud", +"sway", +"themselves", +"winter", +"church", +"cruel", +"cup", +"demon", +"experience", +"freedom", +"pair", +"pop", +"purpose", +"respect", +"shoot", +"softly", +"state", +"strange", +"bar", +"birth", +"curl", +"dirt", +"excuse", +"lord", +"lovely", +"monster", +"order", +"pack", +"pants", +"pool", +"scene", +"seven", +"shame", +"slide", +"ugly", +"among", +"blade", +"blonde", +"closet", +"creek", +"deny", +"drug", +"eternity", +"gain", +"grade", +"handle", +"key", +"linger", +"pale", +"prepare", +"swallow", +"swim", +"tremble", +"wheel", +"won", +"cast", +"cigarette", +"claim", +"college", +"direction", +"dirty", +"gather", +"ghost", +"hundred", +"loss", +"lung", +"orange", +"present", +"swear", +"swirl", +"twice", +"wild", +"bitter", +"blanket", +"doctor", +"everywhere", +"flash", +"grown", +"knowledge", +"numb", +"pressure", +"radio", +"repeat", +"ruin", +"spend", +"unknown", +"buy", +"clock", +"devil", +"early", +"false", +"fantasy", +"pound", +"precious", +"refuse", +"sheet", +"teeth", +"welcome", +"add", +"ahead", +"block", +"bury", +"caress", +"content", +"depth", +"despite", +"distant", +"marry", +"purple", +"threw", +"whenever", +"bomb", +"dull", +"easily", +"grasp", +"hospital", +"innocence", +"normal", +"receive", +"reply", +"rhyme", +"shade", +"someday", +"sword", +"toe", +"visit", +"asleep", +"bought", +"center", +"consider", +"flat", +"hero", +"history", +"ink", +"insane", +"muscle", +"mystery", +"pocket", +"reflection", +"shove", +"silently", +"smart", +"soldier", +"spot", +"stress", +"train", +"type", +"view", +"whether", +"bus", +"energy", +"explain", +"holy", +"hunger", +"inch", +"magic", +"mix", +"noise", +"nowhere", +"prayer", +"presence", +"shock", +"snap", +"spider", +"study", +"thunder", +"trail", +"admit", +"agree", +"bag", +"bang", +"bound", +"butterfly", +"cute", +"exactly", +"explode", +"familiar", +"fold", +"further", +"pierce", +"reflect", +"scent", +"selfish", +"sharp", +"sink", +"spring", +"stumble", +"universe", +"weep", +"women", +"wonderful", +"action", +"ancient", +"attempt", +"avoid", +"birthday", +"branch", +"chocolate", +"core", +"depress", +"drunk", +"especially", +"focus", +"fruit", +"honest", +"match", +"palm", +"perfectly", +"pillow", +"pity", +"poison", +"roar", +"shift", +"slightly", +"thump", +"truck", +"tune", +"twenty", +"unable", +"wipe", +"wrote", +"coat", +"constant", +"dinner", +"drove", +"egg", +"eternal", +"flight", +"flood", +"frame", +"freak", +"gasp", +"glad", +"hollow", +"motion", +"peer", +"plastic", +"root", +"screen", +"season", +"sting", +"strike", +"team", +"unlike", +"victim", +"volume", +"warn", +"weird", +"attack", +"await", +"awake", +"built", +"charm", +"crave", +"despair", +"fought", +"grant", +"grief", +"horse", +"limit", +"message", +"ripple", +"sanity", +"scatter", +"serve", +"split", +"string", +"trick", +"annoy", +"blur", +"boat", +"brave", +"clearly", +"cling", +"connect", +"fist", +"forth", +"imagination", +"iron", +"jock", +"judge", +"lesson", +"milk", +"misery", +"nail", +"naked", +"ourselves", +"poet", +"possible", +"princess", +"sail", +"size", +"snake", +"society", +"stroke", +"torture", +"toss", +"trace", +"wise", +"bloom", +"bullet", +"cell", +"check", +"cost", +"darling", +"during", +"footstep", +"fragile", +"hallway", +"hardly", +"horizon", +"invisible", +"journey", +"midnight", +"mud", +"nod", +"pause", +"relax", +"shiver", +"sudden", +"value", +"youth", +"abuse", +"admire", +"blink", +"breast", +"bruise", +"constantly", +"couple", +"creep", +"curve", +"difference", +"dumb", +"emptiness", +"gotta", +"honor", +"plain", +"planet", +"recall", +"rub", +"ship", +"slam", +"soar", +"somebody", +"tightly", +"weather", +"adore", +"approach", +"bond", +"bread", +"burst", +"candle", +"coffee", +"cousin", +"crime", +"desert", +"flutter", +"frozen", +"grand", +"heel", +"hello", +"language", +"level", +"movement", +"pleasure", +"powerful", +"random", +"rhythm", +"settle", +"silly", +"slap", +"sort", +"spoken", +"steel", +"threaten", +"tumble", +"upset", +"aside", +"awkward", +"bee", +"blank", +"board", +"button", +"card", +"carefully", +"complain", +"crap", +"deeply", +"discover", +"drag", +"dread", +"effort", +"entire", +"fairy", +"giant", +"gotten", +"greet", +"illusion", +"jeans", +"leap", +"liquid", +"march", +"mend", +"nervous", +"nine", +"replace", +"rope", +"spine", +"stole", +"terror", +"accident", +"apple", +"balance", +"boom", +"childhood", +"collect", +"demand", +"depression", +"eventually", +"faint", +"glare", +"goal", +"group", +"honey", +"kitchen", +"laid", +"limb", +"machine", +"mere", +"mold", +"murder", +"nerve", +"painful", +"poetry", +"prince", +"rabbit", +"shelter", +"shore", +"shower", +"soothe", +"stair", +"steady", +"sunlight", +"tangle", +"tease", +"treasure", +"uncle", +"begun", +"bliss", +"canvas", +"cheer", +"claw", +"clutch", +"commit", +"crimson", +"crystal", +"delight", +"doll", +"existence", +"express", +"fog", +"football", +"gay", +"goose", +"guard", +"hatred", +"illuminate", +"mass", +"math", +"mourn", +"rich", +"rough", +"skip", +"stir", +"student", +"style", +"support", +"thorn", +"tough", +"yard", +"yearn", +"yesterday", +"advice", +"appreciate", +"autumn", +"bank", +"beam", +"bowl", +"capture", +"carve", +"collapse", +"confusion", +"creation", +"dove", +"feather", +"girlfriend", +"glory", +"government", +"harsh", +"hop", +"inner", +"loser", +"moonlight", +"neighbor", +"neither", +"peach", +"pig", +"praise", +"screw", +"shield", +"shimmer", +"sneak", +"stab", +"subject", +"throughout", +"thrown", +"tower", +"twirl", +"wow", +"army", +"arrive", +"bathroom", +"bump", +"cease", +"cookie", +"couch", +"courage", +"dim", +"guilt", +"howl", +"hum", +"husband", +"insult", +"led", +"lunch", +"mock", +"mostly", +"natural", +"nearly", +"needle", +"nerd", +"peaceful", +"perfection", +"pile", +"price", +"remove", +"roam", +"sanctuary", +"serious", +"shiny", +"shook", +"sob", +"stolen", +"tap", +"vain", +"void", +"warrior", +"wrinkle", +"affection", +"apologize", +"blossom", +"bounce", +"bridge", +"cheap", +"crumble", +"decision", +"descend", +"desperately", +"dig", +"dot", +"flip", +"frighten", +"heartbeat", +"huge", +"lazy", +"lick", +"odd", +"opinion", +"process", +"puzzle", +"quietly", +"retreat", +"score", +"sentence", +"separate", +"situation", +"skill", +"soak", +"square", +"stray", +"taint", +"task", +"tide", +"underneath", +"veil", +"whistle", +"anywhere", +"bedroom", +"bid", +"bloody", +"burden", +"careful", +"compare", +"concern", +"curtain", +"decay", +"defeat", +"describe", +"double", +"dreamer", +"driver", +"dwell", +"evening", +"flare", +"flicker", +"grandma", +"guitar", +"harm", +"horrible", +"hungry", +"indeed", +"lace", +"melody", +"monkey", +"nation", +"object", +"obviously", +"rainbow", +"salt", +"scratch", +"shown", +"shy", +"stage", +"stun", +"third", +"tickle", +"useless", +"weakness", +"worship", +"worthless", +"afternoon", +"beard", +"boyfriend", +"bubble", +"busy", +"certain", +"chin", +"concrete", +"desk", +"diamond", +"doom", +"drawn", +"due", +"felicity", +"freeze", +"frost", +"garden", +"glide", +"harmony", +"hopefully", +"hunt", +"jealous", +"lightning", +"mama", +"mercy", +"peel", +"physical", +"position", +"pulse", +"punch", +"quit", +"rant", +"respond", +"salty", +"sane", +"satisfy", +"savior", +"sheep", +"slept", +"social", +"sport", +"tuck", +"utter", +"valley", +"wolf", +"aim", +"alas", +"alter", +"arrow", +"awaken", +"beaten", +"belief", +"brand", +"ceiling", +"cheese", +"clue", +"confidence", +"connection", +"daily", +"disguise", +"eager", +"erase", +"essence", +"everytime", +"expression", +"fan", +"flag", +"flirt", +"foul", +"fur", +"giggle", +"glorious", +"ignorance", +"law", +"lifeless", +"measure", +"mighty", +"muse", +"north", +"opposite", +"paradise", +"patience", +"patient", +"pencil", +"petal", +"plate", +"ponder", +"possibly", +"practice", +"slice", +"spell", +"stock", +"strife", +"strip", +"suffocate", +"suit", +"tender", +"tool", +"trade", +"velvet", +"verse", +"waist", +"witch", +"aunt", +"bench", +"bold", +"cap", +"certainly", +"click", +"companion", +"creator", +"dart", +"delicate", +"determine", +"dish", +"dragon", +"drama", +"drum", +"dude", +"everybody", +"feast", +"forehead", +"former", +"fright", +"fully", +"gas", +"hook", +"hurl", +"invite", +"juice", +"manage", +"moral", +"possess", +"raw", +"rebel", +"royal", +"scale", +"scary", +"several", +"slight", +"stubborn", +"swell", +"talent", +"tea", +"terrible", +"thread", +"torment", +"trickle", +"usually", +"vast", +"violence", +"weave", +"acid", +"agony", +"ashamed", +"awe", +"belly", +"blend", +"blush", +"character", +"cheat", +"common", +"company", +"coward", +"creak", +"danger", +"deadly", +"defense", +"define", +"depend", +"desperate", +"destination", +"dew", +"duck", +"dusty", +"embarrass", +"engine", +"example", +"explore", +"foe", +"freely", +"frustrate", +"generation", +"glove", +"guilty", +"health", +"hurry", +"idiot", +"impossible", +"inhale", +"jaw", +"kingdom", +"mention", +"mist", +"moan", +"mumble", +"mutter", +"observe", +"ode", +"pathetic", +"pattern", +"pie", +"prefer", +"puff", +"rape", +"rare", +"revenge", +"rude", +"scrape", +"spiral", +"squeeze", +"strain", +"sunset", +"suspend", +"sympathy", +"thigh", +"throne", +"total", +"unseen", +"weapon", +"weary" +] + + + +n = 1626 + +# Note about US patent no 5892470: Here each word does not represent a given digit. +# Instead, the digit represented by a word is variable, it depends on the previous word. + +def mn_encode( message ): + assert len(message) % 8 == 0 + out = [] + for i in range(len(message)/8): + word = message[8*i:8*i+8] + x = int(word, 16) + w1 = (x%n) + w2 = ((x/n) + w1)%n + w3 = ((x/n/n) + w2)%n + out += [ words[w1], words[w2], words[w3] ] + return out + +def mn_decode( wlist ): + out = '' + for i in range(len(wlist)/3): + word1, word2, word3 = wlist[3*i:3*i+3] + w1 = words.index(word1) + w2 = (words.index(word2))%n + w3 = (words.index(word3))%n + x = w1 +n*((w2-w1)%n) +n*n*((w3-w2)%n) + out += '%08x'%x + return out + + +if __name__ == '__main__': + import sys + if len( sys.argv ) == 1: + print 'I need arguments: a hex string to encode, or a list of words to decode' + elif len( sys.argv ) == 2: + print ' '.join(mn_encode(sys.argv[1])) + else: + print mn_decode(sys.argv[1:]) diff --git a/lib/wallet.py b/lib/wallet.py @@ -36,6 +36,7 @@ from transaction import Transaction from plugins import run_hook import bitcoin from synchronizer import WalletSynchronizer +from mnemonic import Mnemonic COINBASE_MATURITY = 100 DUST_THRESHOLD = 5430 @@ -1278,6 +1279,32 @@ class BIP32_Wallet(Deterministic_Wallet): return True return False + def create_master_keys(self, password): + seed = self.get_seed(password) + self.add_cosigner_seed(seed, self.root_name, password) + + def add_cosigner_seed(self, seed, name, password): + # we don't store the seed, only the master xpriv + xprv, xpub = bip32_root(self.mnemonic_to_seed(seed,'')) + xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation) + self.add_master_public_key(name, xpub) + self.add_master_private_key(name, xprv, password) + + def add_cosigner_xpub(self, seed, name): + # store only master xpub + xprv, xpub = bip32_root(self.mnemonic_to_seed(seed,'')) + xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation) + self.add_master_public_key(name, xpub) + + def mnemonic_to_seed(self, seed, password): + return Mnemonic.mnemonic_to_seed(seed, password) + + def make_seed(self): + return Mnemonic('english').make_seed() + + def prepare_seed(self, seed): + return NEW_SEED_VERSION, Mnemonic.prepare_seed(seed) + class BIP32_Simple_Wallet(BIP32_Wallet): # Wallet with a single BIP32 account, no seed @@ -1380,53 +1407,15 @@ class BIP32_HD_Wallet(BIP32_Wallet): return i -class BIP39_Wallet(BIP32_Wallet): - # BIP39 seed generation - def create_master_keys(self, password): - seed = self.get_seed(password) - xprv, xpub = bip32_root(mnemonic_to_seed(seed,'')) - xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation) - self.add_master_public_key(self.root_name, xpub) - self.add_master_private_key(self.root_name, xprv, password) - - @classmethod - def make_seed(self, custom_entropy=1): - import mnemonic - import ecdsa - import math - n = int(math.ceil(math.log(custom_entropy,2))) - n_added = max(16, 160-n) - print_error("make_seed: adding %d bits"%n_added) - my_entropy = ecdsa.util.randrange( pow(2, n_added) ) - nonce = 0 - while True: - s = "%x"% ( custom_entropy * (my_entropy + nonce)) - if len(s) % 8: - s = "0"* (8 - len(s) % 8) + s - words = mnemonic.mn_encode(s) - seed = ' '.join(words) - # this removes 8 bits of entropy - if not is_old_seed(seed) and is_new_seed(seed): - break - nonce += 1 - print_error(seed) - return seed - - def prepare_seed(self, seed): - import unicodedata - return NEW_SEED_VERSION, unicodedata.normalize('NFC', unicode(seed.strip())) - - - -class NewWallet(BIP32_HD_Wallet, BIP39_Wallet): +class NewWallet(BIP32_HD_Wallet, Mnemonic): # bip 44 root_name = 'x/' root_derivation = "m/44'/0'" wallet_type = 'standard' -class Wallet_2of2(BIP39_Wallet): +class Wallet_2of2(BIP32_Wallet, Mnemonic): # Wallet with multisig addresses. # Cannot create accounts root_name = "x1/" @@ -1457,19 +1446,6 @@ class Wallet_2of2(BIP39_Wallet): if not self.accounts: return 'create_accounts' - def add_cosigner_seed(self, seed, name, password): - # we don't store the seed, only the master xpriv - xprv, xpub = bip32_root(mnemonic_to_seed(seed,'')) - xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation) - self.add_master_public_key(name, xpub) - self.add_master_private_key(name, xprv, password) - - def add_cosigner_xpub(self, seed, name): - # store only master xpub - xprv, xpub = bip32_root(mnemonic_to_seed(seed,'')) - xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation) - self.add_master_public_key(name, xpub) - class Wallet_2of3(Wallet_2of2): @@ -1510,12 +1486,12 @@ class OldWallet(Deterministic_Wallet): self.gap_limit = storage.get('gap_limit', 5) def make_seed(self): - import mnemonic + import old_mnemonic seed = random_seed(128) - return ' '.join(mnemonic.mn_encode(seed)) + return ' '.join(old_mnemonic.mn_encode(seed)) def prepare_seed(self, seed): - import mnemonic + import old_mnemonic # see if seed was entered as hex seed = seed.strip() try: @@ -1526,7 +1502,7 @@ class OldWallet(Deterministic_Wallet): pass words = seed.split() - seed = mnemonic.mn_decode(words) + seed = old_mnemonic.mn_decode(words) if not seed: raise Exception("Invalid seed") @@ -1566,9 +1542,9 @@ class OldWallet(Deterministic_Wallet): self.accounts['0'].check_seed(seed) def get_mnemonic(self, password): - import mnemonic + import old_mnemonic s = self.get_seed(password) - return ' '.join(mnemonic.mn_encode(s)) + return ' '.join(old_mnemonic.mn_encode(s)) def can_sign(self, tx): if self.is_watching_only(): diff --git a/lib/wordlist/english.txt b/lib/wordlist/english.txt @@ -0,0 +1,2048 @@ +abandon +ability +able +about +above +absent +absorb +abstract +absurd +abuse +access +accident +account +accuse +achieve +acid +acoustic +acquire +across +act +action +actor +actress +actual +adapt +add +addict +address +adjust +admit +adult +advance +advice +aerobic +affair +afford +afraid +again +age +agent +agree +ahead +aim +air +airport +aisle +alarm +album +alcohol +alert +alien +all +alley +allow +almost +alone +alpha +already +also +alter +always +amateur +amazing +among +amount +amused +analyst +anchor +ancient +anger +angle +angry +animal +ankle +announce +annual +another +answer +antenna +antique +anxiety +any +apart +apology +appear +apple +approve +april +arch +arctic +area +arena +argue +arm +armed +armor +army +around +arrange +arrest +arrive +arrow +art +artefact +artist +artwork +ask +aspect +assault +asset +assist +assume +asthma +athlete +atom +attack +attend +attitude +attract +auction +audit +august +aunt +author +auto +autumn +average +avocado +avoid +awake +aware +away +awesome +awful +awkward +axis +baby +bachelor +bacon +badge +bag +balance +balcony +ball +bamboo +banana +banner +bar +barely +bargain +barrel +base +basic +basket +battle +beach +bean +beauty +because +become +beef +before +begin +behave +behind +believe +below +belt +bench +benefit +best +betray +better +between +beyond +bicycle +bid +bike +bind +biology +bird +birth +bitter +black +blade +blame +blanket +blast +bleak +bless +blind +blood +blossom +blouse +blue +blur +blush +board +boat +body +boil +bomb +bone +bonus +book +boost +border +boring +borrow +boss +bottom +bounce +box +boy +bracket +brain +brand +brass +brave +bread +breeze +brick +bridge +brief +bright +bring +brisk +broccoli +broken +bronze +broom +brother +brown +brush +bubble +buddy +budget +buffalo +build +bulb +bulk +bullet +bundle +bunker +burden +burger +burst +bus +business +busy +butter +buyer +buzz +cabbage +cabin +cable +cactus +cage +cake +call +calm +camera +camp +can +canal +cancel +candy +cannon +canoe +canvas +canyon +capable +capital +captain +car +carbon +card +cargo +carpet +carry +cart +case +cash +casino +castle +casual +cat +catalog +catch +category +cattle +caught +cause +caution +cave +ceiling +celery +cement +census +century +cereal +certain +chair +chalk +champion +change +chaos +chapter +charge +chase +chat +cheap +check +cheese +chef +cherry +chest +chicken +chief +child +chimney +choice +choose +chronic +chuckle +chunk +churn +cigar +cinnamon +circle +citizen +city +civil +claim +clap +clarify +claw +clay +clean +clerk +clever +click +client +cliff +climb +clinic +clip +clock +clog +close +cloth +cloud +clown +club +clump +cluster +clutch +coach +coast +coconut +code +coffee +coil +coin +collect +color +column +combine +come +comfort +comic +common +company +concert +conduct +confirm +congress +connect +consider +control +convince +cook +cool +copper +copy +coral +core +corn +correct +cost +cotton +couch +country +couple +course +cousin +cover +coyote +crack +cradle +craft +cram +crane +crash +crater +crawl +crazy +cream +credit +creek +crew +cricket +crime +crisp +critic +crop +cross +crouch +crowd +crucial +cruel +cruise +crumble +crunch +crush +cry +crystal +cube +culture +cup +cupboard +curious +current +curtain +curve +cushion +custom +cute +cycle +dad +damage +damp +dance +danger +daring +dash +daughter +dawn +day +deal +debate +debris +decade +december +decide +decline +decorate +decrease +deer +defense +define +defy +degree +delay +deliver +demand +demise +denial +dentist +deny +depart +depend +deposit +depth +deputy +derive +describe +desert +design +desk +despair +destroy +detail +detect +develop +device +devote +diagram +dial +diamond +diary +dice +diesel +diet +differ +digital +dignity +dilemma +dinner +dinosaur +direct +dirt +disagree +discover +disease +dish +dismiss +disorder +display +distance +divert +divide +divorce +dizzy +doctor +document +dog +doll +dolphin +domain +donate +donkey +donor +door +dose +double +dove +draft +dragon +drama +drastic +draw +dream +dress +drift +drill +drink +drip +drive +drop +drum +dry +duck +dumb +dune +during +dust +dutch +duty +dwarf +dynamic +eager +eagle +early +earn +earth +easily +east +easy +echo +ecology +economy +edge +edit +educate +effort +egg +eight +either +elbow +elder +electric +elegant +element +elephant +elevator +elite +else +embark +embody +embrace +emerge +emotion +employ +empower +empty +enable +enact +end +endless +endorse +enemy +energy +enforce +engage +engine +enhance +enjoy +enlist +enough +enrich +enroll +ensure +enter +entire +entry +envelope +episode +equal +equip +era +erase +erode +erosion +error +erupt +escape +essay +essence +estate +eternal +ethics +evidence +evil +evoke +evolve +exact +example +excess +exchange +excite +exclude +excuse +execute +exercise +exhaust +exhibit +exile +exist +exit +exotic +expand +expect +expire +explain +expose +express +extend +extra +eye +eyebrow +fabric +face +faculty +fade +faint +faith +fall +false +fame +family +famous +fan +fancy +fantasy +farm +fashion +fat +fatal +father +fatigue +fault +favorite +feature +february +federal +fee +feed +feel +female +fence +festival +fetch +fever +few +fiber +fiction +field +figure +file +film +filter +final +find +fine +finger +finish +fire +firm +first +fiscal +fish +fit +fitness +fix +flag +flame +flash +flat +flavor +flee +flight +flip +float +flock +floor +flower +fluid +flush +fly +foam +focus +fog +foil +fold +follow +food +foot +force +forest +forget +fork +fortune +forum +forward +fossil +foster +found +fox +fragile +frame +frequent +fresh +friend +fringe +frog +front +frost +frown +frozen +fruit +fuel +fun +funny +furnace +fury +future +gadget +gain +galaxy +gallery +game +gap +garage +garbage +garden +garlic +garment +gas +gasp +gate +gather +gauge +gaze +general +genius +genre +gentle +genuine +gesture +ghost +giant +gift +giggle +ginger +giraffe +girl +give +glad +glance +glare +glass +glide +glimpse +globe +gloom +glory +glove +glow +glue +goat +goddess +gold +good +goose +gorilla +gospel +gossip +govern +gown +grab +grace +grain +grant +grape +grass +gravity +great +green +grid +grief +grit +grocery +group +grow +grunt +guard +guess +guide +guilt +guitar +gun +gym +habit +hair +half +hammer +hamster +hand +happy +harbor +hard +harsh +harvest +hat +have +hawk +hazard +head +health +heart +heavy +hedgehog +height +hello +helmet +help +hen +hero +hidden +high +hill +hint +hip +hire +history +hobby +hockey +hold +hole +holiday +hollow +home +honey +hood +hope +horn +horror +horse +hospital +host +hotel +hour +hover +hub +huge +human +humble +humor +hundred +hungry +hunt +hurdle +hurry +hurt +husband +hybrid +ice +icon +idea +identify +idle +ignore +ill +illegal +illness +image +imitate +immense +immune +impact +impose +improve +impulse +inch +include +income +increase +index +indicate +indoor +industry +infant +inflict +inform +inhale +inherit +initial +inject +injury +inmate +inner +innocent +input +inquiry +insane +insect +inside +inspire +install +intact +interest +into +invest +invite +involve +iron +island +isolate +issue +item +ivory +jacket +jaguar +jar +jazz +jealous +jeans +jelly +jewel +job +join +joke +journey +joy +judge +juice +jump +jungle +junior +junk +just +kangaroo +keen +keep +ketchup +key +kick +kid +kidney +kind +kingdom +kiss +kit +kitchen +kite +kitten +kiwi +knee +knife +knock +know +lab +label +labor +ladder +lady +lake +lamp +language +laptop +large +later +latin +laugh +laundry +lava +law +lawn +lawsuit +layer +lazy +leader +leaf +learn +leave +lecture +left +leg +legal +legend +leisure +lemon +lend +length +lens +leopard +lesson +letter +level +liar +liberty +library +license +life +lift +light +like +limb +limit +link +lion +liquid +list +little +live +lizard +load +loan +lobster +local +lock +logic +lonely +long +loop +lottery +loud +lounge +love +loyal +lucky +luggage +lumber +lunar +lunch +luxury +lyrics +machine +mad +magic +magnet +maid +mail +main +major +make +mammal +man +manage +mandate +mango +mansion +manual +maple +marble +march +margin +marine +market +marriage +mask +mass +master +match +material +math +matrix +matter +maximum +maze +meadow +mean +measure +meat +mechanic +medal +media +melody +melt +member +memory +mention +menu +mercy +merge +merit +merry +mesh +message +metal +method +middle +midnight +milk +million +mimic +mind +minimum +minor +minute +miracle +mirror +misery +miss +mistake +mix +mixed +mixture +mobile +model +modify +mom +moment +monitor +monkey +monster +month +moon +moral +more +morning +mosquito +mother +motion +motor +mountain +mouse +move +movie +much +muffin +mule +multiply +muscle +museum +mushroom +music +must +mutual +myself +mystery +myth +naive +name +napkin +narrow +nasty +nation +nature +near +neck +need +negative +neglect +neither +nephew +nerve +nest +net +network +neutral +never +news +next +nice +night +noble +noise +nominee +noodle +normal +north +nose +notable +note +nothing +notice +novel +now +nuclear +number +nurse +nut +oak +obey +object +oblige +obscure +observe +obtain +obvious +occur +ocean +october +odor +off +offer +office +often +oil +okay +old +olive +olympic +omit +once +one +onion +online +only +open +opera +opinion +oppose +option +orange +orbit +orchard +order +ordinary +organ +orient +original +orphan +ostrich +other +outdoor +outer +output +outside +oval +oven +over +own +owner +oxygen +oyster +ozone +pact +paddle +page +pair +palace +palm +panda +panel +panic +panther +paper +parade +parent +park +parrot +party +pass +patch +path +patient +patrol +pattern +pause +pave +payment +peace +peanut +pear +peasant +pelican +pen +penalty +pencil +people +pepper +perfect +permit +person +pet +phone +photo +phrase +physical +piano +picnic +picture +piece +pig +pigeon +pill +pilot +pink +pioneer +pipe +pistol +pitch +pizza +place +planet +plastic +plate +play +please +pledge +pluck +plug +plunge +poem +poet +point +polar +pole +police +pond +pony +pool +popular +portion +position +possible +post +potato +pottery +poverty +powder +power +practice +praise +predict +prefer +prepare +present +pretty +prevent +price +pride +primary +print +priority +prison +private +prize +problem +process +produce +profit +program +project +promote +proof +property +prosper +protect +proud +provide +public +pudding +pull +pulp +pulse +pumpkin +punch +pupil +puppy +purchase +purity +purpose +purse +push +put +puzzle +pyramid +quality +quantum +quarter +question +quick +quit +quiz +quote +rabbit +raccoon +race +rack +radar +radio +rail +rain +raise +rally +ramp +ranch +random +range +rapid +rare +rate +rather +raven +raw +razor +ready +real +reason +rebel +rebuild +recall +receive +recipe +record +recycle +reduce +reflect +reform +refuse +region +regret +regular +reject +relax +release +relief +rely +remain +remember +remind +remove +render +renew +rent +reopen +repair +repeat +replace +report +require +rescue +resemble +resist +resource +response +result +retire +retreat +return +reunion +reveal +review +reward +rhythm +rib +ribbon +rice +rich +ride +ridge +rifle +right +rigid +ring +riot +ripple +risk +ritual +rival +river +road +roast +robot +robust +rocket +romance +roof +rookie +room +rose +rotate +rough +round +route +royal +rubber +rude +rug +rule +run +runway +rural +sad +saddle +sadness +safe +sail +salad +salmon +salon +salt +salute +same +sample +sand +satisfy +satoshi +sauce +sausage +save +say +scale +scan +scare +scatter +scene +scheme +school +science +scissors +scorpion +scout +scrap +screen +script +scrub +sea +search +season +seat +second +secret +section +security +seed +seek +segment +select +sell +seminar +senior +sense +sentence +series +service +session +settle +setup +seven +shadow +shaft +shallow +share +shed +shell +sheriff +shield +shift +shine +ship +shiver +shock +shoe +shoot +shop +short +shoulder +shove +shrimp +shrug +shuffle +shy +sibling +sick +side +siege +sight +sign +silent +silk +silly +silver +similar +simple +since +sing +siren +sister +situate +six +size +skate +sketch +ski +skill +skin +skirt +skull +slab +slam +sleep +slender +slice +slide +slight +slim +slogan +slot +slow +slush +small +smart +smile +smoke +smooth +snack +snake +snap +sniff +snow +soap +soccer +social +sock +soda +soft +solar +soldier +solid +solution +solve +someone +song +soon +sorry +sort +soul +sound +soup +source +south +space +spare +spatial +spawn +speak +special +speed +spell +spend +sphere +spice +spider +spike +spin +spirit +split +spoil +sponsor +spoon +sport +spot +spray +spread +spring +spy +square +squeeze +squirrel +stable +stadium +staff +stage +stairs +stamp +stand +start +state +stay +steak +steel +stem +step +stereo +stick +still +sting +stock +stomach +stone +stool +story +stove +strategy +street +strike +strong +struggle +student +stuff +stumble +style +subject +submit +subway +success +such +sudden +suffer +sugar +suggest +suit +summer +sun +sunny +sunset +super +supply +supreme +sure +surface +surge +surprise +surround +survey +suspect +sustain +swallow +swamp +swap +swarm +swear +sweet +swift +swim +swing +switch +sword +symbol +symptom +syrup +system +table +tackle +tag +tail +talent +talk +tank +tape +target +task +taste +tattoo +taxi +teach +team +tell +ten +tenant +tennis +tent +term +test +text +thank +that +theme +then +theory +there +they +thing +this +thought +three +thrive +throw +thumb +thunder +ticket +tide +tiger +tilt +timber +time +tiny +tip +tired +tissue +title +toast +tobacco +today +toddler +toe +together +toilet +token +tomato +tomorrow +tone +tongue +tonight +tool +tooth +top +topic +topple +torch +tornado +tortoise +toss +total +tourist +toward +tower +town +toy +track +trade +traffic +tragic +train +transfer +trap +trash +travel +tray +treat +tree +trend +trial +tribe +trick +trigger +trim +trip +trophy +trouble +truck +true +truly +trumpet +trust +truth +try +tube +tuition +tumble +tuna +tunnel +turkey +turn +turtle +twelve +twenty +twice +twin +twist +two +type +typical +ugly +umbrella +unable +unaware +uncle +uncover +under +undo +unfair +unfold +unhappy +uniform +unique +unit +universe +unknown +unlock +until +unusual +unveil +update +upgrade +uphold +upon +upper +upset +urban +urge +usage +use +used +useful +useless +usual +utility +vacant +vacuum +vague +valid +valley +valve +van +vanish +vapor +various +vast +vault +vehicle +velvet +vendor +venture +venue +verb +verify +version +very +vessel +veteran +viable +vibrant +vicious +victory +video +view +village +vintage +violin +virtual +virus +visa +visit +visual +vital +vivid +vocal +voice +void +volcano +volume +vote +voyage +wage +wagon +wait +walk +wall +walnut +want +warfare +warm +warrior +wash +wasp +waste +water +wave +way +wealth +weapon +wear +weasel +weather +web +wedding +weekend +weird +welcome +west +wet +whale +what +wheat +wheel +when +where +whip +whisper +wide +width +wife +wild +will +win +window +wine +wing +wink +winner +winter +wire +wisdom +wise +wish +witness +wolf +woman +wonder +wood +wool +word +work +world +worry +worth +wrap +wreck +wrestle +wrist +write +wrong +yard +year +yellow +you +young +youth +zebra +zero +zone +zoo