mirror of
https://github.com/saymrwulf/fips205-slhdsa-verified.git
synced 2026-09-03 19:53:49 +00:00
Round 3 returned fit-once-one-item-lands (first non-DO-NOT-ATTEST verdict). The one blocker is an independently-executed toolchain session, which is operator-side. This commit closes the two nonblocking recommendations: - extract.sh: source the aeneas toolchain env AFTER the provenance guard, so a party without the toolchain gets the clean exit-2/3/4 diagnostics instead of a confusing env error (the reviewer hit exactly this). Re-verified: exit 2/3 clean in an env-stripped shell, happy path byte-identical. - RECORDED-RUN.md: append the locked cargo run under the pinned nightly — the differential bridge test mono_matches_deployed_verify passes with --locked --lib on nightly-2026-06-01, and the full default-features suite is green (13+3+12+37 passed, 0 failed). Also documents why single-feature integration tests cannot compile (upstream test files hardcode all twelve parameter sets), resolving the round-1 GPT observation. No proof, model, or gate change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
81 lines
4.1 KiB
Bash
Executable file
81 lines
4.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Regenerate the Lean model in gen/ from the pinned fips205 snapshot.
|
|
#
|
|
# SCOPE: the SLH-DSA verify path, parameter set SLH-DSA-SHA2-128s
|
|
# roots: slh_verify(_internal), fors_pk_from_sig, ht_verify,
|
|
# xmss_pk_from_sig, wots_pk_from_sig, chain
|
|
# (sign/keygen are out of scope; the five verify-path hash oracles
|
|
# (h_msg, f, h, t_l, t_len) are opaque — see TRUSTED-BASE.md.)
|
|
#
|
|
# Rust --charon--> SlhVerify.llbc --aeneas--> gen/SlhVerify/*.lean
|
|
#
|
|
# REPRODUCIBILITY (external review round 2, 2026-07-24): this script now
|
|
# REFUSES to extract from a source tree that is not at the pinned commit or
|
|
# is dirty (a wrong/uncommitted source would silently produce a different
|
|
# model). The full pin set (source + charon + aeneas + lean + ocaml) is in
|
|
# verification/PROVENANCE.json; re-running this against the pinned tree
|
|
# reproduces gen/SlhVerify/{Types,Funs}.lean byte-identically.
|
|
#
|
|
# HISTORY (gate-0 finding, resolved 2026-07-22): upstream models the hash
|
|
# family as `crate::hashers::Hashers`, a struct of plain function pointers,
|
|
# which Aeneas cannot translate. The compat patch in fips205-source provides
|
|
# the additive monomorphic verify_mono module whose hash suite is reached
|
|
# through named free functions — this script roots there.
|
|
#
|
|
# Usage: ./extract.sh [PATH_TO_fips205-source]
|
|
# (default: ~/GitClone/FormalVerification/sources/fips205-source)
|
|
# Override the required commit only for a deliberate re-pin:
|
|
# EXPECTED_SRC_COMMIT=<full-sha> ./extract.sh [PATH]
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
CRATE="${1:-$HOME/GitClone/FormalVerification/sources/fips205-source}"
|
|
|
|
# The pinned source commit this repo's model + proofs were verified against.
|
|
# Keep in lockstep with verification/PROVENANCE.json and the README snapshot.
|
|
EXPECTED_SRC_COMMIT="${EXPECTED_SRC_COMMIT:-797b4ef26338e27363683656f93cb065a77daa0e}"
|
|
|
|
# ── Provenance guard: refuse a wrong or dirty source tree (fail-closed) ──────
|
|
[ -d "$CRATE/.git" ] || { echo "ERROR: '$CRATE' is not a git checkout of fips205-source." >&2; exit 2; }
|
|
GOT_COMMIT="$(git -C "$CRATE" rev-parse HEAD)"
|
|
if [ "$GOT_COMMIT" != "$EXPECTED_SRC_COMMIT" ]; then
|
|
echo "ERROR: source is at ${GOT_COMMIT:0:12}, but this repo is pinned to" >&2
|
|
echo " ${EXPECTED_SRC_COMMIT:0:12}. Check out the pin, or set" >&2
|
|
echo " EXPECTED_SRC_COMMIT=<sha> for a deliberate re-pin." >&2
|
|
exit 3
|
|
fi
|
|
if [ -n "$(git -C "$CRATE" status --porcelain)" ]; then
|
|
echo "ERROR: source tree at '$CRATE' is dirty. Extraction must run against" >&2
|
|
echo " a clean, committed tree so the model is reproducible." >&2
|
|
git -C "$CRATE" status --porcelain | sed 's/^/ /' >&2
|
|
exit 4
|
|
fi
|
|
echo "[0/2] provenance OK: fips205-source @ ${EXPECTED_SRC_COMMIT:0:12} (clean)"
|
|
|
|
# Toolchain env is sourced only AFTER the provenance guard, so a party without
|
|
# the aeneas toolchain still gets the clean exit-2/3/4 diagnostics above
|
|
# (round-3 reviewer nit, 2026-07-24).
|
|
source ~/aeneas-toolchain/env.sh
|
|
|
|
echo "[1/2] charon: Rust -> LLBC (monomorphic SHA2-128s verify cone;"
|
|
echo " crate::verify_mono::oracle is the opaque SHA-2 boundary)"
|
|
cd "$CRATE"
|
|
# Single extraction root: the monomorphic entry. The five hash primitives
|
|
# are reached through crate::verify_mono::oracle, marked opaque here — this
|
|
# is the deliberate SHA-2 trust boundary (documented in TRUSTED-BASE.md).
|
|
# The generic Hashers fn-pointer path is NOT in this cone by construction.
|
|
charon cargo --preset=aeneas \
|
|
--start-from 'crate::verify_mono::slh_verify_128s' \
|
|
--opaque 'crate::verify_mono::oracle' \
|
|
--opaque 'sha2' --opaque 'sha3' --opaque 'zeroize' --opaque 'rand_core' \
|
|
--hide-marker-traits \
|
|
--dest-file "$HERE/SlhVerify.llbc" \
|
|
-- --no-default-features --features slh_dsa_sha2_128s
|
|
|
|
echo "[2/2] aeneas: LLBC -> Lean (split files, SlhVerify.* modules;"
|
|
echo " hand-maintained TypesExternal.lean / FunsExternal.lean are"
|
|
echo " NOT overwritten once they exist)"
|
|
cd "$HERE"
|
|
aeneas -backend lean -split-files -subdir SlhVerify -dest gen SlhVerify.llbc
|
|
|
|
echo "Done. Now run ./check.sh (Phase 1: the regenerated model must type-check)."
|