diff --git a/README.md b/README.md index 6dc80e8..3c3737e 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Layout: | `sth-history.jsonl` | **every** Signed Tree Head ever issued — the witness channel: all cloners see the same heads | | `latest-sth.json` | the current head | | `provider.ed25519.pub` | the provider's Ed25519 public key — the REQUIRED identity anchor; each statement's truth additionally rests on the assumptions stated in its leaf | -| `provider.slhdsa.pub` | the provider's SLH-DSA-SHA2-128s public key (FIPS 205) — checks the ADDITIVE post-quantum head signature; needs OpenSSL >= 3.5, and verify.py degrades honestly below that | +| `provider.slhdsa.pub` | the provider's SLH-DSA-SHA2-128s public key (FIPS 205) — checks the second (post-quantum) head signature; needs OpenSSL >= 3.5, and verify.py degrades honestly below that | | `verify.py` | standalone verifier (Python stdlib + the `openssl` binary; fails closed without them; `--all` covers every published receipt) | | `verify_selftest.py` | adversarial self-test: proves the verifier's fail-closed paths reject mutated receipts | diff --git a/verify.py b/verify.py index e227128..629c561 100644 --- a/verify.py +++ b/verify.py @@ -8,8 +8,8 @@ files in this repository alone: 1. every entry's leaf hash, 2. every historical Signed Tree Head against the recomputed prefix root (a split view or tampered entry fails here), - 3. every STH Ed25519 signature — and, where a head carries the ADDITIVE - SLH-DSA-SHA2-128s signature (FIPS 205, heads from 2026-08 on), that + 3. every STH Ed25519 signature — and, where a head carries the second, + post-quantum SLH-DSA-SHA2-128s signature (FIPS 205, heads from 2026-08 on), that too: a present-but-wrong post-quantum signature FAILS the run, a head without one is allowed, and an OpenSSL too old to check it (pre-3.5) is reported loudly as a degradation, never counted as verified, @@ -131,12 +131,12 @@ def check_sth_signature(head) -> str: def check_slh_dsa_signature(head): - """ADDITIVE post-quantum check (SLH-DSA-SHA2-128s, FIPS 205). + """Second-signature (post-quantum) check: SLH-DSA-SHA2-128s, FIPS 205. Returns (status, hard_failure). Ed25519 remains the REQUIRED signature; this one is verified when the head carries it and the local OpenSSL (>= 3.5) can check it. The distinctions matter: - ABSENT - head predates the second signature. Allowed: additive. + ABSENT - head predates the second signature. Allowed by design. VALID - verified against provider.slhdsa.pub. INVALID - present and WRONG. Hard failure - a bad signature is never a degradation. @@ -313,7 +313,7 @@ def main() -> int: print(f"STH #{position} size={size} root={head['root_hash'][:16]}… prefix-root:{structural} signature:{signature} slh_dsa:{slh}") previous = max(previous, size) if slh_tooling_seen: - print("NOTE: this log carries an ADDITIVE SLH-DSA (FIPS 205) signature that " + print("NOTE: this log carries a second, post-quantum SLH-DSA (FIPS 205) signature that " "your OpenSSL cannot check (needs >= 3.5). The required Ed25519 checks " "above still gate this result; the post-quantum signature was NOT verified.") latest_path = HERE / "latest-sth.json" diff --git a/verify_selftest.py b/verify_selftest.py index 18a07c4..48fdae7 100644 --- a/verify_selftest.py +++ b/verify_selftest.py @@ -77,7 +77,7 @@ def main() -> int: cases.append(("--structural-only is explicit, never claims full", code == 0 and "REDUCED" in out and "[full]" not in out)) - # The ADDITIVE post-quantum signature must fail closed when tampered. + # The second (post-quantum) signature must fail closed when tampered. # Applicable only to mirrors whose heads carry it; older mirrors record # the case as not-applicable rather than silently passing. latest = json.loads((HERE / "latest-sth.json").read_text())