risc0-ed25519-verified/verification/check.sh

158 lines
6.3 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# check.sh — THE button. Compiles EVERY shipped .lean file and axiom-audits
# EVERY layer certificate. If a file is in this repo, this script checks it;
# if this script doesn't check it, it must not be in the repo.
#
# Phases:
# 0. resource + source-integrity guards
# 1. stub audit: no `by trivial` specs, no True-target theorems, and — the
# anti-axiom-smuggling gate — ZERO `axiom` declarations under Proofs/
# (external models in gen/ are the only sanctioned axiom site)
# 2. compile gen/ + Proofs/ in dependency order (explicit -o, capped cores,
# per-file timeout). Any "declaration uses 'sorry'" warning is a FAILURE
# (this catches sorry robustly — text greps can't, comments mention it).
# 3. axiom audit: #print axioms for every certificate in CERTS; each must
# report exactly [propext, Classical.choice, Quot.sound]
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
source ~/aeneas-toolchain/env.sh
HERE="$(cd "$(dirname "$0")" && pwd)"
AENEAS_LEAN="$AENEAS_HOME/backends/lean"
TIMEOUT="${LEAN_TIMEOUT:-300}"
export LEAN_MEM_MB="${LEAN_MEM_MB:-8192}" # 8192: ReduceSpec exceeds 6144 (coherence pass 2)
CORES="${LEAN_MAX_CORES:-0-3}"
# Layer manifests (extended as the pyramid grows; ORDER = import order).
GEN_MODULES=(
CurveField/TypesExternal
CurveField/Types
CurveField/FunsExternal
CurveField/Funs
)
PROOFS=(
Denote
P25519
ReduceSpec
SubNegSpec
ConstSpecs
AddSpec
MulSpec
SquareSpec
Square2Spec
Field
InvertSpec
FieldMain
FeQ
EdCurve
EdDenote
EdDouble
EdAddProjNiels
EdAddAffNiels
EdConvert
EdMain
Double-scalar-mul proof campaign, bricks 1-3: table, digit step, loop Three new proof files over the CurveField extraction, composing the proven group-law layer (no new axioms, no associativity assumed — computational layering over the abstract `edAdd`): - `Proofs/DsmTableSpec.lean` — `NafLookupTable5::from(&A)`: the 8 entries are valid `ProjectiveNielsPoint` caches of valid on-curve points denoting the odd multiples A, 3A, ..., 15A as the `edOdd` double-and-add recursion. 7 explicit loop peels over edwards_as_projective_niels_spec / add_projniels_law / compl_as_extended_law, seeded by edwards_double_law. `select`: both masserts (x odd, x < 16) DISCHARGED — panic-freedom is proven, not assumed; post enumerates all 8 digit cases. - `Proofs/DsmStepSpec.lean` — `proj_double_law` (the projective doubling denotes `edAdd P P`; same Z^2-scaled linear_combination discipline as the extended-coordinate law), `compl_as_projective_law` ((X:Z),(Y:T) to (XT:YZ:ZT) preserves the point), `naf_select_entry` (digit-indexed lookup returns THE entry: NafEntryOf r A ((x-1)/2)), and `dsm_step_p_law` / `dsm_step_b_law`: the three-way NAF digit step denotes `edDigit` — add the d-th odd multiple, add its negation, or pass through. - `Proofs/DsmLoopSpec.lean` — the 256-iteration Straus loop by GENUINE induction on the counter (one symbolic body walk, no unrolling): `dsm_loop_spec` — from the identity, the loop returns a valid on-curve point denoting `dsmFold ... edId 256`, the abstract double-and-add fold of both digit arrays over the table points. Digit and table hypotheses are exactly what the NAF spec and naf_table_spec provide (layering). check.sh wired: PROOFS + AUDIT_IMPORTS + 7 new CERTS (naf_table_spec, naf_select_spec, proj_double_law, compl_as_projective_law, dsm_step_p_law, dsm_step_b_law, dsm_loop_spec), each `#print axioms`-audited to exactly [propext, Classical.choice, Quot.sound]. Full check.sh green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 13:07:57 +00:00
DsmTableSpec
DsmStepSpec
DsmLoopSpec
)
# Fully-qualified certificate names; each must be axiom-clean.
CERTS=(
CurveFieldProofs.fieldImplementation
CurveFieldProofs.edwardsImplementation
Double-scalar-mul proof campaign, bricks 1-3: table, digit step, loop Three new proof files over the CurveField extraction, composing the proven group-law layer (no new axioms, no associativity assumed — computational layering over the abstract `edAdd`): - `Proofs/DsmTableSpec.lean` — `NafLookupTable5::from(&A)`: the 8 entries are valid `ProjectiveNielsPoint` caches of valid on-curve points denoting the odd multiples A, 3A, ..., 15A as the `edOdd` double-and-add recursion. 7 explicit loop peels over edwards_as_projective_niels_spec / add_projniels_law / compl_as_extended_law, seeded by edwards_double_law. `select`: both masserts (x odd, x < 16) DISCHARGED — panic-freedom is proven, not assumed; post enumerates all 8 digit cases. - `Proofs/DsmStepSpec.lean` — `proj_double_law` (the projective doubling denotes `edAdd P P`; same Z^2-scaled linear_combination discipline as the extended-coordinate law), `compl_as_projective_law` ((X:Z),(Y:T) to (XT:YZ:ZT) preserves the point), `naf_select_entry` (digit-indexed lookup returns THE entry: NafEntryOf r A ((x-1)/2)), and `dsm_step_p_law` / `dsm_step_b_law`: the three-way NAF digit step denotes `edDigit` — add the d-th odd multiple, add its negation, or pass through. - `Proofs/DsmLoopSpec.lean` — the 256-iteration Straus loop by GENUINE induction on the counter (one symbolic body walk, no unrolling): `dsm_loop_spec` — from the identity, the loop returns a valid on-curve point denoting `dsmFold ... edId 256`, the abstract double-and-add fold of both digit arrays over the table points. Digit and table hypotheses are exactly what the NAF spec and naf_table_spec provide (layering). check.sh wired: PROOFS + AUDIT_IMPORTS + 7 new CERTS (naf_table_spec, naf_select_spec, proj_double_law, compl_as_projective_law, dsm_step_p_law, dsm_step_b_law, dsm_loop_spec), each `#print axioms`-audited to exactly [propext, Classical.choice, Quot.sound]. Full check.sh green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 13:07:57 +00:00
CurveFieldProofs.naf_table_spec
CurveFieldProofs.naf_select_spec
CurveFieldProofs.proj_double_law
CurveFieldProofs.compl_as_projective_law
CurveFieldProofs.dsm_step_p_law
CurveFieldProofs.dsm_step_b_law
CurveFieldProofs.dsm_loop_spec
)
# Imports needed so every certificate in CERTS is in scope for the audit.
AUDIT_IMPORTS=(
Proofs.FieldMain
Proofs.EdMain
Double-scalar-mul proof campaign, bricks 1-3: table, digit step, loop Three new proof files over the CurveField extraction, composing the proven group-law layer (no new axioms, no associativity assumed — computational layering over the abstract `edAdd`): - `Proofs/DsmTableSpec.lean` — `NafLookupTable5::from(&A)`: the 8 entries are valid `ProjectiveNielsPoint` caches of valid on-curve points denoting the odd multiples A, 3A, ..., 15A as the `edOdd` double-and-add recursion. 7 explicit loop peels over edwards_as_projective_niels_spec / add_projniels_law / compl_as_extended_law, seeded by edwards_double_law. `select`: both masserts (x odd, x < 16) DISCHARGED — panic-freedom is proven, not assumed; post enumerates all 8 digit cases. - `Proofs/DsmStepSpec.lean` — `proj_double_law` (the projective doubling denotes `edAdd P P`; same Z^2-scaled linear_combination discipline as the extended-coordinate law), `compl_as_projective_law` ((X:Z),(Y:T) to (XT:YZ:ZT) preserves the point), `naf_select_entry` (digit-indexed lookup returns THE entry: NafEntryOf r A ((x-1)/2)), and `dsm_step_p_law` / `dsm_step_b_law`: the three-way NAF digit step denotes `edDigit` — add the d-th odd multiple, add its negation, or pass through. - `Proofs/DsmLoopSpec.lean` — the 256-iteration Straus loop by GENUINE induction on the counter (one symbolic body walk, no unrolling): `dsm_loop_spec` — from the identity, the loop returns a valid on-curve point denoting `dsmFold ... edId 256`, the abstract double-and-add fold of both digit arrays over the table points. Digit and table hypotheses are exactly what the NAF spec and naf_table_spec provide (layering). check.sh wired: PROOFS + AUDIT_IMPORTS + 7 new CERTS (naf_table_spec, naf_select_spec, proj_double_law, compl_as_projective_law, dsm_step_p_law, dsm_step_b_law, dsm_loop_spec), each `#print axioms`-audited to exactly [propext, Classical.choice, Quot.sound]. Full check.sh green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 13:07:57 +00:00
Proofs.DsmTableSpec
Proofs.DsmStepSpec
Proofs.DsmLoopSpec
)
# ── Phase 0: resource + integrity guards ────────────────────────────────────
free -m | awk '/Mem:/{if($7<2048){print "FATAL: <2GB RAM available — refusing to compile"; exit 1}}'
echo "=== Phase 0: source integrity ==="
for f in "$HERE"/gen/CurveField/*.lean "$HERE"/Proofs/*.lean; do
[ -f "$f" ] || continue
if ! grep -qE '^(/-|import |namespace |theorem |def |open |set_option |--)' "$f"; then
echo "CORRUPTED: $f is not Lean source (olean clobber?). Restore: git checkout HEAD -- $f"
exit 1
fi
done
echo " all sources valid"
# ── Phase 1: stub + axiom-smuggling audit ───────────────────────────────────
echo "=== Phase 1: stub audit ==="
if grep -rn 'by trivial' "$HERE"/Proofs/*Spec*.lean 2>/dev/null; then
echo "STUB DETECTED: 'by trivial' in spec files"; exit 1; fi
if grep -rn ' : True :=' "$HERE"/Proofs/*.lean 2>/dev/null; then
echo "STUB DETECTED: True-target theorem"; exit 1; fi
if grep -rnE '^(private |protected |noncomputable )*axiom ' "$HERE"/Proofs/*.lean 2>/dev/null; then
echo "AXIOM SMUGGLING DETECTED: axiom declaration under Proofs/ — forbidden."
echo "External models belong in gen/*/FunsExternal.lean and must stay outside"
echo "every certificate's dependency cone (Phase 3 verifies that)."
exit 1
fi
echo " clean: no trivial stubs, no True targets, no axioms outside gen/"
# ── Phase 2: compile everything shipped ─────────────────────────────────────
echo "=== Phase 2: compile ==="
LOG=$(mktemp /tmp/check-compile-XXXX.log)
cd "$AENEAS_LEAN"
lake env bash -c "
set -euo pipefail
cd '$HERE/gen' && export LEAN_PATH=\"\$LEAN_PATH:\$PWD:$HERE\"
compile() {
echo \" · \$1\"
LEAN_TIMEOUT=$TIMEOUT LEAN_MAX_CORES=$CORES '$HERE/lean-guard' \"\${1}.lean\" 2>&1 | tee -a '$LOG' || { echo \"FAIL: \$1\"; exit 1; }
}
for m in ${GEN_MODULES[*]}; do compile \"\$m\"; done
cd '$HERE'
for m in ${PROOFS[*]}; do
[ -f \"Proofs/\$m.lean\" ] || { echo \"MISSING: Proofs/\$m.lean listed in manifest\"; exit 1; }
compile \"Proofs/\$m\"
done
# every shipped proof file must be in the manifest (no dead files)
for f in Proofs/*.lean; do
b=\$(basename \"\$f\" .lean)
[ \"\$b\" = AxiomCheck ] && continue
case \"\$b\" in Scalar*) continue;; esac # scalar layer: checked by check-scalar.sh (coherence pass 2)
case \" ${PROOFS[*]} \" in (*\" \$b \"*) ;; (*) echo \"DEAD FILE: \$f not in check manifest\"; exit 1;; esac
done
"
if grep -q "uses 'sorry'" "$LOG"; then
echo "STUB DETECTED: a compiled declaration uses 'sorry'"; exit 1; fi
rm -f "$LOG"
# ── Phase 3: axiom audit of every certificate ───────────────────────────────
echo "=== Phase 3: axiom audit ==="
EXPECTED="[propext, Classical.choice, Quot.sound]"
cd "$AENEAS_LEAN"
lake env bash -c "
set -euo pipefail
cd '$HERE/gen' && export LEAN_PATH=\"\$LEAN_PATH:\$PWD:$HERE\"
cd '$HERE'
AUD=\$(mktemp '$HERE/.audit-XXXX.lean')
{
for i in ${AUDIT_IMPORTS[*]}; do echo \"import \$i\"; done
for c in ${CERTS[*]}; do echo \"#print axioms \$c\"; done
} > \"\$AUD\"
OUT=\$(LEAN_TIMEOUT=$TIMEOUT LEAN_MEM_MB=4096 '$HERE/lean-guard' \"\$AUD\" 2>&1)
echo \"\$OUT\"
rm -f \"\$AUD\"
N_CLEAN=\$(echo \"\$OUT\" | grep -cF \"depends on axioms: $EXPECTED\" || true)
if [ \"\$N_CLEAN\" -ne ${#CERTS[@]} ]; then
echo \"AXIOM AUDIT FAILED: \$N_CLEAN/${#CERTS[@]} certificates clean\"
exit 1
fi
"
echo ""
echo "ALL PROOFS PASS. ALL CERTIFICATES AXIOM-CLEAN. NO DEAD FILES."