Confidential governance infrastructure for Solana.
Private inputs. Public proof.
QUORUM lets a DAO vote, propose, and manage a treasury without leaking the information that makes governance manipulable. Ballots are encrypted in the browser, eligibility is proven with zero knowledge, the running tally stays hidden until close, and the final result is verifiable by anyone. Proposals stay sealed until execution, so there is no front running window. Treasury records stay confidential, with solvency proven by range proof and selective disclosure to auditors.
Live app: https://quorumprivacy.com
| Module | What it provides |
|---|---|
| Sealed ballot voting | One hot ballots encrypted client side, ZK eligibility, threshold tally, verifiable correctness. |
| Hidden proposals | Encrypted until execution, commit reveal, released on pass or after a timelock. |
| Confidential treasury | Hidden balances, ZK solvency proofs, selective disclosure to auditors. |
| Members and delegation | Eligibility committed as a ZK snapshot; private delegation of voting weight. |
| QRM staking | Real Token 2022 staking that settles on chain; a staked tally network with slashing. |
| Proofs and verification | A public surface where anyone verifies the protocol was honest, no trust required. |
Sealed ballot voting. A vote is one hot encoded and encrypted with exponential ElGamal over Ristretto255. Because the scheme is additively homomorphic, encrypted ballots are summed and only the per option totals are decrypted. Eligibility is proven in the browser with a Groth16 proof of membership in a Merkle tree plus a unique nullifier, which prevents double voting without revealing identity or balance. Decryption uses a 3 of 5 threshold key from a Pedersen DKG, so no single party holds the secret. Each partial decryption carries a Chaum Pedersen DLEQ proof, so anyone can verify that the announced totals are the honest decryption of the sealed ballots.
Hidden proposals. The body is encrypted with AES GCM and bound by a SHA 256 commitment. Only the ciphertext and the commitment reach the server. The author reveals later, and the server checks the plaintext against the commitment. Reveal is either on pass or after a timelock.
Confidential treasury. Solvency is proven with a Groth16 range proof: the operator proves reserves meet a public threshold while the balance stays hidden, and the proof is verified on chain. Individual records are disclosed to a chosen auditor with ECIES over Ristretto255, so only that auditor can read them.
Browser (React, client side crypto + in browser ZK proving)
| Sign In With Solana, sealed ballot, proof generation
v
Server functions (typed, zod validated, session JWT)
|
+--> Postgres commitments, nullifiers, proofs, encrypted records
+--> Solana devnet one program "quorum_anchor": eligibility root, tally hash,
on chain Groth16 verifier, Token 2022 staking
The chain stores roots and hashes, never per ballot accounts, so the on chain footprint and rent stay minimal. All ballots and commitments live in the database; a single Merkle root per vote plus the final result hash are anchored on chain.
QUORUM is designed to fail closed. Each guarantee is enforced by cryptography, not by policy.
| Property | How it holds |
|---|---|
| Ballot privacy | Choices are encrypted client side to a threshold key; no single party can decrypt. |
| Receipt freeness | Ciphertexts are re randomized, so a voter cannot prove a choice to a briber. |
| No double voting | A unique nullifier per voter per vote, enforced at storage and at tally. |
| Tally correctness | Chaum Pedersen DLEQ proofs make the totals verifiable by anyone. |
| No live tally | The running result is hidden until close, which defeats whale following. |
| Solvency without exposure | A range proof proves reserves meet a threshold while the balance stays hidden. |
| Fails closed | An invalid proof is rejected; no valid proof means no execution. |
The @quorum/sdk package exposes the same client side primitives QUORUM uses in production, so
anything you seal is compatible with the live tally. Everything runs client side: no server, no
secret keys, no trust.
import { sealBallot, verifyTally } from "@quorum/sdk";
// Seal a vote client side. Your choice never leaves the browser in the clear.
const ballot = await sealBallot(tallyPubkey, "yes", ["yes", "no", "abstain"]);
// Verify any published tally trustlessly. No server, no keys.
const { verified, totals } = verifyTally(transcript);See sdk/ for the full surface: sealBallot, verifyTally, sealProposal,
verifyProposalReveal, and the ECIES disclosure helpers.
- Frontend: TanStack Start, React 19, TypeScript.
- API: typed server functions, validated with zod.
- Data: Postgres.
- Chain: Solana devnet, one Anchor program with an on chain BN254 Groth16 verifier.
- Cryptography: Ristretto255 ElGamal, Pedersen DKG threshold decryption, Chaum Pedersen DLEQ, Groth16 (circom + snarkjs), AES GCM, ECIES.
npm install
npm run dev # start the app
npm run build # production build
npm test # run the crypto and protocol test suiteConfigure the environment before running. The app reads, among others, a database URL, a session secret, a Solana RPC endpoint, the program id, the QRM mint, and the tally group public key. Provide your own values; no credentials are included in this repository.
src/lib/crypto ElGamal, threshold DKG, DLEQ, proposal seal, ECIES
src/lib/zk Groth16 eligibility and solvency proving
src/lib/solana Token 2022 staking, on chain verifier, program client
src/fn the governance API (server functions)
src/routes the app and the dashboard
onchain the quorum_anchor Solana program
sdk @quorum/sdk, the client side primitives
circuits the circom circuits
QUORUM runs on Solana devnet. A mainnet promotion is gated behind third party security audits. Review audits before relying on the protocol with real value.
MIT
