<p>This line:</p>

<pre><code>msg=("0" + hex(int.from_bytes(pub_key,"big"))[2:] + str_i(0)).encode() 
</code></pre>

<p>is incorrect. You are converting the bytes of the pubkey and index into a hex string which you are then hashing. That is not correct. You are supposed to hash the bytes directly, not the hex string.</p>

CC BY-SA 4.0
2020-03-26T16:19:31.623Z
Thanks for your answer. I changed the code, and actually I was doing an unnecessary extra step. However, the outcome is the same. I have looked to other implementations and they look just like mine, but I get a different result.
Oscar Serna
CC BY-SA 4.0
2020-03-26T16:20:23.773Z
My line of code now: msg=pub_key + i.to_bytes(4,"big")
Oscar Serna
CC BY-SA 4.0
2020-03-26T16:31:12.163Z
Ok. I got it! In my desperation, I had also converted to int the chain code and back to bytes (unnecessary as well) and that was messing up my result. Changing that back along side your suggestion, my results match the vector tests from the Bitcoin Wiki page. Thanks a lot man!!
Oscar Serna
CC BY-SA 4.0
2020-03-26T06:16:00.680Z
2020-03-26T06:16:00.680Z
Ava Chow
<p>I am implementing bip32 for my wallet as a project to learn Bitcoin.</p>

<p>I am following this documentation:
<a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki" rel="nofollow noreferrer">https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki</a></p>

<p>Since I am not implementing bip39 yet, I am getting the master private key and code chain from the BIP39 Root Key from this web:
<a href="https://iancoleman.io/bip39/#english" rel="nofollow noreferrer">https://iancoleman.io/bip39/#english</a></p>

<p>using a random set of words which are:</p>

<pre><code>praise vague cruise stem test gesture twin long donate violin special hamster horror rough loan
</code></pre>

<p>which throws:</p>

<pre><code>xprv9s21ZrQH143K2E7weJFDreP9A8dFkx18swFoAJ6DBdsVuSPoFBLzekLca8vEG1i6ikCcvzZb79joaEZAjeM8Nz1DZ549aCnv3YFXy33mLoW
</code></pre>

<p>Comparing this output with another web implementation here: <a href="https://iancoleman.io/bip39/" rel="nofollow noreferrer">https://iancoleman.io/bip39/</a></p>

<p>These two outputs match. However, after this point they don't. And my implementation doesn't match with any of those implementations!</p>

<p>Here is my python code where I deserialize the BIP32 extended key. This matches perfectly with the master private key and chain code from the second web app:</p>

<pre><code>def deserialize_xprvk(s):
    version = s.read(4)
    depth = s.read(1)
    fingerprint = s.read(4)
    index= s.read(4)
    chain_code = s.read(32)
    s.read(1)
    privkey = s.read(32)
    return [version,depth, fingerprint,index,chain_code,privkey]

decoded =deserialize_xprvk( BytesIO(decode_base58_extended(xtprvk)))
</code></pre>

<p>printing "decoded" I get:</p>

<pre><code>0x488ade4
0x0
0x0
0x0
0x10e85c06826fdcd006c244ff6c44200044c1418bdd82cc088c33e48ae7b4c2ca
0xf214c0afd9b311544fdb686cae5100f1ac0ac8aba2b6c55719ba41ac2d4f2d12
</code></pre>

