// 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
  1. Hash every address to a leaf. Prefix 0x00 for leaves and 0x01 for inner nodes (domain separation) so a leaf can never be passed off as an inner node.
  2. 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).
  3. 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.
  4. 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.