<p>I figured out my issue. I don't know if I'm missing something with the results in learnmeabitcoin, but instead I started using test vectors from the Bitcoin wiki:</p>
<p><a href="https://en.bitcoin.it/wiki/BIP_0032_TestVectors" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/BIP_0032_TestVectors</a></p>
<p>The results from my python function above match the unhardened tests from that link. One thing I was forgetting to do was to add the master private key with the left 256 bits of the child hash to generate the child private key. I was able to achieve this by storing the above function in variable <code>child_hash</code>, then ran the following:</p>
<pre><code>child_left_hash = child_hash[:64]
child_chain_code = child_hash[64:]
child_private_key = hex(int(child_left_hash, 16) + int(master_private_key, 16))[2:]
</code></pre>

CC BY-SA 4.0
2022-01-01T21:31:14.283Z
2022-01-02T01:06:18.313Z
2022-01-02T01:06:18.313Z
Tennyx
<p>I am coding my own keys (not for use in production, strictly for learning). I am successfully creating 512 bit seeds from mnemonic phrases, however I am failing at the step of deriving child keys from these seeds. For reference I am using the following post for testing:</p>
<p><a href="https://learnmeabitcoin.com/technical/hd-wallets" rel="nofollow noreferrer">https://learnmeabitcoin.com/technical/hd-wallets</a></p>
<p>What I will do is use that site to generate mnemonics for me, then using the seed I try to match the child keys in the <strong>Child Keys (Basic)</strong> section, to no avail. For instance, I have the following phrase:</p>
<pre><code>lash afraid any alter object topic pony deer helmet favorite chuckle carpet
</code></pre>
<p>which matches the seed and keys in the post:</p>
<pre><code>Extended key: e8448e8e6ac4ce400951f6d630a0963c40b263208dacee0c53b3a3ccf8be9a1540434b626e34b82f28e4fb60842d5a5470e2f8cc2777a559a3c68ac4e9f2559d
Private key: e8448e8e6ac4ce400951f6d630a0963c40b263208dacee0c53b3a3ccf8be9a15
Chain code: 40434b626e34b82f28e4fb60842d5a5470e2f8cc2777a559a3c68ac4e9f2559d
Public key: 03cf895293b95a0ce2457593b82cc6fd646c757a1e2d393932b70dafddc2d9553b
</code></pre>
<p>Here is where I am getting tripped up. My rough python function looks like this:</p>
<pre><code>def create_child_keys(chain_code, public_key, children):
    for n in range(children):
        hex_child_index = hex(n)[2:].zfill(8)
        print(hmac.new(bytes.fromhex(chain_code), msg=bytes.fromhex(public_key + hex_child_index), digestmod=hashlib.sha512).hexdigest())

create_child_keys(extended_key, 3)
</code></pre>
<p>This returns different hashes for the first 3 children than the link posted above. For instance, according to <strong>learnmeabitcoin</strong> the first child should have a private key of:</p>
<pre><code>d547eda1f3d7da655cafec4506d3e333f1add4415968b1994f30bd64b023e2d3
</code></pre>
<p>but mine is:</p>
<pre><code>c9dd74741e44fbd9e763f47829f37d1b2165a5ad6e90697c719d95489c409326
</code></pre>
<p>Hoping something obvious stands out to those more familiar with this process.</p>

CC BY-SA 4.0
2021-12-30T23:37:38.557Z
Check out a python implementation here https://github.com/mcdallas/cryptotools/blob/df233dc50cb8adbf28eeff075fa9026626c598d6/cryptotools/BTC/HD/bip32.py#L132-L149
Mike D
CC BY-SA 4.0
2021-12-31T19:45:59.190Z
@MikeD Thanks for this! As far as I can tell this code is validating my code - so maybe learnmeabitcoin is erroneous? The code I used to validate, with a print statement in the child method for "I":

m = Xprv.from_mnemonic('flash afraid any alter object topic pony deer helmet favorite chuckle carpet')
print('code:', m.code.hex())
print('msg:', m.key.to_public().encode(compressed=True).hex())
print('index 0:', int_to_bytes(0).rjust(4, b'\x00').hex())
m.child(0)

I'll show print logs in another comment, but they match my findings and not the ones from learnmeabitcoin.
Tennyx
CC BY-SA 4.0
2021-12-31T19:47:19.240Z
code: 40434b626e34b82f28e4fb60842d5a5470e2f8cc2777a559a3c68ac4e9f2559d
msg: 03cf895293b95a0ce2457593b82cc6fd646c757a1e2d393932b70dafddc2d9553b
index 0: 00000000
child hash: c9dd74741e44fbd9e763f47829f37d1b2165a5ad6e90697c719d95489c40932608b25a850dc4eec62c74bae84b53cfa13ec4dadfa6a9fddd99a73e9de778ee9e
Tennyx
<bip32-hd-wallets><python>
Having trouble creating a Python function that creates non-hardened HD wallet child keys
Tennyx
# Having trouble creating a Python function that creates non-hardened HD wallet child keys

