Skip to content

Instantly share code, notes, and snippets.

@Steve132
Last active November 9, 2015 23:01
Show Gist options
  • Save Steve132/6ca8289adf43cc400bb6 to your computer and use it in GitHub Desktop.
Save Steve132/6ca8289adf43cc400bb6 to your computer and use it in GitHub Desktop.
Offline BIP039 implementation using your own entropy.
import sys
import hashlib
import argparse
import binascii
import os
import math
def entropy_dice(entropy):
dicesize=int(raw_input("Enter the number of faces each dieroll has (e.g. '6' or '20'): "))
entval=0
rolls=int(math.ceil(float(entropy)*math.log(2.0)/math.log(dicesize)))
for x in range(rolls):
entry=int(raw_input("Enter the value (1-%d) of dice %d/%d: " % (dicesize,x+1,rolls))) % dicesize
entval+=entry
entval*=dicesize
return entval
def entropy_hex(entropy):
return int(raw_input(("Please enter a %d-bit (%d character) hex string:\n") % (entropy,entropy/4)),16)
def entropy_bin(entropy):
return int(raw_input("Please enter a %d-bit binary string:\n") % (entropy),2)
def entropy_generic(entropy):
entval=0
entamount=0
while(entamount < entropy):
print("Entropy so far: %f / %d\n" % (entamount,entropy))
dicesize=int(raw_input("Enter the number of possiblities for the next source: "))
entry=int(raw_input("Enter the value of the next source: ")) % dicesize
entval+=entry
entval*=dicesize
return entval
def entropy_system(entropy):
return int(binascii.hexlify(os.urandom(entropy/8)),16)
entropy_modes={'dice':entropy_dice,'hex':entropy_hex,'bin':entropy_bin,'generic':entropy_generic,'system':entropy_system}
parser=argparse.ArgumentParser(description='Generate a valid offline HD wallet mnemonic from personal entropy')
parser.add_argument('--mode','-m',default='hex',help='Choose the mode of gathering entropy',choices=entropy_modes.keys())
parser.add_argument('--entropy_size','-s',default=128,type=int,help='The number of bits of entropy',choices=[128,160,192,224,256])
parser.add_argument('--wordlist','-w',type=argparse.FileType('r'),help='The 2048 wordlist text file to use',required=True)
args=parser.parse_args()
checksum_size=args.entropy_size//32
wordlist=list(args.wordlist)
entint=entropy_modes[args.mode](args.entropy_size) & (2**args.entropy_size - 1)
entbytes=binascii.unhexlify(hex(entint)[2:].zfill(args.entropy_size//4).strip("L"))
hd=hashlib.sha256(entbytes).hexdigest()
csint=int(hd,16) >> (256-checksum_size)
mnemonic_size=(args.entropy_size+checksum_size)/11
mint=(entint << checksum_size) | csint
backwords=[wordlist[(mint >> (11*x)) & 0x7FF].strip() for x in range(mnemonic_size)]
words=reversed(backwords)
print("Your words are:\n\n")
print(' '.join(words))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment