URI: 
       tfix #2133: deserialize_xkey - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 132fca86b2c4fd594bdfa8ec47987d9a9625c3f3
   DIR parent f2b208429d8fbb1019ddf64a2089f0cc0ba5e8be
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Mon, 23 Jan 2017 20:49:26 +0100
       
       fix #2133: deserialize_xkey
       
       Diffstat:
         M lib/bitcoin.py                      |      33 ++++++++++++-------------------
         M lib/keystore.py                     |      16 ++++++----------
         M plugins/cosigner_pool/qt.py         |       4 ++--
         M plugins/trustedcoin/trustedcoin.py  |       7 +++----
       
       4 files changed, 24 insertions(+), 36 deletions(-)
       ---
   DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py
       t@@ -727,37 +727,30 @@ def _CKD_pub(cK, c, s):
            return cK_n, c_n
        
        
       -def deserialize_xkey(xkey):
       +def deserialize_xkey(xkey, prv):
       +    header = XPRV_HEADER if prv else XPUB_HEADER
            xkey = DecodeBase58Check(xkey)
            assert len(xkey) == 78
            depth = ord(xkey[4])
            fingerprint = xkey[5:9]
            child_number = xkey[9:13]
            c = xkey[13:13+32]
       -    if xkey[0:4].encode('hex') == XPRV_HEADER:
       -        K_or_k = xkey[13+33:]
       +    if xkey[0:4].encode('hex') == header:
       +        n = 33 if prv else 32
       +        K_or_k = xkey[13+n:]
            else:
       -        K_or_k = xkey[13+32:]
       +        raise BaseException('wrong key')
            return depth, fingerprint, child_number, c, K_or_k
        
       +def deserialize_xpub(xkey):
       +    return deserialize_xkey(xkey, False)
        
       -def get_xkey_name(xkey):
       -    depth, fingerprint, child_number, c, K = deserialize_xkey(xkey)
       -    n = int(child_number.encode('hex'), 16)
       -    if n & BIP32_PRIME:
       -        child_id = "%d'"%(n - BIP32_PRIME)
       -    else:
       -        child_id = "%d"%n
       -    if depth == 0:
       -        return ''
       -    elif depth == 1:
       -        return child_id
       -    else:
       -        raise BaseException("xpub depth error")
       +def deserialize_xprv(xkey):
       +    return deserialize_xkey(xkey, True)
        
        
        def xpub_from_xprv(xprv):
       -    depth, fingerprint, child_number, c, k = deserialize_xkey(xprv)
       +    depth, fingerprint, child_number, c, k = deserialize_xprv(xprv)
            K, cK = get_pubkeys_from_secret(k)
            xpub = XPUB_HEADER.decode('hex') + chr(depth) + fingerprint + child_number + c + cK
            return EncodeBase58Check(xpub)
       t@@ -784,7 +777,7 @@ def bip32_private_derivation(xprv, branch, sequence):
            assert sequence.startswith(branch)
            if branch == sequence:
                return xprv, xpub_from_xprv(xprv)
       -    depth, fingerprint, child_number, c, k = deserialize_xkey(xprv)
       +    depth, fingerprint, child_number, c, k = deserialize_xprv(xprv)
            sequence = sequence[len(branch):]
            for n in sequence.split('/'):
                if n == '': continue
       t@@ -803,7 +796,7 @@ def bip32_private_derivation(xprv, branch, sequence):
        
        
        def bip32_public_derivation(xpub, branch, sequence):
       -    depth, fingerprint, child_number, c, cK = deserialize_xkey(xpub)
       +    depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub)
            assert sequence.startswith(branch)
            sequence = sequence[len(branch):]
            for n in sequence.split('/'):
   DIR diff --git a/lib/keystore.py b/lib/keystore.py
       t@@ -29,7 +29,7 @@ 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_xkey
       +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_bc_address
        from bitcoin import *
        
       t@@ -241,7 +241,7 @@ class Xpub:
        
            @classmethod
            def get_pubkey_from_xpub(self, xpub, sequence):
       -        _, _, _, c, cK = deserialize_xkey(xpub)
       +        _, _, _, c, cK = deserialize_xpub(xpub)
                for i in sequence:
                    cK, c = CKD_pub(cK, c, i)
                return cK.encode('hex')
       t@@ -298,7 +298,7 @@ class BIP32_KeyStore(Deterministic_KeyStore, Xpub):
        
            def check_password(self, password):
                xprv = pw_decode(self.xprv, password)
       -        if deserialize_xkey(xprv)[3] != deserialize_xkey(self.xpub)[3]:
       +        if deserialize_xprv(xprv)[3] != deserialize_xpub(self.xpub)[3]:
                    raise InvalidPassword()
        
            def update_password(self, old_password, new_password):
       t@@ -329,7 +329,7 @@ class BIP32_KeyStore(Deterministic_KeyStore, Xpub):
        
            def get_private_key(self, sequence, password):
                xprv = self.get_master_private_key(password)
       -        _, _, _, c, k = deserialize_xkey(xprv)
       +        _, _, _, c, k = deserialize_xprv(xprv)
                pk = bip32_private_key(sequence, k, c)
                return pk
        
       t@@ -623,19 +623,15 @@ def is_old_mpk(mpk):
            return len(mpk) == 128
        
        def is_xpub(text):
       -    if text[0:4] != 'xpub':
       -        return False
            try:
       -        deserialize_xkey(text)
       +        deserialize_xpub(text)
                return True
            except:
                return False
        
        def is_xprv(text):
       -    if text[0:4] != 'xprv':
       -        return False
            try:
       -        deserialize_xkey(text)
       +        deserialize_xprv(text)
                return True
            except:
                return False
   DIR diff --git a/plugins/cosigner_pool/qt.py b/plugins/cosigner_pool/qt.py
       t@@ -129,7 +129,7 @@ class Plugin(BasePlugin):
                self.cosigner_list = []
                for key, keystore in wallet.keystores.items():
                    xpub = keystore.get_master_public_key()
       -            K = bitcoin.deserialize_xkey(xpub)[-1].encode('hex')
       +            K = bitcoin.deserialize_xpub(xpub)[-1].encode('hex')
                    _hash = bitcoin.Hash(K).encode('hex')
                    if not keystore.is_watching_only():
                        self.keys.append((key, _hash, window))
       t@@ -203,7 +203,7 @@ class Plugin(BasePlugin):
                if not xprv:
                    return
                try:
       -            k = bitcoin.deserialize_xkey(xprv)[-1].encode('hex')
       +            k = bitcoin.deserialize_xprv(xprv)[-1].encode('hex')
                    EC = bitcoin.EC_KEY(k.decode('hex'))
                    message = EC.decrypt_message(message)
                except Exception as e:
   DIR diff --git a/plugins/trustedcoin/trustedcoin.py b/plugins/trustedcoin/trustedcoin.py
       t@@ -285,7 +285,7 @@ def get_user_id(storage):
            return long_id, short_id
        
        def make_xpub(xpub, s):
       -    _, _, _, c, cK = deserialize_xkey(xpub)
       +    _, _, _, c, cK = deserialize_xpub(xpub)
            cK2, c2 = bitcoin._CKD_pub(cK, c, s)
            xpub2 = ("0488B21E" + "00" + "00000000" + "00000000").decode("hex") + c2 + cK2
            return EncodeBase58Check(xpub2)
       t@@ -294,7 +294,7 @@ def make_xpub(xpub, s):
        def make_billing_address(wallet, num):
            long_id, short_id = wallet.get_user_id()
            xpub = make_xpub(billing_xpub, long_id)
       -    _, _, _, c, cK = deserialize_xkey(xpub)
       +    _, _, _, c, cK = deserialize_xpub(xpub)
            cK, c = bitcoin.CKD_pub(cK, c, num)
            address = public_key_to_bc_address( cK )
            return address
       t@@ -524,8 +524,7 @@ class TrustedCoinPlugin(BasePlugin):
                challenge = r.get('challenge')
                message = 'TRUSTEDCOIN CHALLENGE: ' + challenge
                def f(xprv):
       -            from electrum.bitcoin import deserialize_xkey, bip32_private_key, regenerate_key, is_compressed
       -            _, _, _, c, k = deserialize_xkey(xprv)
       +            _, _, _, c, k = deserialize_xprv(xprv)
                    pk = bip32_private_key([0, 0], k, c)
                    key = regenerate_key(pk)
                    compressed = is_compressed(pk)