38 lines
1.1 KiB
Python
38 lines
1.1 KiB
Python
# bip39
|
|
from hashlib import sha256, sha512, pbkdf2_hmac
|
|
import hmac
|
|
from os import path
|
|
import gzip
|
|
|
|
# gen phrase from given entropy bytes
|
|
def genPhrase( ent ):
|
|
assert type( ent ) == bytes, 'Entropy must be a bytes object'
|
|
|
|
entbits = bin( int( ent.hex(), 16 ) )[2:].zfill( len( ent ) * 8 )
|
|
entlen = len( entbits )
|
|
|
|
assert entlen % 32 == 0, 'Entropy must be multiple of 32 bits'
|
|
#assert entlen >= 128 and entlen <= 256, 'Entropy must be in range 128-256 bits'
|
|
|
|
cs = bin( int( sha256( ent ).hexdigest(), 16 ) )[2:].zfill( 256 )[0:entlen // 32]
|
|
entbits += cs
|
|
|
|
with gzip.open( path.join( path.dirname( __file__ ), 'bip39-en.txt.gz' ), 'rt' ) as wf:
|
|
wlist = wf.readlines()
|
|
|
|
mphrase = ''
|
|
# group of 11 bits for each word!
|
|
while len( entbits ) > 0:
|
|
wbits = entbits[:11]
|
|
entbits = entbits[11:] # lpop it off
|
|
mphrase += wlist[int( wbits, 2 )].strip() + ' '
|
|
mphrase = mphrase.rstrip()
|
|
|
|
return mphrase
|
|
|
|
# gen seed bytes from phrase and optional password
|
|
def genSeed( phrase, passwd='' ):
|
|
s = pbkdf2_hmac( 'sha512', phrase.encode('utf-8'), b'mnemonic' + passwd.encode('utf-8'), 2048, 64 )
|
|
return s
|
|
|