KUMO

Privacy is Safety

Every transaction on a public blockchain is a broadcast. Your balance, your spending patterns, your counterparties, your timing. All of it indexed, searchable, permanent. This is not transparency. This is surveillance architecture sold as a feature. When your employer can see what you spend your salary on, when your landlord can check your net worth before negotiating rent, when a stranger can trace your entire financial life from a single payment, the system is broken. Privacy is not about hiding. Privacy is about safety. The right to transact without being watched is the right to exist without being profiled.

The Missing Piece

Crypto solved custody. You hold your own keys. Crypto solved settlement. Transactions are final in minutes. Crypto solved access. Anyone with a phone can participate. But crypto failed at privacy. The entire market operates on glass ledgers where every movement is visible to every observer. This is the missing piece. Not regulation. Not scalability. Not user experience. Privacy. Until people can move value without broadcasting their financial lives, crypto remains a tool for speculation, not a tool for living. Usable privacy changes everything. It makes crypto safe for payroll. Safe for savings. Safe for commerce. Safe for life.

Usable Privacy

Privacy tools exist. They have existed for years. But they are built for cryptographers, not for people. Complex CLIs. Manual note management. Fixed denominations. Multi-step withdrawal ceremonies. The average person will never use them. Usable privacy means opening a wallet on your phone and sending money to a friend without thinking about nullifiers or Merkle trees. It means a business running payroll through a shared treasury with the same ease as a bank transfer. It means your grandmother can receive a gift without learning elliptic curve cryptography. The technology must disappear. The privacy must remain.

Everyone Benefits

Privacy is not a niche feature for the paranoid. When transactions are private by default, businesses can operate without competitors monitoring their cash flow. Employees can receive salaries without coworkers knowing their compensation. Charities can accept donations without exposing their donor lists. Freelancers can invoice clients without revealing their entire customer base. The entire market grows when participants feel safe. Adoption follows safety. Safety follows privacy. This is not about building tools for people with something to hide. This is about building infrastructure for people with something to protect.

Protocol

Kumo is a shielded UTXO pool for EVM-compatible chains with EdDSA multisig authorization. Every transaction is validated by a Groth16 zero-knowledge proof over the BN254 curve. The circuit enforces value conservation, nullifier uniqueness, signer threshold satisfaction, and extData binding in a single proof with 7 public signals. The pool contract stores commitments in a LeanIMT (Lean Incremental Merkle Tree) with a depth of 32, supporting over 4 billion unique deposits. Each commitment is Poseidon(amount, signerSetHash, blinding) where signerSetHash = Poseidon(threshold, signerMerkleRoot), embedding the authorization policy directly into the UTXO.

Everyday Use

Kumo is built for mobile and desktop. Open it on your phone, send a shielded transfer to a friend, close the app. Open it on your laptop, check your balance, approve a treasury spend. The wallet is designed for real people making real payments. Pay a contractor without publishing the amount. Split expenses with friends without exposing your balance. Receive a grant without your entire financial history becoming public. Send money to family without every node operator knowing the details. This is private money for daily life, not a research prototype.

UTXO Model

Every transaction consumes exactly 2 input UTXOs and produces exactly 2 output UTXOs. Inputs are spent by revealing their nullifiers: Poseidon(commitment, pathIndex, blinding). The nullifier depends on the Merkle tree path index at the time of spend, which changes as the tree grows, making precomputation impossible. Dummy inputs with zero value bypass Merkle inclusion and signature checks, allowing deposits (no real inputs) and single-input spends (one real, one dummy). Output amounts are range-checked to 248 bits. Value conservation is enforced arithmetically: sumInputs + publicAmount === sumOutputs, where publicAmount is the field-negation of the withdrawal amount for outgoing transfers.

EdDSA Multisig

Each UTXO is authorized by a K-of-N EdDSA multisig over the Baby JubJub curve. Signers are organized in a fixed-depth binary Merkle tree (depth 3, 8 leaves max). Each signer's leaf is Poseidon(Ax, Ay) where (Ax, Ay) is their Baby JubJub public key. The circuit verifies that each enabled signer produces a valid EdDSA-Poseidon signature over Message = Poseidon(commitment, extDataHash), that their public key is in the signer Merkle tree, that the tree root matches the UTXO's signerSetHash, and that all enabled signers are unique (28 pairwise checks for 8 slots). Threshold must be >= 1, fit in 4 bits, and the count of enabled signers must meet the threshold. A single user is simply a 1-of-1 treasury, same circuit, same verifier.

Shielded Transfers

