Bitcoin Forum
November 15, 2019, 07:21:30 AM *
News: Help collect the most notable posts made over the last 10 years.
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: How to securely generate addresses of an HD wallet?  (Read 249 times)
VictorBTC
Newbie
*
Offline Offline

Activity: 13
Merit: 3


View Profile
June 29, 2018, 06:51:27 PM
Merited by LoyceV (2)
 #1

I need a way to provide something public or at least not usable to access my Bitcoin account.

The idea is simple, to allow users to add theirs public credentials that will be used for generating new addresses.

I have read about HD wallets and as far as I know there is the XPUB key, that can be used to generate new addresses. But I haven't found any example how to do this programatically.

So generally

  • A user own an HD wallet
  • The user does something and gets something, that can be used for generating new addresses, of course connected to the root wallet
  • The user provides this public credentials for generating new addresses.
  • Some script generates a new address every time this is required using provided credentials.

Could someone route me to the right direction? Any language is acceptable, but it would be great if this will be possible using Golang

And please tell me, why it is dangerous to create a new wallet locally (generally this is just a set of private/public key) but why I need to run the full node to have a wallet?
1573802490
Hero Member
*
Offline Offline

Posts: 1573802490

View Profile Personal Message (Offline)

Ignore
1573802490
Reply with quote  #2

1573802490
Report to moderator
1573802490
Hero Member
*
Offline Offline

Posts: 1573802490

View Profile Personal Message (Offline)

Ignore
1573802490
Reply with quote  #2

1573802490
Report to moderator
1573802490
Hero Member
*
Offline Offline

Posts: 1573802490

View Profile Personal Message (Offline)

Ignore
1573802490
Reply with quote  #2

1573802490
Report to moderator
The Bitcoin Forum is turning 10 years old! Join the community in sharing and exploring the notable posts made over the years.
1573802490
Hero Member
*
Offline Offline

Posts: 1573802490

View Profile Personal Message (Offline)

Ignore
1573802490
Reply with quote  #2

1573802490
Report to moderator
1573802490
Hero Member
*
Offline Offline

Posts: 1573802490

View Profile Personal Message (Offline)

Ignore
1573802490
Reply with quote  #2

1573802490
Report to moderator
1573802490
Hero Member
*
Offline Offline

Posts: 1573802490

View Profile Personal Message (Offline)

Ignore
1573802490
Reply with quote  #2

1573802490
Report to moderator
cellard
Legendary
*
Offline Offline

Activity: 1372
Merit: 1211


View Profile
June 29, 2018, 07:11:22 PM
 #2

I think there are risks in sharing your master public key, because the seed could be derived if you also had other stuff, im not sure about the details but I have definitely read about key derivation involving xpub so I wouldn't risk it. Just generate a bunch of public keys the usual way in a list and give them said list if you don't want to reuse an address to receive payments? Is it for a webpage or something?

Quote
And please tell me, why it is dangerous to create a new wallet locally (generally this is just a set of private/public key) but why I need to run the full node to have a wallet?

There is no risk to create a new wallet as long as the machine you create a new wallet in is airgapped and uses Linux. You don't NEED a full node to have a wallet, but you should in order to validate transactions your own and be sure you are on the right chain at all times, it's not worth it taking compromises in bitcoin.
VictorBTC
Newbie
*
Offline Offline

Activity: 13
Merit: 3


View Profile
June 29, 2018, 07:25:25 PM
 #3

Thank you so much for the reply. Generally there is no risk, because users will just paste their XPUB keys in their profile settings, this will encrypted and then used for generating a bunch of new addresses.

But I haven't found any example how can I derive new addresses from an XPUB key, also I found that I still need the private key to generate new addresses.

All in all, I am just looking for a way for users to provide some part of their credentials that won't allow in that case me to access their wallets. But allow my scripts to generate new addresses.

Please suggest the best way to achieve that.
THanks
HCP
Legendary
*
Offline Offline

Activity: 1148
Merit: 1848

<insert witty quote here>


View Profile
June 30, 2018, 09:51:16 AM
Merited by aliashraf (1)
 #4

