Electrum is a deterministic wallet where all bitcoin private keys are derived from a single seed. That means that you only have to backup the seed once and it’s good for life. It also means that should the seed be compromised all your bitcoins can be stolen. So let’s look at how electrum seeds are created and secured.
Electrum generates a random seed for a new wallet when you first run it. The seed is a 128 bit random number that is generated by using an “operating system specific randomness source”. Under Linux and Unix like operating systems including Mac OS X that is /dev/urandom and under Windows it is CryptGenRandom().
Electrum employs what is called “key stretching” to increase the security of your wallet seed. Key stretching is a computationally intensive process that is used for two main reasons:
– To make it harder for anyone to try and crack your seed. For a legitimate user the time it takes to do key stretching is negligible but for an attacker that is trying to brute force keys it can be prohibitive.
– To make low entropy seeds safer. Human beings are not a good source of randomness which is why the Electrum seed is computer generated. However, Electrum allows you to enter your own human generated seed if you want to. Key stretching is used to make such seeds harder to attack.
Current versions of electrum run the seed through SHA256 a 100,000 times:
1 2 3 4 5
def stretch_key(self,seed): oldseed = seed for i in range(100000): seed = hashlib.sha256(seed + oldseed).digest() return string_to_number( seed )
From Electrum 2.0 it will be using a specialized Key Derivation function:
1 2 3 4 5
def mnemonic_to_seed(mnemonic, passphrase): from pbkdf2 import PBKDF2 import hmac PBKDF2_ROUNDS = 2048 return PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations = PBKDF2_ROUNDS, macmodule = hmac, digestmodule = hashlib.sha512).read(64)
This approach is standardized by a number of wallet developers including the trezor guys.
To make the Electrum seed more human friendly it is represented as a mnemonic. 12 words out of a dictionary of around 1600 words is enough to represent a 128 bit seed. A common question is whether this is safe? This is safe because the seed itself is a randomly generated 128bit number. The only thing that’s changing is how it is encoded or represented.
The dictionary is found in mnemonic.py and you can actually call that file directly with a hexadecimal number to convert it into a mnemonic:
#-> python mnemonic.py 06c20cf2a83b87005b95e12e85ebee0a style ourselves couple reply cause delight follow throat march also past peer
Just about any hexadecimal number can be an Electrum seed. A safe way to generate a custom electrum seed is using openssl:
openssl rand -hex 32
The above command will spit out a random 256 bit number. To use this as your electrum seed you will need to create a new wallet. You can do this using the command line:
electrum -w /path/to/new/wallet
Or using the file menu > new/restore command. If you choose this latter route you will be shown a file dialog box and you have to navigate to a suitable location on your file system and enter a suitable wallet file name. Click save and you’ll be shown the familiar new wallet creation dialog box:
Choose to restore from seed and enter your hexadecimal seed in the next dialog box to create your wallet.
You can use any size seed you want but there is a caveat. If your seed is greater than 128bits you won’t be able to restore from seed in Electrum 2.0 and later versions. You can still use the soft copy wallet file because that contains the seed version. But not the bare seed.
Electrum 2.0 will have a new seed format that will embed the seed version within the seed. It will also allow you to use arbitrary size seeds although the process of doing so is going to be more complicated.