VESTProof Wire Format & Proto Schema
vest intermediate 7 min read
ELI5
A shipping manifest with many carbon-copy sections: the outer envelope (VESTProof) holds the parcel reference, who sent it, who witnessed it, where it sits in the warehouse rack (MerkleProof), when it was stamped (TimestampProof), and which regulations it satisfies (ComplianceRecord). Every section is a typed sub-form with its own validation rules.
Technical Deep Dive
VESTProof Top-Level Structure
VESTProof (defined in proto/protocols/vest.proto) is the canonical wire type for a complete audit proof:
classDiagram class VESTProof { +proof_id: bytes +timeline_id: bytes +operation: OperationReference +user_signature: UserSignature +witness_signatures: WitnessSignatures +merkle_proof: MerkleProof +timestamp_proof: TimestampProof +cross_refs: CrossReferenceProof[] +compliance: ComplianceRecord +status: ProofStatus +metadata: ProofMetadata } class UserSignature { +algorithm: SignatureAlgorithm +signature: bytes +public_key: bytes +signed_data: SignedData +signed_at: Timestamp } class WitnessSignatures { +aggregate_signature: bytes +individual_signatures: IndividualWitnessSignature[] +threshold: ThresholdConfig +witness_set_hash: bytes } VESTProof --> UserSignature VESTProof --> WitnessSignaturesWire Layout
VESTProof is proto3-encoded; field numbers (not absolute byte offsets) drive the layout. The diagram below is symbolic — each field gets one equal-width slot — because proto3 encoding is variable-length (length-delimited bytes, varint enums):
---config: packet: bitsPerRow: 8---packet-beta title VESTProof proto3 fields 1 through 11 0-7: "proof_id" 8-15: "timeline_id" 16-23: "operation" 24-31: "user_sig" 32-39: "witness_sigs" 40-47: "merkle_proof" 48-55: "timestamp_proof" 56-63: "cross_refs[]" 64-71: "compliance" 72-79: "status" 80-87: "metadata"Signature Algorithms
| Enum value | Constant | Note |
|---|---|---|
| 0 | UNSPECIFIED | invalid |
| 1 | ED25519 | current production default |
| 2 | DILITHIUM | NIST FIPS 204 post-quantum |
| 3 | ECDSA_P256 | legacy |
| 4 | RSA_PSS | legacy |
Dual-Signature Model
Every operation carries two independent signatures:
- UserSignature — Ed25519 or Dilithium key held by the user; signs
SignedData.canonical_datawith a domain separator - WitnessSignatures — BLS12-381 threshold aggregate from ≥ N of M server witnesses; selection policy configurable (RANDOM, ROUND_ROBIN, GEOGRAPHIC, LOAD_BALANCED)
Timestamp Proof Variants
TimestampProof uses a oneof proof with three options:
- RoughtimeProof — midpoint + radius_us + ≥ threshold server responses; prevents backdating
- RFC3161Proof — standard TSA token with certificate chain
- BlockchainProof — block number + tx hash + Merkle path within block
Compliance Record
ComplianceRecord attaches regulatory metadata to each entry. Supported frameworks (via ComplianceFrameworkType): GDPR, CCPA, SOC2, HIPAA, eIDAS, 21 CFR Part 11, PCI DSS, ISO 27001, FedRAMP. Privacy markers track PII types (NAME, EMAIL, SSN, HEALTH, BIOMETRIC, etc.) and legal basis.
AuditEntry vs VESTProof
The proto AuditEntry is the log record; VESTProof is its embedded proof bundle:
| Field | Purpose |
|---|---|
entry_hash | hash of this entry’s content |
prev_entry_hash | hash of the immediately preceding entry (chaining) |
proof | embedded VESTProof |
sequence | monotonic sequence number in the log |
ProofStatus Lifecycle
PENDING → PARTIAL → COMPLETE → SEALED. REVOKED and EXPIRED are terminal states reachable from any non-sealed state.
Key Terms
- VESTProof → complete proof bundle: operation ref + user sig + witness sigs + Merkle + timestamp + compliance
- dual-signature → user Ed25519/Dilithium + BLS threshold witness; both required for COMPLETE status
- RoughtimeProof → distributed timestamp preventing backdating; requires ≥ threshold server responses
- SignedTreeHead (STH) → RFC 6962 checkpoint: signed (tree_size + root_hash + timestamp)
- ComplianceRecord → per-entry regulatory metadata covering frameworks, PII types, retention, and legal basis
Q&A
Q: What prevents a user from submitting a VESTProof with status SEALED from the start? A: Status is set server-side during proof assembly; clients submit the operation and signatures, not the final proof status. The server transitions status from PENDING through to COMPLETE and SEALED.
Q: How many witnesses are required at minimum for BLS threshold in WitnessSignatures?
A: Determined by ThresholdConfig.threshold (uint32). The proto definition does not enforce a minimum; the application layer sets the threshold.
Q: Does the Rust MerkleProof struct have a tree_id or SignedTreeHead field?
A: No. Those fields exist only in the proto MerkleProof. The Rust struct in src/proof.rs has only leaf_hash, path, and tree_depth.
Examples
A minimal VESTProof construction flow (pseudo-proto):
VESTProof { proof_id: blake3(canonical_operation), timeline_id: <document_id>, operation: OperationReference { op_id, op_hash, BLAKE3, "insert", doc_id, actor_pk }, user_signature: UserSignature { ED25519, sig_bytes[64], pk[32], SignedData{...}, ts }, witness_signatures: WitnessSignatures { agg_sig, [w1, w2, w3], Threshold{2,3}, ws_hash }, merkle_proof: MerkleProof { tree_id, LOG, leaf_index, tree_size, root, proof_path, STH }, timestamp_proof: TimestampProof { ROUGHTIME, RoughtimeProof{midpoint, 500us, [s1,s2,s3], 2} }, compliance: ComplianceRecord { [SOC2, GDPR], residency, retention, privacy_markers }, status: COMPLETE,}neighbors on the map
- VEST Protocol Architecture Overview onboarding to the VEST codebase for the first time
- EventEnvelope Wire Wrapper publishing a new domain event proto
- ProtocolMessage Envelope adding a new wire message type
- FNP Dilithium Post-Quantum Signatures understanding digital signatures in FNP