I am reading through both of these code bases for the first time. What I have written here is just my take on what's going on.
Does bitaddress.org use the same method to create a brain wallet as electrumThey do not use the same method to generate private keys from a seed.
bitaddress.org --
https://github.com/pointbiz/bitaddress.org/blob/master/bitaddress.org.html#L3724Electrum --
https://github.com/spesmilo/electrum/blob/master/lib/wallet.py#L272With bitaddress.org, the seed that you enter is run through SHA256 to generate the private key.
var bytes = Crypto.SHA256(key, { asBytes: true });
var btcKey = new Bitcoin.ECKey(bytes);
In contrast, Electrum uses a random number generator to pick a seed for you.
seed = "%032x"%ecdsa.util.randrange( pow(2,128) )
The seed then goes through 100,000 rounds of SHA256 concatenated with itself to generate the private key.
oldseed = seed
for i in range(100000):
seed = hashlib.sha256(seed + oldseed).digest()
Does anyone know how electrum does it?Electrum generates multiple addresses from a single seed by concatenating the previous private key with a double SHA256 hash of the sequence number of the address being generated.
secexp = ( secexp + self.get_sequence(n,for_change) ) % order
def get_sequence(self,n,for_change):
return string_to_number( Hash( "%d:%d:"%(n,for_change) + self.master_public_key ) )
def Hash(data):
return hashlib.sha256(hashlib.sha256(data).digest()).digest()
- secexp is the secret exponent, i.e., the private key
- n is the sequence number of the address (1, 2, 3, etc.) being generated
- for_change is a 1 or 0 value that indicates whether or not this is a change address
- order is the number of discrete points on the elliptic curve, and modding keeps the private key in range
- As far as I can tell from the code, self.master_public_key will always be an empty string
Does anyone see a problem with the above scheme?I'm not a cryptography expert so I can't say anything definitively. Given that bitaddress.org only uses one SHA256 pass to encrypt the passphrase, I'd say there's a good chance that it's a bad idea just to append a number to the seed.
You may want to do something like what Electrum does -- concatenate the private key of the previous address with a hash based on the sequence number (e.g. SHA256 the string '2' for the second address) and mod the result by the maximum value for the private key.