From 993cfb85d4b62f8dbe961318bc56249e232bfee7 Mon Sep 17 00:00:00 2001
From: mrwulf
Date: Fri, 7 Aug 2026 18:11:42 +0200
Subject: [PATCH] =?UTF-8?q?site:=20the=20homepage=20tells=20the=20truth=20?=
=?UTF-8?q?about=20tree=2019=20=E2=80=94=20dual=20anchors,=20honest=20tool?=
=?UTF-8?q?ing,=20and=20a=20note=20to=20the=20paper's=20readers?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The estate doc audit scoped itself to *.md and missed the text a site visitor
actually reads: the string constants in webdocs.py. Fixed here, verified by
RENDERING the page from the live 19-leaf state and checking each block:
- The SVG head label reads "Ed25519 + SLH-DSA" when the live head is
dual-signed, "Ed25519" when it is not — computed, not asserted.
- The trust-anchor card now carries BOTH keys the same way: full PEM,
SHA-256 fingerprint, raw endpoint (/v1/log-slhdsa-public-key), mirror
comparison link. The Ed25519 key stays the required anchor; the SLH-DSA
key is the additive post-quantum one, and the card says whose proof
subject its verify path is (leaf 18).
- The registered homepage overclaim (register: homepage-stdlib-claim) is
closed: "stdlib-only" wording replaced with the truth — stdlib hashing,
signature checks shell out to the openssl binary, fails closed without.
- "one signature and ~N hashes" became "one REQUIRED signature (Ed25519;
heads from tree 14 add an additive post-quantum SLH-DSA signature)".
- The paper card is reframed (frozen under review, describes the 16 July
snapshot, "then-thirteen-leaf") and followed by a new reader-guidance
card (operator-ordered): the paper-era prefix is unchanged inside the
live history — leaves 0-12 byte-identical, the paper's head still
head #5 of sth-history — verify.py --all checks both eras at once; the
advances are additive (44-cert re-attestations, leaf 18, dual-signed
heads, ABSENT on older heads by design); and the 3,867 divergence the
paper honestly reports has since been CLOSED (sn==0 fix, 2026-07-23,
pinned count now 0) — both the divergence and the fix are part of the
retained record.
Layout fact the render surfaced: the served log dir must contain the .pub
files (that is what /v1/log-public-key reads); the SLH-DSA pub joins the
Ed25519 one there. Suite 152/0/0.
Co-Authored-By: Claude Opus 4.8
---
provider/src/pacta_provider/webdocs.py | 64 ++++++++++++++++++++++----
1 file changed, 55 insertions(+), 9 deletions(-)
diff --git a/provider/src/pacta_provider/webdocs.py b/provider/src/pacta_provider/webdocs.py
index 6884285..18a7030 100644
--- a/provider/src/pacta_provider/webdocs.py
+++ b/provider/src/pacta_provider/webdocs.py
@@ -50,7 +50,7 @@ def _leaf_ok(entry: LogEntry) -> bool:
)
-def _svg_tree(entries: list[LogEntry], root_hex: str, signing_backend: str) -> str:
+def _svg_tree(entries: list[LogEntry], root_hex: str, signing_backend: str, head_label: str = "Ed25519") -> str:
"""The accumulator, drawn from its real leaves."""
if not entries:
return "(log is empty)
"
@@ -94,7 +94,7 @@ def _svg_tree(entries: list[LogEntry], root_hex: str, signing_backend: str) -> s
out.append(f'')
root_x, root_y = positions[(len(levels) - 1, 0)]
out.append(f'')
- out.append(f'Signed Tree Head — Ed25519({root_hex[:12]}…)')
+ out.append(f'Signed Tree Head — {escape(head_label)}({root_hex[:12]}…)')
out.append(f'signed by: {escape(signing_backend)} (the proof-attested library itself)')
out.append(f'')
out.append("")
@@ -114,6 +114,28 @@ def _trust_anchor_html(log: TransparencyLog, metadata: dict[str, Any], base: str
f'mirror instead.'
)
pem = escape(key_path.read_text(encoding="utf-8").strip())
+ # The SLH-DSA verification key (additive post-quantum head signature,
+ # 2026-08) is published THE SAME WAY: full PEM on the page, raw endpoint,
+ # mirror comparison. Heads before tree 14 carry no SLH-DSA signature and
+ # verify.py reports them ABSENT — allowed; an append-only log keeps its
+ # history.
+ slh_path = log.log_dir / "provider.slhdsa.pub"
+ if slh_path.is_file():
+ import hashlib as _h
+ slh_pem = escape(slh_path.read_text(encoding="utf-8").strip())
+ slh_fp = _h.sha256(slh_path.read_bytes()).hexdigest()
+ slh_block = f"""
+Second, additive anchor — post-quantum. Heads from
+tree 14 on additionally carry a deterministic SLH-DSA-SHA2-128s (FIPS 205)
+signature over the same payload. The Ed25519 signature above remains the one every consumer must
+check; this one is checked where tooling allows (OpenSSL ≥ 3.5). Its verify path is the
+proof subject of leaf 18.
+{slh_pem}
+SHA-256 fingerprint {slh_fp}
+ · raw: {base or ''}/log-slhdsa-public-key
+ · mirror: provider.slhdsa.pub
"""
+ else:
+ slh_block = ""
return f"""
This key is the sole cryptographic identity anchor: it
authenticates that these statements were made by the operator. It does not, by itself, make
@@ -126,7 +148,7 @@ Pin it, and compare this copy byte-for-byte with the independently hosted
SHA-256 fingerprint {escape(fingerprint)}
· raw: {base or ''}/log-public-key
· curl -s ltl.zkdefi.org/log-public-key
-
"""
+{slh_block}"""
def render_docs(log: TransparencyLog, base_path: str) -> str:
@@ -161,7 +183,9 @@ def render_docs(log: TransparencyLog, base_path: str) -> str:
f"{escape(_counts(newest[c]))} | "
for c in components
)
- tree_svg = _svg_tree(entries, str(latest.get("root_hash", "")), signing_backend)
+ slh_signed = ((latest.get("signatures") or {}).get("slh_dsa") or {}).get("status") == "signed"
+ head_label = "Ed25519 + SLH-DSA" if slh_signed else "Ed25519"
+ tree_svg = _svg_tree(entries, str(latest.get("root_hash", "")), signing_backend, head_label)
return f"""
@@ -176,7 +200,8 @@ def render_docs(log: TransparencyLog, base_path: str) -> str:
accumulator of signed statements that the Lean 4 formal proofs of specific
cryptographic Rust libraries, at specific git commits, machine-re-check with exactly
their documented assumptions — so that you can trust a proof result by checking
-one signature and ~{max(1,(latest.get('tree_size') or 1).bit_length())} hashes in
+one required signature (Ed25519; heads from tree 14 add an additive post-quantum
+SLH-DSA signature) and ~{max(1,(latest.get('tree_size') or 1).bit_length())} hashes in
milliseconds, instead of running a theorem prover for hours.
The trust anchor — pin this key
@@ -216,11 +241,12 @@ which observed axiom cones, what machine protection — signed by the provider.<
table above, or mirror entries/ |
| 3 | <library>.receipt.json |
The proof of inclusion. Binds artifact 2 into the signed tree:
-leaf index, sibling hashes, the Signed Tree Head. ~25 lines of stdlib Python verify it. |
+leaf index, sibling hashes, the Signed Tree Head. ~25 lines of Python verify it (stdlib hashing; signature checks shell out to the openssl binary).
table above, or mirror receipts/ |
| + | the full mirror clone |
Maximal benefit: become a witness. Every leaf + every signed head
-ever issued + verify.py (stdlib-only). python3 verify.py --all
+ever issued + verify.py (Python stdlib + the openssl binary for
+signatures; fails closed without them). python3 verify.py --all
recomputes the entire tree and every historical head — you then hold a retained view that can
later EXPOSE a conflicting head shown to someone else. (A single clone cannot by itself prove the
log never split its view toward another consumer; that requires comparing heads across
@@ -292,19 +318,39 @@ our roadmap. (The full walk-through is lecture 11 in the
The paper
Accountable Distribution of Machine-Checked
Correctness Evidence: A Transparency Model and the Lean Transparency Log
-(PDF, 23 pages, v0.9) — the trust decomposition (expensive verification produces an
+(PDF, 23 pages, v0.9 — frozen while under journal review; it describes the
+log as of its 16 July 2026 snapshot) — the trust decomposition (expensive verification produces an
observation; transparency makes the observation accountable; consumer-local policy decides
acceptance), collision-extracting soundness for inclusion and consistency, scheme-level
accountability GAMES with an explicit composition theorem (head authenticity, position
binding, history binding with a fully proved prefix-transport induction, context-scoped
fork evidence — all discharged by named reductions), the policy boundary where
-operator labels can veto but never grant acceptance, the live thirteen-leaf deployment
+operator labels can veto but never grant acceptance, the then-thirteen-leaf deployment
whose entry 13 attests the accumulator's own mechanized model, and the measured
model/deployment divergence (3,867 lied-size cases, every one accepted only by the
deployed verifier) reported as a result rather than hidden.
Previous versions: v0.2 (19 pages, the
system report) · v0.1 (4 pages).
+Reading the paper against today's log. The paper is frozen
+under review; the log is append-only and has kept moving. Nothing the paper describes was
+altered, so every number in it remains checkable against the live history: the thirteen leaves
+it analyses are still leaves 0–12, byte-identical, and the head it pins (tree 13, root
+3488a2d0…) is still head #5 of sth-history.jsonl —
+python3 verify.py --all re-verifies the paper-era prefix together with everything
+after it. What has moved since the snapshot is additive: leaves 13–16 re-attest the four
+Ed25519 libraries at 44 certificates each (the paper's sixteen-certificate corpora describe the
+leaf 8–11 generation, which those leaves still record); leaf 17 re-attests the
+accumulator's mechanized model at its hardened state; and leaf 18 is the log's first
+post-quantum subject, the SLH-DSA-SHA2-128s verify path. Heads from tree 14 on carry an
+additive SLH-DSA signature beside the Ed25519 signature the paper describes; earlier heads have
+none, by design, and the verifier reports them as ABSENT rather than failing them.
+One result has changed in the good direction: the 3,867-case model/deployment divergence the
+paper honestly reports was closed on 23 July 2026 (the sn==0 fix); the
+current pinned divergence count is 0, and both the divergence and its fix are part of the
+retained record. Where the paper and the live log disagree on a number, the paper is describing
+its snapshot — and the log's history contains that snapshot, unchanged, inside it.
+
Log heads are signed offline; this service is read-only and holds no
key material. Provider tooling, agent tooling, and the full course (12 Jupyter
lectures) live in the pacta repository.
|