Everything You Need to Know About Converting Mnemonic Phrases to ETH Addresses

·

Written by LXDAO Buidler: 0xhardman
This guide demonstrates how to convert a mnemonic phrase to an Ethereum address using Rust, offering blockchain developers deeper insights into cryptographic principles and system architecture.


Introduction

Your Ethereum journey likely began with creating a mnemonic phrase via MetaMask. But how does that 12-word phrase transform into a functional ETH address? This article demystifies the process step-by-step while answering key questions:

  1. Can you create a mnemonic from a dictionary?
  2. Why are mnemonics sensitive?
  3. Can an ETH private key generate a BTC address?
  4. How do 12 words become a private key and address?

Why Rust?

Rust’s reliability and efficiency make it ideal for blockchain development. Ethereum ecosystem projects like Foundry (development toolkit) and Reth (protocol implementation) already leverage Rust’s capabilities.


Step-by-Step Conversion Process

Step 1: Generate Mnemonic Phrase

fn step1_generate_mnemonic() {
    let entropy = &[0x33, 0xE4, 0x6B, 0xB1, ...]; // 128-bit entropy
    let mnemonic = Mnemonic::from_entropy(entropy, Language::English).unwrap();
    println!("Mnemonic: {}", mnemonic.phrase());
}

Step 2: Mnemonic to Seed

fn step2_mnemonic_to_seed(mnemonic: &Mnemonic) -> String {
    let seed = Seed::new(mnemonic, "");
    hex::encode(seed.as_bytes()) // Returns 64-byte hex string
}

Step 3: Seed to Master Key

fn step3_seed_to_master_key(seed_hex: &String) -> (String, String) {
    let key = hmac::Key::new(hmac::HMAC_SHA512, b"Bitcoin seed");
    let tag = hmac::sign(&key, &hex::decode(seed_hex).unwrap());
    let (il, ir) = tag.as_ref().split_at(32);
    (hex::encode(il), hex::encode(ir)) // (master_key, chain_code)
}

Step 4: Derive Private Key via BIP32 Path

fn derive_with_path(master_key: SecretKey, chain_code: [u8; 32], path: &[u32; 5]) -> SecretKey {
    let mut private_key = master_key;
    for &i in path {
        (private_key, chain_code) = derive_child_key(i, private_key, chain_code);
    }
    private_key
}

Step 5: Private Key → Public Key

fn step5_private_key_to_public_key(private_key_hex: String) -> String {
    let private_key = SecretKey::from_slice(&hex::decode(private_key_hex).unwrap()).unwrap();
    hex::encode(serialize_curve_point(curve_point_from_int(private_key)))
}

Step 6: Public Key → ETH Address

fn step6_public_key_to_address(pub_key_hex: String) -> String {
    let public_key_bytes = &PublicKey::from_slice(&hex::decode(pub_key_hex).unwrap()).unwrap().serialize_uncompressed()[1..];
    let mut output = [0u8; 32];
    Keccak::v256().update(public_key_bytes).finalize(&mut output);
    hex::encode(&output[12..]) // Last 20 bytes
}

FAQs

Q1: Can I create a custom mnemonic from a dictionary?

No. Mnemonics require valid entropy + checksum per BIP39 standards.

Q2: Why is my mnemonic phrase sensitive?

It generates all derived private keys. Exposure risks asset theft across linked wallets.

Q3: Can an ETH private key generate a BTC address?

No. Different coins use unique BIP32 paths (e.g., Bitcoin: m/44’/0’/0’, ETH: m/44’/60’/0’/0).

Q4: How do 12 words become an address?

  1. Entropy → Mnemonic (BIP39).
  2. Mnemonic + PBKDF2 → Seed.
  3. Seed + HMAC-SHA512 → Master Key.
  4. Master Key + BIP32 path → Private Key.
  5. Private Key → Public Key → ETH Address (Keccak-256).

Recommended Tools


References

  1. Ethereum 201: Mnemonics – Medium Article
  2. BIP32/BIP44 Specifications – GitHub
  3. Converting Mnemonics to Keys – MDRZA Guide