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.
Try it Live Run BIP39 examples in the interactive playground
Overview
BIP-39 mnemonic generation converts cryptographic entropy into human-readable word sequences. The process ensures deterministic, verifiable, and secure seed phrase creation.
Generation Process
1. Entropy Generation
Generate cryptographically secure random bytes:
import * as Bip39 from '@tevm/voltaire/Bip39' ;
// 128 bits = 12 words
const mnemonic12 = Bip39 . generateMnemonic ( 128 );
// 256 bits = 24 words (recommended)
const mnemonic24 = Bip39 . generateMnemonic ( 256 );
2. Entropy to Mnemonic Conversion
// Custom entropy (must be 16-32 bytes)
const entropy = crypto . getRandomValues ( Bytes32 ()); // 256 bits
const mnemonic = Bip39 . entropyToMnemonic ( entropy );
console . log ( mnemonic . split ( ' ' ). length ); // 24 words
3. Word Count Mapping
Entropy Bits Checksum Bits Total Bits Words Security Level 128 4 132 12 Standard 160 5 165 15 Enhanced 192 6 198 18 High 224 7 231 21 Very High 256 8 264 24 Maximum
Algorithm Details
Step-by-Step Process
1. Generate Entropy (ENT)
ENT = 128 to 256 bits (must be multiple of 32)
2. Calculate Checksum (CS)
CS = SHA256(ENT)[0:ENT/32 bits]
3. Concatenate
4. Split into 11-bit Groups
Each group = 0-2047 (maps to wordlist index)
Words = Binary / 11
5. Map to Wordlist
For each 11-bit group:
word = WORDLIST[group_value]
Example Calculation
// 128-bit entropy
const entropy = Bytes16 (). fill ( 0x00 );
// Binary representation
// 00000000 00000000 ... (128 bits of zeros)
// SHA256 checksum (first 4 bits)
// SHA256(entropy) = 374708fff7719dd5979ec875d56cd2286f6d3cf7ec317a3b25632aab28ec37bb
// First 4 bits: 0011 (3)
// Combined: 128 bits + 4 bits = 132 bits
// Split into 11-bit groups: 132 / 11 = 12 words
// First 11 bits: 00000000000 = 0 → "abandon"
// All zeros → all "abandon" except last word (includes checksum)
const result = Bip39 . entropyToMnemonic ( entropy );
// "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
Entropy Sources
Browser Environment
// Cryptographically secure random
const entropy = crypto . getRandomValues ( Bytes32 ());
const mnemonic = Bip39 . entropyToMnemonic ( entropy );
Node.js Environment
import { randomBytes } from 'crypto' ;
const entropy = randomBytes ( 32 ); // 256 bits
const mnemonic = Bip39 . entropyToMnemonic ( entropy );
Hardware Wallets
Hardware wallets use dedicated secure elements:
// Simulated hardware entropy (do not use in production)
// Real hardware uses secure element RNG
async function hardwareEntropy () {
// Request entropy from hardware device
const hwEntropy = await hardwareDevice . getRandomBytes ( 32 );
return Bip39 . entropyToMnemonic ( hwEntropy );
}
Utility Functions
Calculate Word Count
// Get word count for entropy bits
const wordCount = Bip39 . getWordCount ( 128 ); // 12
const wordCount2 = Bip39 . getWordCount ( 256 ); // 24
Calculate Entropy Bits
// Get entropy bits for word count
const entropy = Bip39 . getEntropyBits ( 12 ); // 128
const entropy2 = Bip39 . getEntropyBits ( 24 ); // 256
Security Considerations
Entropy Quality
Critical: Use cryptographically secure randomness
// ✅ SECURE - Uses crypto.getRandomValues()
const mnemonic = Bip39 . generateMnemonic ( 256 );
// ❌ INSECURE - Never use Math.random()
const badEntropy = Bytes32 ();
for ( let i = 0 ; i < 32 ; i ++ ) {
badEntropy [ i ] = Math . floor ( Math . random () * 256 ); // PREDICTABLE!
}
// ❌ INSECURE - Never use timestamp-based entropy
const timestamp = Date . now ();
const weakEntropy = Bytes32 (). fill ( timestamp & 0xFF );
Entropy Size Recommendations
Minimum: 128 bits (12 words)
Provides 2^128 possible combinations
Considered secure against brute force
Suitable for low-to-medium value wallets
Recommended: 256 bits (24 words)
Provides 2^256 possible combinations
Future-proof against quantum computers
Recommended for high-value wallets
// Low-value wallet (testing, small amounts)
const testWallet = Bip39 . generateMnemonic ( 128 );
// Production wallet (recommended)
const productionWallet = Bip39 . generateMnemonic ( 256 );
Deterministic Generation
Same entropy always produces same mnemonic:
const entropy = Bytes16 (). fill ( 0x42 );
const mnemonic1 = Bip39 . entropyToMnemonic ( entropy );
const mnemonic2 = Bip39 . entropyToMnemonic ( entropy );
console . log ( mnemonic1 === mnemonic2 ); // true
Offline Generation
Best practice: Generate mnemonics offline
// 1. Disconnect from network
// 2. Generate mnemonic
const mnemonic = Bip39 . generateMnemonic ( 256 );
// 3. Write on paper
// 4. Verify by restoring
const isValid = Bip39 . validateMnemonic ( mnemonic );
// 5. Clear browser/device memory
// 6. Reconnect to network
Advanced Usage
Custom Entropy Length
// 160 bits = 15 words
const mnemonic15 = Bip39 . generateMnemonic ( 160 );
// 192 bits = 18 words
const mnemonic18 = Bip39 . generateMnemonic ( 192 );
// 224 bits = 21 words
const mnemonic21 = Bip39 . generateMnemonic ( 224 );
Dice-Roll Entropy (Maximum Security)
For maximum paranoia, generate entropy manually:
// Roll 6-sided die 99 times for 256 bits
// Each roll contributes ~2.58 bits of entropy
function diceToEntropy ( rolls : number []) : Uint8Array {
// Convert base-6 to binary
let binary = '' ;
for ( const roll of rolls ) {
binary += ( roll - 1 ). toString ( 2 ). padStart ( 3 , '0' );
}
// Take first 256 bits
const entropy = Bytes32 ();
for ( let i = 0 ; i < 32 ; i ++ ) {
entropy [ i ] = parseInt ( binary . slice ( i * 8 , i * 8 + 8 ), 2 );
}
return entropy ;
}
// Example: 99 dice rolls
const diceRolls = [ 3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 , 5 , 3 , 5 , 8 , 9 , 7 , 9 , /* ... */ ];
const diceEntropy = diceToEntropy ( diceRolls );
const diceMnemonic = Bip39 . entropyToMnemonic ( diceEntropy );
Verifying Generation
// Generate mnemonic
const mnemonic = Bip39 . generateMnemonic ( 256 );
// Verify it's valid
const isValid = Bip39 . validateMnemonic ( mnemonic );
console . log ( isValid ); // true
// Verify word count
const words = mnemonic . split ( ' ' );
console . log ( words . length ); // 24
// Verify deterministic
const seed1 = await Bip39 . mnemonicToSeed ( mnemonic );
const seed2 = await Bip39 . mnemonicToSeed ( mnemonic );
console . log ( seed1 . every (( byte , i ) => byte === seed2 [ i ])); // true
Common Errors
Invalid Entropy Length
// ❌ Invalid - 20 bytes (160 bits) not supported in this example
const invalidEntropy = new Uint8Array ( 20 );
// Use 16, 20, 24, 28, or 32 bytes
// ✅ Valid
const validEntropy = Bytes32 (); // 256 bits
Non-Random Entropy
// ❌ DANGEROUS - Sequential pattern
const sequential = Bytes32 ();
for ( let i = 0 ; i < 32 ; i ++ ) {
sequential [ i ] = i ;
}
// ❌ DANGEROUS - All same value
const constant = Bytes32 (). fill ( 0xFF );
// ✅ SECURE - Cryptographic randomness
const secure = crypto . getRandomValues ( Bytes32 ());
Implementation Details
Uses @scure/bip39 by Paul Miller:
Audited implementation
Constant-time checksum validation
Support for multiple wordlists
NFKD normalization
Strict BIP-39 compliance
Examples
References