Last active
October 16, 2021 10:47
-
-
Save wizardofozzie/5b5c3d0b3ccea2471246 to your computer and use it in GitHub Desktop.
BIP39 codes & words
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import binascii, re, json, copy, sys | |
from binascii import hexlify, unhexlify | |
from bitcoin.main import * | |
# SEE https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki | |
ELECTRUM_ENG_V1_WORDLIST = [ | |
'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'] | |
LEN_ELECTRUM_ENG_V1_WORDLIST = len(ELECTRUM_ENG_V1_WORDLIST) | |
# https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt | |
BIP0039_ENG_WORDLIST = [ | |
'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'] | |
LEN_BIP39_WORDLIST = len(BIP0039_ENG_WORDLIST) | |
def bip39_seed_to_mnemonic(hexseed): | |
""">>>bip39_seed_to_mnemonic('eaebabb2383351fd31d703840b32e9e2') | |
'turtle front uncle idea crush write shrug there lottery flower risk shell'""" | |
if isinstance(hexseed, string_types) and re.match('^[0-9a-fA-F]*$', hexseed): | |
hexseed = from_string_to_bytes(str(hexseed)) | |
else: | |
raise TypeError("Enter a hex seed!") | |
hexseed = unhexlify(str(hexseed)) | |
if len(hexseed) % 4: | |
raise Exception("Seed not a multiple of 4 bytes!") | |
elif len(hexseed) < 4: | |
raise Exception("Seed must be at least 32 bits of entropy") | |
elif len(hexseed) > 124: | |
raise Exception("Seed cannot exceed 992 bits of entropy") | |
checksum_length = int((len(hexseed) * 8) // 32) | |
checksum = sha256(hexseed) | |
hexbin = changebase( hexlify(hexseed), 16, 2, len(hexseed)*8) | |
checksum_bin = changebase( checksum, 16, 2, len(unhexlify(checksum))*8) | |
binstr_final = from_string_to_bytes(str(hexbin) + str(checksum_bin)[:checksum_length]) | |
binlist_words = [binstr_final[i:i+11] for i in range(0,len(binstr_final),11)] | |
return " ".join( [BIP0039_ENG_WORDLIST[int(x,2)] for x in binlist_words ] ) | |
def bip39_mnemonic_to_seed(mnemonic): | |
""">>>bip39_mnemonic_to_seed('board flee heavy tunnel powder denial science ski answer betray cargo cat') | |
'18ab19a9f54a9274f03e5209a2ac8a91'""" | |
if isinstance(mnemonic, string_types): | |
mnemonic = str(from_string_to_bytes(mnemonic)).lower().strip() | |
elif isinstance(mnemonic, list): | |
mnemonic = " ".join(str(from_string_to_bytes(mnemonic))).lower() | |
else: | |
raise TypeError("Enter a lower case, single-spaced mnemonic!") | |
try: | |
mnemonic_array = str(mnemonic).split(" ") | |
if mnemonic_array[0] is '': mnemonic_array.pop(0) | |
except: | |
raise TypeError("Enter a lower case, single-spaced mnemonic!") | |
if not (93 > len(mnemonic_array) > 3): | |
raise TypeError("32 < entropy < 992 bits; Input too big or too small") | |
if len(mnemonic_array) % 3: | |
raise TypeError("Too many or too few words") | |
assert all(map(lambda x: x in BIP0039_ENG_WORDLIST, mnemonic_array)) | |
binstr = ''.join([ changebase(str(BIP0039_ENG_WORDLIST.index(x)), 10, 2, 11) for x in mnemonic_array]) | |
num_checksum_digits = len(binstr) % 32 | |
binary_checksum = binstr[(len(binstr) - num_checksum_digits):] | |
binary_no_checksum = binstr[ : (-1*num_checksum_digits)] | |
hexoutput = hexlify(changebase(binary_no_checksum, 2, 16, len(binary_checksum) * 8)) | |
assert not (len(hexoutput) % 2) | |
checksum_bin = changebase(sha256(unhexlify(hexoutput)), 16, 2, 256) | |
assert checksum_bin[:num_checksum_digits] != binary_checksum | |
return unhexlify(hexoutput) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
from .py2specials import * | |
from .py3specials import * | |
import binascii | |
import hashlib | |
import re | |
import sys | |
import os | |
import base64 | |
import time | |
import random | |
import hmac | |
from bitcoin.ripemd import * | |
# Elliptic curve parameters (secp256k1) | |
P = 2**256 - 2**32 - 977 | |
N = 115792089237316195423570985008687907852837564279074904382605163141518161494337 | |
A = 0 | |
B = 7 | |
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240 | |
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424 | |
G = (Gx, Gy) | |
def change_curve(p, n, a, b, gx, gy): | |
global P, N, A, B, Gx, Gy, G | |
P, N, A, B, Gx, Gy = p, n, a, b, gx, gy | |
G = (Gx, Gy) | |
def getG(): | |
return G | |
# Extended Euclidean Algorithm | |
def inv(a, n): | |
lm, hm = 1, 0 | |
low, high = a % n, n | |
while low > 1: | |
r = high//low | |
nm, new = hm-lm*r, high-low*r | |
lm, low, hm, high = nm, new, lm, low | |
return lm % n | |
# JSON access (for pybtctool convenience) | |
def access(obj, prop): | |
if isinstance(obj, dict): | |
if prop in obj: | |
return obj[prop] | |
elif '.' in prop: | |
return obj[float(prop)] | |
else: | |
return obj[int(prop)] | |
else: | |
return obj[int(prop)] | |
def multiaccess(obj, prop): | |
return [access(o, prop) for o in obj] | |
def slice(obj, start=0, end=2**200): | |
return obj[int(start):int(end)] | |
def count(obj): | |
return len(obj) | |
_sum = sum | |
def sum(obj): | |
return _sum(obj) | |
# Elliptic curve Jordan form functions | |
# P = (m, n, p, q) where m/n = x, p/q = y | |
def isinf(p): | |
return p[0] == 0 and p[1] == 0 | |
def jordan_isinf(p): | |
return p[0][0] == 0 and p[1][0] == 0 | |
def mulcoords(c1, c2): | |
return (c1[0] * c2[0] % P, c1[1] * c2[1] % P) | |
def mul_by_const(c, v): | |
return (c[0] * v % P, c[1]) | |
def addcoords(c1, c2): | |
return ((c1[0] * c2[1] + c2[0] * c1[1]) % P, c1[1] * c2[1] % P) | |
def subcoords(c1, c2): | |
return ((c1[0] * c2[1] - c2[0] * c1[1]) % P, c1[1] * c2[1] % P) | |
def invcoords(c): | |
return (c[1], c[0]) | |
def jordan_add(a, b): | |
if jordan_isinf(a): | |
return b | |
if jordan_isinf(b): | |
return a | |
if (a[0][0] * b[0][1] - b[0][0] * a[0][1]) % P == 0: | |
if (a[1][0] * b[1][1] - b[1][0] * a[1][1]) % P == 0: | |
return jordan_double(a) | |
else: | |
return ((0, 1), (0, 1)) | |
xdiff = subcoords(b[0], a[0]) | |
ydiff = subcoords(b[1], a[1]) | |
m = mulcoords(ydiff, invcoords(xdiff)) | |
x = subcoords(subcoords(mulcoords(m, m), a[0]), b[0]) | |
y = subcoords(mulcoords(m, subcoords(a[0], x)), a[1]) | |
return (x, y) | |
def jordan_double(a): | |
if jordan_isinf(a): | |
return ((0, 1), (0, 1)) | |
num = addcoords(mul_by_const(mulcoords(a[0], a[0]), 3), (A, 1)) | |
den = mul_by_const(a[1], 2) | |
m = mulcoords(num, invcoords(den)) | |
x = subcoords(mulcoords(m, m), mul_by_const(a[0], 2)) | |
y = subcoords(mulcoords(m, subcoords(a[0], x)), a[1]) | |
return (x, y) | |
def jordan_multiply(a, n): | |
if jordan_isinf(a) or n == 0: | |
return ((0, 0), (0, 0)) | |
if n == 1: | |
return a | |
if n < 0 or n >= N: | |
return jordan_multiply(a, n % N) | |
if (n % 2) == 0: | |
return jordan_double(jordan_multiply(a, n//2)) | |
if (n % 2) == 1: | |
return jordan_add(jordan_double(jordan_multiply(a, n//2)), a) | |
def to_jordan(p): | |
return ((p[0], 1), (p[1], 1)) | |
def from_jordan(p): | |
return (p[0][0] * inv(p[0][1], P) % P, p[1][0] * inv(p[1][1], P) % P) | |
return (p[0][0] * inv(p[0][1], P) % P, p[1][0] * inv(p[1][1], P) % P) | |
def fast_multiply(a, n): | |
return from_jordan(jordan_multiply(to_jordan(a), n)) | |
def fast_add(a, b): | |
return from_jordan(jordan_add(to_jordan(a), to_jordan(b))) | |
# Functions for handling pubkey and privkey formats | |
def get_pubkey_format(pub): | |
if is_python2: | |
two = '\x02' | |
three = '\x03' | |
four = '\x04' | |
else: | |
two = 2 | |
three = 3 | |
four = 4 | |
if isinstance(pub, (tuple, list)): return 'decimal' | |
elif len(pub) == 65 and pub[0] == four: return 'bin' | |
elif len(pub) == 130 and pub[0:2] == '04': return 'hex' | |
elif len(pub) == 33 and pub[0] in [two, three]: return 'bin_compressed' | |
elif len(pub) == 66 and pub[0:2] in ['02', '03']: return 'hex_compressed' | |
elif len(pub) == 64: return 'bin_electrum' | |
elif len(pub) == 128: return 'hex_electrum' | |
else: raise Exception("Pubkey not in recognized format") | |
def encode_pubkey(pub, formt): | |
if not isinstance(pub, (tuple, list)): | |
pub = decode_pubkey(pub) | |
if formt == 'decimal': return pub | |
elif formt == 'bin': return b'\x04' + encode(pub[0], 256, 32) + encode(pub[1], 256, 32) | |
elif formt == 'bin_compressed': | |
return from_int_to_byte(2+(pub[1] % 2)) + encode(pub[0], 256, 32) | |
elif formt == 'hex': return '04' + encode(pub[0], 16, 64) + encode(pub[1], 16, 64) | |
elif formt == 'hex_compressed': | |
return '0'+str(2+(pub[1] % 2)) + encode(pub[0], 16, 64) | |
elif formt == 'bin_electrum': return encode(pub[0], 256, 32) + encode(pub[1], 256, 32) | |
elif formt == 'hex_electrum': return encode(pub[0], 16, 64) + encode(pub[1], 16, 64) | |
else: raise Exception("Invalid format!") | |
def decode_pubkey(pub, formt=None): | |
if not formt: formt = get_pubkey_format(pub) | |
if formt == 'decimal': return pub | |
elif formt == 'bin': return (decode(pub[1:33], 256), decode(pub[33:65], 256)) | |
elif formt == 'bin_compressed': | |
x = decode(pub[1:33], 256) | |
beta = pow(int(x*x*x+A*x+B), int((P+1)//4), int(P)) | |
y = (P-beta) if ((beta + from_byte_to_int(pub[0])) % 2) else beta | |
return (x, y) | |
elif formt == 'hex': return (decode(pub[2:66], 16), decode(pub[66:130], 16)) | |
elif formt == 'hex_compressed': | |
return decode_pubkey(safe_from_hex(pub), 'bin_compressed') | |
elif formt == 'bin_electrum': | |
return (decode(pub[:32], 256), decode(pub[32:64], 256)) | |
elif formt == 'hex_electrum': | |
return (decode(pub[:64], 16), decode(pub[64:128], 16)) | |
else: raise Exception("Invalid format!") | |
def get_privkey_format(priv): | |
if isinstance(priv, int_types): return 'decimal' | |
elif len(priv) == 32: return 'bin' | |
elif len(priv) == 33: return 'bin_compressed' | |
elif len(priv) == 64: return 'hex' | |
elif len(priv) == 66: return 'hex_compressed' | |
else: | |
bin_p = b58check_to_bin(priv) | |
if len(bin_p) == 32: return 'wif' | |
elif len(bin_p) == 33: return 'wif_compressed' | |
else: raise Exception("WIF does not represent privkey") | |
def encode_privkey(priv, formt, vbyte=0): | |
if not isinstance(priv, int_types): | |
return encode_privkey(decode_privkey(priv), formt, vbyte) | |
if formt == 'decimal': return priv | |
elif formt == 'bin': return encode(priv, 256, 32) | |
elif formt == 'bin_compressed': return encode(priv, 256, 32)+b'\x01' | |
elif formt == 'hex': return encode(priv, 16, 64) | |
elif formt == 'hex_compressed': return encode(priv, 16, 64)+'01' | |
elif formt == 'wif': | |
return bin_to_b58check(encode(priv, 256, 32), 128+int(vbyte)) | |
elif formt == 'wif_compressed': | |
return bin_to_b58check(encode(priv, 256, 32)+b'\x01', 128+int(vbyte)) | |
else: raise Exception("Invalid format!") | |
def decode_privkey(priv,formt=None): | |
if not formt: formt = get_privkey_format(priv) | |
if formt == 'decimal': return priv | |
elif formt == 'bin': return decode(priv, 256) | |
elif formt == 'bin_compressed': return decode(priv[:32], 256) | |
elif formt == 'hex': return decode(priv, 16) | |
elif formt == 'hex_compressed': return decode(priv[:64], 16) | |
elif formt == 'wif': return decode(b58check_to_bin(priv),256) | |
elif formt == 'wif_compressed': | |
return decode(b58check_to_bin(priv)[:32],256) | |
else: raise Exception("WIF does not represent privkey") | |
def add_pubkeys(p1, p2): | |
f1, f2 = get_pubkey_format(p1), get_pubkey_format(p2) | |
return encode_pubkey(fast_add(decode_pubkey(p1, f1), decode_pubkey(p2, f2)), f1) | |
def add_privkeys(p1, p2): | |
f1, f2 = get_privkey_format(p1), get_privkey_format(p2) | |
return encode_privkey((decode_privkey(p1, f1) + decode_privkey(p2, f2)) % N, f1) | |
def multiply(pubkey, privkey): | |
f1, f2 = get_pubkey_format(pubkey), get_privkey_format(privkey) | |
pubkey, privkey = decode_pubkey(pubkey, f1), decode_privkey(privkey, f2) | |
# http://safecurves.cr.yp.to/twist.html | |
if not isinf(pubkey) and (pubkey[0]**3+B-pubkey[1]*pubkey[1]) % P != 0: | |
raise Exception("Point not on curve") | |
return encode_pubkey(fast_multiply(pubkey, privkey), f1) | |
def divide(pubkey, privkey): | |
factor = inv(decode_privkey(privkey), N) | |
return multiply(pubkey, factor) | |
def compress(pubkey): | |
f = get_pubkey_format(pubkey) | |
if 'compressed' in f: return pubkey | |
elif f == 'bin': return encode_pubkey(decode_pubkey(pubkey, f), 'bin_compressed') | |
elif f == 'hex' or f == 'decimal': | |
return encode_pubkey(decode_pubkey(pubkey, f), 'hex_compressed') | |
def decompress(pubkey): | |
f = get_pubkey_format(pubkey) | |
if 'compressed' not in f: return pubkey | |
elif f == 'bin_compressed': return encode_pubkey(decode_pubkey(pubkey, f), 'bin') | |
elif f == 'hex_compressed' or f == 'decimal': | |
return encode_pubkey(decode_pubkey(pubkey, f), 'hex') | |
def privkey_to_pubkey(privkey): | |
f = get_privkey_format(privkey) | |
privkey = decode_privkey(privkey, f) | |
if privkey >= N: | |
raise Exception("Invalid privkey") | |
if f in ['bin', 'bin_compressed', 'hex', 'hex_compressed', 'decimal']: | |
return encode_pubkey(fast_multiply(G, privkey), f) | |
else: | |
return encode_pubkey(fast_multiply(G, privkey), f.replace('wif', 'hex')) | |
privtopub = privkey_to_pubkey | |
def privkey_to_address(priv, magicbyte=0): | |
return pubkey_to_address(privkey_to_pubkey(priv), magicbyte) | |
privtoaddr = privkey_to_address | |
def neg_pubkey(pubkey): | |
f = get_pubkey_format(pubkey) | |
pubkey = decode_pubkey(pubkey, f) | |
return encode_pubkey((pubkey[0], (P-pubkey[1]) % P), f) | |
def neg_privkey(privkey): | |
f = get_privkey_format(privkey) | |
privkey = decode_privkey(privkey, f) | |
return encode_privkey((N - privkey) % N, f) | |
def subtract_pubkeys(p1, p2): | |
f1, f2 = get_pubkey_format(p1), get_pubkey_format(p2) | |
k2 = decode_pubkey(p2, f2) | |
return encode_pubkey(fast_add(decode_pubkey(p1, f1), (k2[0], (P - k2[1]) % P)), f1) | |
def subtract_privkeys(p1, p2): | |
f1, f2 = get_privkey_format(p1), get_privkey_format(p2) | |
k2 = decode_privkey(p2, f2) | |
return encode_privkey((decode_privkey(p1, f1) - k2) % N, f1) | |
# Hashes | |
def bin_hash160(string): | |
intermed = hashlib.sha256(string).digest() | |
digest = '' | |
try: | |
digest = hashlib.new('ripemd160', intermed).digest() | |
except: | |
digest = RIPEMD160(intermed).digest() | |
return digest | |
def hash160(string): | |
return safe_hexlify(bin_hash160(string)) | |
def bin_sha256(string): | |
binary_data = string if isinstance(string, bytes) else bytes(string, 'utf-8') | |
return hashlib.sha256(binary_data).digest() | |
def sha256(string): | |
return bytes_to_hex_string(bin_sha256(string)) | |
def bin_ripemd160(string): | |
try: | |
digest = hashlib.new('ripemd160', string).digest() | |
except: | |
digest = RIPEMD160(string).digest() | |
return digest | |
def ripemd160(string): | |
return safe_hexlify(bin_ripemd160(string)) | |
def bin_dbl_sha256(s): | |
bytes_to_hash = from_string_to_bytes(s) | |
return hashlib.sha256(hashlib.sha256(bytes_to_hash).digest()).digest() | |
def dbl_sha256(string): | |
return safe_hexlify(bin_dbl_sha256(string)) | |
def bin_slowsha(string): | |
string = from_string_to_bytes(string) | |
orig_input = string | |
for i in range(100000): | |
string = hashlib.sha256(string + orig_input).digest() | |
return string | |
def slowsha(string): | |
return safe_hexlify(bin_slowsha(string)) | |
def hash_to_int(x): | |
if len(x) in [40, 64]: | |
return decode(x, 16) | |
return decode(x, 256) | |
def num_to_var_int(x): | |
x = int(x) | |
if x < 253: return from_int_to_byte(x) | |
elif x < 65536: return from_int_to_byte(253)+encode(x, 256, 2)[::-1] | |
elif x < 4294967296: return from_int_to_byte(254) + encode(x, 256, 4)[::-1] | |
else: return from_int_to_byte(255) + encode(x, 256, 8)[::-1] | |
# WTF, Electrum? | |
def electrum_sig_hash(message): | |
padded = b"\x18Bitcoin Signed Message:\n" + num_to_var_int(len(message)) + from_string_to_bytes(message) | |
return bin_dbl_sha256(padded) | |
def random_key(): | |
# Gotta be secure after that java.SecureRandom fiasco... | |
entropy = random_string(32) \ | |
+ str(random.randrange(2**256)) \ | |
+ str(int(time.time() * 1000000)) | |
return sha256(entropy) | |
def random_electrum_seed(): | |
entropy = os.urandom(32) \ | |
+ str(random.randrange(2**256)) \ | |
+ str(int(time.time() * 1000000)) | |
return sha256(entropy)[:32] | |
# Encodings | |
def b58check_to_bin(inp): | |
leadingzbytes = len(re.match('^1*', inp).group(0)) | |
data = b'\x00' * leadingzbytes + changebase(inp, 58, 256) | |
assert bin_dbl_sha256(data[:-4])[:4] == data[-4:] | |
return data[1:-4] | |
def get_version_byte(inp): | |
leadingzbytes = len(re.match('^1*', inp).group(0)) | |
data = b'\x00' * leadingzbytes + changebase(inp, 58, 256) | |
assert bin_dbl_sha256(data[:-4])[:4] == data[-4:] | |
return ord(data[0]) | |
def hex_to_b58check(inp, magicbyte=0): | |
return bin_to_b58check(binascii.unhexlify(inp), magicbyte) | |
def b58check_to_hex(inp): | |
return safe_hexlify(b58check_to_bin(inp)) | |
def pubkey_to_address(pubkey, magicbyte=0): | |
if isinstance(pubkey, (list, tuple)): | |
pubkey = encode_pubkey(pubkey, 'bin') | |
if len(pubkey) in [66, 130]: | |
return bin_to_b58check( | |
bin_hash160(binascii.unhexlify(pubkey)), magicbyte) | |
return bin_to_b58check(bin_hash160(pubkey), magicbyte) | |
pubtoaddr = pubkey_to_address | |
# EDCSA | |
def encode_sig(v, r, s): | |
vb, rb, sb = from_int_to_byte(v), encode(r, 256), encode(s, 256) | |
result = base64.b64encode(vb+b'\x00'*(32-len(rb))+rb+b'\x00'*(32-len(sb))+sb) | |
return result if is_python2 else str(result, 'utf-8') | |
def decode_sig(sig): | |
bytez = base64.b64decode(sig) | |
return from_byte_to_int(bytez[0]), decode(bytez[1:33], 256), decode(bytez[33:], 256) | |
# https://tools.ietf.org/html/rfc6979#section-3.2 | |
def deterministic_generate_k(msghash, priv): | |
v = b'\x01' * 32 | |
k = b'\x00' * 32 | |
priv = encode_privkey(priv, 'bin') | |
msghash = encode(hash_to_int(msghash), 256, 32) | |
k = hmac.new(k, v+b'\x00'+priv+msghash, hashlib.sha256).digest() | |
v = hmac.new(k, v, hashlib.sha256).digest() | |
k = hmac.new(k, v+b'\x01'+priv+msghash, hashlib.sha256).digest() | |
v = hmac.new(k, v, hashlib.sha256).digest() | |
return decode(hmac.new(k, v, hashlib.sha256).digest(), 256) | |
def ecdsa_raw_sign(msghash, priv): | |
z = hash_to_int(msghash) | |
k = deterministic_generate_k(msghash, priv) | |
r, y = fast_multiply(G, k) | |
s = inv(k, N) * (z + r*decode_privkey(priv)) % N | |
return 27+(y % 2), r, s | |
def ecdsa_sign(msg, priv): | |
return encode_sig(*ecdsa_raw_sign(electrum_sig_hash(msg), priv)) | |
def ecdsa_raw_verify(msghash, vrs, pub): | |
v, r, s = vrs | |
w = inv(s, N) | |
z = hash_to_int(msghash) | |
u1, u2 = z*w % N, r*w % N | |
x, y = fast_add(fast_multiply(G, u1), fast_multiply(decode_pubkey(pub), u2)) | |
return r == x | |
def ecdsa_verify(msg, sig, pub): | |
return ecdsa_raw_verify(electrum_sig_hash(msg), decode_sig(sig), pub) | |
def ecdsa_raw_recover(msghash, vrs): | |
v, r, s = vrs | |
x = r | |
beta = pow(x*x*x+A*x+B, (P+1)//4, P) | |
y = beta if v % 2 ^ beta % 2 else (P - beta) | |
z = hash_to_int(msghash) | |
Gz = jordan_multiply(((Gx, 1), (Gy, 1)), (N - z) % N) | |
XY = jordan_multiply(((x, 1), (y, 1)), s) | |
Qr = jordan_add(Gz, XY) | |
Q = jordan_multiply(Qr, inv(r, N)) | |
Q = from_jordan(Q) | |
if ecdsa_raw_verify(msghash, vrs, Q): | |
return Q | |
return False | |
def ecdsa_recover(msg, sig): | |
return encode_pubkey(ecdsa_raw_recover(electrum_sig_hash(msg), decode_sig(sig)), 'hex') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, re | |
import binascii | |
import os | |
import hashlib | |
if sys.version_info.major == 2: | |
string_types = (str, unicode) | |
string_or_bytes_types = string_types | |
int_types = (int, float, long) | |
# Base switching | |
code_strings = { | |
2: '01', | |
10: '0123456789', | |
16: '0123456789abcdef', | |
32: 'abcdefghijklmnopqrstuvwxyz234567', | |
58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz', | |
256: ''.join([chr(x) for x in range(256)]) | |
} | |
def bin_dbl_sha256(s): | |
bytes_to_hash = from_string_to_bytes(s) | |
return hashlib.sha256(hashlib.sha256(bytes_to_hash).digest()).digest() | |
def lpad(msg, symbol, length): | |
if len(msg) >= length: | |
return msg | |
return symbol * (length - len(msg)) + msg | |
def get_code_string(base): | |
if base in code_strings: | |
return code_strings[base] | |
else: | |
raise ValueError("Invalid base!") | |
def changebase(string, frm, to, minlen=0): | |
if frm == to: | |
return lpad(string, get_code_string(frm)[0], minlen) | |
return encode(decode(string, frm), to, minlen) | |
def bin_to_b58check(inp, magicbyte=0): | |
inp_fmtd = chr(int(magicbyte)) + inp | |
leadingzbytes = len(re.match('^\x00*', inp_fmtd).group(0)) | |
checksum = bin_dbl_sha256(inp_fmtd)[:4] | |
return '1' * leadingzbytes + changebase(inp_fmtd+checksum, 256, 58) | |
def bytes_to_hex_string(b): | |
return b.encode('hex') | |
def safe_from_hex(s): | |
return s.decode('hex') | |
def from_int_representation_to_bytes(a): | |
return str(a) | |
def from_int_to_byte(a): | |
return chr(a) | |
def from_byte_to_int(a): | |
return ord(a) | |
def from_bytes_to_string(s): | |
return s | |
def from_string_to_bytes(a): | |
return a | |
def safe_hexlify(a): | |
return binascii.hexlify(a) | |
def encode(val, base, minlen=0): | |
base, minlen = int(base), int(minlen) | |
code_string = get_code_string(base) | |
result = "" | |
while val > 0: | |
result = code_string[val % base] + result | |
val //= base | |
return code_string[0] * max(minlen - len(result), 0) + result | |
def decode(string, base): | |
base = int(base) | |
code_string = get_code_string(base) | |
result = 0 | |
if base == 16: | |
string = string.lower() | |
while len(string) > 0: | |
result *= base | |
result += code_string.find(string[0]) | |
string = string[1:] | |
return result | |
def random_string(x): | |
return os.urandom(x) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment