<p>Multiple keys can indeed be derived from the same master key or seed, but it's important to realize that this results in distinct public keys as well as distinct private keys. The public key is converted to an address, handed out, transactions are received on that address, and to spend the received output then, the public key is revealed together with a signature with the <strong>corresponding</strong> private keys.</p>
<p>In other words, the blockchain and the nodes verifying it do not know or care which keys were generated from the same seed. That is purely a local wallet decision. Nodes just see distinct public keys, and signatures with their corresponding private keys. In fact, the very earliest wallet software did not use seed/master key derivation, and just used randomly generated keys for every new address.</p>
<p>To determine which private key to sign with (and which corresponding public key to reveal), wallets just keep a map around from all public key hashes they have generated to the information about their derivation (which index in the derivation, possibly which parent key it was derived from).</p>
<p>When setting up a new wallet using existing seed phrase the wallet can potentially reconstruct the map of the keys easily. Since all the child keys derived from the parent are derived in a deterministic way, <strong>the wallet can just derive hundreds or even thousands of potential keys and addresses where transactions might have landed at some point of time.</strong> Then the blockchain can be checked for those addresses and see if the record about them exists on the chain and if they indeed received any funds.</p>

CC BY-SA 4.0
2022-03-19T18:12:24.560Z
Thanks for the comment. Yes, the network doesn't care which keys where derived from the same seed, but that is not what I was doubting. I have just added a diagram above to maybe more precisely define my problem. The wallet does need to provide some public key for unlocking the unspent output and from the locking script he can only see the already hashed key (address), so he doesn't know what the key should be and since there can be many keys derived from the same seed, he also doesn't have a mechanism to get the right key. (That is why I introduced the seed and etc. in the story). More clear?
Boki XD
CC BY-SA 4.0
2022-03-19T21:37:28.913Z
The wallet just keeps a list around of all public keys and their hashes it has ever generated, so they can be regenerated (along with the private keys) whenever needed.
Pieter Wuille
CC BY-SA 4.0
2022-03-20T08:36:29.760Z
So then wallet basically tries all possible keys before one of them works for a given locking script? What if the wallet gets deleted and you need to recover it on some other device using seed phrase? Then wallet will no longer have any list of keys it generated before.
Boki XD
CC BY-SA 4.0
2022-03-20T09:39:23.440Z
It is sensible for a wallet to maintain a list of generated pairs of private and public keys. This list can be indexed by public key hash. This is not explicitly required by network protocols, not explicitly by consensus rules. These are implementation details - different developers can do things differently.
RedGrittyBrick
CC BY-SA 4.0
2022-03-20T11:02:45.613Z
Thank you for your comment, but if that is correct can you please see and try to answer my comment above regarding if the wallet then tries to unlock the script with all the keys before one actually work and what if I restore my wallet with phrase on other device (because there will be no map/dictionary there)?
Boki XD
CC BY-SA 4.0
2022-03-20T12:02:31.317Z
It doesn't need to try to unlock with everything. The wallet software can just generate a map of information "public key hash H is key number N" for each, up to say a few 100 or 1000 keys. To detect incoming payments, it looks up the pubkey hash in the output in this map. If found, the wallet knows it can spend it (namely with key number N, which can be rederived when needed). This information can be, but doesn't need to be, stored in the wallet, but it can also be recomputed whenever needed. Deriving keys takes milliseconds or less.
Pieter Wuille
CC BY-SA 4.0
2022-03-20T12:42:54.240Z
@PieterWuille Thank you! I think I get it now. I edited your question with the precise thing I was wondering when asking the question. Hope you will take a look if I understood it correctly now.
Boki XD
CC BY-SA 4.0
2022-03-19T17:19:05.673Z
2022-03-20T13:09:54.747Z
2022-03-20T13:09:54.747Z
Pieter Wuille
<p><a href="https://i.sstatic.net/ojpJN.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ojpJN.jpg" alt="enter image description here" /></a>I am building certain system that involves Bitcoin and therefore I need to understand well how it works under the hood.</p>
<p>In order to receive funds, for every new transaction new public key and its hash should be generated. I assume that is done via extending the parent public key and generating new child key for every transaction. All of that makes sense, up until the point when the user who previously received funds, let's say Mike, decides he wants to use funds he received and send them to someone else, let's say Alice. In that situation he has to construct unlocking script with signature and public key that he submits to stack in addition to locking script attached to his previous address where he received funds. Locking script also (in addition to operators) has a public key. Now, at one point EQUALVERIFY function will be executed which is supposed to compare public key hash from locking script and the one from unlocking script and see if they are the same.</p>
<p>My question is, if for every transaction new public key is generated, then how will we even know which public key was used for certain transaction? Although, all of the keys are generated by same user and global seed, they can differ and as far as I understood EQUALVERIFY just performs basic equality operation. It doesn't check if two public key in some way originate from same seed. That would mean that if public keys from both scripts are not exactly the same, EQUALVERIFY will return FALSE.</p>
<p>I believe I am missing some piece of this process.
Thanks!</p>

