URI: 
       thelper functions for bip32 derivations - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 9fccf9c2871a423e7b46d9a5d021a1f165707504
   DIR parent 5288f6a933172a5b3c2fe58f60eccb5de2a9fc6f
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Tue,  1 Apr 2014 19:10:13 +0200
       
       helper functions for bip32 derivations
       
       Diffstat:
         M lib/bitcoin.py                      |      24 +++++++++++++-----------
       
       1 file changed, 13 insertions(+), 11 deletions(-)
       ---
   DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py
       t@@ -540,18 +540,17 @@ def get_pubkeys_from_secret(secret):
        # However, if n is positive, the resulting private key's corresponding
        #  public key can be determined without the master private key.
        def CKD_priv(k, c, n):
       +    is_prime = n & BIP32_PRIME
       +    return _CKD_priv(k, c, rev_hex(int_to_hex(n,4)).decode('hex'), is_prime)
       +
       +def _CKD_priv(k, c, s, is_prime):
            import hmac
            from ecdsa.util import string_to_number, number_to_string
            order = generator_secp256k1.order()
            keypair = EC_KEY(k)
       -    K = GetPubKey(keypair.pubkey,True)
       -
       -    if n & BIP32_PRIME: # We want to make a "secret" address that can't be determined from K
       -        data = chr(0) + k + rev_hex(int_to_hex(n,4)).decode('hex')
       -        I = hmac.new(c, data, hashlib.sha512).digest()
       -    else: # We want a "non-secret" address that can be determined from K
       -        I = hmac.new(c, K + rev_hex(int_to_hex(n,4)).decode('hex'), hashlib.sha512).digest()
       -        
       +    cK = GetPubKey(keypair.pubkey,True)
       +    data = chr(0) + k + s if is_prime else cK + s
       +    I = hmac.new(c, data, hashlib.sha512).digest()
            k_n = number_to_string( (string_to_number(I[0:32]) + string_to_number(k)) % order , order )
            c_n = I[32:]
            return k_n, c_n
       t@@ -563,17 +562,20 @@ def CKD_priv(k, c, n):
        # This function allows us to find the nth public key, as long as n is 
        #  non-negative. If n is negative, we need the master private key to find it.
        def CKD_pub(cK, c, n):
       +    if n & BIP32_PRIME: raise
       +    return _CKD_pub(cK, c, rev_hex(int_to_hex(n,4)).decode('hex'))
       +
       +# helper function, callable with arbitrary string
       +def _CKD_pub(cK, c, s):
            import hmac
            from ecdsa.util import string_to_number, number_to_string
            order = generator_secp256k1.order()
       -    if n & BIP32_PRIME: raise
       -    I = hmac.new(c, cK + rev_hex(int_to_hex(n,4)).decode('hex'), hashlib.sha512).digest()
       +    I = hmac.new(c, cK + s, hashlib.sha512).digest()
            curve = SECP256k1
            pubkey_point = string_to_number(I[0:32])*curve.generator + ser_to_point(cK)
            public_key = ecdsa.VerifyingKey.from_public_point( pubkey_point, curve = SECP256k1 )
            c_n = I[32:]
            cK_n = GetPubKey(public_key.pubkey,True)
       -
            return cK_n, c_n