<p>which matches perfectly with the 2nd implementation (the firs one doesn't show the master private key or chain code).</p>

<p>Then I try to follow the instructions from here:
<a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki" rel="nofollow noreferrer">https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki</a> 
to derivate the child PRIVATE KEY with index 0 for this master key and chain code like this:</p>

<pre><code>#The order of the ciclic group in the finite field of the ecliptic curve
N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

#creates a string to emulate the index in a 4-byte hex format.
def str_i(i):
    i_str = hex(i)[2:]
    while len(i_str)&lt;8:
        i_str="0"+i_str
    return i_str

pub_key = PrivateKey(int.from_bytes(master_priv_key,"big")).point.sec()

#I put an extra "0" because every public key begins with a "02" or "03" but
#the hex() function commits this character.
#The str_i(0) means I am trying to get the index 0.
msg=("0" + hex(int.from_bytes(pub_key,"big"))[2:] + str_i(0)).encode() 

I= hmac.new(
            key = hex(int.from_bytes(chain_code,"big"))[2:].encode() ,
            msg=msg ,
            digestmod=sha512).digest()

I_L, I_R = I[:32], I[32:]

child_privkey_int = (int.from_bytes(I_L,"big") + int.from_bytes(master_priv_key,"big"))%N

child_privkey = PrivateKey(child_privkey_int).wif(compressed= True)

child_chain_code = I_R
</code></pre>

<p>If I run this code and try to get the child private key for path m\0\0\ I get:</p>

<p>"L29Rc5PyDkbUr2z1VcL2DuAhTQkNo3qwF7ENgRotS86ADUkiXPJF"</p>

<p>But in the first web app they get:
"KwuPS3DGMnCc3jMJWtqVVzkCoMyhybxGZrf68fPBEBtFfujBdPGs"</p>

<p>And in the second one they get:
"L1TcvgkPZFa6DyXhv9vYWceTXZhoAR7ZQMdt5rqV6LW3Zutpsqr8"</p>

<p>Is it ok to disagree on different implementations?? or am I doing something really wrong? I am starting to pull off my hair trying to find out where I am messing up.</p>

<p>Thanks.</p>

CC BY-SA 4.0
2020-03-26T01:03:58.720Z
Have you tried implementing the BIP32 test vectors?
Pieter Wuille
CC BY-SA 4.0
2020-03-26T01:06:03.920Z
never heard of it.
Oscar Serna
<bip32-hd-wallets>
Why does my BIP32 implementation throw different results than other web implementations? They also disagree with each other tho
Oscar Serna
# Why does my BIP32 implementation throw different results than other web implementations? They also disagree with each other tho

(Asked by: username_0 on 2020-03-25)

I am implementing bip32 for my wallet as a project to learn Bitcoin.

I am following this documentation:
<https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki>

Since I am not implementing bip39 yet, I am getting the master private key and code chain from the BIP39 Root Key from this web:
<https://iancoleman.io/bip39/#english>

using a random set of words which are:

```
praise vague cruise stem test gesture twin long donate violin special hamster horror rough loan

```

which throws:

```
xprv9s21ZrQH143K2E7weJFDreP9A8dFkx18swFoAJ6DBdsVuSPoFBLzekLca8vEG1i6ikCcvzZb79joaEZAjeM8Nz1DZ549aCnv3YFXy33mLoW

```

Comparing this output with another web implementation here: <https://iancoleman.io/bip39/>

These two outputs match. However, after this point they don't. And my implementation doesn't match with any of those implementations!

Here is my python code where I deserialize the BIP32 extended key. This matches perfectly with the master private key and chain code from the second web app:

```
def deserialize_xprvk(s):
    version = s.read(4)
    depth = s.read(1)
    fingerprint = s.read(4)
    index= s.read(4)
    chain_code = s.read(32)
    s.read(1)
    privkey = s.read(32)
    return [version,depth, fingerprint,index,chain_code,privkey]

decoded =deserialize_xprvk( BytesIO(decode_base58_extended(xtprvk)))

```

printing "decoded" I get:

```
0x488ade4
0x0
0x0
0x0
0x10e85c06826fdcd006c244ff6c44200044c1418bdd82cc088c33e48ae7b4c2ca
0xf214c0afd9b311544fdb686cae5100f1ac0ac8aba2b6c55719ba41ac2d4f2d12

```

which matches perfectly with the 2nd implementation (the firs one doesn't show the master private key or chain code).

Then I try to follow the instructions from here:
<https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki>
to derivate the child PRIVATE KEY with index 0 for this master key and chain code like this:

```
#The order of the ciclic group in the finite field of the ecliptic curve
N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

#creates a string to emulate the index in a 4-byte hex format.
def str_i(i):
    i_str = hex(i)[2:]
    while len(i_str)<8:
        i_str="0"+i_str
    return i_str

pub_key = PrivateKey(int.from_bytes(master_priv_key,"big")).point.sec()

#I put an extra "0" because every public key begins with a "02" or "03" but
#the hex() function commits this character.
#The str_i(0) means I am trying to get the index 0.
msg=("0" + hex(int.from_bytes(pub_key,"big"))[2:] + str_i(0)).encode() 

I= hmac.new(
            key = hex(int.from_bytes(chain_code,"big"))[2:].encode() ,
            msg=msg ,
            digestmod=sha512).digest()

I_L, I_R = I[:32], I[32:]

child_privkey_int = (int.from_bytes(I_L,"big") + int.from_bytes(master_priv_key,"big"))%N

child_privkey = PrivateKey(child_privkey_int).wif(compressed= True)

child_chain_code = I_R

```

If I run this code and try to get the child private key for path m\0\0\ I get:

"L29Rc5PyDkbUr2z1VcL2DuAhTQkNo3qwF7ENgRotS86ADUkiXPJF"

But in the first web app they get:
"KwuPS3DGMnCc3jMJWtqVVzkCoMyhybxGZrf68fPBEBtFfujBdPGs"

And in the second one they get:
"L1TcvgkPZFa6DyXhv9vYWceTXZhoAR7ZQMdt5rqV6LW3Zutpsqr8"

Is it ok to disagree on different implementations?? or am I doing something really wrong? I am starting to pull off my hair trying to find out where I am messing up.

Thanks.

**Tags:** bip32-hd-wallets

> **Comments:**
> **username_1**: Have you tried implementing the BIP32 test vectors?  
> **username_0**: never heard of it.  

---

## 1 answers

### Answer by username_2 on 2020-03-26. Score: 1 | Accepted answer

This line:

```
msg=("0" + hex(int.from_bytes(pub_key,"big"))[2:] + str_i(0)).encode() 

```

is incorrect. You are converting the bytes of the pubkey and index into a hex string which you are then hashing. That is not correct. You are supposed to hash the bytes directly, not the hex string.

> **Comments:**
> **username_0**: Thanks for your answer. I changed the code, and actually I was doing an unnecessary extra step. However, the outcome is the same. I have looked to other implementations and they look just like mine, but I get a different result.  
> **username_0**: My line of code now: msg=pub_key + i.to_bytes(4,"big")  
> **username_0**: Ok. I got it! In my desperation, I had also converted to int the chain code and back to bytes (unnecessary as well) and that was messing up my result. Changing that back along side your suggestion, my results match the vector tests from the Bitcoin Wiki page. Thanks a lot man!!  

---

