Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change --use_master_seed default: to False! #2514

Open
wants to merge 1 commit into
base: py3
Choose a base branch
from
Open

Change --use_master_seed default: to False! #2514

wants to merge 1 commit into from

Conversation

ghost
Copy link

@ghost ghost commented Apr 9, 2020

#2512

If anyone need to use a master_seed to generate private keys for sites in a range, than that person should use the config parameter --use_master_seed True.

By default all user should backup private keys instead of generating a few million key in a limited private key space between 0x1 and 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4140.

While using a seed is good if any of the addresses get compromised from the range of generated private keys an attacker can compromise all and every site generated using that seed!

So, generate a new randomly-selected private key for each new address and let the user practice backing up private keys.

#2512 

If anyone need to use a master_seed to generate private keys for sites in a range, than that person should use the config parameter --use_master_seed True. 

By default all user should backup private keys instead of generating a few million key in a limited private key space between 0x1 and 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4140.

While using a seed is good if any of the addresses get compromised from the range of generated private keys an attacker can compromise all and every site generated using that seed!

So, generate a new randomly-selected private key for each new address and let the user practice backing up private keys.
@ghost
Copy link
Author

ghost commented Apr 9, 2020

@imachug @HelloZeroNet
Consider giving for users private keys in xprv format and not in WIF.
The option to use master_seed should be turned off by default.

https://raw.githubusercontent.com/AbdussamadA/electrum-xprv/master/xprv.py

#!/usr/bin/python3
from electrum import bip32
import ecdsa, sys, datetime, argparse

default_derivation_path = "m/"
key_types = [ 'standard', 'p2wpkh', 'p2wpkh-p2sh', 'p2wsh-p2sh', 'p2pkh', 'p2wsh' ]
entropy_size = 32 #in bytes

parser = argparse.ArgumentParser( description="Generate extended keys" )

mkey_group = parser.add_mutually_exclusive_group( required=True )
mkey_group.add_argument( "-g", "--generate-master", help="Generate master private key of a given type", choices=key_types, dest="gen_master")
mkey_group.add_argument( "-m", "--master", help="provide master private key "-" to read from stdin", dest="master_key" )

parser.add_argument( "-c", "--convert", help="Convert provided master key to this type", choices=key_types, dest="convert" )

output_group = parser.add_argument_group(description="Output options")
output_group.add_argument( "-d", "--derivation-path", help="derivation path", dest="derivation_path", default=default_derivation_path)
output_group.add_argument( "-p", "--xprv", help="Generate xprv (default is xpub)", action="store_true", dest="output_xprv" )

args = parser.parse_args()

if args.gen_master:
key_type = args.gen_master if args.gen_master != "p2pkh" else "standard"
entropy = ecdsa.util.randrange( pow( 2, entropy_size * 8 ) )
entropy_in_bytes = entropy.to_bytes( entropy_size , sys.byteorder )
master_key = bip32.BIP32Node.from_rootseed( seed=entropy_in_bytes, xtype=key_type )
elif args.master_key:
try:
master_key = bip32.BIP32Node.from_xkey( sys.stdin.readline().strip() if args.master_key == '-' else args.master_key )
except BaseException:
sys.exit( "Invalid master key\n" )

if args.convert:
if args.gen_master:
sys.exit( "Convert option cannot be used with generate master option" )
else:
convert_type = args.convert if args.convert !="p2pkh" else "standard"
master_key = master_key._replace( xtype=convert_type )

derivation_path = args.derivation_path if args.derivation_path != "m" else "m/"
if bip32.is_bip32_derivation( derivation_path ):
if not master_key.is_private():
if args.output_xprv:
sys.exit( "Cannot derive extended private key from extended public key\n" )
if derivation_path == "m/":
print( master_key.to_xpub() )
else:
try:
xpub = master_key.subkey_at_public_derivation( derivation_path )
sys.stderr.write( "Derivation Path: {}\n".format( derivation_path ) )
except BaseException:
sys.exit( "Invalid derivation path. Private derivation is not possible with extended public keys.\n" )
else:
print( xpub.to_xpub() )
else:
try:
derived_key = master_key.subkey_at_private_derivation( derivation_path )
sys.stderr.write( "Derivation Path: {}\n".format( derivation_path ) )
except BaseException:
sys.stderr.write( "Invalid derivation path\n" )
else:
if args.output_xprv:
print( derived_key.to_xprv() )
else:
print( derived_key.to_xpub() )
else:
print( "Incorrect derivation path" )

@imachug :
entropy = ecdsa.util.randrange( pow( 2, entropy_size * 8 ) )
entropy_in_bytes = entropy.to_bytes( entropy_size , sys.byteorder )
master_key = bip32.BIP32Node.from_rootseed( seed=entropy_in_bytes, xtype=key_type )

@purplesyringa
Copy link
Contributor

purplesyringa commented Apr 9, 2020

