Bitcoin Anchor Verification v1

Status: v1.1 — drafted 2026-05-05 Spec URI: https://projectmaya.deoscomputing.io/anchor/bitcoin/v1 Maintainer: DEOS Computing (did:web:deos.computing) Companion: /anchor/v1 — the v1.1 OTS calendar attestation flow

This document specifies how a verifier upgrades from "OTS proof is present" (v1.1, --require-anchor) to "OTS proof is anchored in a confirmed Bitcoin block" (v1.2, --require-bitcoin-anchor). It also specifies multi-rail anchoring so a single calendar's compromise does not break timestamp guarantees.


1. Goals

A v1.2 verifier with Bitcoin-anchor support must:

  1. Confirm Bitcoin block-header validity for the block(s) the substrate's anchor proof claims to commit to. Header validity = proof-of-work + difficulty target + chain continuity from a known checkpoint.
  2. Walk the OpenTimestamps proof from the substrate's MMR root through SHA-1, RIPEMD-160, prepend/append byte operations, to a Bitcoin transaction's OP_RETURN data.
  3. Confirm the Bitcoin transaction is included in a Bitcoin block via the standard Merkle proof (Bitcoin-side).
  4. Bound the timestamp by the block's nTime (loose; ±2 hours per Bitcoin consensus) and the median-time-past (tighter; ±1 hour by network convention).
  5. Support multiple anchor rails (OTS + Ethereum L1 + private TSA) so a single calendar / chain compromise is not load-bearing.

A v1.2 verifier also rejects:


2. v1.1 baseline (today)

receipt-verifier --require-anchor checks:

It does not check:

This baseline is what /anchor/v1 ships. It is enough to detect a substrate that publishes no anchor at all; it is NOT enough to detect a substrate that submits to a fake / private OTS calendar that returns plausible bytes but never reaches Bitcoin.

Receipts with --require-anchor carry an OTS-server promise, not a Bitcoin consensus statement.


3. v1.2 verification flow

The flow MUST run in this order so a verifier short-circuits on the cheapest checks first.

3.1 Decode the OTS proof

OTS proofs are a binary format (file extension .ots). The on-disk layout per the OpenTimestamps protocol:

magic    : 31 bytes — "\x00OpenTimestamps\x00\x00Proof\x00\xbf\x89\xe2\xe8\x84\xe8\x92\x94"
version  : 1 byte — currently 0x01
file-hash: opcodes that derive the leaf hash from the substrate's input bytes
timestamp: opcodes + attestations

Opcodes are single-byte tags followed by length-prefixed arguments:

Opcode Meaning
0x00 sha1
0x02 ripemd160
0x03 sha256
0x67 keccak256
0x08 append (concatenate constant bytes after the digest)
0xf0 prepend (concatenate constant bytes before the digest)
0x83 hash-and-fork (rare; produces multiple subtrees)

Attestations are terminal records identifying where the proof commits:

Attestation tag Meaning
\x05\x88\x96\x0d\x73\xd7\x19\x01 (8 bytes) Bitcoin block-attestation: 4-byte block height (big-endian) follows
\x06\x86\x9a\x0d\x73\xd7\x1b\x45 Pending — not yet anchored to Bitcoin
\x83\xdf\xe3\x0d\x2e\xf9\x0c\x8e Litecoin block-attestation (out of v1.2 scope)

A v1.2 verifier MUST parse the full opcode tape and extract:

  1. The leaf bytes the proof is over (typically SHA-256(substrate_root)).
  2. The terminal Bitcoin block height (or pending status).
  3. The expected Bitcoin transaction OP_RETURN payload the proof reduces to (the result of running the opcodes against the leaf bytes).

Reference implementation: opentimestamps-client (Python, public). A pure-Rust port lives in DEOS Computing's working repo.

3.2 Verify the Bitcoin block

Given the terminal block height H from §3.1, fetch the block header from a verifier-trusted Bitcoin SPV source. The verifier MUST:

  1. Validate the header's proof-of-work: H(header) <= difficulty_target per the consensus rules.
  2. Validate that the header chains back to a known checkpoint via parent-hash references (defense against a fork-mined chain that has valid PoW but is not Bitcoin mainnet). Checkpoints SHOULD be hardcoded for blocks at well-known heights (e.g. genesis, halving heights).
  3. Validate that the height H is at least --min-confirmations blocks below the verifier-known chain tip (default: 6).
  4. Extract the block's nTime and the median-time-past (computed from the previous 11 blocks per BIP 113); the receipt's effective timestamp upper bound is the LATER of these.

Sources for block headers:

Source Trust model Recommended for
Local Bitcoin Core node Operator-controlled, full validation High-stakes / federal deployments
Esplora (mempool.space) Public SPV server, multiple operators Production substrates
BlockCypher Single-vendor SPV Cost-sensitive deployments
Hardcoded recent checkpoints + difficulty-extension Verifier-controlled, no network Fully air-gapped verifiers

The substrate itself does NOT verify Bitcoin; it only submits the OTS proof. Verification is a verifier-side operation. The substrate's responsibility ends at "I made the OTS submission and stored the calendar's response."

3.3 Match the OP_RETURN

A Bitcoin transaction in block H carries an OP_RETURN output whose data field commits to the OTS leaf via the proof opcodes. The verifier MUST:

  1. Fetch the transaction from the SPV source (or local node).
  2. Compute the result of running the OTS opcodes from §3.1 against the substrate's MMR root.
  3. Confirm the computed result equals the OP_RETURN data of the transaction.
  4. Confirm the transaction is in block H via the Bitcoin-side Merkle proof (transaction → Merkle root in header).

