2

Electrum version 2 creates a seed from a random number which is then encoded as a mnemonic. The seed is validated by checking that the hmac begins with the bytes 01 or 101 for standard and 2fa types, respectively.

I have looked at the python code on github and indeed it does return the 01 byte but I am still confused as to how one can ensure a hash is going to start with a predicted value (01\101).

How can this be so? Is it that I'm missing the nuance of what the code does or the concept of how hmac works

1 Answer 1

3

When creating a new seed, Electrum 2.x does pretty much the same thing as vanity address generators, or for that matter Bitcoin miners... it "grinds".

It generates a seed based on some entropy and a nonce, and checks if the seed's HMAC starts with the required byte sequence (the "checksum"). If it doesn't, it increments the nonce and checks its HMAC again.

If you're interested, the code which does this is here on GitHub.

It should be noted that Electrum seeds have (by default) 128 bits of entropy. As a result of this grinding, Electrum discards (for standard wallets with a checksum of 0x01) 255 out of every 256 potential seeds. This effectively decreases the entropy in a seed by 8 bits (the length of the checksum). In order to compensate for this, Electrum 2.x adds an additional 8 bits to the total seed length, which brings the seed length to 136 bits and the entropy back up to 128 bits.

7
  • Note that it's considerable faster than most vanity generators, since it only needs to do ~128 HMAC-SHA2 operations, which is really fast.
    – Nick ODell
    May 22, 2015 at 4:47
  • Ah ha so that's why the True loop is used. I thought it was being used just once as while old_seed seems more intuitive to me. I can see the rationale now, especially after running successfully finding numerous cases of Electrum 1 seeds which returned a 01 hmac. I'm curious... is it possible to implement a better system whereby an old seed can never be interpreted as a new seed or is this just the most appropriate given it's a hash based seed? May 22, 2015 at 6:09
  • 1
    @WizardOfOzzie One idea that comes to mind which Electrum could implement (but hasn't yet) is to throw out the standard BIP-39 wordlist, and use a custom one which shares no common words with the Electrum 1.x list. Electrum already eschews BIP-39, so there's no reason to keep the same wordlist. The BIP-39 wordlists aren't even all that good—they violate BIP-39's own recommendation of no similar words (auction/action, motion/emotion, garage/garbage, etc...). May 22, 2015 at 12:25
  • @ChristopherGurnee I was just about to raise the same solution after pondering it all day. It is a much better delineation both programmatically and intuitively IMO May 22, 2015 at 13:15
  • @nickodell you're right. I ran it to be sure :) While we're on the topic, what is the point of running the ecdsa.utils.randrange and incrementing the nonce when it's just as likely running the loop for a random number will return a valid seed? May 23, 2015 at 2:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.