Expand description
OpenTimestamps proof-file wire format — parse, serialize, replay.
Implements the op-stream format from python-opentimestamps (the reference implementation): a file header magic, then a recursive timestamp tree where each node holds attestations and op-edges, and every edge’s child is keyed by the operation’s result on the current message. Verification replays the ops from the stamped digest; attestations hang off terminal messages.
Wire details (pinned from the reference; see the audit ledger’s OTS item for the full table):
- file magic:
\\0OpenTimestamps\\0\\0Proof\\0+ 8 salt bytes (bf 89 e2 e8 84 e8 92 94 — the final two were dropped in the first transcription; caught by the gem’s cross-checked Ruby spec), then major version0x01 0xFFseparators precede every tag except the last sibling- tag
0x00introduces an attestation: 8-byte tag + payload - op tags: SHA256
0x08, APPEND0xF0, PREPEND0xF1, REVERSE0xF2, HEXLIFY0xF3(unknown tags are rejected — extend the enum when a real proof needs them) - varuint is unsigned LEB128; varbytes is varuint-length + bytes
Structs§
- OtsFile
- A parsed OTS proof file: header + root timestamp node.
- OtsWire
Verification - Replay summary: every attestation paired with the terminal message it actually commits.
- Timestamp
Node - One node of the timestamp tree: attestations plus op-edges.
Enums§
- Attestation
- An attestation on a terminal message of the proof tree.
- Op
- A timestamp operation.
- Wire
Error - Errors from the wire format layer.
Constants§
- FILE_
MAGIC - File header magic:
\0OpenTimestamps\0\0Proof\0+ 8 salt bytes. - MAX_
RESULT_ LENGTH - Maximum op payload / message length accepted on deserialization — matches the reference implementation’s guard against maliciously large proofs.
Functions§
- parse
- Parse an OTS proof file for
digest. - replay
- Replay the proof tree from
file.digest, yielding every(terminal_message, attestation)pair. - serialize
- Serialize an OTS proof file (canonical ordering: attestations sorted, ops sorted by tag).
- verify
- Replay and classify: partition every attestation by kind, paired with the message the op-chain computed for it. A proof whose tree yields no attestations verifies nothing.