architecture
KIRITE is a layered protocol stack built on Solana L1. Each layer handles a specific dimension of privacy, and they compose together to provide complete transaction confidentiality.
system overview
layer 1: confidential transfer
The cryptographic foundation. KIRITE leverages Solana's native Confidential Balances token extension, which implements Twisted ElGamal encryption at the runtime level.
twisted elgamal
Standard ElGamal operates on group elements, making it impractical for balance arithmetic. Twisted ElGamal encodes amounts in the exponent, enabling homomorphic addition — the chain can update encrypted balances without decrypting them.
// Twisted ElGamal encryption
Encrypt(amount, pk, r):
C = r·G // randomness commitment
D = amount·G + r·pk // amount + blinding
// Homomorphic addition (on-chain)
(C1, D1) + (C2, D2) = (C1+C2, D1+D2)
// → encrypts (amount1 + amount2) without decryptionproof system
KIRITE uses two types of zero-knowledge proofs:
- Bulletproofs — range proofs that verify amounts are non-negative and within
[0, 2^64). Prevents overflow attacks without revealing values. - Sigma proofs — equality and validity proofs for ciphertext operations. Ensures encrypted operations are well-formed.
layer 2: shield pool
The core mixing engine. Even with encrypted amounts, transaction graph analysis can reveal patterns. The Shield Pool breaks the sender-receiver link by creating a multi-asset anonymity set.
pool design
- Multi-asset — supports any SPL token with Confidential Balances enabled.
- Configurable anonymity sets — minimum set size is protocol-enforced. Withdrawals are blocked until the set is large enough.
- Time-lock mechanism — deposits are locked for a randomized window (base + jitter) to prevent timing correlation.
- Merkle-based membership — deposit commitments are stored in a Merkle tree. Withdrawal proofs demonstrate set membership without revealing which leaf.
// deposit commitment
commitment = Poseidon(amount, nullifier, secret)
// merkle tree insertion
tree.insert(commitment) // → merkle root updated
// withdrawal proof (simplified)
proof = prove({
merkle_root: tree.root,
nullifier: hash(secret),
amount: amount,
// private inputs: merkle path, secret
})layer 3: stealth addresses
The recipient anonymity layer. Stealth addresses ensure that the withdrawal destination cannot be linked to any known public key.
dual-key scheme
KIRITE implements a Dual-Key Stealth Address Protocol (DKSAP):
- The recipient publishes a meta-address (spending key + viewing key).
- The sender generates an ephemeral keypair and computes a shared secret via ECDH.
- A one-time stealth address is derived from the shared secret + recipient's spending key.
- The ephemeral public key is posted to the on-chain registry.
- The recipient scans the registry with their viewing key to detect incoming payments.
layer 4: routing engine
The optimization layer. For complex transactions (e.g., privacy swaps across multiple tokens), the routing engine finds the optimal path through available Shield Pools to minimize fees and maximize privacy.
- Path selection — evaluates anonymity set sizes across pools to route through the most private path.
- Fee batching — aggregates multiple operations into fewer on-chain transactions.
- Cross-token swaps — deposit token A into pool, withdraw token B from another pool via atomic swap.
data flow
| component | execution | trust model |
|---|---|---|
| proof generation | client (browser/WASM) | trustless — user controls |
| key management | client (browser) | trustless — user controls |
| proof verification | on-chain (Solana program) | Solana consensus |
| balance updates | on-chain (homomorphic) | Solana consensus |
| routing optimization | client-side | trustless — public pool data |