2026-07-02 12:38:52 +00:00
|
|
|
#!/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}"
|
2026-07-03 10:54:28 +00:00
|
|
|
export LEAN_MEM_MB="${LEAN_MEM_MB:-8192}" # 8192: ReduceSpec exceeds 6144 (coherence pass 2)
|
2026-07-02 12:38:52 +00:00
|
|
|
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
|
THE SIGNATURE APEX on the risc0 fork: verify_accepts_iff, button-enforced
Replicates dalek's apex with this fork's sha2-0.10 adaptation: the hash
oracle is the single monomorphic sha512_hash3(R, A, m) call (no foreign
types in its signature — the 0.10 Sha512 alias cannot be declared opaque),
and extraction runs --no-default-features so the error path avoids boxed
dyn-Error.
- gen/CurveSig: the extracted verify glue, definitionally welded to the
proven model (TypesExternal/FunsExternal import CurveField; every curve
and scalar call is a certified definition).
- Proofs/SigApexSpec.lean (unchanged from dalek): verify_loop_full (the
32-byte comparison = array equality; axiom cone exactly the standard
three) and verify_accepts_iff — accept IFF compress([s]B - [k]A) = R
byte-for-byte, SHA-512 opaque.
- check.sh Phase 3b: the apex axiom cone is enforced to be EXACTLY
[propext, Classical.choice, Quot.sound, ed25519.Signature,
verifying.sha512_hash3, ed25519.Signature.to_bytes,
signature.error.Error, signature.error.Error.new]
- zero curve, scalar, or backend axioms.
Full check.sh green: 17 standard certificates + the apex audit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:35:20 +00:00
|
|
|
CurveSig/TypesExternal
|
|
|
|
|
CurveSig/Types
|
|
|
|
|
CurveSig/FunsExternal
|
|
|
|
|
CurveSig/Funs
|
2026-07-02 12:38:52 +00:00
|
|
|
)
|
|
|
|
|
PROOFS=(
|
|
|
|
|
Denote
|
|
|
|
|
P25519
|
|
|
|
|
ReduceSpec
|
|
|
|
|
SubNegSpec
|
|
|
|
|
ConstSpecs
|
|
|
|
|
AddSpec
|
|
|
|
|
MulSpec
|
|
|
|
|
SquareSpec
|
|
|
|
|
Square2Spec
|
|
|
|
|
Field
|
|
|
|
|
InvertSpec
|
|
|
|
|
FieldMain
|
|
|
|
|
FeQ
|
2026-07-02 14:23:30 +00:00
|
|
|
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
|
NAF encoder proven end-to-end + the phase-1 double-scalar-mul apex
The complete non_adjacent_form(5) verification (four stages):
- `Proofs/DsmNafLoadSpec.lean` (generated) — the LE byte-to-word load.
- `Proofs/DsmNafMath.lean` — the digit loop's arithmetic core: window-read
lemmas (single/cross-word), the exact ZZ invariant steps (Nat.mod_mul
telescope), the carry-kill argument from V < 2^253, and the exit theorem.
- `Proofs/DsmNafLoopSpec.lean` — the w=5 digit loop by induction on the
remaining-bits measure: per-step 64-bit window read (4-way word split),
digit write via hcast/wrapping_sub (exact value window - 32*carry',
oddness, |d| < 16), invariant carried through even/odd steps.
- `Proofs/DsmNafSpec.lean` — the public spec: both entry masserts
DISCHARGED; the digits satisfy the NAF conditions and
sum naf[k]*2^k = V EXACTLY (integers, no modular slack)
for any scalar whose LE byte value V is below 2^253.
And the campaign's brick 4, `Proofs/DsmMulSpec.lean`:
- `run_basepoint` — the transpiled ED25519_BASEPOINT_POINT is the standard
base point: valid extended coordinates (X*Y = Z*T) and the curve equation,
kernel-checked via denominator-free 121666-scaled witnesses. Includes the
generic witness lemmas fp_mul_eq_of_witness / onCurve_of_witness.
- `vartime_double_base_mul_spec` — THE PHASE-1 COMPUTATIONAL SPEC of
vartime_double_base::mul: for canonical scalars and a valid on-curve A,
the result is valid, on-curve, and denotes
dsmFold (naf a) (naf b) (edPt A) edBasePt edId 256
with both digit arrays proven exact NAF encodings. Phase 2 (group
semantics [a]A + [b]B) requires Edwards associativity — deferred and
documented; nothing assumes it.
Also: removed a vestigial pre-re-extraction axiom stub
(backend.serial.scalar_mul.vartime_double_base.mul) from FunsExternal —
a root-level leftover that shadowed the real namespaced definition during
name resolution in proof files. Never referenced by any certificate (the
#print-axioms audit guards against that); deleted for hygiene.
CERTS += naf_load_spec, naf_exit, naf_digit_loop_spec,
non_adjacent_form_spec, run_basepoint, vartime_double_base_mul_spec —
each audited to exactly [propext, Classical.choice, Quot.sound].
Full check.sh green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 14:52:08 +00:00
|
|
|
DsmNafLoadSpec
|
|
|
|
|
DsmNafMath
|
|
|
|
|
DsmNafLoopSpec
|
|
|
|
|
DsmNafSpec
|
|
|
|
|
DsmMulSpec
|
THE SIGNATURE APEX on the risc0 fork: verify_accepts_iff, button-enforced
Replicates dalek's apex with this fork's sha2-0.10 adaptation: the hash
oracle is the single monomorphic sha512_hash3(R, A, m) call (no foreign
types in its signature — the 0.10 Sha512 alias cannot be declared opaque),
and extraction runs --no-default-features so the error path avoids boxed
dyn-Error.
- gen/CurveSig: the extracted verify glue, definitionally welded to the
proven model (TypesExternal/FunsExternal import CurveField; every curve
and scalar call is a certified definition).
- Proofs/SigApexSpec.lean (unchanged from dalek): verify_loop_full (the
32-byte comparison = array equality; axiom cone exactly the standard
three) and verify_accepts_iff — accept IFF compress([s]B - [k]A) = R
byte-for-byte, SHA-512 opaque.
- check.sh Phase 3b: the apex axiom cone is enforced to be EXACTLY
[propext, Classical.choice, Quot.sound, ed25519.Signature,
verifying.sha512_hash3, ed25519.Signature.to_bytes,
signature.error.Error, signature.error.Error.new]
- zero curve, scalar, or backend axioms.
Full check.sh green: 17 standard certificates + the apex audit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:35:20 +00:00
|
|
|
SigApexSpec
|
2026-07-02 12:38:52 +00:00
|
|
|
)
|
|
|
|
|
# Fully-qualified certificate names; each must be axiom-clean.
|
|
|
|
|
CERTS=(
|
|
|
|
|
CurveFieldProofs.fieldImplementation
|
2026-07-02 14:23:30 +00:00
|
|
|
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
|
NAF encoder proven end-to-end + the phase-1 double-scalar-mul apex
The complete non_adjacent_form(5) verification (four stages):
- `Proofs/DsmNafLoadSpec.lean` (generated) — the LE byte-to-word load.
- `Proofs/DsmNafMath.lean` — the digit loop's arithmetic core: window-read
lemmas (single/cross-word), the exact ZZ invariant steps (Nat.mod_mul
telescope), the carry-kill argument from V < 2^253, and the exit theorem.
- `Proofs/DsmNafLoopSpec.lean` — the w=5 digit loop by induction on the
remaining-bits measure: per-step 64-bit window read (4-way word split),
digit write via hcast/wrapping_sub (exact value window - 32*carry',
oddness, |d| < 16), invariant carried through even/odd steps.
- `Proofs/DsmNafSpec.lean` — the public spec: both entry masserts
DISCHARGED; the digits satisfy the NAF conditions and
sum naf[k]*2^k = V EXACTLY (integers, no modular slack)
for any scalar whose LE byte value V is below 2^253.
And the campaign's brick 4, `Proofs/DsmMulSpec.lean`:
- `run_basepoint` — the transpiled ED25519_BASEPOINT_POINT is the standard
base point: valid extended coordinates (X*Y = Z*T) and the curve equation,
kernel-checked via denominator-free 121666-scaled witnesses. Includes the
generic witness lemmas fp_mul_eq_of_witness / onCurve_of_witness.
- `vartime_double_base_mul_spec` — THE PHASE-1 COMPUTATIONAL SPEC of
vartime_double_base::mul: for canonical scalars and a valid on-curve A,
the result is valid, on-curve, and denotes
dsmFold (naf a) (naf b) (edPt A) edBasePt edId 256
with both digit arrays proven exact NAF encodings. Phase 2 (group
semantics [a]A + [b]B) requires Edwards associativity — deferred and
documented; nothing assumes it.
Also: removed a vestigial pre-re-extraction axiom stub
(backend.serial.scalar_mul.vartime_double_base.mul) from FunsExternal —
a root-level leftover that shadowed the real namespaced definition during
name resolution in proof files. Never referenced by any certificate (the
#print-axioms audit guards against that); deleted for hygiene.
CERTS += naf_load_spec, naf_exit, naf_digit_loop_spec,
non_adjacent_form_spec, run_basepoint, vartime_double_base_mul_spec —
each audited to exactly [propext, Classical.choice, Quot.sound].
Full check.sh green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 14:52:08 +00:00
|
|
|
CurveFieldProofs.naf_load_spec
|
|
|
|
|
CurveFieldProofs.naf_exit
|
|
|
|
|
CurveFieldProofs.naf_digit_loop_spec
|
|
|
|
|
CurveFieldProofs.non_adjacent_form_spec
|
|
|
|
|
CurveFieldProofs.run_basepoint
|
|
|
|
|
CurveFieldProofs.vartime_double_base_mul_spec
|
THE SIGNATURE APEX on the risc0 fork: verify_accepts_iff, button-enforced
Replicates dalek's apex with this fork's sha2-0.10 adaptation: the hash
oracle is the single monomorphic sha512_hash3(R, A, m) call (no foreign
types in its signature — the 0.10 Sha512 alias cannot be declared opaque),
and extraction runs --no-default-features so the error path avoids boxed
dyn-Error.
- gen/CurveSig: the extracted verify glue, definitionally welded to the
proven model (TypesExternal/FunsExternal import CurveField; every curve
and scalar call is a certified definition).
- Proofs/SigApexSpec.lean (unchanged from dalek): verify_loop_full (the
32-byte comparison = array equality; axiom cone exactly the standard
three) and verify_accepts_iff — accept IFF compress([s]B - [k]A) = R
byte-for-byte, SHA-512 opaque.
- check.sh Phase 3b: the apex axiom cone is enforced to be EXACTLY
[propext, Classical.choice, Quot.sound, ed25519.Signature,
verifying.sha512_hash3, ed25519.Signature.to_bytes,
signature.error.Error, signature.error.Error.new]
- zero curve, scalar, or backend axioms.
Full check.sh green: 17 standard certificates + the apex audit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:35:20 +00:00
|
|
|
CurveFieldProofs.verify_loop_full
|
2026-07-02 12:38:52 +00:00
|
|
|
)
|
|
|
|
|
# Imports needed so every certificate in CERTS is in scope for the audit.
|
|
|
|
|
AUDIT_IMPORTS=(
|
|
|
|
|
Proofs.FieldMain
|
2026-07-02 14:23:30 +00:00
|
|
|
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
|
NAF encoder proven end-to-end + the phase-1 double-scalar-mul apex
The complete non_adjacent_form(5) verification (four stages):
- `Proofs/DsmNafLoadSpec.lean` (generated) — the LE byte-to-word load.
- `Proofs/DsmNafMath.lean` — the digit loop's arithmetic core: window-read
lemmas (single/cross-word), the exact ZZ invariant steps (Nat.mod_mul
telescope), the carry-kill argument from V < 2^253, and the exit theorem.
- `Proofs/DsmNafLoopSpec.lean` — the w=5 digit loop by induction on the
remaining-bits measure: per-step 64-bit window read (4-way word split),
digit write via hcast/wrapping_sub (exact value window - 32*carry',
oddness, |d| < 16), invariant carried through even/odd steps.
- `Proofs/DsmNafSpec.lean` — the public spec: both entry masserts
DISCHARGED; the digits satisfy the NAF conditions and
sum naf[k]*2^k = V EXACTLY (integers, no modular slack)
for any scalar whose LE byte value V is below 2^253.
And the campaign's brick 4, `Proofs/DsmMulSpec.lean`:
- `run_basepoint` — the transpiled ED25519_BASEPOINT_POINT is the standard
base point: valid extended coordinates (X*Y = Z*T) and the curve equation,
kernel-checked via denominator-free 121666-scaled witnesses. Includes the
generic witness lemmas fp_mul_eq_of_witness / onCurve_of_witness.
- `vartime_double_base_mul_spec` — THE PHASE-1 COMPUTATIONAL SPEC of
vartime_double_base::mul: for canonical scalars and a valid on-curve A,
the result is valid, on-curve, and denotes
dsmFold (naf a) (naf b) (edPt A) edBasePt edId 256
with both digit arrays proven exact NAF encodings. Phase 2 (group
semantics [a]A + [b]B) requires Edwards associativity — deferred and
documented; nothing assumes it.
Also: removed a vestigial pre-re-extraction axiom stub
(backend.serial.scalar_mul.vartime_double_base.mul) from FunsExternal —
a root-level leftover that shadowed the real namespaced definition during
name resolution in proof files. Never referenced by any certificate (the
#print-axioms audit guards against that); deleted for hygiene.
CERTS += naf_load_spec, naf_exit, naf_digit_loop_spec,
non_adjacent_form_spec, run_basepoint, vartime_double_base_mul_spec —
each audited to exactly [propext, Classical.choice, Quot.sound].
Full check.sh green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 14:52:08 +00:00
|
|
|
Proofs.DsmNafSpec
|
|
|
|
|
Proofs.DsmMulSpec
|
THE SIGNATURE APEX on the risc0 fork: verify_accepts_iff, button-enforced
Replicates dalek's apex with this fork's sha2-0.10 adaptation: the hash
oracle is the single monomorphic sha512_hash3(R, A, m) call (no foreign
types in its signature — the 0.10 Sha512 alias cannot be declared opaque),
and extraction runs --no-default-features so the error path avoids boxed
dyn-Error.
- gen/CurveSig: the extracted verify glue, definitionally welded to the
proven model (TypesExternal/FunsExternal import CurveField; every curve
and scalar call is a certified definition).
- Proofs/SigApexSpec.lean (unchanged from dalek): verify_loop_full (the
32-byte comparison = array equality; axiom cone exactly the standard
three) and verify_accepts_iff — accept IFF compress([s]B - [k]A) = R
byte-for-byte, SHA-512 opaque.
- check.sh Phase 3b: the apex axiom cone is enforced to be EXACTLY
[propext, Classical.choice, Quot.sound, ed25519.Signature,
verifying.sha512_hash3, ed25519.Signature.to_bytes,
signature.error.Error, signature.error.Error.new]
- zero curve, scalar, or backend axioms.
Full check.sh green: 17 standard certificates + the apex audit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:35:20 +00:00
|
|
|
Proofs.SigApexSpec
|
2026-07-02 12:38:52 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# ── 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\"
|
2026-07-02 14:23:30 +00:00
|
|
|
LEAN_TIMEOUT=$TIMEOUT LEAN_MAX_CORES=$CORES '$HERE/lean-guard' \"\${1}.lean\" 2>&1 | tee -a '$LOG' || { echo \"FAIL: \$1\"; exit 1; }
|
2026-07-02 12:38:52 +00:00
|
|
|
}
|
|
|
|
|
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
|
2026-07-03 10:54:28 +00:00
|
|
|
case \"\$b\" in Scalar*) continue;; esac # scalar layer: checked by check-scalar.sh (coherence pass 2)
|
2026-07-02 12:38:52 +00:00
|
|
|
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'
|
2026-07-03 10:54:28 +00:00
|
|
|
AUD=\$(mktemp '$HERE/.audit-XXXX.lean')
|
2026-07-02 12:38:52 +00:00
|
|
|
{
|
|
|
|
|
for i in ${AUDIT_IMPORTS[*]}; do echo \"import \$i\"; done
|
|
|
|
|
for c in ${CERTS[*]}; do echo \"#print axioms \$c\"; done
|
|
|
|
|
} > \"\$AUD\"
|
2026-07-03 10:54:28 +00:00
|
|
|
OUT=\$(LEAN_TIMEOUT=$TIMEOUT LEAN_MEM_MB=4096 '$HERE/lean-guard' \"\$AUD\" 2>&1)
|
2026-07-02 12:38:52 +00:00
|
|
|
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
|
|
|
|
|
"
|
THE SIGNATURE APEX on the risc0 fork: verify_accepts_iff, button-enforced
Replicates dalek's apex with this fork's sha2-0.10 adaptation: the hash
oracle is the single monomorphic sha512_hash3(R, A, m) call (no foreign
types in its signature — the 0.10 Sha512 alias cannot be declared opaque),
and extraction runs --no-default-features so the error path avoids boxed
dyn-Error.
- gen/CurveSig: the extracted verify glue, definitionally welded to the
proven model (TypesExternal/FunsExternal import CurveField; every curve
and scalar call is a certified definition).
- Proofs/SigApexSpec.lean (unchanged from dalek): verify_loop_full (the
32-byte comparison = array equality; axiom cone exactly the standard
three) and verify_accepts_iff — accept IFF compress([s]B - [k]A) = R
byte-for-byte, SHA-512 opaque.
- check.sh Phase 3b: the apex axiom cone is enforced to be EXACTLY
[propext, Classical.choice, Quot.sound, ed25519.Signature,
verifying.sha512_hash3, ed25519.Signature.to_bytes,
signature.error.Error, signature.error.Error.new]
- zero curve, scalar, or backend axioms.
Full check.sh green: 17 standard certificates + the apex audit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:35:20 +00:00
|
|
|
echo "=== Phase 3b: signature-apex audit (SHA-512 + wire-format boundary) ==="
|
|
|
|
|
# The verification-equation apex is grounded in the PROVEN curve model; its
|
|
|
|
|
# only axioms beyond the standard three are the deliberate, documented
|
|
|
|
|
# boundary: the SHA-512 hash oracle and the opaque wire-format types.
|
|
|
|
|
# NO curve axioms, NO scalar axioms, NO backend-dispatch axioms.
|
|
|
|
|
cd "$AENEAS_LEAN"
|
|
|
|
|
lake env bash -c "
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
cd '$HERE/gen' && export LEAN_PATH=\"\$LEAN_PATH:\$PWD:$HERE\"
|
|
|
|
|
cd '$HERE'
|
|
|
|
|
ALLOWED='[propext, Classical.choice, Quot.sound, ed25519.Signature, verifying.sha512_hash3, ed25519.Signature.to_bytes, signature.error.Error, signature.error.Error.new]'
|
|
|
|
|
AUD=\$(mktemp '$HERE/.apex-XXXX.lean')
|
|
|
|
|
{ echo 'import Proofs.SigApexSpec'; echo '#print axioms CurveFieldProofs.verify_accepts_iff'; } > \"\$AUD\"
|
|
|
|
|
OUT=\$(LEAN_TIMEOUT=$TIMEOUT LEAN_MEM_MB=4096 '$HERE/lean-guard' \"\$AUD\" 2>&1)
|
|
|
|
|
echo \"\$OUT\"
|
|
|
|
|
rm -f \"\$AUD\"
|
|
|
|
|
FLAT=\$(echo \"\$OUT\" | tr '\\n' ' ' | tr -s ' ')
|
|
|
|
|
if echo \"\$FLAT\" | grep -qF \"depends on axioms: \$ALLOWED\"; then
|
|
|
|
|
echo ' apex axiom cone = exactly the SHA-512 + wire-format boundary (no curve/scalar/backend axioms)'
|
|
|
|
|
else
|
|
|
|
|
echo 'APEX AUDIT FAILED: verify_accepts_iff cone is not the documented boundary'; exit 1
|
|
|
|
|
fi
|
|
|
|
|
"
|
|
|
|
|
|
2026-07-02 12:38:52 +00:00
|
|
|
echo ""
|
|
|
|
|
echo "ALL PROOFS PASS. ALL CERTIFICATES AXIOM-CLEAN. NO DEAD FILES."
|