This repository contains Go implementations of BIP39 (mnemonic codes) and BIP32/BIP44 (hierarchical deterministic wallets).
This package was created as a direct replacement for popular but now-deleted packages:
github.com/tyler-smith/go-bip39- A widely-used BIP39 implementation that was recently deleted
Many popular packages like github.com/miguelmota/go-ethereum-hdwallet are affected.
If you're looking for alternatives to these packages or need to upgrade your dependencies, this repository provides a drop-in replacement with improved features and ongoing maintenance.
This package maintains API compatibility with the deleted packages, including all the same function names:
EntropyFromMnemonic()for converting mnemonics back to entropyMnemonicToByteArray()with optional raw parameter extensionNewSeedWithErrorChecking()for mnemonic validation before seed generationGetWordList()andGetWordIndex()for wordlist operations
Search terms: go-bip39, go-ethereum-hdwallet, BIP39 migration, HD wallet replacement
The bip39 package is a behavioral drop-in replacement for github.com/tyler-smith/go-bip39 v1.1.0. Its output is verified byte-for-byte against that library by a generated golden test suite (bip39/go_bip39_golden_test.go) covering all official BIP39 test vectors.
Documented deviations:
- NFKD normalization (intentional, spec-compliant).
NewSeedandNewSeedWithErrorCheckingNFKD-normalize the mnemonic and passphrase as required by the BIP39 specification; go-bip39 hashes its input verbatim. Results are identical for pure ASCII input (including every official test vector) and differ only for non-ASCII or non-normalized Unicode input — where this implementation matches Trezor and other reference wallets. - Error values. Error identifiers are distinct (e.g.
ErrInvalidMnemonicvs go-bip39's differently-worded error);errors.Isnever matches across the two packages. - English wordlist only. go-bip39's
SetWordListand multi-language wordlists are not provided. - Stricter validation. Mnemonics containing words outside the wordlist produce an error instead of silently decoding to index 0.
MnemonicToByteArray output formats match go-bip39 exactly:
| Call | Returns | 12 words | 15 | 18 | 21 | 24 |
|---|---|---|---|---|---|---|
default / raw=false |
checksummed integer encoding of the word stream¹ | 17 | 21 | 25 | 29 | 33 |
raw=true |
original entropy | 16 | 20 | 24 | 28 | 32 |
¹ For 12/15/18/21 words the checksummed form is the big-endian encoding of the encoded integer left-padded to entropy-length+1 — i.e. the packed bit stream shifted right by
(totalBits % 8)bits. This historical quirk of go-bip39 is replicated byte-for-byte.
Implements the BIP39 specification for mnemonic codes.
import "github.com/kslamph/bip39-hdwallet/bip39"- Generate random entropy for mnemonic creation
- Convert entropy to mnemonic phrases
- Validate mnemonic phrases
- Convert mnemonic phrases back to entropy
- Generate seeds from mnemonics with optional passphrases
// Generate a random 128-bit entropy
entropy, err := bip39.NewEntropy(128)
if err != nil {
log.Fatal(err)
}
// Generate a mnemonic from the entropy
mnemonic, err := bip39.NewMnemonic(entropy)
if err != nil {
log.Fatal(err)
}
// Validate the mnemonic
if !bip39.IsMnemonicValid(mnemonic) {
log.Fatal("Invalid mnemonic")
}
// Generate a seed from the mnemonic
seed := bip39.NewSeed(mnemonic, "TREZOR")Implements the BIP32 and BIP44 specifications for hierarchical deterministic wallets.
import "github.com/kslamph/bip39-hdwallet/hdwallet"- Create master keys from seeds
- Derive child keys (normal and hardened)
- Derive keys using derivation paths (strict grammar: empty segments and out-of-range indices are rejected)
- Support for BIP44 standard paths
- Serialization to Base58Check (
B58Serialize/B58SerializePublic) - Wallet Import Format export with mainnet/testnet support (
ToWIF)
Key is immutable: accessor methods return defensive copies of internal slices, and String() exposes only non-secret metadata (never key material). Private keys must be read explicitly via PrivateKey, PrivateKeyHex, or ToECDSA.
// Create a master key from the seed
masterKey, err := hdwallet.NewMasterKey(seed)
if err != nil {
log.Fatal(err)
}
// Derive a child key
childKey, err := masterKey.Derive(0)
if err != nil {
log.Fatal(err)
}
// Derive a key using a path
accountKey, err := masterKey.DerivePath("m/44'/0'/0'/0/0")
if err != nil {
log.Fatal(err)
}
// Serialize as xprv/xpub (the format follows the key's own state)
xprv := accountKey.B58Serialize() // extended private key
xpub := accountKey.B58SerializePublic() // extended public key
// Export as WIF (Mainnet by default, or hdwallet.Testnet)
wif, err := accountKey.ToWIF()
// Read metadata safely — String() never prints secret material
fmt.Println(accountKey) // hdwallet.Key{private:true, depth:5, index:0, ...}go get github.com/kslamph/bip39-hdwalletThis implementation follows the BIP39, BIP32, and BIP44 specifications exactly. It uses cryptographic secure random number generation and industry standard hashing algorithms.
- Never log private keys.
String()only outputs non-secret metadata; usePrivateKeyHex()when you deliberately need the private key. - Derivation path parsing is strict: malformed paths such as
"m//0"or indices beyond2147483647returnErrInvalidPathinstead of being silently accepted. - Child-key arithmetic uses constant-time modular scalar operations (
secp256k1.ModNScalar). - This library has not been independently audited; review it carefully before production use with real funds.
This package maintains a high test coverage standard (over 95% for both packages) to ensure reliability and correctness of cryptographic operations.
Run tests with:
go test ./...To generate and view local coverage reports:
# Generate coverage report
go test -coverprofile=coverage.txt ./...
# View coverage in browser
go tool cover -html=coverage.txtThis project is licensed under the MIT License - see the LICENSE file for details.