And now for something completely different: private keys are generated in the same range without master_seed.

@purplesyringa
Copy link
Contributor

While using a seed is good if any of the addresses get compromised from the range of generated private keys an attacker can compromise all and every site generated using that seed!

Please elaborate on how this attack could be performed. AFAIK BIP32 was created to have a single private key that can't be compromised if any derived key is stolen.

@ghost
Copy link
Author

ghost commented Apr 9, 2020

And now for something completely different: private keys are generated in the same range without master_seed.

@imachug
Without master_seed private keys are completely random! They are not generated from the range like BIP32 keys. You have a range let's say 1000-10000, your seed is xyz which gives you xy keys from 8548-9300 which means if a private key is compromised in your given range, a simple "brute force" (generating millions of keys in + - in xy range) will compromise all of your private keys.
In this case doesn't matter the seed because while the seed is not known, all your sites are compromised.

@purplesyringa
Copy link
Contributor

They are not generated from the range like BIP32 keys. You have a range let's say 1000-10000, your seed is xyz which gives you xy keys from 8548-9300 which means if a private key is compromised in your given range, a simple "brute force" (generating millions of keys in + - in xy range) will compromise all of your private keys.

Huh, if you think the private key is generated as seed || inttobytes(id) (or similar), you're really wrong. The fact that the range is smaller is definitely true, but it's 100'000'000 keys, not 10'000. This, uh, ought to be enough for anybody.

@ghost
Copy link
Author

ghost commented Apr 9, 2020

They are not generated from the range like BIP32 keys. You have a range let's say 1000-10000, your seed is xyz which gives you xy keys from 8548-9300 which means if a private key is compromised in your given range, a simple "brute force" (generating millions of keys in + - in xy range) will compromise all of your private keys.

Huh, if you think the private key is generated as seed || inttobytes(id) (or similar), you're really wrong. The fact that the range is smaller is definitely true, but it's 100'000'000 keys, not 10'000. This, uh, ought to be enough for anybody.

10000 was just an example. I can use a hybrid quantum computer at https://www.dwavesys.com to run a python code and generate 100,000,000 private keys in a given range in a few minutes. With 64 GB RAM is also just a few hour really.

Overall, this pull request should be merged and the use of master_seed should be "False" by default.

@purplesyringa
Copy link
Contributor

generate 100,000,000 private keys in a given range in a few minutes

Again, the private keys are not in a given range, they are almost random. Think of BIP32 as of a deterministic random key generator.

@ghost
Copy link
Author

ghost commented Apr 9, 2020

generate 100,000,000 private keys in a given range in a few minutes

Again, the private keys are not in a given range, they are almost random. Think of BIP32 as of a deterministic random key generator.

I'm not in favor of BIP32 because keys are related to each other in a way which is dangerous.

Any private key which exposed in BIP32 helps attacker determinate the location of the range and so the other private keys. All private key should be generated randomly without any seed and independently from each other, meaning not generating from a randrange.

@purplesyringa
Copy link
Contributor

Okay, I've done some research and found out that all private keys can only be recovered if the master public key is known and some private key is known. The first sounds impossible because we only share (sometimes, accidentally) the master address, and recovering the public key from an address is impossible AFAIK.

@ghost
Copy link
Author

ghost commented Apr 10, 2020

Each private key below the master key is generated from a range, that is why you have something called index. If one or more private key are compromised, you convert that key to a big integer and you will get a very good idea about the range of the other private keys.

BIP32 is helps in recovery of all of your private key to all of your site at once, it is not secure at all! BIP32 is created for the idiots who not backing up keys, no security or anything like that if one or more keys compromised in the range.

@filips123
Copy link
Contributor

BIP32 is created for the idiots who not backing up keys

Except that Bitcoin developers and community recommend to not use "normal" private keys and to use deterministic wallets instead...

Source

@ghost
Copy link
Author

ghost commented Apr 10, 2020

BIP32 is created for the idiots who not backing up keys

Except that Bitcoin developers and community recommend to not use "normal" private keys and to use deterministic wallets instead...

Source

Theymos (the owner of bitcoin.it domain) is a maniac liar. He has self interest. For example Wikipedia says that BitcoinTalk.org is founded by Satoshi Nakamoto which is false! Satoshi Nakamoto never published a single post on BitcoinTalk.org which registered by Theymos in 2011.

You can reuse your Bitcoin address how much time you want if the private key is secure! BIP32 is a big trash when it comes to security. So yes, we don't need BIP32 "super seed" in ZeroNet by default. It should be turned off and everyone should back up the private keys, like how ZeroNet ask you to do when you siteCreate without "master_seed".

@filips123 Bitcoin developers are on GitHub which is funny, I would expect them to develop Bitcoin in a decentralized manner not on Microsoft. @imachug have a very good GitHub alternative. ;)

@purplesyringa
Copy link
Contributor

