iancoleman / bip39

A web tool for converting BIP39 mnemonic codes
https://iancoleman.io/bip39/
MIT License
3.41k stars 1.42k forks source link

Derived Addresses - Show more rows starting from index - differ with Electrum wallet starting from index 20 #639

Closed nullsavvy closed 11 months ago

nullsavvy commented 11 months ago

Mnemonic Code Converter; v0.5.4

Using default settings and the BIP39 Mnemonic; mystery sorry truck rural express wait method winner enforce logic gospel silent alone fantasy ride pilot price pool token chair dress mansion canvas current

Gives a list of 20 derived addresses ending with index 19

m/44'/0'/0'/0/19 | 1ExNZ3wknG2AvxmRwWVZ4KyFxFEaig1Mc2 | 031892f6aecf539e515098405a87cb0bcdbed4783b5921c074197430e9c8d93f78 | L4fRF35iJySPKzuMgNPTTk8mbWsLQBaxPL5xn5sztS7METCdSu7Q

Show more rows starting from index with a setting of 10 rows starting from (left blank) gives;

m/44'/0'/0'/0/20 | 1DCcxvVrj6tFrPfg4YZWYme4BYNS1d34D6 | 02e69c24dd22e7244ac88af356bb470145d4c807153623282aae79a42ee7ac951f | KxtdkL6mPZ3FTo4DDJuyLV9KrvQt2pD4gttZ5xLm9CNC89jtJjwB

m/44'/0'/0'/0/21 | 1NHueDEy5KtRjTtw6UviZee92MC81P8itw | 0314390dc92cdaa847804899662c0890647a3b2946919beeefd1342c3ecc197b98 | KwsqKsHvqPDh2YdTdcK9E1ACCwLLzTw2aKV4ifaZb2w2CN4A2uao

m/44'/0'/0'/0/22 | 18grScUvWQ1giG5fim2ZfcuLBkr17eqgyS | 034ad39f4dd5ee2be42965e6518fe448c2916e559e32b1dda1723e05cfb10ce189 | L2NRyk6z4jXgcL1EE9ZZ1HXoHCWPhLk9rhjonFPPxCh142TKhxX2

m/44'/0'/0'/0/23 . . . .

Electrum v4.4.5 From the menu select; Wallet -> Private keys -> Export to get a list of 30 keys which are equal to the Mnemonic converter up to index 19. Addresses and keys with index 20 to 29 are different.

19; 1ExNZ3wknG2AvxmRwWVZ4KyFxFEaig1Mc2 p2pkh:L4fRF35iJySPKzuMgNPTTk8mbWsLQBaxPL5xn5sztS7METCdSu7Q 20; 1Pf4nvfsT2CKwLQnYcgPxJwhPYYyNC9gCV p2pkh:L4rRmiSnsbcLSpkfXoHWacGMXET54C3BGFm6F6ZUcVoXWyDTBuCu 21; 1Kpxk91gKVd2NxV3rUrXZSh1qvSVmh1ANU p2pkh:L2BgzfZpynYpX4oSXETLi1UBQCsf7tcGsDXHipEzzmzomYSvzavw 22; 1EpuKpH4qK9eLocjK68tpJ3vdEW4swRidJ p2pkh:L3C5sDWh7gbHyeunLMMD1cGojXzsJbjyV3vb5L8Sc31zborfFC6j 23; . . . .

iancoleman commented 11 months ago

Thanks for this.

I reproduced the original discrepancy with electrum.

However bip32.org and rust crate bip32 both match this tool.


Testing further, bip32.org derivation matches this tool. So maybe electrum is not generating correctly? To reproduce:

Load http://bip32.org/

Enter Root Bip32 extended key xprv9s21ZrQH143K2RNTXyvRSpYo18F2u9zxag3PwCqZgZbyEATwSERJQixPzL5cXHrV7EiVPTWp1u5UTZ1gdYqcRVqf2bf4iapyxsLDYM7Vd68

Set Derivation Path to custom

Set Custom Path to m/44'/0'/0'/0/20

See the address is 1DCcxvVrj6tFrPfg4YZWYme4BYNS1d34D6 which matches this tool but does not match electrum


Testing further, rust crate bip32 also matches this tool. Minimal example:

use bip32::{Mnemonic, PublicKey, Prefix, XPrv};
fn main() {
    // Generate Mnemonic using the default language (English)
    let m = "mystery sorry truck rural express wait method winner enforce logic gospel silent alone fantasy ride pilot price pool token chair dress mansion canvas current";
    let mnemonic = Mnemonic::new(m, Default::default()).unwrap();
    // Derive a BIP39 seed value using the given password
    let seed = mnemonic.to_seed("");
    // Derive the root `XPrv` from the `seed` value
    let root_xprv = XPrv::new(&seed).unwrap();
    println!("Root xprv {:?}", root_xprv.to_string(Prefix::XPRV));
    // Derive a child `XPrv` using the provided BIP32 derivation path
    let child_path = "m/44'/0'/0'/0/20";
    let child_xprv = XPrv::derive_from_path(&seed, &child_path.parse().unwrap()).unwrap();
    // Get the `XPub` associated with `child_xprv`.
    let child_xpub = child_xprv.public_key();
    // Get the ECDSA/secp256k1 signing and verification keys for the xprv and xpub
    let verification_key = child_xpub.public_key();
    println!("Public Key Hex: {:x?}", verification_key.to_bytes());
}

Open to ideas about why this difference exists. I can't work out how to generate the electrum key at index 20.

nullsavvy commented 11 months ago

Sorry I'm not familiar enough with the matter to give any idea about why this difference exist. But thank you very much for the detailed problem analysis, which I can use to drop an issue at electrum. Maybe they can explain us what is happening at index 20.