<transactions><script><public-key><transaction-verification><verification>
Using EQUALVERIFY with different public keys, but generated from the same seed
Boki XD
# Using EQUALVERIFY with different public keys, but generated from the same seed

(Asked by: username_0 on 2022-03-19)

[![enter image description here](https://i.sstatic.net/ojpJN.jpg)](https://i.sstatic.net/ojpJN.jpg)I am building certain system that involves Bitcoin and therefore I need to understand well how it works under the hood.

In order to receive funds, for every new transaction new public key and its hash should be generated. I assume that is done via extending the parent public key and generating new child key for every transaction. All of that makes sense, up until the point when the user who previously received funds, let's say Mike, decides he wants to use funds he received and send them to someone else, let's say Alice. In that situation he has to construct unlocking script with signature and public key that he submits to stack in addition to locking script attached to his previous address where he received funds. Locking script also (in addition to operators) has a public key. Now, at one point EQUALVERIFY function will be executed which is supposed to compare public key hash from locking script and the one from unlocking script and see if they are the same.

My question is, if for every transaction new public key is generated, then how will we even know which public key was used for certain transaction? Although, all of the keys are generated by same user and global seed, they can differ and as far as I understood EQUALVERIFY just performs basic equality operation. It doesn't check if two public key in some way originate from same seed. That would mean that if public keys from both scripts are not exactly the same, EQUALVERIFY will return FALSE.

I believe I am missing some piece of this process.
Thanks!

**Tags:** transactions, script, public-key, transaction-verification, verification


---

## 1 answers

### Answer by username_1 on 2022-03-19. Score: 1 | Accepted answer

Multiple keys can indeed be derived from the same master key or seed, but it's important to realize that this results in distinct public keys as well as distinct private keys. The public key is converted to an address, handed out, transactions are received on that address, and to spend the received output then, the public key is revealed together with a signature with the **corresponding** private keys.

In other words, the blockchain and the nodes verifying it do not know or care which keys were generated from the same seed. That is purely a local wallet decision. Nodes just see distinct public keys, and signatures with their corresponding private keys. In fact, the very earliest wallet software did not use seed/master key derivation, and just used randomly generated keys for every new address.

To determine which private key to sign with (and which corresponding public key to reveal), wallets just keep a map around from all public key hashes they have generated to the information about their derivation (which index in the derivation, possibly which parent key it was derived from).

When setting up a new wallet using existing seed phrase the wallet can potentially reconstruct the map of the keys easily. Since all the child keys derived from the parent are derived in a deterministic way, **the wallet can just derive hundreds or even thousands of potential keys and addresses where transactions might have landed at some point of time.** Then the blockchain can be checked for those addresses and see if the record about them exists on the chain and if they indeed received any funds.

> **Comments:**
> **username_0**: Thanks for the comment. Yes, the network doesn't care which keys where derived from the same seed, but that is not what I was doubting. I have just added a diagram above to maybe more precisely define my problem. The wallet does need to provide some public key for unlocking the unspent output and from the locking script he can only see the already hashed key (address), so he doesn't know what the key should be and since there can be many keys derived from the same seed, he also doesn't have a mechanism to get the right key. (That is why I introduced the seed and etc. in the story). More clear?  
> **username_1**: The wallet just keeps a list around of all public keys and their hashes it has ever generated, so they can be regenerated (along with the private keys) whenever needed.  
> **username_0**: So then wallet basically tries all possible keys before one of them works for a given locking script? What if the wallet gets deleted and you need to recover it on some other device using seed phrase? Then wallet will no longer have any list of keys it generated before.  
> **username_2**: It is sensible for a wallet to maintain a list of generated pairs of private and public keys. This list can be indexed by public key hash. This is not explicitly required by network protocols, not explicitly by consensus rules. These are implementation details - different developers can do things differently.  
> **username_0**: Thank you for your comment, but if that is correct can you please see and try to answer my comment above regarding if the wallet then tries to unlock the script with all the keys before one actually work and what if I restore my wallet with phrase on other device (because there will be no map/dictionary there)?  
> **username_1**: It doesn't need to try to unlock with everything. The wallet software can just generate a map of information "public key hash H is key number N" for each, up to say a few 100 or 1000 keys. To detect incoming payments, it looks up the pubkey hash in the output in this map. If found, the wallet knows it can spend it (namely with key number N, which can be rederived when needed). This information can be, but doesn't need to be, stored in the wallet, but it can also be recomputed whenever needed. Deriving keys takes milliseconds or less.  
> **username_0**: @username_1 Thank you! I think I get it now. I edited your question with the precise thing I was wondering when asking the question. Hope you will take a look if I understood it correctly now.  

---

