ZKWhisper — Losing Your Keys Without Losing Your Sovereignty
13 Aug 2023 · 4 min read · code on GitHub →
Wallet recovery today forces a choice: trust only yourself (and pray you never lose the seed phrase), or trust a custodian (and stop being your own bank). ZKWhisper is my attempt at a third option — friends can help you recover your wallet, without you, them, or the chain ever seeing anything secret.
The philosophy
Crypto’s founding promise is self-custody: your keys, your coins. The dirty secret is that self-custody outsources an extremely hard systems problem — durable, secure storage of a random 256-bit string — to the least reliable component in the stack: a human. People laminate seed phrases, split them across bank lockers, tattoo them (really), and still an estimated fifth of all Bitcoin sits stranded in wallets nobody can open anymore.
The usual fix is to hand the problem back to an institution. That works, but it quietly deletes the whole point — you’re back to asking permission to access your own money.
I think the mature position is that we should stop pushing responsibility onto users and start building systems that feel invisible while keeping the values intact. Humans already have a great recovery mechanism: other humans. You trust a handful of people in your life. The trick is to use them without trusting them with anything — no guardian should learn your secret, learn who the other guardians are, or be able to collude their way into your wallet.
The math that makes it work
Shamir’s (k, n) secret sharing
Encode your secret S as the constant term of a random polynomial of degree k−1, so that f(0) = S. Each guardian i gets one point on the curve: the share (xi, f(xi)). A degree-(k−1) polynomial is fully determined by any k points — and completely undetermined by k−1. This isn’t “hard to crack”; it’s information-theoretically perfect. With fewer than k shares, every possible secret remains equally likely.
Recovery is Lagrange interpolation evaluated at zero: S = f(0) = Σ yi · ∏j≠i xj / (xj − xi). Collect any k of your n shares, run the sum, and the secret reappears.
Merkle trees, twice
Two trees keep everyone honest. One is an identity tree: signing up inserts a commitment — a hash of two private values, a secret and a nullifier — as a leaf, and later you prove “I know the preimage of some leaf in this tree” without pointing at which one. The second is built per recovery setup, over the guardian shares: every share carries the root and its inclusion path, so a tampered or fabricated share exposes itself before you waste time interpolating — the paths simply won’t hash up to the same root.
Saying it without saying it
All of the above happens inside a zk-SNARK (Circom circuits, Groth16). The circuit checks that your secret and nullifier hash to the committed value, walks the Merkle path to the public root, and confirms the reconstruction — then hands the chain a tiny proof that says only: “this is all true.” The contract verifies the proof. No secret, no shares, no guardian identities ever touch the chain.
The part I care about most
Guardians never know each other. There is no guardian list on-chain, no group chat, no ceremony. Collusion requires first discovering who else is a guardian — and the system gives no one, including the guardians, a way to find out. The social graph stays in your head, which is exactly where it’s safest.
Implementation-wise it’s the usual suspects — Circom circuits proving in the browser, a Solidity verifier, a Next.js client — built in a caffeinated blur for ETH Superhack. The code is on GitHub; the ideas above are the part worth keeping.
← All blogs