the "XPUB" is exactly what you're looking for... I tend to use various Bitcoin Libraries to do the heavy lifting (ie. pybitcointools etc)... no sense in re-inventing the wheel Wink so if you have a hunt around some of the libraries in various languages you'll probably find some clues on how to do it:
Python - https://github.com/vbuterin/pybitcointools (got "hidden" by the dev... so maybe try this fork: https://github.com/primal100/pybitcointools)
PHP - https://github.com/dan-da/hd-wallet-derive
JS - https://iancoleman.io/bip39/ (if you paste the XPUB into the BIP32 root key field... click the BIP32 tab and set the derivation path to "m" it generates addresses, source code here)
you can also experiment with: http://bip32.org/ (source code here)

This seems to be a Go implementation of BIP32 key derivation, but I don't know enough about Go to be able to say whether or not it will derive addresses from an XPUB:
https://github.com/tyler-smith/go-bip32


NOTE: There are two "dangers" of an XPUB:

1. If it "leaks", the privacy of your entire wallet is compromised, as anyone with your XPUB can create a watching-only wallet and derive all your addresses and see your entire transaction history etc
2. If someone has your XPUB, and ONE private key for an address generated by that XPUB... they can derive the private keys for ALL the addresses generated from that XPUB (as if they had the XPRV)

VictorBTC
Newbie
*
Offline Offline

Activity: 13
Merit: 3


View Profile
June 30, 2018, 05:38:08 PM
Last edit: June 30, 2018, 05:51:02 PM by VictorBTC
 #5

Thank you so much for the answer, appreciate your help.

Could you please explain the following things

1. For instance using this library https://github.com/dan-da/hd-wallet-derive , there are different ways for generating bitcoin address, xprv, xpub, mnemonic. Which one is safer and better for using by users.
2. If using derivation from xpub key, are there any limits for generating number of addresses ?
3. If someone will get my xprv key, can he access my funds ?
4. Do I have a chance to derive the same key several times using an XPUB key

I would be grateful for help.

Thx.
HCP
Legendary
*
Offline Offline

Activity: 1148
Merit: 1848

<insert witty quote here>


View Profile
June 30, 2018, 09:40:29 PM
 #6

1. For instance using this library https://github.com/dan-da/hd-wallet-derive , there are different ways for generating bitcoin address, xprv, xpub, mnemonic. Which one is safer and better for using by users.
Safest is XPUB. Using XPRV or mnemonic is effectively using the private keys with the obvious security issues (for users). Ie. They would be effectively trusting your system with ALL their money... Not an ideal scenario for them, plus it's likely to mean a lot of people will consider your service some sort of scam Tongue

Quote
2. If using derivation from xpub key, are there any limits for generating number of addresses ?
No. Theoretically, the limit is "infinity" Wink

Quote
3. If someone will get my xprv key, can he access my funds ?
Yes. XPRV is Master Private Key. All the private keys are derived from this.


Quote
4. Do I have a chance to derive the same key several times using an XPUB key.
An XPUB derives keys in a set sequence, I don't believe that it is possible to generate the same address twice from one XPUB. Or did you mean "can two different XPUBs generate the same address?" If so, for all intents and purposes, the chances of two XPUBs generating the same address are the same as two people generating the same Bitcoin key. So, effectively the answer is zero.

(Technically, the chance is "non-zero", but so infinitesimally small that it is regarded as zero.)

VictorBTC
Newbie
*
Offline Offline

Activity: 13
Merit: 3


View Profile
July 02, 2018, 06:36:06 PM
 #7

Thank you so much for such detailed and useful answers.  I have one more question regarding the path of derived addresses

I have read the specification, but didn't understand whether this is required of this is just a convention?

For instance consider the following path
Code:
Bitcoin first external first m / 44' / 0' / 0' / 0 / 0

https://i.stack.imgur.com/7jgkj.png

If I change the constant number 44, what consequences may I experience? As far as I know all online tools for calculating balances just check all available values to calculate the final balance.

And in case the last value corresponds to a address index, what is the maximum value of addresses though ?

And if there any lib, that just makes it simple to derive and address passing all these values as function argument to generate a valid new address?
HCP
Legendary
*
Offline Offline

Activity: 1148
Merit: 1848

<insert witty quote here>


View Profile
July 03, 2018, 04:33:27 AM
 #8

I have read the specification, but didn't understand whether this is required of this is just a convention?
For instance consider the following path
Code:
Bitcoin first external first m / 44' / 0' / 0' / 0 / 0
https://i.stack.imgur.com/7jgkj.png
If I change the constant number 44, what consequences may I experience?
If you change 44 to something else, then you'll find that BIP44 compatible wallets will NOT be able to derive the same addresses. If a wallet adheres to (or enforces) BIP44, then they should be using m/44'/.... unless the wallet also offers "custom" derivation paths that allow a user to define whatever they want... (and then just append the "/0/x" on the end)

