Every payment,
a different door.
Send. Scan. Spend. Nothing links.
Everything below is computed live with the Web Crypto API (ECDH over P-256, SHA-256) plus a small in-page elliptic-curve implementation. Click through the three steps.
1 Recipient publishes a meta-address
Two keypairs: a scan key (finds payments) and a spend key (moves funds). Only the two public halves are ever published — and that same meta-address is reused for every payment.
2 Sender pays — a fresh address each time
The sender makes a one-time ephemeral keypair, does ECDH with your scan public key, hashes the shared secret to a scalar h, and computes stealth = spendPub + h·G. Click repeatedly — every address is different.
The ledger above is what a public chain would show: an ephemeral key and a one-time address per payment. Nothing in it points back to the recipient's meta-address.
3 Recipient scans — only they can recognise payments
The recipient re-derives the shared secret from each ephemeral key using their scan private key, recomputes the address, and compares. A stranger with the wrong key finds nothing.
What's hidden vs. what's public
Public (visible to everyone)
- The recipient's meta-address (scan pub + spend pub), if they choose to publish it
- Each payment's ephemeral public key
R - Each payment's one-time address
spendPub + h·G - Amounts and timing (in a real chain — stealth addresses do not hide these)
Hidden (only sender + recipient)
- The ECDH shared secret between ephemeral key and scan key
- The scalar
hderived from it - Which one-time addresses belong to which meta-address
- The spend private key
spendPriv + hfor each address
- The sender computes
S = ECDH(r, scanPub). The recipient can compute the identicalS = ECDH(scanPriv, R)— Diffie–Hellman symmetry. - Both hash it:
h = SHA-256(S ‖ "stealthbox/v1") mod n. Becauseris fresh each time,his different each time. - The one-time public key is
spendPub + h·G. Only someone who knowsspendPrivcan derive the matching private keyspendPriv + h— the “Prove spend” button signs a message with it and verifies against the stealth address. - Splitting scan and spend keys means a scanning service can find your payments with just the scan key, without ever being able to spend them.
Curve note: this demo uses P-256 because it is what the browser's Web Crypto API provides. A Solana build would use ed25519 (and x25519 for the Diffie–Hellman step). The displayed “address” is the base58 encoding of the stealth point's x-coordinate — address-shaped for illustration, not a valid Solana account.
Known limitations — please read
- Reduces linkability, not anonymity. Stealth addresses stop observers from trivially grouping payments to one recipient. They do not hide amounts, timing, or the sender, and they do not make anyone anonymous.
- Spending leaks. When you move funds out of several stealth addresses into one wallet, or fund their gas from a known wallet, you re-link them on-chain. Careful spending hygiene is required and not solved by this primitive.
- Scanning is the cost. The recipient must examine every candidate payment. Real systems add view tags and indexers to make that practical.
- Compromised scan key = lost privacy. Whoever gets your scan key can see all your incoming payments (though not spend them). Compromised spend key = lost funds.
- This is a teaching demo, not a wallet. It uses P-256 via the browser, a hand-written curve routine that is not constant-time, and has had no security review. Do not reuse its code or keys for real value.
- No on-chain component exists yet. There is no program, token, or deployed service behind this page.