CRUMB a card from devarno-cloud

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 --> WitnessSignatures

Wire 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 valueConstantNote
0UNSPECIFIEDinvalid
1ED25519current production default
2DILITHIUMNIST FIPS 204 post-quantum
3ECDSA_P256legacy
4RSA_PSSlegacy

Dual-Signature Model

Every operation carries two independent signatures:

  1. UserSignature — Ed25519 or Dilithium key held by the user; signs SignedData.canonical_data with a domain separator
  2. 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:

FieldPurpose
entry_hashhash of this entry’s content
prev_entry_hashhash of the immediately preceding entry (chaining)
proofembedded VESTProof
sequencemonotonic 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