The recommendation is that if you don't want to follow the BIP44 spec, you should apply for your own BIP number... and use that. If you're creating a new coin, you should apply/register for a new coin number (see below) and use that.


Quote
As far as I know all online tools for calculating balances just check all available values to calculate the final balance.
Not quite... they generally stick to a set "base" derivation path like m/44'/0'/0'... ie. BIP44, Coin = 0 (Bitcoin, list of "registered" coin numbers here: https://github.com/satoshilabs/slips/blob/master/slip-0044.md), Account = 0.

From there, they'll use "external/internal" of 0/1 for deriving separate "receive" and "change" addresses respectively... and then an incrementing "address index"

ie.
ReceiveAddress0 = m/44'/0'/0'/0/0
ReceiveAddress1 = m/44'/0'/0'/0/1
ReceiveAddress2 = m/44'/0'/0'/0/2
ReceiveAddress3 = m/44'/0'/0'/0/3
...
ReceiveAddressN = m/44'/0'/0'/0/N

ChangeAddress0 = m/44'/0'/0'/1/0
ChangeAddress1 = m/44'/0'/0'/1/1
ChangeAddress2 = m/44'/0'/0'/1/2
ChangeAddress3 = m/44'/0'/0'/1/3
...
ChangeAddressN = m/44'/0'/0'/1/N

To avoid having to generate addresses "forever" when restoring wallets... most wallets will implement a "gap limit" system... ie. they'll loop around "generate address -> check address for activity -> generate next address"
etc until they have generated X addresses that have ZERO activity (note, NOT balance... but activity). The value of X is known as the gap limit... and is variable from wallet to wallet. Electrum uses 20 receive, 5 change... I've seen some wallets use 100.


Quote
And in case the last value corresponds to a address index, what is the maximum value of addresses though ?
Theoretically, there isn't one... technically, it is probably the largest (INT) number that your OS/system is able to represent.


Quote
And if there any lib, that just makes it simple to derive and address passing all these values as function argument to generate a valid new address?
I would think it should be relatively easy to create a simple wrapper function of your own to do this.


Quote
I have one more question regarding the path of derived addresses
It was actually 3 questions, but I'll let it slide Wink Tongue

VictorBTC
Newbie
*
Offline Offline

Activity: 13
Merit: 3


View Profile
July 03, 2018, 01:39:07 PM
 #9

I am really thank for your answers !! Really appreciate your help !

I have found the following answer https://bitcoin.stackexchange.com/questions/36955/what-bip32-derivation-path-does-electrum-use/36956

And in case I will use a BIP32 compatible wallet I have to generate addresses using the following format

Code:
m/0/k - Receive address
m/1/k - Change address

Where K is the address index.

All in all, the main question I am interested in, as far as this is only a convention, how do I know what format should I use? For instance one user uses the Electrum wallet another user uses the Bitcoin Core wallet.

What is the right strategy for generating addresses for different HD wallets?

Thanks. 
HCP
Legendary
*
Offline Offline

Activity: 1148
Merit: 1848

<insert witty quote here>


View Profile
July 04, 2018, 10:27:26 AM
 #10

Sadly... there is not "one strategy to rule them all"... as unfortunately, the wallets don't all use the same derivation paths Undecided

Have a look here: https://onedrive.live.com/view.aspx?resid=584F122BA17116EE!313&app=Excel

And take note of the xpub/xprv path... You'll see that the paths are different from wallet to wallet.

One strategy you could try is to provide a drop-down where the user can select which wallet they've used to generate the xpub and then use the appropriate derivation path for that particular wallet. Not necessarily ideal or fool-proof, but probably the best option available at present.


VictorBTC
Newbie
*
Offline Offline

Activity: 13
Merit: 3


View Profile
July 04, 2018, 10:49:43 PM
 #11

Thank you so much for your help !!

For who are interested, I have tested the Electrum wallet and it generates addresses using the following paths

Code:
m/0/<n> path (receiving addresses)
m/1/<n> path (change addresses)

By default 20 Receive Addresses and 6 Change addresses are generated by Electrum
Pages: [1]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!