The most common confusion among Trezor users: "I forgot my PIN — can you brute-force it?" No. "I forgot my passphrase — can you brute-force it?" Yes, often. Same device, completely different security models. This guide is about the second case.
PIN vs passphrase — the architectural split
| Property | PIN | Passphrase (25th word) |
|---|---|---|
| Where verified | On-device secure element | Off-device (in Trezor Suite / wallet) |
| Algorithm | Device-specific protected memory | PBKDF2-HMAC-SHA512, 2048 iter |
| Rate limit | Exponential, then wipe | None — unlimited offline tries |
| Offline brute force | Impossible | Yes — main attack surface |
| Recovery if forgotten | Wipe + restore from seed | Brute-force with seed + address |
The math: how the passphrase becomes a wallet
# BIP39 master seed derivation (RFC):
seed = PBKDF2-HMAC-SHA512(
password = mnemonic_normalized, # NFKD UTF-8
salt = b"mnemonic" + passphrase, # passphrase is the variable
iterations = 2048,
dklen = 64
)
# Master node from seed:
master_key, master_chain = HMAC-SHA512(b"Bitcoin seed", seed)
# BIP44 derivation for first BTC receive address:
# m/44'/0'/0'/0/0
# At each step, address can be matched against blockchain.The crucial point: the passphrase enters the formula as a variable in PBKDF2. Different passphrase string → different seed → different master key → different addresses. Empty passphrase produces the "standard" wallet; "hello" produces a hidden wallet; "Hello" produces yet another hidden wallet. There is no integrity check inside the wallet — every passphrase is "valid" but only one matches your known address.
Brute-forcing with btcrecover
# Build a passphrase candidate list
cat > pass.txt <<EOF
mydog2017
MyDog2017
mydog2017!
MyDog2017!
mydog17
mydog2018
EOF
# Run btcrecover with seed + known address
python3 seedrecover.py \
--bip39 \
--mnemonic "abandon abandon abandon ... about" \
--addrs bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
--addr-limit 20 \
--passphrase-list pass.txt
# Or with a tokenlist (combinator-style)
python3 seedrecover.py \
--bip39 \
--mnemonic "abandon abandon abandon ... about" \
--addrs bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
--addr-limit 20 \
--passphrase-tokenlist tokens.txt \
--typos 2 --typos-caseGPU acceleration with hashcat
Hashcat mode 12700 implements MyEtherWallet/BIP39 PBKDF2 derivation. For passphrase recovery you can pre-derive seed+passphrase, then check the resulting address externally — but the cleaner path is mode 28200 (electrum 2.x) for Electrum, or a custom address-matching pipeline.
| GPU | BIP39 PBKDF2 derivations / s | 10M candidate runtime |
|---|---|---|
| RTX 4090 | ~50,000 | ~3.3 min |
| RTX 3090 | ~30,000 | ~5.5 min |
| CMP 90HX | ~22,000 | ~7.5 min |
| Single CPU core | ~3,000 | ~55 min |
Building a smart candidate list
For most users the passphrase is short, memorable and predictable. Common patterns:
- Pet / kid / spouse name + year (e.g.
Bella2017) - City of birth or important date (
Lisbon1985) - Capitalized phrase (
Send It,HodlForever) - Single common word (
password,bitcoin) - Crypto inside joke (
WenLambo,NotYourKeys) - Empty string (yes, many users set "passphrase" but never typed one — empty is valid)
Recoverable vs not
Recoverable
- • Seed + at least one known hidden address
- • Short passphrase from human memory
- • Tokenlist of candidate words
- • Empty passphrase (test this first!)
Not recoverable
- • PIN forgotten + no seed backup
- • Passphrase forgotten + no seed
- • Passphrase forgotten + no known address
- • Random 20+ char passphrase, no fragments
Related guides
- Hardware wallet recovery overview — Ledger and Trezor scenarios.
- Ledger 24-word recovery — sister flow on the other major hardware wallet.
- BIP39 missing words — when the seed itself is incomplete.
- KDF comparison — why passphrase brute force is fast.
Frequently asked questions
Difference between Trezor PIN and passphrase?
PIN is on-device, rate-limited, NOT recoverable. Passphrase is the BIP39 25th word, derived off-device, IS recoverable with seed + known address.
How is the passphrase wallet derived?
PBKDF2-HMAC-SHA512(mnemonic, "mnemonic" + passphrase, 2048 iter, 64 bytes). Output is the BIP32 master seed.
How fast can a passphrase be brute-forced?
CPU: thousands per second. GPU: tens of thousands per second. A 1-million-entry list runs in minutes.
What is plausible deniability mode?
Every passphrase produces a valid wallet, so an attacker cannot tell which is "real" without checking the blockchain. Same feature makes brute force tractable.
Can the PIN be recovered?
No. Wipe the device after enough wrong attempts and restore from seed.
Recover a forgotten Trezor passphrase
Send us your seed (or just the passphrase candidate list with a derived xpub), one known address from the hidden wallet, and any password fragments you remember. We run the address-matching attack on multi-GPU hardware. Pay only on success.