Cross-check
draft-fassbender-scitt-time-anchor, revisions -03 and -06. Bitcoin-Anchored Temporal Proof for Transparency Services
What this is
One artifact, anchored by the independent producer-side implementation of -03 published on this site, and verified by a second verifier written independently by someone else: the clean-room verifier for -06 published by EMILIA Protocol, used unmodified at commit 6ea9afb. The producer and the verifier were written by different people, from different revisions of the published document, with no shared code. Both revisions pin the same OpenTimestamps release, python-opentimestamps v0.4.5, for the proof format.
Not commissioned. This implementer proposed the cross-check to the document's author when she told him of the second implementation. She introduced the two implementers by email, asked that nothing be routed through her, and took no part in the runs; from there it was arranged directly between them. The runs EMILIA Protocol performed on its own side are reported here as its author stated them in writing; the runs performed on this side are marked as such.
The proposal was for each verifier to check an artifact produced by the other. Only one direction was possible: the EMILIA release is a verifier and produces no proofs, so this cross-check runs from the -03 producer to the -06 verifier.
Result
The two implementations agree on the proof. It was produced by the -03 implementation, whose verifier returns valid on it. The EMILIA verifier replays each of its three Bitcoin branches to the digest reported by the producer side, and each of those digests is the Merkle root of the block at that branch's attested height. The artifact predates block 968588.
They differ only where the profile allows a verifier to differ: on whether it can place the attested block on the validated most-work chain. With a validated chain source the verifier returns valid; without one it returns unverifiable. Both outcomes were observed, and both are correct under the note on header sources in Section 3.1.
The vector
Runs
| Verifier | Chain source | Run by | Outcome |
|---|---|---|---|
EMILIA -06 verifier, 6ea9afb | none validated | EMILIA Protocol | unverifiable at step 7 (-06 numbering); all three branches replay to the expected digests |
-03 verifier on this site, verify_run.py | this implementer's own full node | this implementer | valid at 968588, 144 confirmations |
EMILIA -06 verifier, 6ea9afb, through this implementer's adapter | this implementer's own full node | this implementer | valid at 968588, 154 confirmations; all three branches verified |
EMILIA -06 verifier, 6ea9afb | none | this implementer | unverifiable |
On its side, EMILIA Protocol checked the two block headers against public sources and recomputed their hashes and proof of work. That is not placing them on a validated chain, so its verifier correctly returned unverifiable. On the pending proof, which carries calendar attestations only, it also returned unverifiable, as it should. It independently fetched the producer's published manifest and its proof: the manifest hashes to 9c55d358..., all 16 files match it, and the proof replays to block 960468.
The third run, the EMILIA verifier returning valid through this implementer's node, is this implementer's run. It has not been reproduced by EMILIA Protocol, which has no independently validated chain source. Anyone who operates a full node can repeat it with the commands below.
The confirmation counts differ between runs because they were taken at different chain tips.
Reorganisation handling
The verifier asks its header source two questions at different times: the header at a height, then the confirmation depth at the selected height. The adapter written for this cross-check, node_header_source.py, answers both only from the node's active chain, and answers the depth only if that chain still carries the same block at that height both before and after the depth is read. Otherwise it answers nothing, and the verifier returns unverifiable.
A test against a simulated node, test_reorg.py, replaces the block at the attested height at two points: between the header read and the depth read, and after the depth value is read but before the re-check. Both return unverifiable; without a change the run returns valid. The same test against a copy of the adapter with the re-check removed fails the second case, which shows the re-check is necessary. EMILIA Protocol reproduced the test on its side, at commit 0eb4238 of the mirror and with its verifier at 6ea9afb, with the same three results.
The simulated headers carry the real Merkle roots and nTime values of the two blocks but no proof of work. The test is about how the adapter behaves when the chain changes, not about the chain.
What this establishes, and what it does not
Established by the chain: the artifact predates block 968588, and the producer's published manifest predates block 960468. These are block-height bindings, and they are the only strong claims here.
Not established: the time at which the producer recorded the pending proof, 2026-09-25T19:55:58Z. That is the producer's own record, not a cryptographic bound. The nTime of block 968588 is informative and is shown only alongside the height. The node-backed valid of the EMILIA verifier is this implementer's run. Nothing here says either implementation is correct beyond this vector.
Two statements made by this implementer during the exchange were corrected in writing. The pending proof was first offered as making the ordering checkable; it does not, since only the block-height binding is cryptographic. And the artifact was at one point bounded by the block's nTime rather than by its height.
Files
The files below are the mirror at commit ad31c27, served here unchanged. SHA256SUMS lists paths relative to this directory, including the subdirectories vector/, evidence/ and anchors/. Fetch the set with the same layout, or clone the mirror, and run sha256sum -c SHA256SUMS.
- vector/cc1.txtThe artifact. Raw bytes, no trailing newline.
- vector/cc1.txt.anchored.otsThe upgraded proof, three Bitcoin branches, produced and upgraded by the -03 implementation.
- vector/cc1.txt.ots.pendingThe same proof as first written, calendar attestations only.
- node_header_source.pyAdapter between the EMILIA verifier's header-source interface and a self-operated full node. No verification logic.
- run_emilia.pyRuns the EMILIA verifier with and without the node as chain source.
- test_reorg.pyReorganisation test against a simulated node.
- evidence/verify-2026-09-26.outOutput of the -03 verifier. Some labels print in Portuguese:
resultadois result,confirmaçõesis confirmations. - evidence/emilia-run-2026-09-26.outOutput of the EMILIA verifier, with and without the node.
- evidence/test-reorg-2026-09-27.outReorganisation test, 3/3.
- evidence/test-reorg-mutant-2026-09-27.outThe same test against the adapter without the re-check, 2/3.
- anchors/SHA256SUMS-adapterHashes of the adapter, runner and EMILIA output, the values sent to EMILIA Protocol on 2026-09-26. The paths inside are those of the working directory, not of this layout.
- anchors/SHA256SUMS-adapter.anchored.otsProof of that manifest, block 968752.
- README.mdThe mirror's description and reproduction commands.
- SHA256SUMSManifest of every other file listed here except its own proof.
- SHA256SUMS.otsProof of the manifest, produced by the -03 implementation, block 968885.
- LICENSEMIT.
One correction to the mirror, recorded here rather than made there. Its README says a joint description of the cross-check would be published separately. There is none: each party describes the cross-check in its own words, and this page is this implementer's. The README is left as committed, because the manifest that covers it is anchored and is the state EMILIA Protocol verified.
How to re-verify
Requires Python 3.11 or later. From this directory or a clone of the mirror, with the EMILIA verifier at 6ea9afb cloned alongside as emilia-verifier and the -03 package as producer-03:
sha256sum -c SHA256SUMS PYTHONPATH=../emilia-verifier/src:. python3 test_reorg.py vector/cc1.txt vector/cc1.txt.anchored.ots
The node-backed run also requires a Bitcoin full node you operate, with RPC credentials in ~/.bitcoin/bitcoin.conf:
PYTHONPATH=../emilia-verifier/src:.:../producer-03 python3 run_emilia.py vector/cc1.txt vector/cc1.txt.anchored.ots
The full sequence, including the mutant check, is in README.md. A verifier that cannot place the attested block on the validated most-work chain returns unverifiable, not valid; a public block explorer is not sufficient for valid.
Source
Produced by Tiago Pinto, Portugal, September 2026. The adapter, runner and test are MIT-licensed. The EMILIA verifier is EMILIA Protocol's, MIT-licensed separately, and is not included here. This page is served from the author's own server, in static HTML, without JavaScript, without analytics, without cookies, without external dependencies.