// merkle membership proofs
Prove you're on the list. Show nothing else.
Status:
Ticker (placeholder, no token exists):
// the working demo
Build a tree. Prove one leaf. Verify it.
All hashing is real SHA-256 through the browser's Web Crypto API; the tree is plain JavaScript in this page. Edit anything and the root changes.
1 The allowlist → a Merkle tree
One address per line (2–64). Leaves are SHA-256(0x00 ‖ address); parents are SHA-256(0x01 ‖ left ‖ right). The only value that needs publishing is the root.
Demo values only — never paste a real seed phrase or private key. Allowlist entries are public by nature; random generated ones are fine.
Building…
selected leaf + path to rootsibling hashes in the proofroot (published)
2 Pick your entry → generate its proof
The proof is just the sibling hash at each level, plus which side it sits on. That's log₂(n) hashes, however large the list.
3 A verifier checks it
The verifier knows only the published root. They get the address and the proof, hash their way up, and compare. Edit any field — or use the break-it buttons — to watch verification fail.
Generate a proof first.
// how it works
What's hidden vs. what's public
What the verifier learns
- That the claimed address is one of the leaves under the root
- The address itself (it must be hashed to start the climb)
- The left/right path — which pins down the leaf's position in the list
- Nothing about the other addresses beyond their hashes
What a ZK version would add
- The prover would show “I know a leaf and a path that hash to this root” inside a zero-knowledge proof
- The verifier would learn only that membership holds — not the address, not the position
- This page does not implement that; it demonstrates the Merkle structure such proofs are built on
- Practical ZK systems typically swap SHA-256 for a ZK-friendly hash (e.g. Poseidon) inside the circuit
- Hash every address to a leaf. Prefix
0x00for leaves and0x01for inner nodes (domain separation) so a leaf can never be passed off as an inner node. - Pair neighbours and hash upward until one 32-byte root remains. If a level has an odd node out, it is promoted unchanged to the next level (instead of duplicated, which can create ambiguous trees).
- To prove one leaf, hand over the sibling at each level. The verifier recomputes the climb; if the result equals the published root, membership is confirmed. Changing a single bit of any input changes the root completely.
- On Solana, a program can store just the root and check proofs in a transaction, instead of storing the whole list in an account. SHA-256 is available as a native syscall; this page uses the same hash function.
Known limitations — please read
- This proof is not private about which entry. The verifier sees the address and its position. A Merkle proof shows membership only; hiding which member needs a zero-knowledge circuit, which is not built here.
- Trust sits in the root. A proof only shows an address is in the tree that produced a given root. Whoever publishes the root decides who is on the list; you must trust (or independently verify) that root.
- The list itself is not hidden. If the full allowlist is public, anyone can compute the root and every proof. Hiding the list requires keeping it off-chain.
- No replay or double-use protection. Anyone who sees a valid proof can reuse it. Real systems add nullifiers or bind proofs to the claimer's signature; this demo does neither.
- Teaching demo, not production code. Unaudited; not a substitute for a reviewed library or on-chain program.
- No on-chain component exists yet. There is no program, token, or deployed service behind this page.