Damus
Wilder profile picture
Wilder
@Wilder
How Claude Helped Me Crack a Bitcoin "Spending PIN":

On Bitcoin je Retro, I was contacted by a frustrated Bitcoin user who had forgotten the spending PIN for a significant amount of Bitcoin stored in his Android mobile wallet, Bitcoin Wallet https://github.com/bitcoin-wallet/bitcoin-wallet.
The only thing he knew was that the PIN had 8 digits, which isn't a lot, but it's not a small number either. And he asked me to crack it.

I installed the mobile wallet and imported the encrypted Bitcoin wallet protected by a PIN. I noticed that the PIN appears in two places where a brute-force attack is possible—"Send Coins," where you must enter the PIN, and if it's correct, the transaction goes through. And another function, "Change Spending PIN," where you must first enter the old PIN, then the new one; if they match, the PIN is changed, and the private keys are re-encrypted.

I asked Claude to import the encrypted wallet. He identified it as a v8 protobuf encrypted with a spending PIN and determined its format: KDF parameters scrypt N=65536, r=8, p=1; a 32-byte AES-256-CBC key; and PKCS#7 padding.

I asked Claude to download the source code for this Bitcoin wallet and analyze whether a brute-force attack would be better carried out via the "Send Coins" functionality (which he deemed a stupid, slow idea) or via "Change Spending PIN" (which he deemed a good, significantly faster idea).
He immediately showed me the verification formula that must be satisfied during a brute-force attack:
crypt(utf16be(pin), salt) → AES decrypt → unpad → secp256k1 The public key derived from the plaintext must match the stored public key (encryption_parameters + key.public_key in wallet.proto)
Based on that, he implemented a fully functional cracker in a few minutes. And he ran it right away. On my 16-core laptop, he could only manage 80 attempts per second. He estimated that trying all 8-digit possibilities would take 2–3 weeks.

Claude suggested that we could significantly speed this up if I gave him access to a cloud service (AWS, Hetzner, anything).
I generated and gave him an API key for our Hetzner. Using it, Claude ordered the 5 most powerful servers (we couldn't get more due to our Hetzner limit)—probe-cpx62. He installed, configured, and launched them all fully automatically, without any manual intervention.
At the same time, he created a parallelized version of the PIN cracker, breaking down the PIN ranges to be tested so it could crack them in parallel across all servers.
He also wrote a monitoring script and kept me updated on the progress.
After 14.5 hours of active operation on 5 powerful servers, he reported:

HIT, PIN = .....
It was found by shard 1 (178.104.180.200) after ~14.5 hours (52,237.9s)
The PIN meets the condition:
verify_pin(PIN, salt, iv, ct, pub) == True (the secp256k1 public key from the decrypted private key matches the stored one)
I'm shutting down all the servers.
Claude's total runtime was less than 30 minutes.

I didn't see any code; I didn't log in to any server. Claude designed and implemented all the above operations on his own (I really didn't advise him on anything).
I just waited for the result, which I got on the first try.

As humans, we'll soon be redundant in the AI agents' loop—I already feel that way.

2
5t34k · 1d
Yet so often when I talk to people they tell me AI is overhyped and actually useless because their chatGPT free tier gives them bad answers to their poorly written prompts. Still a huge information asymmetry at the moment.