ZKProof & ZKEngine
aegis advanced 7 min read
ELI5
A ZK proof is a sealed envelope: three wax stamps (A, B, C) on the outside prove the contents are genuine without ever opening it. The ZKEngine is the stamp press — it makes envelopes and keeps a copy; the Verifier checks the wax pattern without breaking the seal.
Technical Deep Dive
ZKProof Structure
ZKProof in src/zk_proof.rs models a Groth16-style proof with three elliptic-curve commitments:
| Field | Default size | Role |
|---|---|---|
commitment_a | 32 bytes | π_A in Groth16 |
commitment_b | 32 bytes | π_B in Groth16 |
commitment_c | 32 bytes | π_C in Groth16 |
public_inputs | Vec<Vec<u8>> | Inputs visible to verifier |
timestamp_ms | u64 | Wall-clock at creation |
is_valid() checks that all three commitment vectors are non-empty. size_bytes() sums the three commitment lengths plus the total bytes across public_inputs.
ZKEngine
ZKEngine stores generated proofs in a HashMap<String, ZKProof>. Key operations:
- generate_proof(proof_id, inputs) — creates a
ZKProof, stores it underproof_id, returns it. Overwrites any existing proof with the same id. - get_proof(proof_id) — clones the stored proof or returns
None. - verify_structure(proof) — requires
proof.is_valid()AND!proof.public_inputs.is_empty(). A proof with no public inputs fails structure verification even if commitments are set.
Class Diagram
classDiagram class ZKProof { +proof_id: String +commitment_a: Vec~u8~ +commitment_b: Vec~u8~ +commitment_c: Vec~u8~ +public_inputs: Vec~Vec~u8~~ +timestamp_ms: u64 +is_valid() bool +size_bytes() usize } class ZKEngine { -proofs: HashMap~String, ZKProof~ +generate_proof(id, inputs) Result~ZKProof~ +get_proof(id) Option~ZKProof~ +verify_structure(proof) bool +proof_count() usize +average_proof_size() usize +clear() } ZKEngine "1" --> "0..*" ZKProof : storesGeneration Sequence
sequenceDiagram participant Caller participant ZKEngine participant ZKProof Caller->>ZKEngine: generate_proof("p1", inputs) ZKEngine->>ZKProof: ZKProof::new("p1") ZKProof-->>ZKEngine: proof (commitments zeroed, ts set) ZKEngine->>ZKProof: .with_inputs(inputs) ZKEngine->>ZKEngine: proofs.insert("p1", proof) ZKEngine-->>Caller: Ok(proof)Note: the current implementation initialises commitment_a/b/c to vec![0u8; 32]. In a production Groth16 backend these would be populated from the actual circuit proving key.
Difference: is_valid vs verify_structure
| Check | is_valid() | verify_structure() |
|---|---|---|
| Non-empty commitments | Yes | Yes (via is_valid) |
| Non-empty public_inputs | No | Yes |
A proof with commitments set but no public inputs passes is_valid() but fails verify_structure().
Key Terms
- ZKProof → Groth16-style proof with three 32-byte commitment components; defined in
src/zk_proof.rs - commitment_a/b/c → Elliptic-curve points A, B, C in Groth16 notation; default 32 bytes each
- public_inputs → Witness-independent inputs the verifier can see; required for
verify_structure - ZKEngine → In-memory proof store and factory; HashMap-backed, no persistence
- Groth16 → Pairing-based zk-SNARK with O(1) verification; requires trusted setup
Q&A
Q: A caller calls generate_proof("p1", inputs) twice — does the second call fail or overwrite?
A: It overwrites silently. HashMap::insert replaces the existing entry and the old proof is dropped.
Q: What is the total default size of a freshly-created ZKProof with no public inputs?
A: commitment_a (32) + commitment_b (32) + commitment_c (32) + public_inputs sum (0) = 96 bytes.
Q: average_proof_size() returns 0 on an empty engine — does it also return 0 if all proofs have zero-length public_inputs?
A: No. With zero-length public inputs, each proof still contributes 96 bytes (the three commitments). average_proof_size() would return 96, not 0.
Examples
Generate and structurally verify a proof:
let mut engine = ZKEngine::new();let proof = engine.generate_proof("p1", vec![vec![1, 2, 3]]).unwrap();assert!(engine.verify_structure(&proof)); // public_inputs non-empty → true
// Proof with no inputs fails structure checklet bare = ZKProof::new("bare");assert!(!engine.verify_structure(&bare)); // public_inputs empty → falseneighbors on the map
- FNP Halo2 Zero-Knowledge Circuits understanding zero-knowledge proofs in FNP
- FNP End-to-End Encryption & Zero Trust Architecture understanding FNP's security layers
- Commitment Scheme & CommitmentTypes designing a new AEGIS commitment for a previously untracked attribute
- Verifier & Verification Protocol diagnosing why verify_zk_proof returns Ok(false) for a proof that appears structurally valid