(Asked by: username_0 on 2021-12-30)

I am coding my own keys (not for use in production, strictly for learning). I am successfully creating 512 bit seeds from mnemonic phrases, however I am failing at the step of deriving child keys from these seeds. For reference I am using the following post for testing:

<https://learnmeabitcoin.com/technical/hd-wallets>

What I will do is use that site to generate mnemonics for me, then using the seed I try to match the child keys in the **Child Keys (Basic)** section, to no avail. For instance, I have the following phrase:

```
lash afraid any alter object topic pony deer helmet favorite chuckle carpet

```

which matches the seed and keys in the post:

```
Extended key: e8448e8e6ac4ce400951f6d630a0963c40b263208dacee0c53b3a3ccf8be9a1540434b626e34b82f28e4fb60842d5a5470e2f8cc2777a559a3c68ac4e9f2559d
Private key: e8448e8e6ac4ce400951f6d630a0963c40b263208dacee0c53b3a3ccf8be9a15
Chain code: 40434b626e34b82f28e4fb60842d5a5470e2f8cc2777a559a3c68ac4e9f2559d
Public key: 03cf895293b95a0ce2457593b82cc6fd646c757a1e2d393932b70dafddc2d9553b

```

Here is where I am getting tripped up. My rough python function looks like this:

```
def create_child_keys(chain_code, public_key, children):
    for n in range(children):
        hex_child_index = hex(n)[2:].zfill(8)
        print(hmac.new(bytes.fromhex(chain_code), msg=bytes.fromhex(public_key + hex_child_index), digestmod=hashlib.sha512).hexdigest())

create_child_keys(extended_key, 3)

```

This returns different hashes for the first 3 children than the link posted above. For instance, according to **learnmeabitcoin** the first child should have a private key of:

```
d547eda1f3d7da655cafec4506d3e333f1add4415968b1994f30bd64b023e2d3

```

but mine is:

```
c9dd74741e44fbd9e763f47829f37d1b2165a5ad6e90697c719d95489c409326

```

Hoping something obvious stands out to those more familiar with this process.

**Tags:** bip32-hd-wallets, python

> **Comments:**
> **username_1**: Check out a python implementation here https://github.com/mcdallas/cryptotools/blob/df233dc50cb8adbf28eeff075fa9026626c598d6/cryptotools/BTC/HD/bip32.py#L132-L149  
> **username_0**: @username_1 Thanks for this! As far as I can tell this code is validating my code - so maybe learnmeabitcoin is erroneous? The code I used to validate, with a print statement in the child method for "I":  m = Xprv.from_mnemonic('flash afraid any alter object topic pony deer helmet favorite chuckle carpet') print('code:', m.code.hex()) print('msg:', m.key.to_public().encode(compressed=True).hex()) print('index 0:', int_to_bytes(0).rjust(4, b'\x00').hex()) m.child(0)  I'll show print logs in another comment, but they match my findings and not the ones from learnmeabitcoin.  
> **username_0**: code: 40434b626e34b82f28e4fb60842d5a5470e2f8cc2777a559a3c68ac4e9f2559d msg: 03cf895293b95a0ce2457593b82cc6fd646c757a1e2d393932b70dafddc2d9553b index 0: 00000000 child hash: c9dd74741e44fbd9e763f47829f37d1b2165a5ad6e90697c719d95489c40932608b25a850dc4eec62c74bae84b53cfa13ec4dadfa6a9fddd99a73e9de778ee9e  

---

## 1 answers

### Answer by username_0 on 2022-01-01. Score: 2 | Accepted answer

I figured out my issue. I don't know if I'm missing something with the results in learnmeabitcoin, but instead I started using test vectors from the Bitcoin wiki:

<https://en.bitcoin.it/wiki/BIP_0032_TestVectors>

The results from my python function above match the unhardened tests from that link. One thing I was forgetting to do was to add the master private key with the left 256 bits of the child hash to generate the child private key. I was able to achieve this by storing the above function in variable `child_hash`, then ran the following:

```
child_left_hash = child_hash[:64]
child_chain_code = child_hash[64:]
child_private_key = hex(int(child_left_hash, 16) + int(master_private_key, 16))[2:]

```


---

