PPST: extending SPST to arbitrary private computation
F_RP Construction II. Generalises SPST to private programmable state: arbitrary arithmetic circuits over committed pre/post-state, with R1CS-embedded program execution and atomic PPST-SPST composition.
- FROM
- Dax the Dev <[email protected]>
- SOURCE
- https://blog.skill-issue.dev/blog/ppst_private_programmable_state/
- FILED
- 2026-05-02 15:00 UTC
- REVISED
- 2026-05-02 15:00 UTC
- TIME
- 6 min read
- SERIES
- relayerless-privacy
- TAGS
SPST gave us private value transfer with self-paying fees on a smart-contract chain. That’s the Solana analogue of Zcash’s Sapling — and exactly what every existing relayer-dependent privacy mixer (Tornado, RAILGUN, Light v1) does, just without the relayer.
But Tornado-style protocols are not the goal. The goal is Turing-complete private computation: a Solana program that runs on encrypted state and produces a proof of correct execution without leaking what the state was, what the inputs were, or what the program output. That’s PPST.
This is post 4 of 11 in the relayerless-privacy series. Reading post 3 first will help, but the construction here stands alone.
What “private program” means here
Definition (Private Program). A private program is an arithmetic circuit
over the BN254 scalar field, specified by an R1CS constraint system of size . Each program is identified by
where is the Groth16 verification key. The program identifier is a public, deterministic commitment to the program’s logic.
Definition (Private State). A vector committed as
State commitments are leaves in a state Merkle tree of depth 32, root . This is a separate tree from the SPST note-commitment tree.
Definition (State Transition). A triple where is private auxiliary input and
The transition consumes via nullification and produces as a new tree leaf. The program logic is never revealed to the verifier — only is.
The PPST relation
The relation is the set of pairs:
Public instance .
Private witness .
Nine constraints, all enforced by the outer PPST circuit:
| # | Name | Constraint |
|---|---|---|
| P1 | Program identification | |
| P2 | Pre-state commitment | |
| P3 | Pre-state membership | |
| P4 | State nullification | |
| P5 | Program execution | |
| P6 | Post-state commitment | |
| P7 | Post-state tree update | |
| P8 | Fee extraction | value-bearing state OR companion SPST |
| P9 | State authorization | embedded in pre-state |
P5 is the heart of the construction. The user-defined program — written in Circom, Noir, Leo, or any high-level circuit DSL — is embedded as a sub-circuit inside the outer PPST relation. The R1CS for becomes constraints inside the R1CS for .
How the program embedding works
The outer circuit sizes look like:
where R1CS constraints (Merkle paths, commitment hashes, PRF evaluations — see SPST §3.1.6) and is the program circuit size.
| Program complexity | Total PPST | Groth16 prove (M2) | |
|---|---|---|---|
| Simple (token transfer, vote, ACL) | 10³ — 10⁴ | 35,000 — 50,000 | 1 — 3 s |
| Moderate (private AMM swap, auction bid, credential) | 10⁵ — 10⁶ | 125,000 — 10⁶ | 5 — 60 s |
| Complex (private ML inference, DB queries) | > 10⁷ | impractical for direct Groth16 | minutes — hours |
Complex programs need IVC. PPST extends naturally: decompose the computation into uniform steps each running , fold them with Nova or SuperNova, then wrap the final accumulator in a Groth16 decider proof. The on-chain verifier always sees a constant-size 128-byte proof regardless of . Off-chain proving is but the chain doesn’t care.
Theorem 3.6 — PPST soundness
Statement. If Groth16 is knowledge-sound and Poseidon is collision-resistant, no PPT adversary can cause the PPST verifier to accept a transaction corresponding to an invalid state transition (one where ) except with negligible probability.
Proof sketch. Suppose produces a valid PPST transaction whose underlying transition is invalid. By Groth16 knowledge soundness, the extractor recovers a witness satisfying constraints P1–P9 — including P5: . Direct contradiction. ∎
Corollary (State Integrity). The state tree maintains the invariant that every leaf is a commitment to a state that resulted from a valid execution of an authorized program starting from a previously valid state. By induction on accepted transactions, this invariant holds at all times.
Theorem 3.7 — PPST zero-knowledge
Statement. PPST reveals nothing about , , , or the internal logic of beyond the public outputs.
Proof sketch. Direct from perfect ZK of Groth16. The simulator depends only on the public instance , not on the witness. For any two valid witnesses consistent with the same , the proof distributions are identical.
What does leak:
program_idis intentionally public. It identifies which program executed so the verifier can pick the right verification key. Full function privacy (hiding the program identity) requires a universal circuit or a commitment-to-vk argument and is left as a future extension.- The fact that some state transition occurred under that program.
- The fee .
What does not leak:
- The specific state values.
- The auxiliary inputs.
- Which specific leaf in was consumed.
Theorem 3.8 — PPST-SPST composability
This is the magic. PPST and SPST compose into a single atomic transaction: execute a private program AND transfer shielded value, in one ZK proof.
Construct the composite relation with a linking constraint:
binding the PPST state nullifier to the SPST input nullifiers. Both sub-proofs reference the same link value as a public input.
Cross-constraint (Value Mediation): if the program outputs a transfer amount , the SPST component enforces
That is — value flowing from the SPST shielded pool into the program’s state (or out of it) is reconciled inside the proof. An observer cannot tell whether the program consumed value, produced value, or merely transferred it.
Practical realisation. For a moderate program ():
Groth16 prover time on commodity hardware: 5–10 seconds. Single 128-byte proof on-chain. ~200,000 CU verification cost on Solana.
Comparison with Aleo and Aztec
| Aspect | Pros | Cons |
|---|---|---|
| PPST (this work) | Composes with SPST atomically; deployable as Solana smart-contract layer; relayer-free; 128-byte Groth16 proof | program_id leaks (no function privacy); per-program Groth16 ceremony; complex programs need IVC |
| Aleo records model (ZEXE) | Universal Marlin/Varuna SRS; native L1 chain with prover marketplace; relayer-free | Requires its own L1; program ID also visible; delegated proving leaks witness |
| Aztec PXE + AVM | Universal PLONK/Honk SRS; Noir DSL; client-side proving; relayer-free via FPCs | L2 rollup architecture (separate sequencer); function call boundary L→public visible |
The thing PPST gets that Aleo and Aztec don’t is deployment as a protocol layer on a high-performance Layer-1. Aleo and Aztec each require running their own consensus or sequencer. PPST runs as a Solana program on the same validators as Jupiter and Helium — inheriting Solana’s TPS, finality, and infrastructure.
What’s left
PPST plus SPST gives us private value + private computation. That’s two of the three privacy properties. The remaining gap is submitter anonymity: even with a perfect ZK proof, the wrapping Solana transaction is signed by an Ed25519 key whose public key is on-chain. Address graph analysis trivially links the “private” transaction to the submitter’s identity.
The next post is about closing that gap — without a relayer, without a mixing service, and without a separate L1.
Bibliography
- Bowe, S., Chiesa, A., Green, M., Miers, I., Mishra, P., Wu, H. (2020). ZEXE: Enabling Decentralized Private Computation. IEEE S&P 2020.
- Chiesa, A., Hu, Y., Maller, M., Mishra, P., Vesely, N., Ward, N. (2020). Marlin: Preprocessing zkSNARKs with Universal and Updatable SRS. EUROCRYPT 2020. https://eprint.iacr.org/2019/1047
- Aztec Network. Client-side Proof Generation. https://aztec.network/blog/client-side-proof-generation
- Kothapalli, A., Setty, S., Tzialla, I. (2022). Nova: Recursive Zero-Knowledge Arguments from Folding Schemes. https://eprint.iacr.org/2021/370
- Noir Language Documentation. https://noir-lang.org/docs/
Previous: SPST: self-paying shielded transactions ← · Next: TAB: threshold-anonymous broadcast →