Whitepaper · DARK-CB-1 · draft
A design for encrypted balances and encrypted transfer amounts with ordinary self-custody, no mixing, and a proof system a stranger can check without trusting us. It is live on Robinhood Chain mainnet; the external audit report is added when it is published.
00 · Abstract
Dark is a wallet for USDG on Robinhood Chain in which each account's balance, and the amount of each payment between Dark accounts, is stored on chain as ciphertext. The account itself is ordinary: one address, one owner, one key. The USDG behind every balance sits in one contract; there is no shuffling of coins between users, and no party — Dark included — that can decrypt a balance or move funds on a user's behalf.
Deposits into and withdrawals out of the vault are public token transfers. Only the interior — how much each account holds, and how much moves between them — is confidential.
01 · Account model
Balances are encrypted with twisted ElGamal on the Grumpkin curve. Each account holds an available ciphertext and a pending ciphertext. Incoming payments land in pending; only the owner can fold pending into available, and only with a proof. This split is what stops a sender from interfering with a recipient's next transaction.
An account registers once by publishing its public key together with a proof that it knows the matching secret. From then on anyone can pay it, and nobody — including the sender — can learn the recipient's balance from the payment.
02 · Operations
| Operation | Amount | Proof | Pausable |
|---|---|---|---|
| Register | — | knowledge of the secret | no |
| Deposit | public | none | yes |
| Transfer | encrypted | range + balance + correctness | yes |
| Apply pending | — | none (owner only) | never |
| Withdraw | public | balance sufficiency | never |
Withdraw and apply pending can never be paused.
The pause exists so the team can stop new money coming in if something is wrong. It cannot stop money going out. This is enforced by the contract, not by policy.
03 · Proofs
A transfer proof shows that the sender knows their secret, that the amount is within the permitted range, that they hold at least that much, and that the ciphertexts written for sender and recipient encrypt the same amount under the right keys. Every public input except the new ciphertext is read by the contract from its own storage, the registry, or configuration — never supplied by the caller.
Each event carries the account's post-state ciphertexts, so any account's balance at any block can be rebuilt from the public log by anyone. The owner also keeps a sealed copy of their own balance on chain, so a wallet can recover it without replaying history.
Measured on Robinhood Chain testnet
04 · Selective disclosure
A disclosure is a signed document asserting one fact about one account at one block — an exact balance, or a range — with a proof. It is sealed under a fresh key and stored as ciphertext; the key travels in the link's URL fragment, which browsers never send to a server.
The verifier rebuilds the document's binding hash from its fields, requires an EIP-712 signature by the account, reads the ciphertext from the chain itself, and checks the proof against it. A document whose fields have been edited after signing fails. A balance whose only contributions are public deposits is reported as public_balance rather than "verified", because proving knowledge of a number anyone could compute proves nothing.
Revocation cannot unsee.
Revoking a link stops it resolving. Anyone who already opened it may have saved the proof, and a saved proof stays valid. The product says this in the same words wherever revocation appears.
05 · Trust box
| Party | Can | Cannot |
|---|---|---|
| Dark (the team) | pause deposits and transfers; tighten caps; see request metadata; serve the web app's code | move or freeze funds; block withdrawals; read a balance; change the proof checkers (they cannot be changed at all: a fix means a new vault that users move to, as with Dark v1.1) |
| The vault owner (timelock) | change caps and the guardian, after 48 hours in public | renounce ownership; bypass the delay |
| Robinhood Chain operator | order and filter transactions, including withdrawals; upgrade the chain without delay | read encrypted balances |
| USDG issuer | freeze USDG, including the vault's | read or move encrypted balances |
| The proving setup (Aztec Ignition) | allow forged proofs only if every ceremony participant colluded | be swapped: the reference string is public, bundled and hash-pinned |
| An auditor | read the code | decrypt anything: there is no auditor key |
On the web, Dark serves the wallet code on every load.
A compromised deployment could serve code that captures keys. The Android app and the standalone exit tool do not depend on Dark's servers for their code, and the exit tool depends on them for nothing.
Beta risks
Shieldify reviewed the vault contract in October 2026 and reported nothing above informational severity. The zero-knowledge circuits, the proof verifiers and the curve library have not had an external audit yet, and no review rules out every bug. A bug could let someone take USDG from the contract, and the loss would fall on whoever withdraws last. Only deposit what you can afford to lose. The Dark team can pause deposits and private transfers and lower the caps at once, but can never stop withdrawals. The contract can never hold more than $250,000, and holds at most $50,000 while the launch caps apply. If a later audit requires a new contract version, moving your balance means a public withdrawal and deposit, which reveals that amount.
06 · Limits and caps
The v1 vault carries immutable ceilings: at most 250,000 USDG in the vault, 2,500 per transfer, 2,500 per deposit, and 10,000 net inflow per account. Anything beyond those needs a new, audited vault. The operating caps sit at or below these and can be tightened without delay by the guardian, but only widened through the timelock.
The team's monitoring checks the vault every minute: solvency against the token contract, bookkeeping against the public log, the caps, the owner and guardian, the verifier bytecode against pinned hashes, timelock activity, and outflow rate. A check that cannot be evaluated is treated as failing.
07 · Exit
Custody claims are cheap. Dark ships a separate, permissively licensed tool that withdraws from the vault using a recovery phrase and any blockchain endpoint, and a static page that does the same in a browser with the prover and its parameters bundled. Neither contacts a Dark server. This is run as a drill with every Dark hostname blocked, and documented in the docs.
08 · Status
Dark v1 was deployed on Robinhood Chain mainnet (chain 4663) on 2026-09-28, with the vault 0xeD7a0c6899a6AC94Aea7A5b2F8f24a948042DA9C; it stays open for withdrawals forever. The launch caps hold total value locked to $50,000. Dark v1.1 runs the same reviewed vault code with proof checkers rebuilt on a fixed prover: the vault is 0x0811b38E81a13c2fECD639a38Ce10330D16A1bd6 and the key registry 0x0F81204c85598F3360BD0835694f463080864FF0.
Shieldify's review of the vault contract (October 2026) is published; v1.1's rebuilt proof checkers have not yet been reviewed by Shieldify; the circuits have not had an external audit yet. The normative specification, with every wire format pinned, is DARK-CB-1.