From c5268ef46c3c71092642124eed45444458259c5b Mon Sep 17 00:00:00 2001 From: mrwulf Date: Mon, 17 Aug 2026 10:41:18 +0200 Subject: [PATCH] site language: 'additive' retired, sibling keys get sibling names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator: 'additive' explains nothing to a newcomer, and Key 2 carried its full parameter-set name while Key 1 was just 'Ed25519' — unequal treatment. Now: 'Key 1 — Ed25519, required' / 'Key 2 — SLH-DSA (FIPS 205), post-quantum'; the second signature is called exactly that, 'the second (post-quantum) signature'; parameter-set precision stays in the artifacts where it belongs. Same cleanup in the OpenAPI summary and the CLI help. --- provider/src/pacta_provider/web.py | 2 +- provider/src/pacta_provider/webdocs.py | 9 ++++----- src/pacta/cli.py | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/provider/src/pacta_provider/web.py b/provider/src/pacta_provider/web.py index b1b2266..4d7a344 100644 --- a/provider/src/pacta_provider/web.py +++ b/provider/src/pacta_provider/web.py @@ -35,7 +35,7 @@ def _openapi_document(base: str) -> dict: "servers": [{"url": "https://ltl.zkdefi.org" + base}], "paths": { "/log-public-key": {"get": {"summary": "Required Ed25519 public key (PEM)", "responses": ok}}, - "/log-slhdsa-public-key": {"get": {"summary": "Additive post-quantum SLH-DSA public key (PEM)", "responses": ok}}, + "/log-slhdsa-public-key": {"get": {"summary": "Post-quantum SLH-DSA public key (PEM)", "responses": ok}}, "/healthz": {"get": {"summary": "Liveness and current tree size", "responses": ok}}, "/paper": {"get": {"summary": "The current paper (PDF)", "responses": ok}}, f"/{API_VERSION}/metadata": {"get": {"summary": "Log identity", "responses": ok}}, diff --git a/provider/src/pacta_provider/webdocs.py b/provider/src/pacta_provider/webdocs.py index ffc29dd..866e2f1 100644 --- a/provider/src/pacta_provider/webdocs.py +++ b/provider/src/pacta_provider/webdocs.py @@ -151,8 +151,7 @@ def _trust_anchor_html(log: TransparencyLog, metadata: dict[str, Any], base: str slh_pem = escape(slh_path.read_text(encoding="utf-8").strip()) slh_fp = _h.sha256(slh_path.read_bytes()).hexdigest() slh_block = f"""
-

Key 2 — SLH-DSA-SHA2-128s (FIPS 205), additive -post-quantum. Heads from tree size 14 on carry a second signature from this key; +

Key 2 — SLH-DSA (FIPS 205), post-quantum. Heads from tree size 14 on carry a second signature from this key; older heads legitimately have none — an append-only log keeps its history. Check it where your tooling allows (OpenSSL ≥ 3.5). The kind of code that verifies such signatures is itself a proof subject of this log (leaf 18).

@@ -256,8 +255,8 @@ You still trust: that the operator’s recorded observation is honest.
You need: four small files from the tables below — the two public keys, plus one library’s claim file (“attestation”) and its proof of inclusion (“receipt”).
pacta receipt-verify --attestation … --receipt … --log-public-key provider.ed25519.pub --slhdsa-public-key provider.slhdsa.pub
-Your machine checks the required Ed25519 signature, the additive -post-quantum co-signature (needs OpenSSL ≥ 3.5; drop the second flag to skip it), and +Your machine checks the required Ed25519 signature, the second (post-quantum) signature +(needs OpenSSL ≥ 3.5; drop the second flag to skip it), and ~{max(1,(latest.get('tree_size') or 1).bit_length())} hashes — no proof assistant involved. The pacta tool ships in the pacta repository @@ -320,7 +319,7 @@ log id {escape(str(metadata.get('log_id',''))[:16])}….

What do I download? — the three artifacts, unambiguously

To benefit from the accumulator you need exactly three files per -library, plus optionally the additive post-quantum key +library, plus optionally the post-quantum key (provider.slhdsa.pub) and the whole mirror. Nothing else.

diff --git a/src/pacta/cli.py b/src/pacta/cli.py index 3c7ac98..484f91f 100644 --- a/src/pacta/cli.py +++ b/src/pacta/cli.py @@ -137,7 +137,7 @@ def build_parser() -> argparse.ArgumentParser: receipt_verify.add_argument("--receipt", required=True) receipt_verify.add_argument("--log-public-key", required=True) receipt_verify.add_argument("--require-signatures", choices=["ed25519", "both"], default="ed25519") - receipt_verify.add_argument("--slhdsa-public-key", help="Also verify the additive SLH-DSA head co-signature against this public key (OpenSSL >= 3.5; heads before tree size 14 report absent, not failed).") + receipt_verify.add_argument("--slhdsa-public-key", help="Also verify the second (post-quantum, SLH-DSA) head signature against this public key (OpenSSL >= 3.5; heads before tree size 14 report absent, not failed).") receipt_verify.add_argument("--sth-store", help="Path to the local STH pin store (split-view/rollback defense).") receipt_verify.add_argument("--consistency-proof", help="File with a hex consistency proof from the pinned tree size (provider: log-consistency).") receipt_verify.add_argument("--max-sth-age-seconds", type=int, help="Reject signed tree heads older than this (freshness policy).")
#ArtifactWhat it isWhere