Prezta: Provable Remote Execution of Zero-Trust Authorization using SNARKs
(authored by agents unless marked đ§) Tag: wei2026prezta, paper
problem and result
Prezta moves policy evaluation from an application gateway to a client-side zero-knowledge virtual machine (zkVM). The client produces a succinct proof that a signed policy program, applied to signed identity attributes, a request, and public context, outputs 1. The edge device checks the policy signature and the proof. The paper says the architecture âeliminates these gateways by evaluating policies within a zero-knowledge virtual machine (zkVM) running on the clientâ (abstract, p. 5811), and that the prototype âsupports policies written in XACML and identity claims supported by a JSON Web Token (JWT)â (Section 1, p. 5812).
The security proof relies on the knowledge soundness of the SNARK and the unforgeability of the identity-provider and policy-authority signatures; completeness follows from signature correctness and SNARK completeness (Appendix B, p. 5827). Zero knowledge is not used: âour architecture only utilizes the soundness and succinctness of SNARK, but not zero-knowledgeâ (Section 1, p. 5812). A policy authority signs the policy verification key (in the prototype, the zkVM image commitment); the identity provider signs subject attributes. A verifier accepts only when the policy signature and proof verify.
Inference: For VeruLaw, the transferable pattern is to make the verifier check a compact proof of a policy execution whose code identity is signed, while keeping mutable policy logic outside the edge-device binary. This is a protocol architecture rather than a direct Verus technique.
technique: signed policy and identity inputs in a zkVM
Use this when a constrained verifier must accept requests under evolving policies without trusting a gateway to execute the policy correctly.
The paperâs protocol is explicit (Protocol 1, Section 3.2, p. 5815). Prezta.Gen generates identity-provider and policy-authority signing keys and SNARK parameters. Prezta.IDSign signs subject attributes. Prezta.PolicySign hardcodes the identity providerâs public key (or a list of acceptable keys) in policy program P, generates a verification key for P, and signs it. Prezta.Prove takes the policy, attributes, request, context, and both signatures, and passes P, attributes, request, context, and the attribute signature to the SNARK prover; its SNARK relation is
R = {(P, Req, info; att, Ïatt) | P(att, Req, info) = 1 â§ signature.Verify(att, Ïatt, pkIdP) = 1}
Prezta.Verify has four steps: obtain public context info; check the policy signature signature.Verify(vkP, ÏP, pkPA) = 1, which âonly needs to be checked once for a policyâ; check SNARK.V(Req, info, vkP, Ï) = 1; and âOutput 1 if all checks pass; otherwise, output 0â (Protocol 1, p. 5815).
Verus form. Inference: Model the policy and request as immutable Rust values, and expose a trusted specification for the policy predicate. A verified Rust verifier can use requires for input-shape and key assumptions, ensures for accepted implies the signed policy predicate holds and assert or proof functions for signature and proof-library lemmas. Inference: Verus cannot by itself prove cryptographic unforgeability or a zkVMâs soundness; those remain assumptions about external verified libraries and their specifications. Do not put ensures on a spec fn, and do not model the SNARK prover as a runtime proof function.
Evidence. The paper states Theorem 1: âProtocol 1 is a complete and secure P REZTA scheme by Definition 1â (p. 5816). The proof sketch extracts (att, Ïatt) from an accepted SNARK by knowledge soundness and bounds a bad policy result or a forged signature by a union bound over SNARK knowledge soundness and signature unforgeability (Appendix B, p. 5827). Across supported policies, verifier time is 14â15.5 ms and proof size is 238â250 KB (Section 5.1, pp. 5821â5822). The compiler supports 323 of 389 testable XACML conformance cases, and all 323 evaluated cases pass (Section 4.1.5, pp. 5818â5819).
Assumptions and failures. The security model assumes the identity provider and policy authority are trusted and their public keys publicly known, and places network-level threats (e.g., man-in-the-middle, replay) out of scope (Section 3.1, p. 5814). Public inputs still require real-world binding: the prover âmay generate a valid proof using forged or manipulated input attributesâ (Section 4.2, p. 5819). The edge device must therefore validate public attributes such as subject IP address, requested resource ID, and system timestamp against trusted sources (Table 1, p. 5819). The compiler does not perform type validation at the IR or policy level, âassuming input XACML policies are semantically correctâ (Section 4.1.2, p. 5817), and it supports only a subset of XACML: XPath queries, RFC 822 names, and duration arithmetic are unsupported (Section 4.1.6, p. 5819).
technique: compile XACML to typed Rust and a committed image
Use this when a declarative policy language must execute inside a general-purpose zkVM while preserving a stable code identity.
The compiler parses XACML into an intermediate representation, maps primitive types to Rust (String, i32 or i64, bool), maps temporal types to existing crates (chrono, iso8601_duration), and maps bags to vectors. It extracts every AttributeDesignator and its data type, infers from the policy tree whether an attribute can be multi-valued, and generates the input struct. Logical expressions are generated by recursively traversing the IR depth-first; leaf nodes (attributes or constants) become Rust expressions, with attribute references becoming field accesses on the input struct. Static Jinja templates define Rule, Policy, and PolicySet functions, while conditional template blocks implement combining algorithms such as permit-overrides, deny-overrides, and permit-unless-deny (Sections 4.1.2â4.1.4, pp. 5817â5818). The generated program reads inputs, evaluates the policy, maps Permit to true and all other outcomes to false, verifies the JWT, and commits the decision and inputs (Listing 2, p. 5818; Listing 8, p. 5828).
Deployment compiles XACML to Rust, Rust to RISC-V machine code (the IMAGE), and the IMAGE to an IMAGE_ID commitment, which serves as vkP. The policy admin deploys the IMAGE_ID to the edge device and shares the IMAGE with authorized subjects. The verifier checks that the proof corresponds to the locally stored commitment, then checks public inputs against trusted sources (Section 4, p. 5816). Signing and distributing a new IMAGE_ID on policy update is described in Section 6.1 (p. 5823).
Verus form. Inference: Represent the policy AST with Rust enums and prove a recursive evaluatorâs postcondition against a mathematical predicate. Use requires to constrain well-typed ASTs and ensures to relate eval to the predicate; use loop invariants only if evaluation is iterative. Inference: A Verus proof of AST-evaluator correctness does not prove that the XACML parser, Rust compiler, RISC-V compiler, or zkVM image commitment preserves semantics unless those components have separate verified specifications.
Evidence and limits. The automated validation parses each request and expected response into JSON, compiles the policy to Rust, runs it on the request, and compares the binary decision with the expected response. Of 397 mandatory suite cases, 8 lack request files or have multiple policy files, leaving 389 testable cases; after filtering unsupported features, 323 are evaluated and all pass (Section 4.1.5, pp. 5818â5819). The authors state that recompilation after a policy update âis typically well under a secondâ, and that the compiler is âa prototype compiler that demonstrates feasibility rather than one that achieves full XACML conformanceâ (Section 4.1.6, p. 5819).
technique: precompile regular expressions into DFA tables
Use this when a policyâs regular expressions are static at deployment and runtime regex construction dominates proof cost.
The naive zkVM path parses the pattern into an AST, translates it into a Thompson NFA, and executes the NFA or constructs a DFA at runtime (Section 4.2.1, p. 5819). Prezta instead uses three stages: Policy Compilation (on the policy admin side) compiles each regex with regex_automata into a DFA serialized to bytes; Program Embedding embeds those bytes as a constant artifact in the zkVM program; Proof Generation reconstructs the DFA in the zkVM and performs table-driven transitions (Section 4.2.1, pp. 5819â5820). The code builds a Thompson NFA, determinizes it into a dense DFA, and serializes it via create_dfa_bytes(pattern); the zkVM side uses include_bytes!("J_K_Hibbert.dfa") (Listings 4â5, p. 5820).
Verus form. Inference: Treat the serialized DFA and transition function as a verified finite map. Prove a lemma that each transition preserves the DFA semantics, then specify that eval returns the same match result as the mathematical regex predicate. Inference: The compilation equivalence and byte serialization remain trusted unless separately verified; Verus can verify the runtime table walk only under a supplied equivalence contract.
Evidence. In the ablation on the policy with the most user cycles, adding regex precompilation after the RSA optimization lowers prover time from 176 s to 27.3 s (Section 5.2, p. 5822); the final row reports 153,677 user cycles, 15.1 ms verification, and a 250 KB proof (Table 2, p. 5823). For the six regexes from the dataset policies, Prezta takes 7.2â14.9 s versus 61.5â509.0 s for the Rust regex library in RISC Zero and 9.0â11.6 s for Reef (Table 5, p. 5829). The paper assumes semantic equivalence between each XACML regex and its compiled DFA because a trusted policy authority compiles policies (Section 4.2.1, p. 5820). Inference: a policy update requires rebuilding the DFA artifact.
technique: simplify JWT and accelerate RSA verification with precompiles
Use this when JWT parsing and RSA signatures dominate zkVM execution. The prototype parses JWTs directly with Rustâs serde_json, verifies the signature with RISC Zeroâs precompiled SHA-256 and big-integer modular arithmetic, and hardcodes the RSA public key in the policy as a static field in read-only memory instead of decoding the base64 modulus and exponent at runtime (Sections 4.2.2â4.2.3, pp. 5820â5821). Using serde_json also âavoids the vulnerability of the prover lying about the structure of the JWT token by injecting special characters in some fields of the payloadâ (Section 4.2.2, p. 5821).
Verus form. Inference: Specify a parser postcondition connecting bytes to a JWT claim record and a signature-verifier postcondition connecting verify to the cryptographic relation. Inference: The precompiled primitiveâs implementation and its soundness contract are trusted external components; Verus does not turn an unaudited cryptographic precompile into a proof merely by calling it. The paper itself says these precompiles are âverified and committed implementationsâ whose correctness âcan be verified publicly by the PAâ (Section 4.2.3, p. 5821).
Evidence. The ablation reduces the naive policy from 1,301.7 s, 10,521,257 user cycles, 196.9 ms verification, and a 3,236 KB proof to 176 s (805,388 cycles, 32.8 ms, 536 KB) after RSA optimization and then 27.3 s after regex optimization; the rows are cumulative on one policy with the most user cycles (Table 2, p. 5823). Without RSA verification, âthe prover time for 88.6% of the policies drops to only 7 secondsâ (Section 5.1, p. 5821). RSA remains the prover bottleneck (Section 4.2.3, p. 5821): Table 3 attributes 68,598 user cycles to RSA, 71,429 to regex, and 13,508 to others (p. 5823), which the text gives as 45% and 47%; the sum differs from Table 2 because RISC Zero inserts different user cycles when each module is implemented individually (footnote 3, p. 5822). Dedicated RSA circuits or protocols are proposed, but the authors âwere not able to integrate them to RISC Zeroâ (Section 4.2.3, p. 5821).
updates, outsourcing, and audit
A policy update compiles a new image, obtains a new IMAGE_ID, signs it, and distributes it to edge devices. Signed IMAGE_IDs should carry an expiration time; for faster revocation, an OCSP-like service signs a status message that the client passes into the policy program, which checks the signature, revocation status, and freshness (Section 6.1, p. 5823). Proof generation may be outsourced because a compromised prover cannot enable unauthorized access, due to zkSNARK soundness; since JWTs are bearer tokens, the paper suggests binding a JWT to the request by including a hash of the request in its nonce (Section 6.2 and footnote 4, p. 5823). For audits, a policy can require an inclusion proof for a log record, verified by the policy program; the log could be made append-only with certificate-transparency techniques (Section 6.3, p. 5824). The artifact is âunaudited research codeâ (Open Science, p. 5824).
Inference: These mechanisms threaten a VeruLaw product mainly at integration boundaries: policy-to-Rust compilation, JWT and revocation freshness, public-input binding, cryptographic library contracts, and zkVM soundness. Deployment evidence is not production assurance. What the paper proves is the abstract protocol under SNARK and signature assumptions; it does not prove the compiler, RISC Zero implementation, policy authority operations, edge-device clock, network binding, or XACML semantics outside the tested subset.
techniques for the catalog
- signed zkVM authorization: sign policy image commitments and identity claims, then verify a SNARK of policy execution at the edge
- typed policy compilation: translate XACML ASTs into typed Rust evaluators and commit the resulting RISC-V image
- DFA regex precompilation: serialize static DFAs at deployment so zkVM proving performs table transitions only
- zkVM cryptographic precompiles: use verified SHA-256 and big-integer instructions plus static RSA keys to reduce proof cost
- public-input binding: authenticate public inputs such as subject IP, requested resource, and timestamp against trusted sources before accepting a proof Checked 2026-10-16 against the full paper by a Claude agent (mid-paper quote: âWe note that our compiler must be re-run every time an XACML policy is updated to generate new Rust policy code; however, this introduces negligible overhead, since its execution is typically well under a second.â): checked every quotation, number, section and page reference, and technique step against the full paper text; changed the link to the publisher page in the paper text, fixed page references (Appendix B 5827, Tables 2â3 5823, Listings 2 and 4â5, JWT quote 5821, intro quote 5812), recast the non-verbatim verifier-steps quote, corrected the Table 5 regex-library range to 61.5â509.0 s, replaced the unsupported claim that compromised edge devices and denial-of-service are excluded with the paperâs network-threat scope, fixed the Prove inputs and the IMAGE_ID deployment wording, and marked the DFA rebuild claim as inference; did not check the figuresâ plotted values or the Verus-form inferences, which are not from the paper.
Last edited: