diff --git a/bitcoin/deterministic.py b/bitcoin/deterministic.py index 36b1b63e..99cfec64 100644 --- a/bitcoin/deterministic.py +++ b/bitcoin/deterministic.py @@ -189,11 +189,39 @@ def coinvault_priv_to_bip32(*args): return bip32_serialize((MAINNET_PRIVATE, 0, b'\x00'*4, 0, I2, I3+b'\x01')) -def bip32_descend(*args): +def bip32_path(*args): if len(args) == 2 and isinstance(args[1], list): key, path = args else: key, path = args[0], map(int, args[1:]) - for p in path: - key = bip32_ckd(key, p) - return bip32_extract_key(key) + + return reduce(bip32_ckd,path,key) + +def bip32_descend(*args): + return bip32_extract_key(bip32_path(*args)) + +#explicit harden method. +def bip32_harden(x): + return (1 << 31) + x + +def bip32_path_from_string(pathstring): #can only handle private key style paths not others. + def process(x): + nhx=x.strip("'") + return bip32_harden(int(nhx)) if nhx != x else int(nhx) + pe=pathstring.split("/") + return [process(x) for x in pe[1:]] + + +def hd_lookup(root,account=None,index=None,change=0,coin=0): + depth=bip32_deserialize(root)[1] + if(depth==0): #if root is master (has a depth=0) + if(index): + return bip32_path(root,bip32_harden(44),bip32_harden(coin),bip32_harden(account),change,index) + else: + return bip32_path(root,bip32_harden(44),bip32_harden(coin),bip32_harden(account)) + elif(depth==3): + return bip32_path(root,change,index) + else: + raise Exception("%s does not appear to be a bip44-compatible xpubkey!" % (root)) + + diff --git a/bitcoin/english.txt b/bitcoin/english.txt deleted file mode 100644 index 942040ed..00000000 --- a/bitcoin/english.txt +++ /dev/null @@ -1,2048 +0,0 @@ -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 diff --git a/bitcoin/mnemonic.py b/bitcoin/mnemonic.py index 14399d31..2f9d885f 100644 --- a/bitcoin/mnemonic.py +++ b/bitcoin/mnemonic.py @@ -1,78 +1,93 @@ import hashlib import os.path import binascii -import random +from os import urandom as secure_random_bytes from bisect import bisect_left +import re +import collections +import json +import bz2 -wordlist_english=list(open(os.path.join(os.path.dirname(os.path.realpath(__file__)),'english.txt'),'r')) +#this type has list semantics but is optimized for O(1) search using a hashtable for speed +class Wordlist(list): + def __init__(self,*collection,**kwargs): + list.__init__(self,*collection,**kwargs) + self.lookup=dict((value,index) for index,value in enumerate(self)) + + def index(self,x): + try: + return self.lookup[x] + except KeyError as ke: + raise IndexError("'%s' is not in list" % (ke.args)) + + def __contains__(self,x): + return x in self.lookup -def eint_to_bytes(entint,entbits): - a=hex(entint)[2:].rstrip('L').zfill(32) - print(a) + +_wordlists_path=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'wordlists.json.bz2') +wordlists = dict(((k,Wordlist(v)) for k,v in json.load(bz2.BZ2File(_wordlists_path,'r')).iteritems())) + +def eint_to_bytes(entint, entbits): + a = hex(entint)[2:].rstrip('L').zfill(entbits // 4) return binascii.unhexlify(a) -def mnemonic_int_to_words(mint,mint_num_words,wordlist=wordlist_english): - backwords=[wordlist[(mint >> (11*x)) & 0x7FF].strip() for x in range(mint_num_words)] + +def mnemonic_int_to_words(mint, mint_num_words, wordlist=wordlists["english"]): + backwords = [wordlist[(mint >> (11 * x)) & 0x7FF].strip() for x in range(mint_num_words)] return backwords[::-1] - + + def entropy_cs(entbytes): - entropy_size=8*len(entbytes) - checksum_size=entropy_size//32 - hd=hashlib.sha256(entbytes).hexdigest() - csint=int(hd,16) >> (256-checksum_size) - return csint,checksum_size - -def entropy_to_words(entbytes,wordlist=wordlist_english): + entropy_size = 8 * len(entbytes) + checksum_size = entropy_size // 32 + hd = hashlib.sha256(entbytes).hexdigest() + csint = int(hd, 16) >> (256 - checksum_size) + return csint, checksum_size + + +def entropy_to_words(entbytes, wordlist=wordlists["english"]): if(len(entbytes) < 4 or len(entbytes) % 4 != 0): raise ValueError("The size of the entropy must be a multiple of 4 bytes (multiple of 32 bits)") - entropy_size=8*len(entbytes) - csint,checksum_size = entropy_cs(entbytes) - entint=int(binascii.hexlify(entbytes),16) - mint=(entint << checksum_size) | csint - mint_num_words=(entropy_size+checksum_size)//11 - - return mnemonic_int_to_words(mint,mint_num_words,wordlist) + entropy_size = 8 * len(entbytes) + csint, checksum_size = entropy_cs(entbytes) + entint = int(binascii.hexlify(entbytes), 16) + mint = (entint << checksum_size) | csint + mint_num_words = (entropy_size + checksum_size) // 11 -def words_bisect(word,wordlist=wordlist_english): - lo=bisect_left(wordlist,word) - hi=len(wordlist)-bisect_left(wordlist[:lo:-1],word) - - return lo,hi - -def words_split(wordstr,wordlist=wordlist_english): - def popword(wordstr,wordlist): - for fwl in range(1,9): - w=wordstr[:fwl].strip() - lo,hi=words_bisect(w,wordlist) - if(hi-lo == 1): - return w,wordstr[fwl:].lstrip() - wordlist=wordlist[lo:hi] - raise Exception("Wordstr %s not found in list" %(w)) - - words=[] - tail=wordstr - while(len(tail)): - head,tail=popword(tail,wordlist) - words.append(head) + return mnemonic_int_to_words(mint, mint_num_words, wordlist) + + +def words_split(wordstr, wordlist=wordlists["english"]): + words = wordstr.split() + for w in words: + if(w not in wordlist): + raise Exception("Word %s not in wordlist" % (w)) return words -def words_to_mnemonic_int(words,wordlist=wordlist_english): - if(instance(words,str)): - words=words_split(words,wordlist) - return sum([wordlist.index(w) << (11*x) for x,w in enumerate(words[::-1])]) -def words_verify(words,wordlist=wordlist_english): - if(isinstance(words,str)): - words=words_split(words,wordlist) +def words_to_mnemonic_int(words, wordlist=wordlists["english"]): + if(isinstance(words, basestring)): + words = words_split(words, wordlist) + return sum([wordlist.index(w) << (11 * x) for x, w in enumerate(words[::-1])]) + + +def mnemonic_int_verify(mint, mint_bits): + cs_bits = mint_bits // 32 + entropy_bits = mint_bits - cs_bits + eint = mint >> cs_bits + csint = mint & ((1 << cs_bits) - 1) + ebytes = eint_to_bytes(eint, entropy_bits) + ecsint, ecsint_size = entropy_cs(ebytes) + return csint == ecsint + + +def words_verify(words, wordlist=wordlists["english"]): + if(isinstance(words, basestring)): + words = words_split(words, wordlist) - mint = words_to_mnemonic_int(words,wordlist) + mint=words_to_mnemonic_int(words, wordlist) mint_bits=len(words)*11 - cs_bits=mint_bits//32 - entropy_bits=mint_bits-cs_bits - eint=mint >> cs_bits - csint=mint & ((1 << cs_bits)-1) - ebytes=_eint_to_bytes(eint,entropy_bits) - return csint == entropy_cs(ebytes) + return mnemonic_int_verify(mint,mint_bits) def mnemonic_to_seed(mnemonic_phrase,passphrase=u''): try: @@ -98,19 +113,82 @@ def pbkdf2_hmac_sha256(password,salt,iters=2048): return pbkdf2_hmac_sha256(password=mnemonic_phrase,salt='mnemonic'+passphrase) -def words_mine(prefix,entbits,satisfunction,wordlist=wordlist_english,randombits=random.getrandbits): - prefix_bits=len(prefix)*11 - mine_bits=entbits-prefix_bits - pint=words_to_mnemonic_int(prefix,wordlist) - pint<<=mine_bits - dint=randombits(mine_bits) +def _getrandbits(num_bits): + bytes=(num_bits >> 3) + (1 if (num_bits & 0x7) else 0) + rint=int(binascii.hexlify(secure_random_bytes(bytes)),16) + return rint & ((1 << num_bits)-1) + +def words_generate(num_bits_entropy=128,num_words=None,randombits=_getrandbits,wordlist=wordlists["english"]): + if(num_words is not None and num_words % 3 == 0): + num_bits_entropy=(32*11*num_words) // 33 + rint=randombits(num_bits_entropy) + return entropy_to_words(eint_to_bytes(rint,num_bits_entropy),wordlist) + + +#pattern syntax: a word is (\w*)(?::(\w*))?...but split it first +def words_mine(pattern,valid=lambda x : True ,wordlist=wordlists["english"],randombits=_getrandbits): + if(isinstance(pattern,basestring)): + pattern=pattern.split() + if(len(pattern) % 3 != 0): + raise RuntimeError("The number of words in the pattern must be a multiple of 3") + + rec=re.compile(r'(\w*)(?::(\w*))?') + ranges=[] + + for word in pattern: + m=rec.match(word) + if(not m): + raise RuntimeError("Could not parse pattern word %s" % (word)) + lower=0 + upper=1 << 11 + lw,uw=m.group(1,2) + if(lw): + if(lw != ""): + try: + lower=int(lw) & 0x7FF + except: + lower=next((index for index,value in enumerate(wordlist) if lw <= value)) + if(uw): + if(uw != ""): + try: + upper=int(uw) & 0x7FF + except: + upper=next((index for index,value in enumerate(wordlist) if uw <= value)) + elif(lw): + upper=next((index for index,value in enumerate(wordlist[::-1]) if lw >= value[:len(lw)])) + upper=2048-upper + ranges.append((lower,upper)) + + total_randomness=reduce(lambda a,b: a*(b[1]-b[0]),ranges,1) + + mint_bits=len(pattern)*11 + def gen_mint(rangess,randombitss): + mint=0 + for r in rangess: + mint<<=11 + mint|=r[0] + randombitss(11) % (r[1]-r[0]) + return mint + + tint=gen_mint(ranges,randombits) count=0 - while(not satisfunction(entropy_to_words(eint_to_bytes(pint+dint,entbits)))): - dint=randombits(mine_bits) + + while(not mnemonic_int_verify(tint,mint_bits) or not valid(mnemonic_int_to_words(tint,len(pattern),wordlist))): + tint=gen_mint(ranges,randombits) + + count+=1 if((count & 0xFFFF) == 0): - print("Searched %f percent of the space" % (float(count)/float(1 << mine_bits))) + print("Searched %f percent of the space" % (100.0*float(count)/float(total_randomness))) - return entropy_to_words(eint_to_bytes(pint+dint,entbits)) + return mnemonic_int_to_words(tint,len(pattern),wordlist) + + +def _build_mnemonic_file(): + import urllib2 + mnemonic_languages=["english","japanese","spanish","french","chinese_simplified","chinese_traditional"] + wordlists={} + for la in mnemonic_languages: + wordlists[la]=urllib2.urlopen("https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/%s.txt" % (la)).read().split() + json.dump(wordlists,bz2.BZ2File('wordlists.json.bz2','w')) if __name__=="__main__": import json @@ -119,6 +197,7 @@ def words_mine(prefix,entbits,satisfunction,wordlist=wordlist_english,randombits for v in testvectors['english']: ebytes=binascii.unhexlify(v[0]) w=' '.join(entropy_to_words(ebytes)) + passed=words_verify(w) seed=mnemonic_to_seed(w,passphrase='TREZOR') passed = passed and w==v[1] passed = passed and binascii.hexlify(seed)==v[2] diff --git a/bitcoin/transaction.py b/bitcoin/transaction.py index 9ca546d6..bd31d8ad 100644 --- a/bitcoin/transaction.py +++ b/bitcoin/transaction.py @@ -482,7 +482,6 @@ def select(unspent, value): # Only takes inputs of the form { "output": blah, "value": foo } - def mksend(*args): argz, change, fee = args[:-2], args[-2], int(args[-1]) ins, outs = [], [] diff --git a/bitcoin/wordlists.json.bz2 b/bitcoin/wordlists.json.bz2 new file mode 100644 index 00000000..b2597258 Binary files /dev/null and b/bitcoin/wordlists.json.bz2 differ