purplesyringa commented Apr 10, 2020

Each private key below the master key is generated from a range, that is why you have something called index. If one or more private key are compromised, you convert that key to a big integer and you will get a very good idea about the range of the other private keys.

You don't have to be so specific, I have a good enough overview on elliptic curve cryptography.

Let's take a look at my implementation of BIP32 non-hardened keys:

# Round 1
h = hmac.new(key=b"Bitcoin seed", msg=seed, digestmod="sha512").digest()
private_key1 = h[:32]
x, y = self.private_to_public(private_key1)
public_key1 = bytes([0x02 + (y[-1] % 2)]) + x
private_key1 = bytes_to_int(private_key1)

# Round 2
msg = public_key1 + self._int_to_bytes(child, 4)
h = hmac.new(key=h[32:], msg=msg, digestmod="sha512").digest()
private_key2 = bytes_to_int(h[:32])

return self._int_to_bytes((private_key1 + private_key2) % self.n)

The first part computes the base of the private key by using HMAC. The second part uses HMAC and the child ID to generate the offset. It's true that if the second part was just private_key2 = child or similar, there would be a range of private keys: base, base+1, ..., base+maxchild.

Luckily, the offset is not calculated in such a silly way, it's HMAC which uses both the child number and the seed. So, you know that the private key is base + HMAC(chain_key, public_key || child), but you know neither base, nor chain_key, nor public_key.

Here's how the attack you mentioned works: notice that if the public key and the chain key were both known and you somehow got a private key of some site, it would become possible to compute HMAC(chain_key, public_key || child), then subtract this from the known private key to get base and then use the formula to get any private key you want.

Luckily, in our case, if master_seed (it's called seed in the code above) is not stolen, there's no way to recover any other private keys because there's no way to get the public key and the chain key. Please notice that even if someone accidentally publishes his master address, this is not a problem because there's no way to recover a public key from an address.

In conclusion: your attack can't be performed on ZeroNet.

@purplesyringa
Copy link
Contributor

You don't get it do you? There is no reason to base ZeroNet in Bitcoin if you don't receive any funds to those addresses! For example an investigative journalist may turn to ZeroNet and able to receive funds directly to his site address, when he spends the part you wrote about public key is broken.

We don't use Bitcoin, we use secp256k1 and BIP32, i.e. Bitcoin cryptography, these are different things.

I'm understanding your last message as "Pretend if someone uses the same private key for both their ZeroNet site and their Bitcoin wallet. In this case, their funds and other sites may be in danger". Do I get it right?

Please notice that importing your master seed from Bitcoin to ZeroNet is just shooting yourself in the foot.

@purplesyringa
Copy link
Contributor

What's the advantage of using xprv instead of WIF?

@ghost
Copy link
Author

ghost commented Apr 10, 2020

What's the advantage of using xprv instead of WIF?

@imachug
Nothing in ZeroNet's case because ZeroNet just pretends that "zites" using Bitcoin public keys for addressing.

@ghost
Copy link
Author

ghost commented Apr 10, 2020

We don't use Bitcoin, we use secp256k1 and BIP32, i.e. Bitcoin cryptography, these are different things.

I'm understanding your last message as "Pretend if someone uses the same private key for both their ZeroNet site and their Bitcoin wallet. In this case, their funds and other sites may be in danger". Do I get it right?

So you telling me that 1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D is not a valid Bitcoin address and is dangerous to receive funds into this address or you say that the WIF private key can't be used to spend the received funds from this address?

You say "Bitcoin cryptography" while in reality files are hashed using sha512 which by itself very secure. So tell me @imachug what the hell is 1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D, is not a valid Bitcoin address?

@HelloZeroNet https://www.blockchain.com/btc/address/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D Not valid for sure and your funds are in big danger right @imachug?

@ghost
Copy link
Author

ghost commented Apr 10, 2020

@HelloZeroNet would be nice to hear from you regarding "we don't use Bitcoin" thing what @imachug posted..

@ghost
Copy link
Author

ghost commented Apr 10, 2020

🤣 https://www.blockchain.com/btc/tx/43954c4e0b411e599b3d805a77063a03226d13be38a118b4ea7e418e45dae619 is clearly showing that @shortcutme has spent from 1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D so tell me @imachug that ZeroNet is not using Bitcoin public keys for addressing or that is dangerous to send funds to the addresses generated by ZeroNet! Hey, @filips123 say something, help imachug because he is very tired and lost his mind....

Public key for 1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D is 0486a00bddb1e4d12022319d84ab18ee5a7b313dd54ee5dd58495e450c1b8b3e2ea3debb6a873ad2f0ff137aefa038fb362777b2f573f163c9104bc37f4f8290bc

I see no problem with Sigscript so the funds on @HelloZeroNet are secure. (not according to @imachug who even say this is not a Bitcoin address 🤣 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants