{"vulnerability": "cve-2012-2459", "sightings": [{"uuid": "dbb35706-b4bf-46fe-b82f-dc191eca4323", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2012-2459", "type": "seen", "source": "https://gist.github.com/motolese/14f6c5a8151e9fb449829e58444e63c4", "content": "", "creation_timestamp": "2026-04-10T18:26:02.000000Z"}, {"uuid": "0fdf5309-b64e-4912-8089-510990fc39e0", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2012-2459", "type": "seen", "source": "https://gist.github.com/motolese/79baccbf5bcc258810124ab8d463e52a", "content": "", "creation_timestamp": "2026-04-10T23:21:37.000000Z"}, {"uuid": "060cedeb-123e-4660-87dd-537b981acdfb", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2012-2459", "type": "seen", "source": "https://gist.github.com/ruvnet/2737be4a2fe48dc2e4f31e9b00e988f0", "content": "# Tamper-Evident Witness Logs: State of the Art and Where RVM Stands\n\n*A research survey grounding RVM's witness chain (ADR-134 v2, `crates/rvm/crates/rvm-witness`) against transparency-log, verifiable-database, and secure-logging state of the art. All claims about RVM are verified against source on branch `claude/compassionate-volta-5gbbqj` (commit `29069cb2`, \"witness v2 \u2014 keyed-BLAKE3 chain with 128-bit links + Merkle sealing\"). External claims are cited inline. Measured numbers are reproduced from the repo's criterion benchmarks (`crates/rvm/benches/benches/witness.rs`) and the figures recorded in `crates/rvm/README.md`; derived figures are labeled as derived.*\n\n---\n\n## PART 1 \u2014 Where we stand\n\n### 1.1 The system in one paragraph\n\nRVM is a `no_std`, `forbid(unsafe_code)` microhypervisor in which every privileged action must emit a witness record *before* the mutation commits (\"no witness, no mutation,\" ADR-134). The witness log is therefore on the syscall path, and the per-record budget is sub-microsecond. The v2 format (current write format) is a **96-byte record chained by a keyed-BLAKE3 MAC**: `chain_mac = trunc128(BLAKE3_keyed(key, content[0..44] || prev_mac[16]))`. The 60-byte MAC input fits a single 64-byte BLAKE3 block, so each append costs exactly one keyed compression. Records carry the predecessor's full 128-bit MAC (`prev_mac`) \u2014 no folding. Every append also memcpys the 16-byte `chain_mac` into a `SegmentAccumulator`; every 256 records (configurable), `seal_segment` builds a domain-separated Merkle tree over the accumulated MACs (leaf = `BLAKE3(0x00 || seq_le || mac)`, node = `BLAKE3(0x01 || l || r)`), signs `BLAKE3(0x02 || root || first_seq_le || count_le)` with a pluggable signer, and emits a `SealedSegment` (root + range + 64-byte signature) plus per-record Merkle inclusion proofs. Odd nodes are **promoted, not duplicated**. Signers: keyed-BLAKE3 (symmetric, in-crate), and via `rvm_proof::SealSignerAdapter`: HMAC-SHA256, dual-HMAC (64-byte symmetric), Ed25519 with `verify_strict`, and a TEE-backed signer that binds each digest into an attestation quote's report data before signing (`rvm-proof/src/tee_signer.rs`).\n\n### 1.2 Measured numbers (from `crates/rvm/README.md`, criterion benches)\n\n| Operation | Target | Measured |\n|---|---|---|\n| v1 emit (legacy, verify-only) | &lt; 500 ns | **~17 ns** |\n| v2 append (96 B record, one keyed BLAKE3 compression) | &lt; 1 \u00b5s | **~112 ns** |\n| v2 segment seal (256 records: 256 leaf + 255 node hashes + 1 signature) | \u2014 | **~61 \u00b5s** |\n| v1 chain verify (64 records) | \u2014 | ~892 ns |\n\nDerived: amortized per-record cost with sealing every 256 records \u2248 112 ns + 61 \u00b5s/256 \u2248 **~350 ns/record**, i.e. ~2.9 M fully-sealed records/s single-threaded, ~8.9 M/s chain-only. Storage overhead of sealing \u2248 (32 B root + 64 B sig + 12 B metadata)/256 \u2248 0.4 B/record on top of the 96 B record. Caveat for all comparisons below: these are **in-memory** appends into a fixed ring buffer with no persistence, indexing, or proof generation on the hot path \u2014 that is the design point (a hypervisor audit trail), not a general verifiable database.\n\n### 1.3 v1 \u2192 v2 migration, honestly stated\n\nv1 was a 64-byte record with FNV-1a (optionally SHA-256) hashes whose chain values were folded to 32 bits to fit the cache line; the in-tree doc comment itself notes a forged 32-bit link \"collides after ~2^16 attempts\" (birthday bound), and unkeyed hashes meant anyone could recompute a consistent forged chain. v2 fixes both: full-width 128-bit links, and *keyed* MACs so forging any link requires the chain key. v1 is frozen verify-only; serialized logs dispatch on a version byte at offset 19 (v1 = `0`, v2 = `2`), v1 records may appear only as a prefix, and `v1_head_to_genesis` anchors the verified v1 head into the first v2 record's `prev_mac` so the legacy history is cryptographically bound rather than abandoned. The 46 added tests cover content tampering, reorder, truncation, wrong-key, unkeyed forgery, range replay of seals (`first_sequence` perturbation), position swaps in inclusion proofs, v1/v2 mixed logs, and promotion-width Merkle trees (n \u2208 {1,2,3,5,7,8}).\n\n### 1.4 Where this sits in the design space\n\nFour broad families of tamper-evident log structure:\n\n1. **Pure hash chains** (Schneier\u2013Kelsey lineage; also TPM PCRs, which are literally a hash chain in hardware). O(1) append, but verification is linear, there are no sublinear inclusion proofs, and the head must be anchored externally or truncation is undetectable. ([Schneier &amp; Kelsey 1998](https://www.schneier.com/academic/archives/1998/01/cryptographic_suppor.html); [TCG integrity measurement guidance](https://trustedcomputinggroup.org/wp-content/uploads/TCG-Guidance-Integrity-Measurements-Event-Log-Processing_v1_r0p118_24feb2022-1.pdf))\n2. **Merkle tree logs** (Crosby\u2013Wallach history trees; RFC 6962 Certificate Transparency). O(log n) inclusion *and* consistency proofs \u2014 the latter prove append-only evolution between two tree heads. ([Crosby &amp; Wallach, USENIX Security 2009](https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf); [RFC 6962](https://www.rfc-editor.org/rfc/rfc6962.html))\n3. **Merkle Mountain Ranges (MMR)** \u2014 a forest of perfect binary trees (\"peaks\") supporting unbounded append with tiny persistent state, used by OpenTimestamps and Grin. ([OpenTimestamps MMR doc](https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md); [Grin MMR docs](https://docs.grin.mw/wiki/chain-state/merkle-mountain-range/); [IACR ePrint 2025/234, a recent formal treatment](https://eprint.iacr.org/2025/234.pdf))\n4. **Cryptographic accumulators** (RSA/bilinear): constant-size commitments and witnesses, but per-update costs in the microsecond-to-millisecond range with trusted setup or group operations \u2014 generally rejected for hot paths and `no_std` kernels; no production transparency log uses them.\n\nRVM v2 is a deliberate **hybrid of (1) and (2)**: a keyed chain on the hot path (cheapest possible per-record binding, plus last-record tamper detection that unkeyed chains lack) with batched Merkle commitments for exportable, third-party-verifiable evidence. This is structurally the same amortization move CT makes (entries are batched into signed tree heads, not individually signed) and that QMDB makes with its append-only \"twigs\" (subtrees Merkleized in batch) ([QMDB paper, \u00a7design](https://arxiv.org/pdf/2501.05262)). Two properties distinguish RVM from the transparency-log family and should be kept in view throughout this report: **(a)** the chain MAC is symmetric \u2014 verification of the chain (not the seals) requires the secret key, so chain verification is only meaningful inside the trust domain holding the key, whereas CT-family logs are publicly verifiable end to end; **(b)** the ring buffer overwrites (`total_overwritten`) and a full segment drops leaves (`segment_dropped` \u2014 records remain chain-protected but lose Merkle coverage), so durability and complete coverage depend on the drain/seal cadence, which the API surfaces (`needs_drain`, `segment_is_full`) but does not enforce.\n\n### 1.5 Context: RVF behavioral fingerprints in CI\n\nA related, lighter-weight use of the \"commit now, verify later\" pattern already runs in this repo's CI: `scripts/sona-drift/` stores 6-component deterministic behavioral fingerprints of three independent SONA learning implementations in a committed RVF vector store (`reference.rvf`), and fails CI when an implementation's fingerprint drifts from the reference \u2014 an executable contract that \"learn-from-feedback actually learns,\" created after the same no-op stub shipped twice (#519, #553). It is not cryptographic (no chain, no signatures), but it is the same architectural idea as a sealed segment: a compact reference commitment against which future behavior is checked, and a natural future consumer of witness-grade anchoring.\n\n---\n\n## PART 2 \u2014 Transparency-log state of the art\n\n### 2.1 RFC 6962, RFC 9162, and what actually got deployed\n\n[RFC 6962](https://www.rfc-editor.org/rfc/rfc6962.html) (Certificate Transparency, 2013) defined the canonical Merkle tree log: domain-separated hashing (`0x00` leaf prefix, `0x01` node prefix \u2014 the same constants RVM uses), signed tree heads (STHs), Merkle **inclusion proofs** (a leaf is in the tree) and Merkle **consistency proofs** (tree at size *n* is an append-only extension of the tree at size *m*). [RFC 9162](https://www.rfc-editor.org/info/rfc9162/) (CT v2, 2021) obsoletes it on paper \u2014 restructured `TransItem` types, more flexible consistency-proof endpoints, algorithm agility \u2014 but is **Experimental**, and the deployed ecosystem never migrated to it. Instead, the production evolution went a different direction: static, tile-based logs (below). Lesson worth internalizing: the part of RFC 6962 that survived everywhere is the *data structure and proof definitions*, not the RPC API.\n\nThe consistency proof is the one RFC 6962 primitive RVM does not have. RVM's sealed segments each commit to a contiguous range (`first_sequence`, `count` bound into the seal digest \u2014 which prevents range-replay), and the records *inside* are chained across segment boundaries by `prev_mac`, but an external verifier holding only sealed segments cannot prove segment *k+1* extends segment *k* without the secret chain key. CT-family verifiers get exactly this for free from consistency proofs between any two STHs ([Crosby &amp; Wallach 2009](https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf) introduced the construction; RFC 6962 \u00a72.1.2 standardized it).\n\n### 2.2 Trillian \u2192 Tessera, tiles, and the static-log turn\n\n[Trillian](https://github.com/google/trillian) (Google) ran CT and the Go checksum database for years as an RPC-served Merkle log over MySQL/Spanner. Its successor [Trillian Tessera](https://blog.transparency.dev/introducing-trillian-tessera) abandons the RPC proof-server model: logs are published as **tiles** \u2014 flat files containing 256-entry subtrees \u2014 per the [C2SP tlog-tiles spec](https://github.com/C2SP/C2SP/blob/main/tlog-tiles.md), and clients compute their own proofs from cached/CDN-served tiles. Tessera also moves from Trillian's \"queue now, sequence later\" model to durable sequence assignment at add time, with batching as the throughput/latency tuning knob. The same architecture reached CT itself via [Sunlight](https://letsencrypt.org/2024/03/14/introducing-sunlight) (Filippo Valsorda + Let's Encrypt, 2024) and the [static-ct-api spec](https://github.com/C2SP/C2SP/blob/main/static-ct-api.md), now [accepted by browser CT policies and running in production at Let's Encrypt for over a year](https://letsencrypt.org/2025/06/11/reflections-on-a-year-of-sunlight), with at least four interoperable implementations (Sunlight, trillian-tessera, Cloudflare Azul, Itko).\n\n[Rekor v2](https://blog.sigstore.dev/rekor-v2-ga/) (Sigstore's signature transparency log, GA on the tile-backed [rekor-tiles](https://github.com/sigstore/rekor-tiles) rewrite) is the most instructive recent datapoint: it cut entry types from ~11 to 2 (`hashedrekord`, `dsse`), moved timestamps out of the log into a dedicated timestamp authority, made all reads CDN-cacheable static assets, and plans to **shard (rotate) the log roughly every 6 months** to bound log size. Sharding-by-rotation is the transparency-log world's answer to the same problem RVM's ring buffer answers brutally (overwrite): logs cannot grow forever, so freeze-and-rotate with the old log still verifiable. RVM's frozen v1-prefix-plus-anchored-genesis migration is structurally the same maneuver and is \u2014 said plainly \u2014 already aligned with current practice here.\n\n### 2.3 Checkpoints, cosigning witnesses, and split-view detection\n\nThe modern ecosystem converged on a tiny stack of C2SP specs that are directly reusable:\n\n- **[tlog-checkpoint](https://github.com/C2SP/C2SP/blob/main/tlog-checkpoint.md)**: a checkpoint (\u2248 signed tree head) is a 3-line text body \u2014 origin string, tree size, base64 root hash \u2014 followed by \"signed note\" signatures. Logs interacting with the public witness network MUST carry at least one Ed25519 signature.\n- **[tlog-cosignature](https://github.com/C2SP/C2SP/blob/main/tlog-cosignature.md)**: a witness cosignature is a timestamped signature over the checkpoint; the spec admits Ed25519 and **ML-DSA-44 (FIPS 204), with witnesses RECOMMENDED to use ML-DSA-44** \u2014 post-quantum is already in this layer, not hypothetical.\n- **[tlog-witness](https://github.com/C2SP/C2SP/blob/main/tlog-witness.md)**: the HTTP protocol by which a log presents a new checkpoint *plus a consistency proof from the witness's last-seen checkpoint*; the witness signs only if the proof verifies, thereby attesting append-only growth.\n\nWhy this matters: a Merkle log alone proves nothing about **equivocation** \u2014 a malicious log can show different tree heads to different verifiers (a *split view*). CT's original answer, gossip ([IETF trans-gossip draft](https://datatracker.ietf.org/doc/draft-ietf-trans-gossip/)), **was never deployed**; browsers do at most partial, privacy-constrained SCT auditing ([Stark, \"CT: a bird's-eye view\"](https://emilymstark.com/2020/07/20/certificate-transparency-a-birds-eye-view.html); [Rescorla, \"CT in Reality\"](https://educatedguesswork.org/posts/transparency-part-2/)). The field's working answer became **witness cosigning**: a quorum of independent witnesses each verify consistency and cosign each checkpoint, so a client that requires *k* cosignatures cannot be split-viewed unless *k* witnesses collude with the log. [Sigsum](https://git.sigsum.org/sigsum/plain/doc/design.md) built this in from day one as a deliberately minimal log (Ed25519 only, fixed 32-byte leaves, witness quorum declared in a client-side trust policy); the [transparency.dev witness ecosystem](https://blog.transparency.dev/can-i-get-a-witness-network) (omniwitness software, TrustFabric's [Armored Witness](https://github.com/transparency-dev/armored-witness) \u2014 a dedicated open-hardware USB device \u2014 and Tillitis [TKey witnesses](https://www.tillitis.se/guide-tkey-sigsum-lab-witness-howto/)) provides an operating multi-log witness network today. The [Go checksum database](https://go.dev/blog/module-mirror-launch) (sum.golang.org) demonstrated the client side at ecosystem scale: every `go` command verifies inclusion **and consistency** proofs against its last-seen tree head using [golang.org/x/mod/sumdb/tlog](https://pkg.go.dev/golang.org/x/mod/sumdb/tlog), RFC 6962-compatible.\n\n### 2.4 Concrete applicability to RVM\n\nWhat they do that we don't, in one list: (1) consistency proofs between tree heads / sealed states; (2) a standardized, signed checkpoint serialization; (3) third-party cosigning with quorum policies for split-view detection; (4) publicly verifiable everything (no secret-key verifier). None of these belong on RVM's 112 ns hot path \u2014 and notably none of these systems put them on *their* hot paths either; they all live at the publication boundary. RVM's `SealedSegment {root, first_sequence, count, signature}` is one serialization step away from a tlog-checkpoint body (origin = log identity/key hash, size = `first_sequence + count`, root hash), at which point sealed roots could be (a) submitted as entries to Rekor (`hashedrekord` over the seal digest) or a Sigsum log, inheriting their witness networks for ~zero infrastructure cost, or (b) served as a self-hosted tlog-tiles log of segment roots that omniwitness instances can cosign directly. Part 6 ranks these.\n\n---\n\n## PART 3 \u2014 High-performance verifiable databases and ledgers\n\nHeadline comparison first, with the workload caveat repeated: RVM's ~112 ns is an in-memory MAC-chain append in a fixed ring; the systems below persist to disk, maintain indexes, and produce richer proofs. The honest claim is: *for the narrow operation RVM performs, it is at or beyond the per-record cost of every system surveyed, by one to four orders of magnitude \u2014 because it does less, on purpose, and defers the rest to sealing.* The interesting comparison is therefore the **batching/sealing strategy**, where RVM's design matches the field's convergent answer.\n\n| System | Per-record / per-update figure | What's included | Source |\n|---|---|---|---|\n| **RVM v2** | ~112 ns append; ~61 \u00b5s / 256-record seal (~350 ns amortized, derived) | in-RAM keyed MAC chain + ring write; seal adds Merkle root + 1 sig | repo benches |\n| **QMDB** | 2.28 M updates/s (enterprise box, multithreaded \u2248 ~440 ns/update aggregate); 63 K/s on a $540 mini-PC at 15 B entries | full persistent verifiable KV: O(1) SSD IO/update, in-memory Merkleization, 2.3 B/entry DRAM | [QMDB paper](https://arxiv.org/pdf/2501.05262), [repo](https://github.com/LayerZero-Labs/qmdb) |\n| **NOMT** | ~43 K updates/s/thread; 50 K-account update incl. read/prove/commit in 1151 ms vs 134 M accounts | persistent binary Merkle trie, SSD-page-aligned | [Habermeier, \"Introducing NOMT\"](https://www.rob.tech/blog/introducing-nomt/), [repo](https://github.com/thrumdev/nomt) |\n| **LedgerDB (Alibaba)** | ~280 K TPS converged (1 KB journals); 80\u00d7 Hyperledger Fabric | centralized ledger DB, TSA two-way-peg external anchoring | [VLDB 2020 paper](http://www.vldb.org/pvldb/vol13/p3138-yang.pdf) |\n| **CCF (Microsoft)** | \"database-like throughput\" (tens of K tx/s class) with TEE replication | replicated TEE ledger, Merkle tree, signed receipts | [CCF paper](https://arxiv.org/pdf/2310.11559) |\n| **Crosby\u2013Wallach history tree** | ~1,750 events/s insert (2009 hardware, syslog workload) | persistent tree with log-size inclusion+consistency proofs | [USENIX Sec '09](https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf) |\n| **QED (BBVA)** | ~2,000 ops/s/shard sustained, billions of events/shard | hybrid history tree + sparse \"hyper\" tree | [QED repo](https://github.com/BBVA/qed) |\n\n**QMDB** is the closest philosophical relative. Its core move \u2014 append-only \"twigs\" (fixed-size subtrees) that are Merkleized in batch rather than per-update, with the upper tree kept tiny and in memory \u2014 is the same amortization as RVM's `SegmentAccumulator`: pay memcpy per record, pay hashing per batch. QMDB's twig size (2048 leaves) vs RVM's default 256 reflects the same tuning axis RVM exposes as the `SEG` const generic (the in-tree comment notes 256 was chosen for kernel-stack-friendly 8 KiB scratch; larger deployments can instantiate 1024). QMDB also offers *historical proofs* (prove past state at the latest head) \u2014 something RVM gets implicitly since witness records are events, not state. The `(QED?)` in the research brief: [QED](https://github.com/BBVA/qed) was BBVA's 2019-era standalone tamper-evident log combining a Crosby\u2013Wallach history tree with a sparse Merkle \"hyper\" tree for membership-by-key; it is effectively abandoned but its docs remain a good engineering walkthrough of why pure history trees need a companion index.\n\n**NOMT** ([and the AlDBaran survey of this space](https://arxiv.org/pdf/2508.10493)) represents the \"align the Merkle structure with SSD physics\" school \u2014 binary trie nodes packed into flash-page-aligned pages. Not directly applicable to a RAM-resident ring, but directly applicable the moment RVM witness segments are persisted at volume: the lesson is that *the verification structure and the storage layout should be co-designed*, which RVM's flat 96-byte-record + sidecar-seal layout already satisfies trivially.\n\n**Jellyfish Merkle Tree** ([Diem paper](https://developers.diem.com/papers/jellyfish-merkle-tree/2021-01-14.pdf), used by Aptos) contributes the versioning idea: nodes are keyed by `(version, nibble-path)` rather than hash, making every commit non-overlapping and driving LSM compaction to zero. RVM's monotone `sequence` plays the same role at record granularity. JMT is a *state* tree (sparse, keyed), not an event log \u2014 the reminder it offers is that if RVM ever wants \"prove the current value of X,\" that is a different data structure than the witness chain, not an extension of it.\n\n**Amazon QLDB** is the cautionary tale. Launched 2019 as a managed centralized ledger with Merkle-based digests; [AWS announced its discontinuation in July 2024](https://www.infoq.com/news/2024/07/aws-kill-qldb/) with end of support July 31, 2025, recommending migration to Aurora PostgreSQL \u2014 a path that [loses cryptographic verifiability outright](https://www.dolthub.com/blog/2024-08-12-qldb-deprecated-alternatives/). The transferable lessons: (1) vendor-managed immutability has a business-decision failure mode \u2014 proof artifacts must be vendor-neutral and exportable, which RVM's self-contained `SealedSegment` + `MerkleProof` already are; (2) QLDB's digests were only verifiable *against QLDB* \u2014 there was no ecosystem checkpoint format, no witnesses, no way to anchor externally without bespoke tooling. That is precisely the gap Part 6's first recommendation closes.\n\n**CCF** and **immudb** bracket the deployment spectrum. [CCF](https://arxiv.org/pdf/2310.11559) (open-source, runs Azure Confidential Ledger) maintains its Merkle tree *inside* replicated TEEs and issues **receipts** \u2014 a Merkle path plus a signed root \u2014 as universally verifiable evidence; the receipt format is being standardized as a [COSE Receipts profile in the IETF SCITT working group](https://www.ietf.org/archive/id/draft-ietf-scitt-receipts-ccf-profile-01.html). An RVM `SealedSegment` + `MerkleProof` pair is semantically a CCF receipt; adopting the COSE serialization would make it interoperable (Part 6). [immudb](https://docs.immudb.io/master/production/performance-guide.html) is the pragmatic OSS ledger: per-transaction inner Merkle trees feeding a main append-only hash tree (AHT) supporting inclusion *and consistency* proofs, with the B-tree index built asynchronously off the write path \u2014 again the same convergent shape: cheap append, deferred expensive structure, consistency proofs at the boundary.\n\n---\n\n## PART 4 \u2014 Cryptographic primitives and formal foundations\n\n### 4.1 BLAKE3 keyed mode and 128-bit truncation\n\n[BLAKE3](https://github.com/BLAKE3-team/BLAKE3) (Aumasson, Neves, O'Connor, Wilcox-O'Hearn, 2020) claims **128-bit security for all goals** (collision, preimage, PRF/MAC) at \u226532-byte output, with keyed mode as a dedicated PRF/MAC (no length-extension, unlike raw Merkle\u2013Damg\u00e5rd; no HMAC wrapper needed) \u2014 see the [official spec/paper](https://github.com/BLAKE3-team/BLAKE3-specs) and the [C2SP BLAKE3 spec](https://github.com/C2SP/C2SP/blob/main/BLAKE3.md). It uses 7 rounds of the BLAKE2s-derived permutation vs BLAKE2s's 10; the best public cryptanalysis reaches only reduced rounds, and the designers' margin argument has held since release \u2014 but it is fair to note BLAKE3's margin is deliberately thinner than SHA-256's, a tradeoff accepted for exactly the kind of throughput RVM needs.\n\nFor RVM's **truncated 128-bit MAC links**, the relevant security notion is PRF truncation, which is benign: a truncated PRF is a PRF, and forgery probability is ~2\u207b\u00b9\u00b2\u2078 per attempt for an attacker without the key. The 2\u2076\u2074 birthday collision bound on 128-bit outputs is *not* the operative bound while the key is secret, because an adversary cannot evaluate the function offline. The operative threat is therefore **key compromise**, under which the entire chain (not just one link) becomes re-writable \u2014 see forward security, \u00a74.4. Two implementation details match best practice: keying via `blake3::derive_key` with a hardcoded, versioned context string (`\"rvm-witness 2026 v2 chain key\"`) is exactly the [recommended derive_key discipline](https://docs.rs/blake3/latest/blake3/fn.derive_key.html); and the compile-time-public default key is explicitly flagged dev-only in the API docs, with `with_key` required for production.\n\n### 4.2 Domain separation and the odd-node lesson\n\nRVM's `0x00`/`0x01` leaf/node prefixes are the RFC 6962 \u00a72.1 construction, which exists to block **leaf/node confusion second-preimage attacks** (an attacker presenting an internal node as a leaf or vice versa). The `0x02` seal-domain digest binding `(root, first_sequence, count)` extends the same discipline to the signature layer, closing range-replay and truncation-claim attacks (both unit-tested). The historical anchor here is [CVE-2012-2459](https://bitcoinops.org/en/topics/merkle-tree-vulnerabilities/): Bitcoin's Merkle construction **duplicated** the last node at odd levels, so `[1,2,3,4,5,6]` and `[1,2,3,4,5,6,5,6]` produced identical roots \u2014 a malleability flaw that could stall nodes on invalid forks ([Bitcoin Core still carries the warning comment](https://github.com/bitcoin/bitcoin/blob/master/src/consensus/merkle.cpp)). RVM **promotes** odd nodes unchanged instead of duplicating \u2014 the MMR/Grin-style fix. One subtlety worth stating for reviewers: bare promotion creates trees where different leaf counts could share structure, but RVM closes this because (a) the leaf hash binds the absolute sequence number and (b) the seal digest binds `count`; the test suite covers all promotion widths. [Grin's defense-in-depth variant](https://docs.grin.mw/wiki/chain-state/merkle-mountain-range/) \u2014 prepending each node's MMR position into its hash \u2014 is the belt-and-suspenders version of the same idea.\n\n### 4.3 MMR vs sealed segments\n\nMMRs ([Todd/OpenTimestamps](https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md); deployed in Grin, Zcash, Nervos via FlyClient per [ePrint 2025/234](https://eprint.iacr.org/2025/234.pdf)) maintain O(log n) \"peaks\" for an unbounded append-only sequence: each append does amortized O(1) hashing, the root (\"bagging the peaks\") commits to the entire history, and consistency between any two sizes is provable. RVM's sealed segments are instead a sequence of *independent* fixed-size roots \u2014 cheaper and bounded-memory per segment (which matters in a kernel), but with no single evolving commitment over all history and no cross-segment consistency proof. The natural synthesis, costing ~32 B \u00d7 log\u2082(#segments) of state: feed each sealed segment root as a leaf into an MMR maintained *outside* the hot path (at seal time, i.e., every 256 records \u2014 one or two extra hashes amortized). This yields a single anchorable head over unbounded history plus RFC 6962-style consistency proofs between any two seal points, without touching the 112 ns append. This is recommendation #3 in Part 6.\n\n### 4.4 Forward security: the known weakness of keyed chains\n\nA keyed-MAC chain has a property CT-style public logs don't: an attacker who obtains the chain key (e.g., full hypervisor compromise) can rewrite *all unsealed and un-anchored history* undetectably, and even sealed history if the seal signer key is co-located. The classical literature answer is **forward-secure key evolution**: [Schneier &amp; Kelsey (1998)](https://www.schneier.com/academic/archives/1998/01/cryptographic_suppor.html) ratchet the MAC key per entry and erase old keys so compromise at time *t* cannot forge entries before *t*; [Ma &amp; Tsudik's FssAgg (2008)](https://eprint.iacr.org/2008/185.pdf) adds aggregate signatures so the whole log carries one evolving authenticator; systemd's journald implements the idea as Forward Secure Sealing \u2014 and the [2023 security analysis of journald's FSS (ePrint 2023/867)](https://eprint.iacr.org/2023/867) finding practical flaws in that implementation is a useful warning that the ratchet details are easy to get wrong. For RVM the cheap variant is a per-segment ratchet: `key_{n+1} = derive_key(ctx, key_n)`, erase `key_n` at seal time; with the BLAKE3 `derive_key` machinery already in-tree this is one compression per 256 records. TEE-held keys (the existing `TeeWitnessSigner` direction) and forward-secure ratcheting compose \u2014 the TEE bounds *who* can use the key, the ratchet bounds *when* a leak matters.\n\n### 4.5 Post-quantum signers\n\nOnly the **signature layer** needs PQ attention \u2014 BLAKE3 MACs and Merkle hashing are symmetric primitives, where Grover gives at most a square-root speedup and 128-bit-security hashes/MACs remain comfortably out of reach (256-bit internal state). For signatures: [FIPS 204 ML-DSA](https://csrc.nist.gov/pubs/fips/204/final) (standardized August 2024) is the ecosystem's chosen lattice scheme \u2014 and notably the [C2SP cosignature spec already RECOMMENDS ML-DSA-44 for witnesses](https://github.com/C2SP/C2SP/blob/main/tlog-cosignature.md). The cost is size: ML-DSA-44 signatures are 2,420 bytes and public keys 1,312 bytes vs Ed25519's 64/32 ([FIPS 204](https://www.encryptionconsulting.com/understanding-fips-204/)) \u2014 RVM's fixed `[u8; 64]` signature field cannot hold one, so PQ requires a v3 seal envelope or a variable-length export wrapper. The alternative with particularly good fit for *log sealing*: **stateful hash-based signatures** (LMS/XMSS per [NIST SP 800-208](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf), and CNSA 2.0's preferred firmware-signing choice) \u2014 security reduces to the same hash-function assumptions the log already rests on, signing volume is low (one per segment), and the scheme's notorious state-management hazard (catastrophic one-time-key reuse on counter rollback) is *exactly* the kind of monotone-counter discipline a witness log with monotone `sequence` and a TEE already maintains. Hybrid (Ed25519 + PQ dual-signing) is the standard migration posture.\n\n### 4.6 Formal and accountability foundations\n\nThe intellectual lineage RVM should cite and mine: [Crosby\u2013Wallach (USENIX Security 2009)](https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf) defined the tamper-evident log with logarithmic inclusion/consistency proofs and the auditor model (logger kept honest by challenges); [PeerReview (Haeberlen, Kuznetsov, Druschel, SOSP 2007)](https://dl.acm.org/doi/10.1145/1323293.1294279) showed how per-node tamper-evident logs plus deterministic replay yield *accountability* \u2014 Byzantine deviations are eventually detected and irrefutably attributed, while correct nodes can always defend themselves; this is the natural formal frame for RVM's deterministic witness-replay/state-reconstruction story (`rvm-witness/src/replay.rs`, dormant-memory reconstruction). On the verification side, [Dowling\u2013G\u00fcnther\u2013Herath\u2013Stebila (ESORICS 2016)](https://s3.amazonaws.com/files.douglas.stebila.ca/files/research/papers/ESORICS-DGHS16.pdf) gave the first provable-security treatment of CT's logging scheme (collision-resistance of Merkle hashing, proof soundness); mechanized verification of Merkle log *implementations* remains thin in the literature \u2014 mostly pencil-and-paper reductions plus well-tested reference code \u2014 which makes a small verified verifier a credible research bet rather than a solved problem (Part 6, R8). The [IETF COSE Merkle tree proofs draft](https://datatracker.ietf.org/doc/html/draft-ietf-cose-merkle-tree-proofs-04) is where proof *interchange* is being standardized.\n\n---\n\n## PART 5 \u2014 Attestation and TEE anchoring\n\nA tamper-evident log is only as trustworthy as its head. Four anchoring patterns dominate, with distinct trust and latency profiles:\n\n**1. TEE quote binding (what RVM already has the skeleton for).** RVM's `TeeWitnessSigner` pads a 32-byte digest into the 64-byte quote `report_data`, generates and self-verifies a quote against an expected measurement, then HMAC-signs \u2014 so every signature is bound to a platform measurement. This is the standard SGX/TDX/SEV-SNP pattern: `report_data` binds arbitrary application data (here: a seal digest) into hardware-signed evidence. The production-grade reference is [CCF](https://arxiv.org/pdf/2310.11559), which goes further: the *service identity key* lives only in TEEs, governance changes are themselves ledger transactions, and receipts chain back to attested code measurements. The gap between RVM's current self-attestation and remote attestation is verification collateral (quote verification needs PCS/DCAP collateral off-device) \u2014 the `SignatureError::ExpiredCollateral` variant shows this is anticipated.\n\n**2. TPM PCR extension.** A PCR is a hardware hash chain: `PCR \u2190 H(PCR || event)`, quoted by a TPM-resident attestation key, with the host keeping the event log and verifiers replaying it ([TCG guidance](https://trustedcomputinggroup.org/wp-content/uploads/TCG-Guidance-Integrity-Measurements-Event-Log-Processing_v1_r0p118_24feb2022-1.pdf), [RFC 9683](https://datatracker.ietf.org/doc/html/rfc9683), [Linux IMA](https://ima-doc.readthedocs.io/en/latest/event-log-format.html)). For RVM edge deployments with a TPM but no full TEE, extending each sealed segment root into a PCR (and quoting periodically) gives hardware-rooted truncation evidence at ~1 ms per extend \u2014 entirely off the hot path at one extend per 256 records. The TPM audit-session pattern ([TPM 2.0 command auditing](https://link.springer.com/chapter/10.1007/978-1-4302-6584-9_16)) is the direct ancestor of RVM's design: host keeps the log, hardware keeps the running digest, auditor gets a signed digest later.\n\n**3. Public-log checkpointing.** Publish sealed roots (or periodic chain heads) to an external transparency log \u2014 Rekor v2 or a Sigsum log \u2014 and rely on *their* witness networks for split-view protection. Cost: one HTTP POST per seal (batchable, tolerant of long offline windows since seals are self-contained); benefit: independent, publicly auditable evidence that a given audit trail existed by time T and was never rewritten. This is the cheapest credible external anchor for connected deployments and the explicit design intent of [Sigsum](https://git.sigsum.org/sigsum/plain/doc/design.md) (32-byte-hash leaves \u2014 a sealed root fits natively) and the [SCITT architecture](https://datatracker.ietf.org/doc/draft-ietf-scitt-architecture/) (signed statements + COSE receipts for supply-chain-style claims; an RVM appliance's sealed roots are \"statements\" in SCITT terms).\n\n**4. Blockchain anchoring.** [OpenTimestamps](https://petertodd.org/2016/opentimestamps-announcement) aggregates arbitrarily many digests into one Bitcoin transaction via calendar servers (free, trust-minimized long-term, MMR-based) at the cost of confirmation latency (tens of minutes to hours). Appropriate as a *third* layer for high-assurance archival (\"this audit trail existed before date D, provable against a public chain\"), not as the primary anchor: latency and operational dependencies are wrong for a hypervisor, and the transparency-log ecosystem deliberately moved away from chains toward witness quorums for exactly that reason.\n\nFor RVM's stated target \u2014 edge/hypervisor with a TEE signer adapter \u2014 the right composition is: TEE-held chain + seal keys (bounds key theft), seal roots extended into a PCR or bound into quotes (hardware-rooted local evidence, works offline), and opportunistic checkpoint publication to a public log when connectivity exists (global split-view protection). Each layer is one operation per segment, never per record.\n\n---\n\n## PART 6 \u2014 Gap analysis and ranked recommendations\n\n**Already at or beyond practice \u2014 say so plainly:**\n- Per-record cost: ~112 ns for a keyed, full-width-linked, tamper-evident append is faster than any surveyed system's per-record verifiable write, including QMDB's aggregate ~440 ns/update (which does far more work). For the operation performed, this is state of the art; do not trade it away.\n- Amortized sealing (1 signature / 256 records, expensive crypto off the hot path) is the same convergent strategy as CT STHs, Tessera batches, QMDB twigs, and CCF's periodic signed roots.\n- Domain separation (RFC 6962-style leaf/node prefixes + a seal domain binding range), promotion-not-duplication (post-CVE-2012-2459 practice), `derive_key` context discipline, and version-byte migration with the v1 head cryptographically anchored into v2 genesis are all current best practice, implemented and tested.\n- Self-contained, vendor-neutral proof artifacts (`SealedSegment` + `MerkleProof`) \u2014 the exact property whose absence made QLDB's deprecation destructive.\n\n**Gaps, ranked.** Effort: S (&lt; 1 week), M (1\u20134 weeks), L (quarter+).\n\n| # | Recommendation | Effort | What it measurably buys | Class |\n|---|---|---|---|---|\n| **R1** | **Publicly verifiable cross-segment binding**: include the previous segment's seal digest (or root) in the next segment's seal digest (`0x02 || root || first_seq || count || prev_seal`). One 32-byte field, no hot-path change. | **S** | Append-only ordering of the *entire sealed history* becomes verifiable from seals alone, without the secret chain key \u2014 the single biggest verifiability gap today. A verifier holding seals k and k+n detects any splice/replacement between them. | Cheap win |\n| **R2** | **Checkpoint serialization compatible with [C2SP tlog-checkpoint](https://github.com/C2SP/C2SP/blob/main/tlog-checkpoint.md)** + Ed25519 note signatures at the export layer (host-side, not `no_std` kernel). | **S** | Sealed roots become publishable to Rekor v2 / Sigsum and cosignable by the existing [omniwitness network](https://blog.transparency.dev/can-i-get-a-witness-network) with zero bespoke verifier tooling. Unlocks R5. | Cheap win |\n| **R3** | **MMR over sealed segment roots** (maintained at seal time; peaks state = 32 B \u00d7 log\u2082 segments). Add consistency-proof generation between any two MMR sizes. | **M** | Unbounded-log support (ring buffer stops being the history's outer bound) + RFC 6962-equivalent consistency proofs between any two checkpoints \u2014 the property every transparency-log client (Go sumdb, Sigsum, witnesses) requires before it will trust growth. Subsumes R1 if digests are designed together. | High value |\n| **R4** | **Forward-secure chain-key ratchet**: `key_{n+1} = blake3::derive_key(ctx_epoch, key_n)` per segment, erase old key at seal; document the compromise window as \"current segment only.\" Review against [journald FSS analysis (ePrint 2023/867)](https://eprint.iacr.org/2023/867) failure modes. | **S\u2013M** | Key compromise at time t can no longer rewrite history before the last ratchet \u2014 converts \"kernel compromise = total history rewrite\" into \"kernel compromise = \u2264256-record exposure.\" Classical, well-understood ([Schneier\u2013Kelsey](https://www.schneier.com/academic/archives/1998/01/cryptographic_suppor.html), [FssAgg](https://eprint.iacr.org/2008/185.pdf)). | Cheap win |\n| **R5** | **External anchoring pipeline**: opportunistic publication of checkpoints (R2) to Rekor v2/Sigsum; on-device fallback of extending seal digests into a TPM PCR or TEE quote `report_data` (the `TeeWitnessSigner` plumbing already exists). | **M** | Split-view and truncation detection rooted outside the device's trust domain; offline-tolerant. One operation per 256 records. | High value |\n| **R6** | **Coverage guarantees**: auto-seal (or hard backpressure) when `segment_is_full`, making `segment_dropped == 0` an invariant rather than a counter; define drain cadence so `total_overwritten` records are always sealed-before-overwrite. | **S** | Eliminates the two silent-coverage-loss modes visible in the current API. An auditor can then state \"every emitted record has Merkle coverage,\" not \"records may be chain-protected only.\" | Cheap win |\n| **R7** | **PQ signer path**: v3 seal envelope with variable-length signatures; LMS ([SP 800-208](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf)) for segment sealing (low volume, hash-based assumptions matching the log; monotone-state discipline already native), ML-DSA-44 where C2SP-ecosystem compatibility matters ([witness cosignatures are already moving there](https://github.com/C2SP/C2SP/blob/main/tlog-cosignature.md)); hybrid-sign during migration. | **M** | Harvest-now-forge-later resistance for long-lived audit archives; format compatibility with where the witness ecosystem is already going. The 64-byte fixed field is the blocker, not the crypto. | Medium-term |\n| **R8** | **Verified verifier**: mechanize `verify_chain_v2` + `verify_inclusion` + (post-R3) consistency verification \u2014 small, loop-bounded, allocation-free functions well-suited to Kani/Creusot/hax; target the [Crosby\u2013Wallach](https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf)/[ESORICS-2016](https://s3.amazonaws.com/files.douglas.stebila.ca/files/research/papers/ESORICS-DGHS16.pdf) security definitions. Pair with a PeerReview-style accountable-replay formalization of witness replay. | **L** | A machine-checked argument that the verification path accepts exactly the honest logs \u2014 a differentiator no production transparency log currently ships, and a publishable result. | Research bet |\n| **R9** | **COSE receipt export** ([SCITT/CCF receipt profile](https://www.ietf.org/archive/id/draft-ietf-scitt-receipts-ccf-profile-01.html), [COSE Merkle proofs draft](https://datatracker.ietf.org/doc/html/draft-ietf-cose-merkle-tree-proofs-04)) for `SealedSegment`+`MerkleProof`. | **M** | Interop with SCITT-era supply-chain tooling; an RVM appliance's audit evidence becomes consumable by standard verifiers. Lower priority until the drafts stabilize. | Medium-term |\n\n**Ordering rationale.** R1/R2/R4/R6 are each small, independent, and close the gaps a transparency-log security engineer would flag first (secret-key-only chain verifiability across seals; no standard checkpoint; unbounded key-compromise window; silent coverage loss). R3 and R5 are the structural upgrades that move RVM from \"internally tamper-evident\" to \"externally auditable with split-view detection\" \u2014 the property that, per the entire Part 2 literature, hash structures alone cannot provide and that took the CT ecosystem a decade (failed gossip \u2192 witness cosigning) to learn. R7 rides an ecosystem transition already underway. R8 is the bet that fits this repo's prove-not-hype culture: the hot path is already fast and the design already sound; the remaining frontier is *proof* that the verifier is right.\n\n---\n\n*Sources are linked inline throughout. Primary code references: `crates/rvm/crates/rvm-witness/src/{v2,seal,versioned,lib,replay}.rs`, `crates/rvm/crates/rvm-proof/src/{signer,tee_signer}.rs`, `crates/rvm/benches/benches/witness.rs`, `crates/rvm/crates/rvm-witness/README.md`, and `crates/rvm/README.md` (performance table), all at commit `29069cb2` / branch `claude/compassionate-volta-5gbbqj`; CI fingerprint context from `scripts/sona-drift/README.md`.*\n", "creation_timestamp": "2026-06-12T17:01:32.000000Z"}]}