Canonicity pass (the layer is now closed under its own preconditions):
- sub_val_spec post carries the exact value equation
(exists beta <= 1, scVal r + scVal b = scVal a + ell*beta, with the
underflow guard beta = 1 -> scVal a < scVal b)
- add/montgomery_reduce/mul/aggregate posts all carry scVal r < ell:
canonical inputs give canonical outputs everywhere. Needed because
from_bytes_wide (hash-to-scalar) feeds Montgomery outputs into add.
Hash-to-scalar foundation (toward Scalar::from_hash / EdDSA verify):
- extraction scope + from_bytes_wide (brings constants::R); regenerated gen
- source repos carry a documented Aeneas-compat patch: the bare
`hi[4] = words[7] >> 20` extracts ill-typed at pin bf13c42e; masked
(semantic no-op, words[7] >> 20 < 2^44)
- Proofs/ScalarWideSpec.lean: R constant lemmas (R = 2^260 mod ell,
witness 2^260 = R + 255*ell) and montgomery_mul_spec, the single
Montgomery round: [r]*2^260 = [a]*[b], canonical bounded output
check-scalar.sh: 10 proof files, 11 kernel audits, all exactly
[propext, Classical.choice, Quot.sound]. Button pressed fresh: green.
This v4.1.x fork implements Scalar52::sub with TWO loops (loop0 = borrow
chain; loop1 adds L &&& underflow_mask — the arithmetic-mask constant-time
conditional), a genuinely different code path from upstream v5's
subtle-based conditional_add_l. Verified per R2 against this fork's own gen:
- sub_loop_spec (= loop0): borrow chain, verbatim technique from dalek
- sub_loop1_zero_spec / sub_loop1_one_spec: the masked-L add, both mask
values (0 / 2^64-1), full carry chains
- sub_val_spec: denote(sub a b) = denote a - denote b in ZMod l; the
underflow mask um = ((borrow>>>63) XOR 1) - 1 resolved per case
- add_loop_spec + add_val_spec: denote(add a b) = denote a + denote b
(v4 add_loop extracts token-identical to v5; composition through this
fork's own sub_val_spec)
check-scalar.sh: full manifest, 5/5 kernel axiom audit
[propext, Classical.choice, Quot.sound], green at 300-400s/4096MB.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- check.sh: proofs memory default 6144 -> 8192 (ReduceSpec's norm_num
step peaks above 6144; guard aborted gracefully — R3 was broken, S1
held). Matches pasta's calibration.
- check.sh: dead-file gate now exempts Scalar* (delegated to
check-scalar.sh); the gate had been un-passable since the scalar layer
landed, masked by the memory failure.
- check.sh: axiom-audit phase routed through lean-guard (cgroup + flock;
was raw lean -M), audit temp file moved into the workspace (lake env
rejects /tmp inputs — the /tmp phase had never run green).
- check-scalar.sh: NEW Phase 3 kernel axiom audit — ScalarProofs.L_val
must report exactly [propext, Classical.choice, Quot.sound].
- README: signature layer '⏳ planned' (was 'in progress' with nothing
started); planned certificate names marked as such.
Validated: full check.sh + check-scalar.sh green end-to-end in the pass-2
sweep (see formal-verification-control/COHERENCE-PASS-2.md).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Transpile the Scalar52 limb backend (backend::serial::u64::scalar
add/sub/mul/square/montgomery_*) from Rust to Lean via Charon/Aeneas,
scoped at the function level to the iterator-free arithmetic core.
- verification/extract-scalar.sh: function-level Charon/Aeneas extraction
- verification/gen/CurveScalar/{Types,Funs}.lean: transpiled model (27 defs).
This fork (v4.1.2) implements Scalar52::sub's constant-time conditional add
with a pure arithmetic mask (constants::L[i] & underflow_mask), so the
extraction pulls in NO external functions or types (unlike v5 dalek, which
routes sub through subtle, and v4.1.3, which uses a local black_box).
- verification/gen/CurveScalar/{TypesExternal,FunsExternal}.lean: decl-free
stub modules kept so the check manifest is uniform across forks.
- verification/Proofs/ScalarDenote.lean: semantic foundation — Scalar52
denotation into ℤ/ℓℤ, limb-bound invariant, and L_val (the transpiled
constants::L denotes exactly the group order ℓ, kernel-checked).
- verification/check-scalar.sh: guarded compile of the gen modules plus the
denotation foundation.
check-scalar.sh passes: gen compiles; denotation + L = ℓ proven.
add/sub/mul remain in progress.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extraction widened to backend::serial::curve_models + edwards (v4 Aeneas).
Ed* proof suite shared with the risc0 twin EXCEPT proj_double_spec: upstream
reordered ProjectivePoint::double's instructions between v4.1.2 (this fork)
and v4.1.3 (risc0), so the step sequence was resequenced to match THIS
fork's generated body — the proofs track each fork's actual code, not a
template. All 20 proofs pass under lean-guard; both certificates axiom-clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ported from the locally verified Hermes working copy; FeQ and Square2Spec
(dead files in the published replica) now compile and are in the check
manifest. Basic.lean (never compiled under v4 Aeneas) removed rather than
shipped dead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>