bip39
This commit is contained in:
parent
98ae202d80
commit
c90bc6aa26
|
@ -62,9 +62,14 @@ def Hash(x):
|
||||||
|
|
||||||
hash_encode = lambda x: x[::-1].encode('hex')
|
hash_encode = lambda x: x[::-1].encode('hex')
|
||||||
hash_decode = lambda x: x.decode('hex')[::-1]
|
hash_decode = lambda x: x.decode('hex')[::-1]
|
||||||
|
|
||||||
hmac_sha_512 = lambda x,y: hmac.new(x, y, hashlib.sha512).digest()
|
hmac_sha_512 = lambda x,y: hmac.new(x, y, hashlib.sha512).digest()
|
||||||
mnemonic_hash = lambda x: hmac_sha_512("Bitcoin mnemonic", x).encode('hex')
|
|
||||||
|
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)
|
||||||
|
|
||||||
from version import SEED_PREFIX
|
from version import SEED_PREFIX
|
||||||
is_seed = lambda x: hmac_sha_512("Seed version", x).encode('hex')[0:2].startswith(SEED_PREFIX)
|
is_seed = lambda x: hmac_sha_512("Seed version", x).encode('hex')[0:2].startswith(SEED_PREFIX)
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,9 @@ class WalletStorage:
|
||||||
os.chmod(self.path,stat.S_IREAD | stat.S_IWRITE)
|
os.chmod(self.path,stat.S_IREAD | stat.S_IWRITE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Wallet:
|
class Wallet:
|
||||||
|
|
||||||
def __init__(self, storage):
|
def __init__(self, storage):
|
||||||
|
@ -179,12 +182,6 @@ class Wallet:
|
||||||
|
|
||||||
self.next_addresses = storage.get('next_addresses',{})
|
self.next_addresses = storage.get('next_addresses',{})
|
||||||
|
|
||||||
if self.seed_version not in [4, 6]:
|
|
||||||
msg = "This wallet seed is not supported."
|
|
||||||
if self.seed_version in [5]:
|
|
||||||
msg += "\nTo open this wallet, try 'git checkout seed_v%d'"%self.seed_version
|
|
||||||
print msg
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# This attribute is set when wallet.start_threads is called.
|
# This attribute is set when wallet.start_threads is called.
|
||||||
self.synchronizer = None
|
self.synchronizer = None
|
||||||
|
@ -297,7 +294,7 @@ class Wallet:
|
||||||
|
|
||||||
|
|
||||||
def init_seed(self, seed):
|
def init_seed(self, seed):
|
||||||
import mnemonic
|
import mnemonic, unicodedata
|
||||||
|
|
||||||
if self.seed:
|
if self.seed:
|
||||||
raise Exception("a seed exists")
|
raise Exception("a seed exists")
|
||||||
|
@ -307,6 +304,10 @@ class Wallet:
|
||||||
self.seed_version = SEED_VERSION
|
self.seed_version = SEED_VERSION
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.seed_version = SEED_VERSION
|
||||||
|
self.seed = unicodedata.normalize('NFC', unicode(seed.strip()))
|
||||||
|
return
|
||||||
|
|
||||||
# find out what kind of wallet we are
|
# find out what kind of wallet we are
|
||||||
try:
|
try:
|
||||||
seed.strip().decode('hex')
|
seed.strip().decode('hex')
|
||||||
|
@ -682,14 +683,13 @@ class Wallet:
|
||||||
return '&'.join(dd)
|
return '&'.join(dd)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_seed(self, password):
|
def get_seed(self, password):
|
||||||
s = pw_decode(self.seed, password)
|
s = pw_decode(self.seed, password)
|
||||||
if self.seed_version == 4:
|
if self.seed_version == 4:
|
||||||
seed = s
|
seed = s
|
||||||
self.accounts[0].check_seed(seed)
|
self.accounts[0].check_seed(seed)
|
||||||
else:
|
else:
|
||||||
seed = mnemonic_hash(s)
|
seed = mnemonic_to_seed(s,'').encode('hex')
|
||||||
return seed
|
return seed
|
||||||
|
|
||||||
|
|
||||||
|
@ -702,7 +702,6 @@ class Wallet:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_private_key(self, address, password):
|
def get_private_key(self, address, password):
|
||||||
if self.is_watching_only():
|
if self.is_watching_only():
|
||||||
return []
|
return []
|
||||||
|
@ -1763,3 +1762,5 @@ class WalletSynchronizer(threading.Thread):
|
||||||
# Updated gets called too many times from other places as well; if we use that signal we get the notification three times
|
# Updated gets called too many times from other places as well; if we use that signal we get the notification three times
|
||||||
self.network.trigger_callback("new_transaction")
|
self.network.trigger_callback("new_transaction")
|
||||||
self.was_updated = False
|
self.was_updated = False
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue