<p>You are not deriving hardened child keys. You cannot derive hardened keys from an xpub. Just because the xpub itself is hardened does not mean that its children are.</p>

CC BY-SA 4.0
2019-07-25T02:41:48.030Z
Thank you Andrew. That is probably the reason. If you have idea how to explicitly generate hardened child keys please share.
madu
CC BY-SA 4.0
2019-07-25T02:34:56.163Z
2019-07-25T02:34:56.163Z
Ava Chow
<p>I am puzzled by the hardened key derivation from a watch-only BIP44 wallet.</p>

<p>Let me first explain what I am trying to do.</p>

<ul>
<li>I am implementing a 2-of-3 multisig scheme</li>
<li>I am using Bcoin node and wallet</li>
<li>All 3 keys are externally generated</li>
<li>I want to use Bcoin watch-only wallet</li>
</ul>

<p>ts to create addresses and scripts</p>

<p><strong>This is what I have done so far:</strong></p>

<ol>
<li>Created 3 xprv keys and xpubs keys using this tool <a href="https://bip32jp.github.io/english/index.html" rel="nofollow noreferrer">here</a></li>
<li>I used custome path <code>m/44'/0'/0'</code> to have hardened keys because Bcoin wallet requires BIP44 hardened keys</li>
<li>I created 3 <strong>watch-only</strong> wallets using the <code>xpub</code> keys.</li>
<li>Then I added each of the keys as shared keys to each other (I only really have to do this for one wallet)</li>
</ol>

<p>The code is as below:</p>

<pre><code>const HSM_accountKey = "xpub_HSM...."
const IC_accountKey = "xpub_IC..."
const Paper_accountKey = "xpub_Paper..."

const result_wallet_HSM = await walletClient.createWallet('wallet_HSM', options_wallet);
const result_wallet_IC = await walletClient.createWallet('wallet_IC', options_wallet);
const result_wallet_Paper = await walletClient.createWallet('wallet_Paper', options_wallet);


const wallet_IC_account = await wallet_IC.getAccount('default');
const wallet_Paper_account = await wallet_Paper.getAccount('default');
const result_addkey1 = await wallet_HSM.addSharedKey('default', wallet_IC_account.accountKey);
const result_addkey2 = await wallet_HSM.addSharedKey('default', wallet_Paper_account.accountKey);
</code></pre>

<p>Now I have created a watch-only 2-of-3 multisig wallet.
What I want to do now is to create addresses. I do not want to derive more child extended keys. I only need one derivation level.
Now I want to create multisig addresses for my users.</p>

<pre><code>// Create addresses from each wallet
const wallet_HSM_address = await wallet_HSM.createAddress('default');
const wallet_IC_address = await wallet_IC.createAddress('default');
const wallet_Paper_address = await wallet_Paper.createAddress('default');

// Keyrings for script generation
const keyring_HSM = KeyRing.fromJSON(wallet_HSM_address);
const keyring_IC = KeyRing.fromJSON(wallet_IC_address);
const keyring_Paper = KeyRing.fromJSON(wallet_Paper_address);

//Get the pubkeys from each wallet
const pubKeys = [keyring_HSM.publicKey, keyring_HSM.publicKey, keyring_Paper.publicKey];

const multiSigScript = Script.fromMultisig(m, n, pubKeys);
const receivingAddress = multiSigScript.getAddress().toBase58(network); 
</code></pre>

<p>I have a feeling that I am going about this step in a round-about way but you get what I am trying to do.</p>

<p>To re-state, what I want to do now is to create individual receiving addresses for my users and the corresponding P2SH scripts.</p>

<p>Now, this is what <strong>I need help understanding</strong>.</p>

<ul>
<li>According to BIP32, you cannot derive hardened public keys with CDKpub. You need the xprv to derive child keys.</li>
<li>However, from what I have done, I can derive child public keys. I have sent tesetnet coins to these addresses (<code>receivingAddress</code> in the code above) and they work. The wallet receives coins.</li>
<li>How then, was the watch-only wallet able to create hardened child public keys? I did not input <code>xprv</code> to the wallet.</li>
<li>Or, is it that I am NOT creating hardened child public keys when I used the path <code>m/44'/0'/0'</code>? 
Is the <code>receivingAddress</code> I am creating in the above code not a hardened one? Meaning that if someone is able to find the child private keys of one user and the <code>xpub</code>, they will be able to derive all the chile private keys?</li>
</ul>

<p>My apologies for the long question. I am a bit confused as to how the wallets are able to create child public keys without having any private key in the wallet.</p>

<p>Thank you.</p>

CC BY-SA 4.0
2019-07-24T15:49:37.850Z
I don't see anywhere in your code where you are deriving child keys. All I see is that you've generated 3 private/public keypairs and made a multisig out of them. That's nothing special.
Ava Chow
CC BY-SA 4.0
2019-07-25T00:05:12.360Z
Thanks Andrew. What is the difference between deriving child keys and generating child keys? What I am trying to do is to generate child keys for users of the system for them to have a receiving address. What is my misunderstanding? And then later on I need to generate the corresponding child private keys to spend the coins received to those address. So I want to be able to generate those private keys from the index.
madu
CC BY-SA 4.0
2019-07-25T02:16:03.730Z
deriving child keys and generating child keys mean the same thing. But, AFAICT, you aren't doing that in your code at all.
Ava Chow
CC BY-SA 4.0
2019-07-25T02:18:19.333Z
@AndrewChow Thanks so much. Could you kindly tell me what it is happening at `createAddress()`? Is it not generating a child key? Each time I call `createAddress()` it generates a new child address with a certain index. What am I misunderstanding here.
madu
CC BY-SA 4.0
2019-07-25T02:34:12.783Z
I was not aware that `createAddress()` is creating a new address. If that is the case, it is not deriving hardened addresses, especially if you only gave it an xpub.
Ava Chow
<bip32-hd-wallets><p2sh><xpub><bcoin>
Hardened address generation with BIP44 watch-only wallet with xpub
madu
# Hardened address generation with BIP44 watch-only wallet with xpub

