py3
This commit is contained in:
@@ -28,15 +28,15 @@ import struct
|
||||
|
||||
from unicodedata import normalize
|
||||
|
||||
from version import *
|
||||
import bitcoin
|
||||
from bitcoin import pw_encode, pw_decode, bip32_root, bip32_private_derivation, bip32_public_derivation, bip32_private_key, deserialize_xprv, deserialize_xpub
|
||||
from bitcoin import public_key_from_private_key, public_key_to_p2pkh
|
||||
from bitcoin import *
|
||||
from .version import *
|
||||
from . import bitcoin
|
||||
from .bitcoin import pw_encode, pw_decode, bip32_root, bip32_private_derivation, bip32_public_derivation, bip32_private_key, deserialize_xprv, deserialize_xpub
|
||||
from .bitcoin import public_key_from_private_key, public_key_to_p2pkh
|
||||
from .bitcoin import *
|
||||
|
||||
from bitcoin import is_old_seed, is_new_seed, is_seed
|
||||
from util import PrintError, InvalidPassword
|
||||
from mnemonic import Mnemonic, load_wordlist
|
||||
from .bitcoin import is_old_seed, is_new_seed, is_seed
|
||||
from .util import PrintError, InvalidPassword
|
||||
from .mnemonic import Mnemonic, load_wordlist
|
||||
|
||||
|
||||
class KeyStore(PrintError):
|
||||
@@ -170,7 +170,7 @@ class Imported_KeyStore(Software_KeyStore):
|
||||
# fixme: this assumes p2pkh
|
||||
_, addr = xpubkey_to_address(x_pubkey)
|
||||
for pubkey in self.keypairs.keys():
|
||||
if public_key_to_p2pkh(pubkey.decode('hex')) == addr:
|
||||
if public_key_to_p2pkh(bfh(pubkey)) == addr:
|
||||
return pubkey
|
||||
|
||||
def update_password(self, old_password, new_password):
|
||||
@@ -247,22 +247,22 @@ class Xpub:
|
||||
_, _, _, _, c, cK = deserialize_xpub(xpub)
|
||||
for i in sequence:
|
||||
cK, c = CKD_pub(cK, c, i)
|
||||
return cK.encode('hex')
|
||||
return bh2u(cK)
|
||||
|
||||
def get_xpubkey(self, c, i):
|
||||
s = ''.join(map(lambda x: bitcoin.int_to_hex(x,2), (c, i)))
|
||||
return 'ff' + bitcoin.DecodeBase58Check(self.xpub).encode('hex') + s
|
||||
return 'ff' + bh2u(bitcoin.DecodeBase58Check(self.xpub)) + s
|
||||
|
||||
@classmethod
|
||||
def parse_xpubkey(self, pubkey):
|
||||
assert pubkey[0:2] == 'ff'
|
||||
pk = pubkey.decode('hex')
|
||||
pk = bfh(pubkey)
|
||||
pk = pk[1:]
|
||||
xkey = bitcoin.EncodeBase58Check(pk[0:78])
|
||||
dd = pk[78:]
|
||||
s = []
|
||||
while dd:
|
||||
n = int(bitcoin.rev_hex(dd[0:2].encode('hex')), 16)
|
||||
n = int(bitcoin.rev_hex(bh2u(dd[0:2])), 16)
|
||||
dd = dd[2:]
|
||||
s.append(n)
|
||||
assert len(s) == 2
|
||||
@@ -277,7 +277,6 @@ class Xpub:
|
||||
return derivation
|
||||
|
||||
|
||||
|
||||
class BIP32_KeyStore(Deterministic_KeyStore, Xpub):
|
||||
|
||||
def __init__(self, d):
|
||||
@@ -363,12 +362,12 @@ class Old_KeyStore(Deterministic_KeyStore):
|
||||
self.mpk = mpk
|
||||
|
||||
def format_seed(self, seed):
|
||||
import old_mnemonic
|
||||
from . import old_mnemonic
|
||||
# see if seed was entered as hex
|
||||
seed = seed.strip()
|
||||
if seed:
|
||||
try:
|
||||
seed.decode('hex')
|
||||
bfh(seed)
|
||||
return str(seed)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -379,7 +378,7 @@ class Old_KeyStore(Deterministic_KeyStore):
|
||||
return seed
|
||||
|
||||
def get_seed(self, password):
|
||||
import old_mnemonic
|
||||
from . import old_mnemonic
|
||||
s = self.get_hex_seed(password)
|
||||
return ' '.join(old_mnemonic.mn_encode(s))
|
||||
|
||||
@@ -388,7 +387,7 @@ class Old_KeyStore(Deterministic_KeyStore):
|
||||
secexp = klass.stretch_key(seed)
|
||||
master_private_key = ecdsa.SigningKey.from_secret_exponent(secexp, curve = SECP256k1)
|
||||
master_public_key = master_private_key.get_verifying_key().to_string()
|
||||
return master_public_key.encode('hex')
|
||||
return bh2u(master_public_key)
|
||||
|
||||
@classmethod
|
||||
def stretch_key(self, seed):
|
||||
@@ -399,20 +398,20 @@ class Old_KeyStore(Deterministic_KeyStore):
|
||||
|
||||
@classmethod
|
||||
def get_sequence(self, mpk, for_change, n):
|
||||
return string_to_number(Hash("%d:%d:"%(n, for_change) + mpk.decode('hex')))
|
||||
return string_to_number(Hash(("%d:%d:"%(n, for_change)).encode('ascii') + bfh(mpk)))
|
||||
|
||||
def get_address(self, for_change, n):
|
||||
pubkey = self.get_pubkey(for_change, n)
|
||||
address = public_key_to_p2pkh(pubkey.decode('hex'))
|
||||
address = public_key_to_p2pkh(bfh(pubkey))
|
||||
return address
|
||||
|
||||
@classmethod
|
||||
def get_pubkey_from_mpk(self, mpk, for_change, n):
|
||||
z = self.get_sequence(mpk, for_change, n)
|
||||
master_public_key = ecdsa.VerifyingKey.from_string(mpk.decode('hex'), curve = SECP256k1)
|
||||
master_public_key = ecdsa.VerifyingKey.from_string(bfh(mpk), curve = SECP256k1)
|
||||
pubkey_point = master_public_key.pubkey.point + z*SECP256k1.generator
|
||||
public_key2 = ecdsa.VerifyingKey.from_public_point(pubkey_point, curve = SECP256k1)
|
||||
return '04' + public_key2.to_string().encode('hex')
|
||||
return '04' + bh2u(public_key2.to_string())
|
||||
|
||||
def derive_pubkey(self, for_change, n):
|
||||
return self.get_pubkey_from_mpk(self.mpk, for_change, n)
|
||||
@@ -436,8 +435,8 @@ class Old_KeyStore(Deterministic_KeyStore):
|
||||
secexp = self.stretch_key(seed)
|
||||
master_private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
|
||||
master_public_key = master_private_key.get_verifying_key().to_string()
|
||||
if master_public_key != self.mpk.decode('hex'):
|
||||
print_error('invalid password (mpk)', self.mpk, master_public_key.encode('hex'))
|
||||
if master_public_key != bfh(self.mpk):
|
||||
print_error('invalid password (mpk)', self.mpk, bh2u(master_public_key))
|
||||
raise InvalidPassword()
|
||||
|
||||
def check_password(self, password):
|
||||
@@ -590,17 +589,20 @@ def bip39_is_checksum_valid(mnemonic):
|
||||
def is_xpubkey(x_pubkey):
|
||||
return x_pubkey[0:2] == 'ff'
|
||||
|
||||
|
||||
def parse_xpubkey(x_pubkey):
|
||||
assert x_pubkey[0:2] == 'ff'
|
||||
return BIP32_KeyStore.parse_xpubkey(x_pubkey)
|
||||
|
||||
|
||||
def xpubkey_to_address(x_pubkey):
|
||||
if x_pubkey[0:2] == 'fd':
|
||||
addrtype = ord(x_pubkey[2:4].decode('hex'))
|
||||
hash160 = x_pubkey[4:].decode('hex')
|
||||
# TODO: check that ord() is OK here
|
||||
addrtype = ord(bfh(x_pubkey[2:4]))
|
||||
hash160 = bfh(x_pubkey[4:])
|
||||
address = bitcoin.hash_160_to_bc_address(hash160, addrtype)
|
||||
return x_pubkey, address
|
||||
if x_pubkey[0:2] in ['02','03','04']:
|
||||
if x_pubkey[0:2] in ['02', '03', '04']:
|
||||
pubkey = x_pubkey
|
||||
elif x_pubkey[0:2] == 'ff':
|
||||
xpub, s = BIP32_KeyStore.parse_xpubkey(x_pubkey)
|
||||
@@ -611,7 +613,7 @@ def xpubkey_to_address(x_pubkey):
|
||||
else:
|
||||
raise BaseException("Cannot parse pubkey")
|
||||
if pubkey:
|
||||
address = public_key_to_p2pkh(pubkey.decode('hex'))
|
||||
address = public_key_to_p2pkh(bfh(pubkey))
|
||||
return pubkey, address
|
||||
|
||||
def xpubkey_to_pubkey(x_pubkey):
|
||||
@@ -649,7 +651,6 @@ def load_keystore(storage, name):
|
||||
return k
|
||||
|
||||
|
||||
|
||||
def is_old_mpk(mpk):
|
||||
try:
|
||||
int(mpk, 16)
|
||||
@@ -657,10 +658,12 @@ def is_old_mpk(mpk):
|
||||
return False
|
||||
return len(mpk) == 128
|
||||
|
||||
|
||||
def is_address_list(text):
|
||||
parts = text.split()
|
||||
return bool(parts) and all(bitcoin.is_address(x) for x in parts)
|
||||
|
||||
|
||||
def get_private_keys(text):
|
||||
parts = text.split('\n')
|
||||
parts = map(lambda x: ''.join(x.split()), parts)
|
||||
@@ -668,15 +671,18 @@ def get_private_keys(text):
|
||||
if bool(parts) and all(bitcoin.is_private_key(x) for x in parts):
|
||||
return parts
|
||||
|
||||
|
||||
def is_private_key_list(text):
|
||||
return bool(get_private_keys(text))
|
||||
|
||||
|
||||
is_mpk = lambda x: is_old_mpk(x) or is_xpub(x)
|
||||
is_private = lambda x: is_seed(x) or is_xprv(x) or is_private_key_list(x)
|
||||
is_any_key = lambda x: is_old_mpk(x) or is_xprv(x) or is_xpub(x) or is_private_key_list(x)
|
||||
is_private_key = lambda x: is_xprv(x) or is_private_key_list(x)
|
||||
is_bip32_key = lambda x: is_xprv(x) or is_xpub(x)
|
||||
|
||||
|
||||
def bip44_derivation(account_id):
|
||||
if bitcoin.TESTNET:
|
||||
return "m/44'/1'/%d'"% int(account_id)
|
||||
|
||||
Reference in New Issue
Block a user