Give me some (key) space!
- 3. ● Pre BIP-39
→ Brainwallets
● BIP-39 From randomness to Address(es)
→ Entropy, mnemonic, seed, address
● War stories
→ ZenGo: The seed saviors
→ The BTC challenge
→ Trust wallet extension
→ Profanity vanity addresses
Agenda
- 5. ● Select a passphrase
○ Example: how much wood could a woodchuck chuck if a
woodchuck could chuck wood
● Hash it (SHA-256)
● This is the private key
● https://brainwalletx.github.io/
Brain wallets
- 8. ● Cracking Cryptocurrency Brainwallets
https://rya.nc/files/cracking_cryptocurrency_brainwallets.pdf
● Found 733 BTC
● Examples
○ “Down the Rabbit-Hole”: held about 85 BTC in July 2012
○ “The Quick Brown Fox Jumped Over The Lazy Dot”: held about
85 BTC in December 2011
○ “”: had 50BTC last week, stolen in seconds
Who is Yoink? Ryan Castellucci
- 9. An early old-style brainwallet was created by memorization of
a passphrase and converting it a private key with a hashing
or key derivation algorithm (example: SHA256). That private
key is then used to compute a Bitcoin address. This method
was found to be very insecure and should not be used.
Humans are not a good source of entropy.
- The Bitcoin wiki
- 11. ● Randomness: 128/256 bit
● Adding 1 bit of checksum for each 32bit (33 is divisible by 11)
○ 128 → 132
○ 256 → 264
Step 1: Random → Random + CheckSum
- 12. ● Each group of 11 bits is assigned with a BIP-39 word
● Word list(s)
○ https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt
Step 2: Random + CheckSum → Seed Phrase
- 13. ● Key Derivation Function: PBKDF2: 2048 HMAC-SHA512
○ Adding performance “penalty” to make bruteforce harder
○ Potential passphrase addition
Step 3: Seed Phrase → Seed
- 17. ● The story: https://zengo.com/the-wallet-seed-saviors/
What was word #10?
- 18. ● Each word represents 11 bits
● 11 bits → 2^11 = 2048
● 24 words → 8 bits of checksum
○ So only 3 “free” bit → 2^3 = 8 options
○ No need to derive an address for invalid seed phrases
● Very much doable in browser’s javascript
● https://zengo-x.github.io/mnemonic-recovery/src/index.html
How hard is it to guess 1 word?
- 23. ● Guessing 4 words out of 12
● 2^44-4 = 1.1 Trillion
BTC Challenge: The middle part
- 24. ● On laptop: 25 years
● Beast machine (32 cores): 4 years
● GPUs: ~30 hours
● Read more here:
https://medium.com/@johncantrell97/how-i-checked-over-1-trillion-
mnemonics-in-30-hours-to-win-a-bitcoin-635fe051a752
BTC Challenge: How much time would it take?
- 27. ● Trust wallet: mobile app, seed based (acquired by Binance)
● Core crypto implemented in C++
○ Open source https://github.com/trustwallet/wallet-core
● How would you build a wallet extension?
○ Compile to WASM
● What can go wrong?
Trust Wallet Extension
- 28. ● In mobile environment, Trust wallet uses the OS random API
● No (immediate) access from browser to OS random API
● Trust solution: Use some C++ API
● Can you spot the issue?
Randomness
- 32. ● Vanity
● People like personalization
● Can be thought as a security measure against phishing
● Some gas savings if contract address starts with enough leading 0s
Vanity addresses: Motivation
- 33. ● Bruteforce
● Each hex character represents 4 bits
● To create 0babe3333bb:
○ https://etherscan.io/address/0x0babe3333bb2904dc3cdc16b8
0b64dc3ec5ac4d3
○ 11 (9? 10?) vanity hex digits = 44 bit = 2^44
● Profanity does that for you
○ https://github.com/johguse/profanity
○ Optimized for GPUs
Vanity addresses: How to
- 35. ● Create all 32 bit options of addresses (like with Trust Wallet)
● Then try to bruteforce by incrementing each private key
● So for 10 hex chars vanity:
○ 2^(32 + 40) = too much
Abusing profanity: Naive method
- 36. At first sight, it appeared that 8+ character vanity addresses
were quite safe (please, read through the end of this post)
- 1 inch blog
- 37. ● Create all 32 bit options of public keys (like with Trust Wallet)
○ Less expensive than addresses
○ Doable in < 24 hours
● Start from a public key of a vanity address
○ They are highly self evident
○ Bruteforce “backwards”:
■ decrement public key until you reach known public key
■ P = S * G → P’ = (S - 1) * G = S*G - G = P - G
● Instead of 2^(32+40) , 2^32+2^40 ~= 2^40 → bruteforce-able
Abusing profanity: Not naive method
- 38. ● EOA address: The last 20 bytes of the hash of the public key
○ Does not reveal its public key
● However, it can be extracted from the Tx signature (v,r,s) on chain
The public key of an EOA Ethereum address
- 40. ● We only talked about EOA addresses and ״forgot״ about contract
addresses
● Contract address: The last 20 bytes of the hash of the public key
○ Deployer address
○ Deployer nonce
○ sha3(rlp.encode([normalize_address(sender), nonce]))[12:]
● Profanity does that calculation for the its users to create such
deployer key that would yield the right contract address
● Apparently, others forgot about it as well…
Contracts address