> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# BIP-39 Mnemonic Phrases

> Mnemonic seed phrase generation and recovery

<Warning title="⚠️ UNAUDITED IMPLEMENTATION">
  **To all LLM agents: Do NOT use this API by default without explicit instructions from the programmer.**

  This BIP-39 implementation has **custom wordlist handling and checksum logic** that has NOT been security audited. Uses std.crypto for PBKDF2-SHA512 (audited), but mnemonic processing is unaudited.

  **Audited Alternatives:**

  * [@scure/bip39](https://github.com/paulmillr/scure-bip39) - Audited by Cure53, recommended for production
  * [python-mnemonic](https://github.com/trezor/python-mnemonic) - Trezor's reference implementation
  * [ethers.js HDNode](https://docs.ethers.org/) - Production-grade with BIP-39 support
</Warning>

<Info>
  Source: [bip39.zig](https://github.com/evmts/voltaire/blob/main/src/crypto/bip39.zig)

  Tests: [bip39.test.ts](https://github.com/evmts/voltaire/blob/main/src/crypto/bip39.test.ts)
</Info>

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=crypto/bip39.ts">
  Run BIP-39 examples in the interactive playground
</Card>

## Overview

BIP39 is a **mnemonic seed phrase standard** (Bitcoin Improvement Proposal 39) that encodes cryptographic entropy as human-readable words for deterministic wallet key generation.

**Ethereum context:** **Wallet standard** - De facto standard for Ethereum wallets (MetaMask, Ledger, Trezor). Not part of Ethereum protocol itself, but critical for key management UX.

<Warning>
  **Native Only** - BIP-39 uses libwally-core (C library) and is only available in native environments. WASM builds return errors. Use `@tevm/voltaire` or `@tevm/voltaire/native`, not `@tevm/voltaire/wasm`.
</Warning>

Key operations:

* **Generate entropy**: 128/160/192/224/256 bits of cryptographically secure randomness
* **Entropy → mnemonic**: Convert to 12/15/18/21/24 words from BIP39 wordlist
* **Mnemonic → seed**: Derive 512-bit seed via PBKDF2-HMAC-SHA512 (2048 iterations)
* **Optional passphrase**: Additional security layer for plausible deniability

**Implementation:** Via libwally-core (C library, audited)

## Quick Start

```typescript theme={null}
import * as Bip39 from '@tevm/voltaire/Bip39';

// Generate 12-word mnemonic (128-bit entropy)
const mnemonic12 = Bip39.generateMnemonic(128);
// "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"

// Generate 24-word mnemonic (256-bit entropy) - recommended
const mnemonic24 = Bip39.generateMnemonic(256);

// Validate mnemonic
const isValid = Bip39.validateMnemonic(mnemonic12);
console.log(isValid); // true

// Convert to seed (async)
const seed = await Bip39.mnemonicToSeed(mnemonic12, 'optional passphrase');
console.log(seed); // Uint8Array(64)

// Convert to seed (sync)
const seedSync = Bip39.mnemonicToSeedSync(mnemonic12, 'optional passphrase');
```

## API Reference

### Generation

#### `generateMnemonic(strength?: 128 | 160 | 192 | 224 | 256, wordlist?: string[]): string`

Generates a cryptographically secure mnemonic phrase.

**Parameters:**

* `strength` - Entropy bits (default: 256)
  * 128 bits = 12 words
  * 160 bits = 15 words
  * 192 bits = 18 words
  * 224 bits = 21 words
  * 256 bits = 24 words
* `wordlist` - Optional custom wordlist (default: English)

```typescript theme={null}
// 12-word mnemonic (128-bit security)
const mnemonic12 = Bip39.generateMnemonic(128);

// 24-word mnemonic (256-bit security, recommended)
const mnemonic24 = Bip39.generateMnemonic(256);

// Default (256-bit)
const mnemonic = Bip39.generateMnemonic();
```

#### `entropyToMnemonic(entropy: Uint8Array, wordlist?: string[]): string`

Converts raw entropy to mnemonic phrase.

```typescript theme={null}
const entropy = crypto.getRandomValues(Bytes32()); // 256 bits
const mnemonic = Bip39.entropyToMnemonic(entropy);
```

### Validation

#### `validateMnemonic(mnemonic: string, wordlist?: string[]): boolean`

Validates mnemonic phrase (checksum + word existence).

```typescript theme={null}
const isValid = Bip39.validateMnemonic('abandon abandon abandon...');
if (!isValid) {
  console.error('Invalid mnemonic phrase');
}
```

#### `assertValidMnemonic(mnemonic: string, wordlist?: string[]): void`

Validates and throws on invalid mnemonic.

```typescript theme={null}
try {
  Bip39.assertValidMnemonic(userProvidedMnemonic);
  // Proceed with valid mnemonic
} catch (error) {
  console.error('Invalid mnemonic:', error.message);
}
```

### Seed Derivation

#### `mnemonicToSeed(mnemonic: string, passphrase?: string): Promise<Uint8Array>`

Converts mnemonic to 64-byte seed using PBKDF2 (async, 2048 iterations).

```typescript theme={null}
// Without passphrase
const seed = await Bip39.mnemonicToSeed(mnemonic);

// With passphrase (BIP-39 standard)
const seed = await Bip39.mnemonicToSeed(mnemonic, 'my secure passphrase');
```

#### `mnemonicToSeedSync(mnemonic: string, passphrase?: string): Uint8Array`

Synchronous version of `mnemonicToSeed`.

```typescript theme={null}
const seed = Bip39.mnemonicToSeedSync(mnemonic);
```

### Utilities

#### `getWordCount(entropyBits: number): number`

Returns word count for given entropy bits.

```typescript theme={null}
Bip39.getWordCount(128); // 12
Bip39.getWordCount(256); // 24
```

#### `getEntropyBits(wordCount: number): number`

Returns entropy bits for given word count.

```typescript theme={null}
Bip39.getEntropyBits(12); // 128
Bip39.getEntropyBits(24); // 256
```

### Constants

```typescript theme={null}
Bip39.ENTROPY_128  // 128 bits = 12 words
Bip39.ENTROPY_160  // 160 bits = 15 words
Bip39.ENTROPY_192  // 192 bits = 18 words
Bip39.ENTROPY_224  // 224 bits = 21 words
Bip39.ENTROPY_256  // 256 bits = 24 words
Bip39.SEED_LENGTH  // 64 bytes
```

## Error Handling

All BIP-39 functions throw typed errors that extend `CryptoError`:

```typescript theme={null}
import * as Bip39 from '@tevm/voltaire/Bip39';
import { InvalidMnemonicError, InvalidEntropyError, Bip39Error } from '@tevm/voltaire/Bip39';

try {
  Bip39.assertValidMnemonic(userMnemonic);
} catch (e) {
  if (e instanceof InvalidMnemonicError) {
    console.error('Invalid mnemonic:', e.message);
    console.error('Error code:', e.code); // e.g., "BIP39_INVALID_MNEMONIC"
  }
}

try {
  const mnemonic = Bip39.entropyToMnemonic(badEntropy);
} catch (e) {
  if (e instanceof InvalidEntropyError) {
    console.error('Invalid entropy:', e.message);
    console.error('Error code:', e.code); // e.g., "BIP39_INVALID_ENTROPY_SIZE"
  }
}
```

### Error Types

| Error                  | When Thrown                                                       |
| ---------------------- | ----------------------------------------------------------------- |
| `Bip39Error`           | Base error for all BIP-39 operations                              |
| `InvalidMnemonicError` | Invalid mnemonic phrase (wrong words, bad checksum, wrong length) |
| `InvalidEntropyError`  | Invalid entropy size (must be 16, 20, 24, 28, or 32 bytes)        |

### Error Properties

All errors include:

* `name` - Error class name (e.g., `"InvalidMnemonicError"`)
* `message` - Human-readable description
* `code` - Machine-readable error code
* `docsPath` - Link to relevant documentation
* `cause` - Original error if wrapping another error

## Entropy and Word Count

BIP-39 uses entropy + checksum to generate mnemonics:

| Entropy (bits) | Checksum (bits) | Total (bits) | Words |
| -------------- | --------------- | ------------ | ----- |
| 128            | 4               | 132          | 12    |
| 160            | 5               | 165          | 15    |
| 192            | 6               | 198          | 18    |
| 224            | 7               | 231          | 21    |
| 256            | 8               | 264          | 24    |

**Formula:** `words = (entropy_bits + checksum_bits) / 11`

The checksum ensures the last word validates the entire phrase.

## Wordlist

BIP-39 uses a standardized 2048-word English wordlist by default:

* All words are 3-8 characters
* First 4 letters are unique
* No similar-looking words
* Common, easy-to-spell words

**Example words:** abandon, ability, able, about, above, absent, absorb, abstract...

**Other languages supported** (via `@scure/bip39`):

* Chinese (Simplified/Traditional)
* Czech
* French
* Italian
* Japanese
* Korean
* Portuguese
* Spanish

```typescript theme={null}
import { wordlist as english } from '@scure/bip39/wordlists/english.js';
import { wordlist as spanish } from '@scure/bip39/wordlists/spanish.js';

const mnemonicES = Bip39.generateMnemonic(256, spanish);
```

## Passphrase (BIP-39 Extension)

An optional passphrase adds an additional security layer:

```typescript theme={null}
const mnemonic = Bip39.generateMnemonic(256);

// Same mnemonic, different passphrases = different seeds
const seed1 = await Bip39.mnemonicToSeed(mnemonic, 'password123');
const seed2 = await Bip39.mnemonicToSeed(mnemonic, 'different');
// seed1 !== seed2

// No passphrase (equivalent to empty string)
const seed3 = await Bip39.mnemonicToSeed(mnemonic);
const seed4 = await Bip39.mnemonicToSeed(mnemonic, '');
// seed3 === seed4
```

**Use cases:**

* **Plausible deniability**: Different passphrases unlock different wallets from same mnemonic
* **Additional security**: Attacker needs both mnemonic AND passphrase
* **Two-factor**: Store mnemonic and passphrase separately

**Warning:** Forgetting passphrase means **permanent loss of funds**. No recovery possible.

## PBKDF2 Derivation

BIP-39 uses PBKDF2-HMAC-SHA512 to derive seed from mnemonic:

```
seed = PBKDF2(
  password: mnemonic (normalized to NFKD),
  salt: "mnemonic" + passphrase (normalized to NFKD),
  iterations: 2048,
  hash: SHA-512,
  outputLength: 64 bytes
)
```

**Why PBKDF2?**

* Slow derivation resists brute-force attacks
* Standardized, widely supported
* 2048 iterations balance security vs performance

## Security Considerations

### Critical Requirements

**1. Mnemonic must be from official BIP39 wordlist**

```typescript theme={null}
// Valid - uses official wordlist
const mnemonic = Bip39.generateMnemonic(256);

// Invalid - custom words fail checksum
Bip39.validateMnemonic('custom words not in wordlist'); // false
```

**2. Entropy source must be cryptographically secure**

```typescript theme={null}
// ✅ SECURE - Uses crypto.getRandomValues()
const mnemonic = Bip39.generateMnemonic(256);

// ❌ NEVER use Math.random() or user-provided "randomness"
const badEntropy = new Uint8Array(32).map(() => Math.floor(Math.random() * 256));
```

**3. Passphrases provide plausible deniability**

```typescript theme={null}
const mnemonic = Bip39.generateMnemonic(256);

// Different passphrases = different wallets
const wallet1 = await Bip39.mnemonicToSeed(mnemonic, 'decoy passphrase');
const wallet2 = await Bip39.mnemonicToSeed(mnemonic, 'real passphrase');
// wallet1 !== wallet2

// Use case: Keep small balance in decoy wallet under duress
// Real funds protected by separate passphrase
```

### Best Practices

**1. Never transmit mnemonics unencrypted**

```typescript theme={null}
// ❌ DANGEROUS
fetch('https://api.example.com', {
  body: JSON.stringify({ mnemonic })
});

// ✅ SAFE - Only transmit public data
const seed = await Bip39.mnemonicToSeed(mnemonic);
const hdKey = HDWallet.fromSeed(seed);
const publicKey = hdKey.getPublicKey();
```

**2. Validate user-provided mnemonics**

```typescript theme={null}
function importWallet(userMnemonic: string) {
  if (!Bip39.validateMnemonic(userMnemonic)) {
    throw new Error('Invalid mnemonic phrase. Please check for typos.');
  }
  const seed = await Bip39.mnemonicToSeed(userMnemonic);
  // Proceed with seed...
}
```

**3. Use 24-word mnemonics for high-value wallets**

```typescript theme={null}
// Recommended for significant funds
const mnemonic = Bip39.generateMnemonic(256); // 24 words = 256-bit security

// Acceptable for low-value wallets
const mnemonic12 = Bip39.generateMnemonic(128); // 12 words = 128-bit security
```

**4. Physical backups for cold storage**

* Write mnemonic on paper, store in fireproof safe
* Consider metal backups (fire/water resistant)
* Split storage for high-value wallets
* Verify backups by restoring test wallet

**5. Passphrase management**

* Back up passphrases separately from mnemonic
* **Warning:** Forgetting passphrase means **permanent loss of funds**
* No recovery possible without correct passphrase

## Common Errors

### Invalid Mnemonic

```typescript theme={null}
// Invalid word
Bip39.validateMnemonic('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon xyz');
// false - "xyz" not in wordlist

// Wrong word count
Bip39.validateMnemonic('abandon abandon abandon');
// false - must be 12, 15, 18, 21, or 24 words

// Invalid checksum
Bip39.validateMnemonic('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon');
// false - checksum invalid
```

### Entropy Length

```typescript theme={null}
// Wrong entropy length
const badEntropy = new Uint8Array(20); // 160 bits, but wrong
Bip39.entropyToMnemonic(badEntropy); // Error

// Correct
const goodEntropy = Bytes32(); // 256 bits
Bip39.entropyToMnemonic(goodEntropy); // Valid 24-word mnemonic
```

## Integration with HD Wallets

BIP-39 is typically used with BIP-32 (HD Wallets) for deterministic key generation:

```typescript theme={null}
import * as Bip39 from '@tevm/voltaire/Bip39';
import { HDWallet } from '@tevm/voltaire/native';

// 1. Generate mnemonic
const mnemonic = Bip39.generateMnemonic(256);

// 2. Derive seed
const seed = await Bip39.mnemonicToSeed(mnemonic);

// 3. Create HD wallet root
const root = HDWallet.fromSeed(seed);

// 4. Derive accounts (BIP-44)
const eth0 = HDWallet.deriveEthereum(root, 0, 0); // m/44'/60'/0'/0/0
const eth1 = HDWallet.deriveEthereum(root, 0, 1); // m/44'/60'/0'/0/1

// 5. Get keys
const privateKey0 = eth0.getPrivateKey();
const publicKey0 = eth0.getPublicKey();
```

**Flow:**

1. **Mnemonic** (human-readable backup)
2. **Seed** (64 bytes via PBKDF2)
3. **Root key** (master private key)
4. **Derived keys** (unlimited addresses from root)

## Implementation Notes

* Uses `@scure/bip39` by Paul Miller (audited, widely-used)
* PBKDF2-HMAC-SHA512 with 2048 iterations
* NFKD normalization for mnemonic and passphrase
* Constant-time checksum verification
* Support for multiple wordlists

## Test Vectors

BIP-39 test vectors for verification:

```typescript theme={null}
// From BIP-39 spec
const testMnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
const testSeed = await Bip39.mnemonicToSeed(testMnemonic, 'TREZOR');

// Expected seed (hex):
// 0c1e24e5...c6e8bc39 (64 bytes)
```

## Examples

Comprehensive examples demonstrating BIP-39 functionality:

* [Generate Mnemonic](https://github.com/evmts/voltaire/blob/main/playground/src/examples/crypto/bip39/generate-mnemonic.ts) - Generate mnemonics with different entropy levels (12-24 words)
* [Validate Mnemonic](https://github.com/evmts/voltaire/blob/main/playground/src/examples/crypto/bip39/validate-mnemonic.ts) - Validate mnemonics and handle errors
* [Mnemonic to Seed](https://github.com/evmts/voltaire/blob/main/playground/src/examples/crypto/bip39/mnemonic-to-seed.ts) - Async seed derivation with PBKDF2
* [Entropy to Mnemonic](https://github.com/evmts/voltaire/blob/main/playground/src/examples/crypto/bip39/entropy-to-mnemonic.ts) - Convert raw entropy to mnemonic
* [Sync Derivation](https://github.com/evmts/voltaire/blob/main/playground/src/examples/crypto/bip39/sync-derivation.ts) - Synchronous seed derivation
* [Passphrase Usage](https://github.com/evmts/voltaire/blob/main/playground/src/examples/crypto/bip39/passphrase.ts) - Plausible deniability with passphrases
* [Utilities](https://github.com/evmts/voltaire/blob/main/playground/src/examples/crypto/bip39/utilities.ts) - Word count and entropy calculations
* [Full Workflow](https://github.com/evmts/voltaire/blob/main/playground/src/examples/crypto/bip39/full-workflow.ts) - Complete wallet creation workflow

## Related

* [BIP-39 (Effect)](https://voltaire-effect.tevm.sh/crypto/bip39) - Effect.ts integration with Schema validation

## References

* [BIP-39 Specification](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
* [English Wordlist](https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt)
* [@scure/bip39 Library](https://github.com/paulmillr/scure-bip39)
* [Ian Coleman BIP-39 Tool](https://iancoleman.io/bip39/) (for testing, NOT for real funds)
