nvk / walletsrecovery.org

Information about wallet defaults for external recovery
https://walletsrecovery.org/
115 stars 96 forks source link

Electrum derivation path is not really BIP44/49/84 #129

Closed andronoob closed 3 years ago

andronoob commented 3 years ago

There're two versions of Electrum seed system, the old one is a reversible encoding, the new one (Electrum2.0) is a variant of BIP39, which is one-way hashed to derive BIP32 entropy (thus the "root" master key/node).

Both are not compatible with BIP39.

I'm not familiar with pre-Electrum2.0 seed (the old Electrum seed). Maybe you can point me to the docs or the source code.

Here I'm describing Electrum2.0 seed only.

It seems that the offical documentation only mentions how the version bits (which is used as something like checksum as well) are defined. I don't see how the seed phrase can then derive into private keys (and addresses). Maybe I just haven't find it?

https://electrum.readthedocs.io/en/latest/seedphrase.html

In the source code, I find 4 types of the version bits, rather than 3 types described in the documentation:

https://github.com/spesmilo/electrum/blob/fdaf6e775cdbe461a8466d1d7e46360c8a90e4d7/electrum/version.py#L6

The BIP32 entropy is derived from the seed (mnemonic) phrase by 2048-round PBKDF2, using HMAC-SHA512, which is almostly the same to BIP39, the difference is that Electrum2.0 uses the string "electrum" + passphrase, while BIP39 uses the string "mnemonic" + passphrase:

https://github.com/spesmilo/electrum/blob/64a94e95225bdd62fd5aa8a6dec5ac27e03b9dae/electrum/mnemonic.py#L159

Pay attention that Electrum once had a bug (Electrum issue No.4566) around normalization of BIP39 passphrase, it once removed more whitespaces (like, deleting one whitespace from two consecutive whitespaces). I'm not sure how Electrum would treat passphrase of Electrum2.0 seed phrases.

I once encountered a lot of posts describing that Electrum2.0 uses derivation paths different than BIP44/49/84, which can be confirmed in the source code as well:

https://github.com/spesmilo/electrum/blob/9d0bb295e6f55a2bff9f5b6770fa744c16af6e8a/electrum/keystore.py#L975 https://github.com/spesmilo/electrum/blob/6058829870fde0ef17b2e08a567110ecc381ab94/electrum/plugins/trustedcoin/trustedcoin.py#L572

Seed Version Bit Type Derivation Path (splited keychain, aka using "internal chain" as change address)
0x01 standard m/ (could be used in multisig as well)
0x100 segwit m/0'/ (p2wpkh) or m/1'/ (p2wsh, for multisig)
0x101 2fa (2.7 or later, exactly 12 words) m/0'/ and m/1'/ (2 private keys in 2of3 multisig)
0x101 2fa (pre-2.7, more than 19 words) * m/ (derived from the leading 12 words) and m/ (derived from the 12th and later words) (2 private keys in 2of3 multisig)
0x102 2fa_segwit m/0'/ and m/1'/ (2 private keys in 2of3 multisig)

DISCLAIMER: although I have tried my best to make the info above accurate, I can't guarantee its accuracy.

nvk commented 3 years ago

I’m aware, we were keeping only the BIP39 option of Electrum here. If you want to make a pr and add the other Electrum options maybe as different rows I will merge it. Alternatively, you could create a separate document for Electrum like Casa did, and we could have a link on the Electrum table entry linking to it.

andronoob commented 3 years ago

Replied as a new issue: #132

nvk commented 3 years ago

cool.