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:
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