(Asked by: username_0 on 2019-07-24)

I am puzzled by the hardened key derivation from a watch-only BIP44 wallet.

Let me first explain what I am trying to do.

* I am implementing a 2-of-3 multisig scheme
* I am using Bcoin node and wallet
* All 3 keys are externally generated
* I want to use Bcoin watch-only wallet

ts to create addresses and scripts

**This is what I have done so far:**

1. Created 3 xprv keys and xpubs keys using this tool [here](https://bip32jp.github.io/english/index.html)
2. I used custome path `m/44'/0'/0'` to have hardened keys because Bcoin wallet requires BIP44 hardened keys
3. I created 3 **watch-only** wallets using the `xpub` keys.
4. Then I added each of the keys as shared keys to each other (I only really have to do this for one wallet)

The code is as below:

```
const HSM_accountKey = "xpub_HSM...."
const IC_accountKey = "xpub_IC..."
const Paper_accountKey = "xpub_Paper..."

const result_wallet_HSM = await walletClient.createWallet('wallet_HSM', options_wallet);
const result_wallet_IC = await walletClient.createWallet('wallet_IC', options_wallet);
const result_wallet_Paper = await walletClient.createWallet('wallet_Paper', options_wallet);

const wallet_IC_account = await wallet_IC.getAccount('default');
const wallet_Paper_account = await wallet_Paper.getAccount('default');
const result_addkey1 = await wallet_HSM.addSharedKey('default', wallet_IC_account.accountKey);
const result_addkey2 = await wallet_HSM.addSharedKey('default', wallet_Paper_account.accountKey);

```

Now I have created a watch-only 2-of-3 multisig wallet.
What I want to do now is to create addresses. I do not want to derive more child extended keys. I only need one derivation level.
Now I want to create multisig addresses for my users.

```
// Create addresses from each wallet
const wallet_HSM_address = await wallet_HSM.createAddress('default');
const wallet_IC_address = await wallet_IC.createAddress('default');
const wallet_Paper_address = await wallet_Paper.createAddress('default');

// Keyrings for script generation
const keyring_HSM = KeyRing.fromJSON(wallet_HSM_address);
const keyring_IC = KeyRing.fromJSON(wallet_IC_address);
const keyring_Paper = KeyRing.fromJSON(wallet_Paper_address);

//Get the pubkeys from each wallet
const pubKeys = [keyring_HSM.publicKey, keyring_HSM.publicKey, keyring_Paper.publicKey];

const multiSigScript = Script.fromMultisig(m, n, pubKeys);
const receivingAddress = multiSigScript.getAddress().toBase58(network); 

```

I have a feeling that I am going about this step in a round-about way but you get what I am trying to do.

To re-state, what I want to do now is to create individual receiving addresses for my users and the corresponding P2SH scripts.

Now, this is what **I need help understanding**.

* According to BIP32, you cannot derive hardened public keys with CDKpub. You need the xprv to derive child keys.
* However, from what I have done, I can derive child public keys. I have sent tesetnet coins to these addresses (`receivingAddress` in the code above) and they work. The wallet receives coins.
* How then, was the watch-only wallet able to create hardened child public keys? I did not input `xprv` to the wallet.
* Or, is it that I am NOT creating hardened child public keys when I used the path `m/44'/0'/0'`?
  Is the `receivingAddress` I am creating in the above code not a hardened one? Meaning that if someone is able to find the child private keys of one user and the `xpub`, they will be able to derive all the chile private keys?

My apologies for the long question. I am a bit confused as to how the wallets are able to create child public keys without having any private key in the wallet.

Thank you.

**Tags:** bip32-hd-wallets, p2sh, xpub, bcoin

> **Comments:**
> **username_1**: I don't see anywhere in your code where you are deriving child keys. All I see is that you've generated 3 private/public keypairs and made a multisig out of them. That's nothing special.  
> **username_0**: Thanks Andrew. What is the difference between deriving child keys and generating child keys? What I am trying to do is to generate child keys for users of the system for them to have a receiving address. What is my misunderstanding? And then later on I need to generate the corresponding child private keys to spend the coins received to those address. So I want to be able to generate those private keys from the index.  
> **username_1**: deriving child keys and generating child keys mean the same thing. But, AFAICT, you aren't doing that in your code at all.  
> **username_0**: @AndrewChow Thanks so much. Could you kindly tell me what it is happening at `createAddress()`? Is it not generating a child key? Each time I call `createAddress()` it generates a new child address with a certain index. What am I misunderstanding here.  
> **username_1**: I was not aware that `createAddress()` is creating a new address. If that is the case, it is not deriving hardened addresses, especially if you only gave it an xpub.  

---

## 1 answers

### Answer by username_1 on 2019-07-25. Score: 1 | Accepted answer

You are not deriving hardened child keys. You cannot derive hardened keys from an xpub. Just because the xpub itself is hardened does not mean that its children are.

> **Comments:**
> **username_0**: Thank you Andrew. That is probably the reason. If you have idea how to explicitly generate hardened child keys please share.  

---