Step 4 requires fetching the Merkle path. SPV servers expose this as GET /tx/{txid}/merkle-proof or similar.

3.4 Bound the receipt's effective timestamp

If all checks pass, the receipt's issued_at_ns claim is bounded:

A receipt whose claimed issued_at_ns is OUTSIDE this window MUST be rejected as anachronistic — either the substrate is lying about its timestamp or the OTS proof corresponds to a different submission.


4. Multi-rail anchoring (ANCH1.1-5, P1 by audit)

A v1.2 substrate MAY submit each MMR root to multiple anchor providers. Today's --ots-calendars URL,URL,... already supports submission to multiple OTS calendars; the multi-rail extension goes further:

Rail Service Anchor latency Cost
OTS OpenTimestamps calendar ~30 min to Bitcoin block Free
Ethereum L1 Sepolia/mainnet OP_RETURN-equivalent (storage commit) ~12 sec per block ~$5-50 per anchor
Private TSA RFC 3161 trusted timestamp authority seconds per-vendor
Filecoin DataCap / FVM commit minutes per-vendor
EigenDA data-availability commit seconds per-vendor

The receipt's anchors array carries one entry per rail:

"anchors": [
  { "service": "opentimestamps", "proof": "<base64 of OTS bytes>" },
  { "service": "ethereum-l1", "proof": "<base64 of {block_hash, tx_hash, receipt_proof}>" },
  { "service": "rfc3161-tsa", "proof": "<base64 of CMS TSTInfo>" }
]

A verifier with --require-bitcoin-anchor requires the OTS rail to verify; a verifier with --require-any-anchor requires at least one rail to verify; a verifier with --require-anchors=2 requires ≥2 distinct rails to verify.

The cost of multi-rail submission falls on the substrate operator. For high-value tenants (banking, government), multi-rail is expected; for low-value SaaS deployments, OTS-only remains acceptable.


5. Substrate-side obligations

A v1.2 substrate adds:

  1. --bitcoin-headers-source URL — verifier hint for where to fetch headers (NOT used by the substrate itself; published in /trust-root so verifiers know what the operator recommends).
  2. --anchor-rails RAIL1,RAIL2,... — enabled rails. Default: opentimestamps. Adding ethereum-l1 requires --ethereum-rpc URL and --ethereum-private-key-from-env VAR.
  3. GET /attestation/v1/anchor/{root_hex} — already shipped in v1.0; v1.2 extends the response to include Bitcoin block height + transaction id once the OTS proof has been upgraded to Bitcoin (ANCH1.1-3).
  4. Background "upgrade job" (ANCH1.1-3) that periodically re-fetches pending OTS proofs from the calendar to check for Bitcoin confirmation. Implementation: a separate thread or a periodic timer that re-issues GET /tip/{calendar_url}/{leaf_hash} against each calendar.

6. Verifier-side CLI

The receipt-verifier CLI gains:

receipt-verifier
  [--require-anchor]                 # v1.1: OTS-presence (already shipped)
  [--require-bitcoin-anchor]         # v1.2: full Bitcoin block-header verification
  [--require-any-anchor]             # v1.2: any rail must verify
  [--require-anchors=N]              # v1.2: at least N distinct rails must verify
  [--bitcoin-headers-url URL]        # v1.2: SPV source
  [--min-bitcoin-confirmations N]    # v1.2: default 6
  [--bitcoin-checkpoints FILE]       # v1.2: trusted checkpoint file (optional)
  [--ethereum-rpc-url URL]           # v1.2: for ethereum-l1 rail verification
  <api-base-url> <receipt-id>

The v1.1 baseline of --require-anchor is preserved exactly so v1.1 callers don't break. New flags are additive.


7. Security considerations

This section satisfies the RFC 3552 requirement.

7.1 OTS calendar trust

A single OTS calendar can lie. Mitigations:

7.2 Bitcoin SPV trust

The SPV source can lie about block headers, transaction inclusion, or chain tip. Mitigations:

7.3 Eclipse attacks on the SPV source

A network-level attacker can isolate the verifier's SPV source from the real Bitcoin network. Detection requires querying multiple sources from independent network paths. Out of scope for v1.2; v2 may add a "fetch from N independent endpoints over different ASes" requirement.

7.4 Reorg-after-confirmation

A 6-confirmation block can theoretically be reorged. For receipts where this risk matters (high-value financial transactions), the verifier SHOULD use a higher confirmation depth. The probability of a 6-block reorg on Bitcoin mainnet is operationally negligible (<10^-5 historically) but not zero.

7.5 Delayed Bitcoin confirmation

A receipt issued at time T and submitted to OTS may not reach Bitcoin for ≥30 minutes. During that interval, the proof is in a "pending" state. Verifiers MUST handle pending proofs explicitly:

The substrate's background upgrade job (§5.4) shortens the pending window from "as long as the verifier waits" to "as long as the substrate's polling interval × calendar latency."


8. Implementation status

v1.1 ships:

v1.2 closes the gap to Bitcoin-anchored timestamps verifiable offline:

Eclipse-attack mitigation deferred to v2.


9. References


10. Maintainer

DEOS Computing — design questions and conformance reports to github.com/DEOS-Computing.

License: CC BY 4.0 (text), Apache-2.0 (reference code).