mirror of
https://github.com/saymrwulf/fips205-slhdsa-verified.git
synced 2026-09-04 20:03:44 +00:00
The third reviewer demonstrated that the round-2 in-Lean exact-cone audit, though sound for LISTED certs, left three fail-opens OUTSIDE the cone check — and made check.sh print ALL GREEN over a repo proving False. All closed; no theorem, proof, or fold changed (the 11 cones are unchanged). F1 — the audited SET was unbound. Audit.lean now (a) enumerates EVERY theorem defined in the eight certificate modules and requires each cone ⊆ boundary, so an un-manifested `theorem _ : False := cheat _` fails regardless of naming (this is the exact exploit the reviewer used); and (b) prints a MANIFEST fingerprint over the whole committed manifest, which check.sh binds to — so deleting/swapping a cert row fails outside Lean too. F2 — only cones were bound, not statements. Each cert now also carries the structural fingerprint (Expr.hash) of its elaborated type; a statement gutted to a tautology of the same cone changes the fingerprint and fails. F3 — the gen/ model bytes were unbound. New check.sh Phase 0 sha256-pins all four gen/SlhVerify/*.lean (incl. the two hand-maintained *External files, now hashed in PROVENANCE.json) BEFORE compiling; a hand-edited model fails first. F4/F5 — docs. README cone diagram now roots honestly at slh_verify_internal and states the pure/prehash domain-separator byte, the ctx>255 check, M' assembly, and deserialization are ABOVE the root and uncovered (new TRUSTED-BASE item 10). The false "rules out a wrong ADRS field" claim is corrected in README + ChainSpec (a transliteration makes the field visible, not excluded). check-selftest.sh: eight attacks, all rejected (dead file; extra axiom; dropped oracle; vanished cert; un-manifested False theorem; gutted statement; hand-edited model; deleted manifest row). Full transcript + green check.sh in verification/RECORDED-RUN.md. Standing limit unchanged and disclosed: an audit cannot defend against an author who edits the manifest AND check.sh AND the proofs together; the consumer defense is the pinned commit reviewed at the pin. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
57 lines
3.4 KiB
Markdown
57 lines
3.4 KiB
Markdown
# TRUSTED-BASE — what the certificates do NOT cover
|
||
|
||
Eleven certificates over the extracted `verify_mono` model are now proven
|
||
(`verification/check.sh` green; the apex is
|
||
`fips205.slh_verify_128s_accepts_iff`). This file states what those
|
||
certificates deliberately do NOT establish; it is maintained as the campaign
|
||
proceeds and is part of every claim.
|
||
|
||
1. **The five verify-path hash oracles.** `h_msg, f, h, t_l, t_len`
|
||
(SLH-DSA-SHA2-128s instantiations over SHA-256; `prf`/`prf_msg` are
|
||
sign-side only and do not appear in the cone) are modeled as opaque
|
||
functions with assumed functional behavior. Their correctness against
|
||
FIPS 180-4 is NOT proven here — the same standing boundary as SHA-512
|
||
in the ed25519 apex. A collision or misimplementation inside the hash
|
||
layer is invisible to these certificates.
|
||
2. **Signing and key generation.** Out of extraction scope entirely. A
|
||
verified verify path says nothing about the safety of signature or key
|
||
production (including randomness).
|
||
3. **The transpilation pair.** Charon and Aeneas (pinned versions in the
|
||
toolchain) are trusted to preserve semantics from Rust (MIR) to the
|
||
Lean model. Divergence between rustc's semantics and the extracted
|
||
model is trusted base.
|
||
4. **The Lean kernel and its three axioms**
|
||
(`propext, Classical.choice, Quot.sound`).
|
||
5. **Build correspondence.** No reproducible-builds claim: the proof is
|
||
about the pinned source, not about any particular compiled binary
|
||
(the estate's R5 gap, stated everywhere it matters).
|
||
6. **Parameter-set scope.** Claims will bind SLH-DSA-SHA2-128s only;
|
||
other parameter sets are unverified until separately extracted and
|
||
proven (R2).
|
||
7. **Aeneas-compat + de-plumbing patch surface.** The fn-pointer-to-named-
|
||
oracle rewrite in `fips205-source` (phase 1) and the two de-plumbing
|
||
rounds (index-loop rewrites of the iterator adapters on the verify path,
|
||
de-plumbing round 2 at `bea1051`; current snapshot head `797b4ef`) are
|
||
part of the verified surface: the
|
||
certificates cover the *patched* verify path, and the patch commits are
|
||
the auditable delta from upstream `30bac08`. Each rewrite's equivalence
|
||
to upstream is argued in its commit and checked, for SHA2-128s, by the
|
||
snapshot differential test — it is not itself machine-checked.
|
||
8. **The `base_2b` inner loop.** `helpers.base_2b_loop0_loop0` (which
|
||
determines the FORS indices and WOTS digits) is threaded opaquely and
|
||
has no certificate; a defect there could change the recomputed root while
|
||
all eleven theorems still hold.
|
||
9. **The deployed generic verifier.** The proved subject is the private
|
||
`verify_mono` facade. The bridge to upstream's generic `pk.verify()` is
|
||
the finite in-snapshot differential test, not a machine-checked
|
||
refinement.
|
||
10. **Everything above the extraction root.** The root is
|
||
`verify_mono::slh_verify_128s = slh_verify_internal_free(M′, sig, pk)`,
|
||
which takes the message-digest input **M′ as an argument**. The code in
|
||
`slh_verify`/`verify` (`src/lib.rs`) that runs *before* this root is NOT
|
||
covered by any certificate: the assembly of M′; the pure-vs-prehash
|
||
**domain-separator byte** (`0u8` for `verify` vs `1u8` for `hash_verify`
|
||
— the whole cross-variant domain separation); the FIPS-205 `ctx.len() >
|
||
255` bound; and signature/public-key deserialization. The certificates
|
||
say nothing about this input handling — a defect there (e.g. a wrong
|
||
separator byte) would be outside every proof.
|