Send ETH to anyone with a kumo address. The transfer happens entirely inside the pool. No value moves on-chain externally. No recipient address is visible. No amount is revealed. The sender's UTXO is consumed, two new UTXOs are created (one for the recipient, one for change), and the only on-chain evidence is that a transaction occurred. Not what kind. Not how much. Not between whom. Your friend opens their wallet and the balance appears. No coordination needed. No link request. No QR code exchange mid-transfer. Just paste their address or pick from contacts and send.

Privacy

On-chain, all transaction outputs are 5120 bytes, 5 slots of 1024 bytes each. Each slot is independently encrypted with X25519-XSalsa20-Poly1305 using a fresh ephemeral keypair (forward secrecy). The plaintext is padded to exactly 952 bytes before encryption, making all slots indistinguishable regardless of content. An observer sees: a transact() call, two new commitments, two spent nullifiers, and 10240 bytes of random-looking data. They cannot determine the transaction type (deposit, transfer, withdrawal), the amounts, the parties, or whether it involves one person or five. The anonymity set is the entire pool, every commitment is a potential input to any future transaction.

For Businesses

Pay your team without publishing salaries. Receive client payments without exposing total revenue. Run a shared treasury with 2-of-3 or 3-of-5 approval, where each spend is proposed, reviewed, and signed by your partners before execution. Attach encrypted descriptions to every payment for internal records that survive server failures. Your competitors cannot see your cash flow. Your clients cannot see each other. Your payroll is between you and your employees.

Encrypted Notes

Inside each 1024-byte slot: ephemeralPublicKey (32 bytes) + nonce (24 bytes) + ciphertext (968 bytes). The ciphertext decrypts to a 952-byte padded plaintext. Version byte 0x01 = personal note (amount + blinding + signerSetHash). Version 0x02 = treasury note (name, description, threshold, all signer pubkeys, all encryption pubkeys, signer index, amount, blinding, signerSetHash, treasuryId). Version 0x03 = personal note with description. Recipients discover their UTXOs by trial-decrypting every on-chain output with their X25519 private key. Failed decryptions return null instantly (Poly1305 MAC failure).

Address Format

A kumo address encodes: version (1 byte) + EdDSA public key Ax (32 bytes) + Ay (32 bytes) + X25519 encryption public key (32 bytes) + Poseidon checksum (4 bytes) = 101 bytes, base58-encoded with a "kumo1" prefix. The address contains everything a sender needs: the recipient's signing key (to construct the output UTXO's signer set) and their encryption key (to encrypt the note so they can discover and spend it). Sharing an address reveals nothing about balance, transaction history, or pool activity. Give it to anyone. Post it publicly. It is safe to share.

For Friends

Split dinner. Pay rent. Send a birthday gift. The recipient shares their kumo address once. You save it as a contact. Every future payment is one tap. They never see your balance. You never see theirs. The transaction is invisible to everyone except the two of you. No bank statement. No block explorer trail. No third party logging the transfer. Just private money between people who trust each other.

Treasury Coordination

The coordination backend stores encrypted proposal blobs that it cannot read. When a signer creates a proposal, they build the complete transaction blueprint (input UTXOs, output specs, extData, message hashes), encrypt it separately to each co-signer's X25519 key, and submit the array of encrypted blobs. Each signer decrypts their copy, reviews the details, signs the message hashes with their EdDSA key, re-encrypts their signatures to all co-signers, and submits the approval. When threshold approvals are collected, any signer can decrypt all signatures, build the circuit input with K signature sets, generate the Groth16 proof, and submit the on-chain transaction. The backend is optional and self-hostable.

Mobile and Desktop

The wallet runs in any modern browser. No app store. No download. No installation. Open the URL on your phone and you have a private wallet. Open it on your laptop and you have the same wallet. Scan QR codes to add contacts. Share your address as a QR code. The interface adapts to your screen. The sidebar collapses on mobile. Proof generation runs on your device, on your CPU, in your browser. Your keys never leave your device. Works offline for reading balances. Works online for sending.

Authentication

All backend API requests are authenticated with EdDSA signatures. The signed message is Poseidon(SHA256(nonce), SHA256(payload)) where the nonce is a timestamp with random suffix. The backend verifies the signature, checks nonce freshness, and atomically claims the nonce to prevent replay. Sensitive endpoints verify the caller is a signer in the requested treasury. No accounts, no tokens, no sessions, just cryptographic identity.

Proof Generation

Proofs are generated client-side using snarkjs with a Groth16 prover over BN254. The circuit compiles to approximately 157,000 R1CS constraints. The proving key is approximately 98MB and the WASM witness generator is approximately 3.8MB. Proof generation takes 15-30 seconds in a modern browser depending on CPU cores. Web Workers parallelize multi-scalar multiplications across available cores. The proof output is 3 G1/G2 points verified on-chain by a Groth16 verifier contract using BN254 precompiles (ecAdd, ecMul, ecPairing).

