Security Model
Platus enforces guarantees in three layers:
- C: ZK circuit (
packages/noir) - K: Smart contract (
packages/contracts) - S: SDK pre-submission (
packages/sdk)
Properties held only in S are convenience, safety-critical properties are in C and/or K.
Actors
| Party | Trust Model |
|---|---|
| User device, contracts, UltraHonk | Honest — key never exfiltrated, immutable code |
| Bundler, indexer/RPC | Untrusted — can censor or reorder, cannot violate safety |
| Chain observer, batch peers, quantum adversary | Active — see all data, harvest ciphertexts |
Properties
| # | Property | (C/K/S) | Mechanism |
|---|---|---|---|
| 1 | Value conservation | C + K | Pedersen commitments + binding Schnorr over aggregated blinding factors |
| 2 | Spend authority | C | In-circuit Schnorr on rerandomized key rk = ak + α·G |
| 3 | No double-spend | C + K | Nullifiers nf = H(nk, ρ, ψ, cm); spent-set + transient dedup |
| 4 | No intra-Action inflation | C | nf1 ≠ nf2 + 129-bit range checks |
| 5 | Faerie-Gold resistance | C | cm binds nf; rho-chaining (ρ_new = nf_old) |
| 6 | Membership soundness | C + K | Depth-16 Merkle proof + rootHistory anchor |
| 7 | Recipient unlinkability | C + S | Stealth addresses, fresh esk, view tags |
| 8 | Batch isolation | K | Gas-capped per-action execution; per-bundle settlement |
| 9 | Refund integrity | K | Pre-execution balance snapshots (F1) |
| 10 | Aggregator soundness | C + K | VK pinning: ACTION_VK_HASH, RECURSIVE_2_LEAF_VK_HASH, RECURSIVE_2_INNER_VK_HASH |
| 11 | Post-quantum confidentiality | S | ML-KEM-768 hybrid encryption |
Key Mechanisms
Binding signature. The contract reconstructs bvk = Σ cv_net,i − netPublicValue·H and verifies the bundler's Schnorr signature, proving value balance without revealing amounts. Per-bundle asset uniformity prevents cross-asset minting.
Spend authorization. The Schnorr check on rk happens in-circuit, with challenge e bound to authCtx (chainId, orchestrator, deadline, asset, etc.) via publicsDigest. No per-Action on-chain signature needed.
Nullifier defense. nf = H(nk, ρ, ψ, cm) binds to the specific note. Circuit enforces nf1 ≠ nf2 and cm1 ≠ cm2 (via rho-chaining). Cross-transaction dedup on-chain; transient dedup in-bundle.
Refund integrity (F1). Pre-execution snapshots ensure only balanceOf − snapshot (this bundle's deposit) can be swept to refundTarget, protecting foreign AppAccount balances even when enableSpends=false.
VK pinning. Each recursion layer asserts child key_hash matches pinned VKs; finalize constrains root to {leaf, inner} set. Contract passes pinned hashes as public inputs.
Post-quantum. Hybrid ECDH + ML-KEM-768 via HKDF. Ciphertexts harvest-now-decrypt-later resistant; spend authority (Schnorr) not yet PQ-secure.
Residual Risks
- View-tag grief: Corrupt hint forces full decapsulation scan (note recoverable)
- Censorship: Mitigated by multiple bundlers, self-submission,
rootHistorywindow - Stranded assets: Non-
refundAssetstokens sent to Orchestrator are unrecoverable - Fee-on-transfer tokens: Revert on
Vault.pullexact-balance check