SlideShare a Scribd company logo
The most secure
crypto wallet
Give me some (key) space!
● 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
Brain wallets
● 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
● https://blockchair.com/bitcoin/address/1GjjGLYR7UhtM1n6z7QDpQs
kBicgmsHW9k
What can go wrong?
● https://blockchair.com/bitcoin/address/1GjjGLYR7UhtM1n6z7QDpQs
kBicgmsHW9k
Yoink!
● 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
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
BIP-39
● 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
● 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
● Key Derivation Function: PBKDF2: 2048 HMAC-SHA512
○ Adding performance “penalty” to make bruteforce harder
○ Potential passphrase addition
Step 3: Seed Phrase → Seed
Step 4: Seed → address(es)
ZenGo:
The seed saviors
Give me some (key) space!
● The story: https://zengo.com/the-wallet-seed-saviors/
What was word #10?
● 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?
Demo
The BTC challenge
BTC Challenge: How it started
BTC Challenge: How it ended
● Guessing 4 words out of 12
● 2^44-4 = 1.1 Trillion
BTC Challenge: The middle part
● 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?
BTC Challenge: #8 word released
Trust wallet
extension
● 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
● 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
The issue
● 2 GPUs
● < 24 hours
Brute-forcing 32 bits
Profanity vanity
Addresses
● 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
● 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
○
Vanity addresses: The issue
● 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
At first sight, it appeared that 8+ character vanity addresses
were quite safe (please, read through the end of this post)
- 1 inch blog
● 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
● 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
○
Vanity addresses: The losses (phase #1)
● 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
Contracts address: Wintermute
○
Vanity addresses: The losses (phase #2)
www.zengo.com
Scan QR code to Download the App

More Related Content

Give me some (key) space!

  • 2. 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
  • 14. Step 4: Seed → address(es)
  • 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?
  • 19. Demo
  • 21. BTC Challenge: How it started
  • 22. BTC Challenge: How it ended
  • 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?
  • 25. BTC Challenge: #8 word released
  • 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
  • 30. ● 2 GPUs ● < 24 hours Brute-forcing 32 bits
  • 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
  • 39. ○ Vanity addresses: The losses (phase #1)
  • 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
  • 42. ○ Vanity addresses: The losses (phase #2)
  • 43. www.zengo.com Scan QR code to Download the App