KIRITE Documentation
Privacy layer on Solana. A fixed-denomination ZK shield pool + stealth-address recipients + a relayer-fronted withdraw flow. Built natively on Solana with the standard ZK privacy primitives (Poseidon-Merkle commitments, Groth16 membership proofs, DKSAP stealth addresses) — no L2, no bridge, no custom VM.
the signature exists. the hand does not.
Two pieces, one private payment
Shield PoolZK
Poseidon-Merkle commitment pool. Withdraw with a Groth16 membership proof; the chain only sees a nullifier hash and a Merkle root. Pre-image stays on the depositor's device.
✓fixed denominations (0.01 / 0.05 / 0.1 / 1 / 10 SOL)
✓Groth16 + Solana native syscalls (alt_bn128, poseidon)
✓per-nullifier on-chain marker (no double-spend)
Stealth AddressDKSAP
Withdraws land on a one-time address derived from the recipient's public spend + view keys. The recipient scans for incoming notes with the view key alone.
✓ECDH-derived one-time address per payment
✓dual-key (spend / view) so audit is opt-in
✓recipient address never appears in the deposit-side log
Start Here
01
read the quick start
The full deposit / proof / withdraw cycle in one page. Read the quick start.
02
review the threat model
What KIRITE protects, what it does not, and where practical privacy still depends on traffic. See the threat model.
03
read the compliance posture
Sanctions screening, freeze response, and the public reporting channel. Compliance.
Design Principles
non-custodialkeys stay local
Note material (nullifier secret, blinding factor) is generated and stored on the user's device. The pool authority cannot move user funds.
client-side proofsbrowser-generated zk
Groth16 proofs are generated in the browser via snarkjs WASM. The relayer receives only the proof and a nullifier hash; the secret pre-image is never transmitted.
l1 nativeno sidechain, no L2
The Anchor program runs on Solana directly. Verification uses the native
alt_bn128 and poseidon syscalls; no off-chain prover, no bridged state.screenedOFAC + freeze
The relayer auto-refreshes the OFAC SDN list and refuses sanctioned addresses on every deposit and withdraw. The pool exposes a freeze instruction for emergency response.
Protocol at a Glance
| property | value |
|---|---|
| chain | Solana mainnet-beta (privacy program in rollout) |
| proof system | Groth16 on BN254 (alt_bn128 syscall) |
| commitment hash | Poseidon (BN254 / Circom-compatible parameters) |
| merkle tree | height 15 (32,768 leaves per pool) |
| denominations | 0.01 / 0.05 / 0.1 / 1 / 10 SOL |
| protocol fee | 0.1% on withdraw, routed to relayer treasury → $KIRITE stakers (phase 2) |
| browser proof gen | ~1s on a desktop, ~3s on mobile |
| screening | OFAC SDN auto-refresh weekly + manual block list |
how privacy works
KIRITE breaks the deposit ↔ withdraw link and hides the recipient address. Privacy requires sending in one of the fixed denominations: 0.01 / 0.05 / 0.1 / 1 / 10 SOL. Every deposit and withdraw in a pool moves the same exact amount, so observers cannot match a withdraw to its specific deposit. Anonymity is bounded by the active leaf count per pool (32 on v1).