On-Chain Contract

The pool contract is a single non-upgradeable Solidity contract. It stores a LeanIMT commitment tree, a nullifier registry, a circular root history buffer, and immutable references to the Groth16 verifier. The transact() function validates extDataHash, verifies the root is known, checks nullifiers are unspent, recomputes publicAmount from extData, calls the verifier, marks nullifiers spent, inserts two output commitments, and processes native token transfers. The contract has no owner, no admin key, no pause mechanism, and no upgradeability. Deployable on any EVM-compatible chain.

Client Architecture

The wallet maintains an incremental sync cache. On first load, it scans all commitment and nullifier events from the deploy block, builds a local Merkle tree, validates the root against on-chain state, trial-decrypts every output, and runs an incremental nullifier check (rebuilding the tree one commitment at a time to compute nullifiers at every possible tree size). On subsequent loads, it fetches only new events since the last checkpoint. Root mismatch triggers automatic fallback to full rescan. Personal UTXOs and transaction history are persisted in an AES-256-GCM encrypted vault derived from the user's password via PBKDF2 with 600,000 iterations. Your data is yours. Encrypted. On your device.

EVM Compatible

The contract, circuit, and frontend are chain-agnostic. Deploy on Ethereum mainnet, Arbitrum, Optimism, Base, Polygon, or any chain that supports BN254 precompiles. The same proof, the same verifier, the same privacy guarantees. The frontend supports configurable RPC endpoints and pool addresses. Point it at any deployment. Run your own backend. Host your own frontend. The entire stack is open and forkable.

Stack

Contracts: Solidity 0.8.20, Foundry, OpenZeppelin ReentrancyGuard, @zk-kit LeanIMT, Poseidon-solidity. Circuits: circom 2.1.5, circomlib (EdDSAPoseidonVerifier, Poseidon, comparators, bitify, mux, gates). Backend: Node.js, Express, better-sqlite3, @zk-kit/eddsa-poseidon, poseidon-lite. Frontend: vanilla JavaScript, snarkjs, TweetNaCl (X25519 + XSalsa20-Poly1305), ethers.js, @paulmillr/qr. No framework. No build step. No React. No bundler beyond esbuild for three vendored library bundles. The entire frontend is static HTML, CSS, and JavaScript served by nginx.

Self Custody

Your keys are generated in your browser. They never leave your device. There is no server that holds your private key. There is no custodian. There is no account. There is no email. There is no phone number. There is no identity verification. You create a wallet. You get a keypair. You get an address. That is your identity in the system. If you lose your keys and your backup, your funds are gone. Nobody can recover them. Nobody can freeze them. Nobody can seize them. This is the tradeoff. Total control. Total responsibility.

Compliance

Privacy and compliance are not opposites. Compliant privacy means users can prove what they need to prove, to whom they choose, when they choose. A user can export their transaction history. A user can share their viewing key with an auditor. A user can demonstrate the source of funds without exposing their entire balance sheet to the public. The protocol does not prevent compliance. The protocol prevents involuntary disclosure. There is a difference between choosing to share information and having it extracted without consent.

Backup and Recovery

Download an encrypted backup file. Take it to any device, any browser. Enter your password. The wallet syncs with the chain and rebuilds everything automatically. Your balance. Your UTXOs. Your treasuries. Your contacts. Your transaction history. All from chain events and your encrypted backup. Nothing depends on a server you do not control. The backup is encrypted with your password. Without the password it is useless. With the password it is everything.

No Trace

Deposits enter the pool. Withdrawals exit the pool. There is no on-chain link between the two. Transaction graph analysis cannot connect your inflows and outflows. The pool is a shared anonymity set. Every deposit strengthens it. Every user benefits from every other user. The more people use the pool, the harder it becomes to correlate any individual transaction. Privacy is a public good. Your deposit protects others. Their deposits protect you.

Open Source

Every line of code is public. The contracts. The circuits. The frontend. The backend. The deployment configuration. The build scripts. The test suite. Nothing is proprietary. Nothing is obfuscated. Fork it. Audit it. Deploy your own instance. Run your own backend. Host your own frontend. The protocol works the same regardless of who operates the infrastructure. Trust the math, not the operator.

Why Now

The tools are ready. Groth16 provers run in browsers. BN254 precompiles are available on every major EVM chain. Poseidon hashing is efficient in circuits. EdDSA verification works inside SNARKs. The cryptographic primitives that were research papers five years ago are production-ready today. The missing piece was never the math. It was the product. A wallet that normal people can use. A treasury that businesses can trust. A protocol that works on phones. That is what this is.

kumo
kumo
everyday privacy