OpenTimestamps & Bitcoin anchoring
A signed log proves we attest to its history — it doesn't prove we can't quietly rewrite that history and re-sign it.
If the only clock in the system is the one the log operator controls, "tamper-evident" is a courtesy, not a guarantee. OpenTimestamps fixes that: it commits a hash into the Bitcoin blockchain, so "this existed by time T" no longer depends on anyone's word — including ours.
Whisper's transparency log already makes issuance and revocation append-only and independently checkable. This page is the layer underneath that: how the log's signed checkpoint gets a Bitcoin timestamp, why a block height is a clock nobody can move, and how to verify the proof yourself with nothing but a stock ots client and a block explorer.
The problem OpenTimestamps solves
A hash and a signature prove integrity ("this exact bytes, signed by this key") but not time. If Whisper wanted to back-date an identity's issuance — to make a compromised key look like it was registered before an incident, say — a self-signed timestamp is worthless as a defense: the log operator holds both the signing key and the clock. Auditors and courts have the same objection to any purely internal timestamp, which is why RFC 3161 Time-Stamping Authorities exist — except a TSA is itself a trusted third party you must trust not to backdate on request.
OpenTimestamps (Todd, 2016) removes the trusted party by borrowing a clock nobody controls: Bitcoin's proof-of-work chain. A commitment mined into a block can only have existed at or before that block's height, because moving it earlier would require re-mining every block since — an amount of work that grows with the security budget of the entire Bitcoin network. That is the whole idea: the timestamp's integrity is backed by physics and economics, not by trusting Whisper, a calendar server, or anyone else.
The mechanism, precisely
1. Hash, don't publish
The client never sends the document — only its SHA-256 digest. For Whisper this digest is the signed transparency-log checkpoint root: 32 bytes, the same C2SP signed-note structure served at /checkpoint. Anchoring only the root reveals nothing about the log's contents — not even how many entries it holds.
2. Calendar servers aggregate
A submitted hash goes to one or more public calendar servers (e.g. alice.btc.calendar.opentimestamps.org, bob.btc.calendar.opentimestamps.org, finney.calendar.eternitywall.com). A calendar batches everyone's hashes that arrive within its commit window into its own Merkle tree and returns a pending attestation: a Merkle path from your hash up to a root the calendar promises to commit to Bitcoin. This is the aggregation step that makes the scheme practically free — thousands of unrelated timestamps from unrelated services worldwide share a single on-chain transaction, so the marginal cost per timestamp is close to zero and no client needs a wallet, gas, or a node.
3. One Bitcoin transaction commits the root
Periodically (calendars typically batch on the order of an hour) the calendar mines its current aggregate root into a real Bitcoin transaction, committing the 32 bytes via a standard OP_RETURN output (or, in some implementations, via a Pay-to-Contract-style tweak of an output's public key — either way the commitment is unspendable data, not a transfer of value). Once that transaction confirms, the calendar's promise becomes checkable fact: anyone can walk the Merkle path from your original hash, through the calendar's aggregate root, into the transaction, into that block's own Merkle root of transactions — the same 80-byte block header structure defined for Bitcoin's block format — and match it byte-for-byte.
4. Block height is the timestamp — and it's unforgeable
The proof's timestamp is the height (and therefore the median time) of the block that mined the commitment. Rewriting it would mean re-mining that block and every block after it with more cumulative proof-of-work than the honest chain — the identical guarantee that secures every Bitcoin transaction, at Bitcoin's full difficulty. Nobody, including Whisper, including the calendar operator, can move a confirmed commitment to an earlier height after the fact. That's the "even we cannot back-date the log" claim, made literal.
5. The .ots file is the whole proof, portable and offline-verifiable
An .ots file is a small binary description of the operation chain from your original hash to a Bitcoin block: a sequence of sha256/ripemd160/append/prepend ops (the calendar's Merkle path) terminating in an attestation — either pending (a calendar promise, not yet a chain fact) or bitcoin (the transaction id and block height, with the path proven against a real header). Verifying it needs no calendar, no OTS service, and no Whisper endpoint at all — only Bitcoin block headers, which anyone can fetch from a full node or a public explorer.
Honesty window. A freshly stamped checkpoint is pending — a calendar's promise — until its batch confirms and the proof is upgraded with the real Bitcoin transaction and Merkle path, typically within an hour. Whisper reports this status plainly rather than implying real-time anchoring: the "cannot be back-dated" guarantee only applies once a root is upgraded and confirmed.
Whisper's anchor, end to end
Every signed checkpoint of the transparency log — the same Ed25519-signed origin / tree_size / root_hash triple served over C2SP tlog-tiles — gets its root submitted to public OTS calendars off any hot path. Minting, resolution, and the log itself never wait on a calendar; if every calendar were unreachable, checkpoints would still sign and serve, and the anchoring backlog would simply catch up later. Once a calendar's batch confirms, the proof is upgraded and the checkpoint's Bitcoin attestation is served for anyone to fetch and verify independently of Whisper's word:
GET https://whisper.online/checkpoint # origin, tree_size, root_hash, Ed25519 signature
GET https://whisper.online/checkpoint/ots # the OpenTimestamps proof for the current checkpoint
GET https://whisper.online/ots/<tree_size> # the proof for a specific historical checkpoint
Verify it yourself: stock tools vs. Whisper
With stock tools — no Whisper software, just the open OpenTimestamps client and a public Bitcoin explorer:
# fetch the current signed checkpoint and its Bitcoin proof
# name the checkpoint 'checkpoint' so `ots verify` finds it beside `checkpoint.ots`
curl -s https://whisper.online/checkpoint -o checkpoint
curl -s https://whisper.online/checkpoint/ots -o checkpoint.ots
# the standard, independent OpenTimestamps client (pip install opentimestamps-client)
pip install opentimestamps-client
ots verify checkpoint.ots
# Success! Bitcoin block 955344 attests existence as of 2026-06-30 CEST
# cross-check the block itself against a second, unrelated source
curl -s https://mempool.space/api/block-height/955344
curl -s https://blockstream.info/api/block-height/955344
# both must return the identical block hash — no coordination with Whisper or OTS required
ots verify recomputes the operation chain from your local file's hash, arrives at a commitment, and confirms that commitment is present in the header of block 955344 by querying a local Bitcoin node's block index — the reference client verifies against a node you run, never a third party. If you don't run one, the two curl calls above check the same block hash against independent explorers; two unrelated explorers agreeing on that hash is itself a cross-check that no single party is feeding you a forged header.
With Whisper — the trustless verifier folds the same check into a single command, alongside DNSSEC and DANE, for any agent identity:
whisper verify --trustless acef2002a323d40d4.<tenant>.agents.whisper.online
# ✓ DNSSEC IANA root -> ... -> agents.whisper.online (RRSIGs valid)
# ✓ DANE-EE served leaf SPKI == TLSA 3 1 1 b653a4ef…fcb82d1d
# ✓ transparency RFC-6962 inclusion proof valid against signed checkpoint
# ✓ bitcoin checkpoint root confirmed @ block 955344 (2026-06-30)
# CRYPTOGRAPHICALLY PROVEN — Whisper API not trusted
Per-agent inclusion plus the checkpoint's anchor status is also available as plain JSON, for scripting into a compliance pipeline:
curl -s https://rdap.whisper.online/ip/2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4/transparency | jq '.inclusion, .checkpoint.ots'
Why not just stamp Bitcoin directly?
A self-funded daily OP_RETURN transaction is a documented, optional sovereignty upgrade — it removes dependence on third-party calendars entirely — but it reintroduces a hot wallet into infrastructure that otherwise needs none, purely to save the calendars' aggregation step. Calendars keep the anchor at effectively zero marginal cost and zero custody risk, which is why they're the default; a wallet-funded path is a deliberate later choice, not a requirement to get a real Bitcoin timestamp today.
What this doesn't prove
OpenTimestamps proves existence by a time, not exclusivity or correctness of what's inside the log. A malicious log operator could still, in principle, run two consistent-looking logs in parallel (a "split view") and show each auditor a different one — which is exactly what independent witnessing (a second, non-Whisper party co-signing the same checkpoint) is for, layered on top of the Bitcoin anchor rather than replacing it. See Transparency log for the full witnessing picture and current status.
Next
- Transparency log — the RFC-6962 Merkle log this checkpoint comes from, and the checkpoint/inclusion-proof API in full.
- Verify an agent —
whisper verify --trustless, the full DNSSEC → DANE → transparency → Bitcoin chain in one command.