dalek-ed25519-verified/verification/gen/CurveSig/FunsExternal.lean
mrwulf 5bf9ed5176 Merge scalar into CurveField; integrate the verify glue against the model
Gen merge: extract.sh now co-extracts the Scalar52 backend and the public
scalar::from_bytes_mod_order[_wide] conversions into the SAME CurveField
model, so the whole library — field, curve_models, edwards, scalar — shares
one type universe (Scalar is a single structure, not two). The scalar proof
chain repoints by one import line (ScalarDenote: CurveScalar.Funs ->
CurveField.Funs); check-scalar.sh's gen list follows. Both buttons — the
scalar certificates and the field/group/dsm certificates — pass fresh over
the merged gen, so the merge is proven-safe, not merely hoped-safe.

Verify glue (gen/CurveSig): the extracted ed25519-dalek verify_sha512 path,
integrated against the proven model:
- TypesExternal.lean imports CurveField.Types, so CompressedEdwardsY /
  EdwardsPoint / Scalar in the glue ARE the proven model's types. Only the
  genuinely foreign types stay opaque: sha2.Sha512, ed25519.Signature,
  signature.error.Error.
- FunsExternal.lean imports CurveField.Funs, so every curve/scalar call
  (compress, vartime_double_scalar_mul_basepoint, as_bytes, neg,
  from_bytes_mod_order[_wide]) resolves to a proven definition — no axioms.
  The `?`-operator plumbing (Try::branch, FromResidual::from_residual) and
  compressed_from_bytes get real definitions. Only the SHA-512 hasher
  (sha512_new/update/finalize_bytes) and two opaque wire accessors
  (Signature.to_bytes, Error.new) remain axiomatized — the deliberate,
  documented hash-oracle boundary.

Audited: `verify_sha512`'s entire axiom cone is
  [propext, Classical.choice, Quot.sound,
   sha2.Sha512, sha512_new, sha512_update, sha512_finalize_bytes,
   ed25519.Signature.to_bytes, signature.error.Error.new]
— zero curve axioms, zero scalar axioms. The verify path is definitionally
grounded in the certified model; the only trust boundary is SHA-512.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 18:13:58 +02:00

75 lines
3.5 KiB
Text

/- ──────────────────────────────────────────────────────────────────────────────
gen/CurveSig/FunsExternal.lean — external functions for the verify glue.
TIER A/B — REAL DEFINITIONS (no axioms): importing CurveField.Funs makes
the curve calls (compress, vartime_double_scalar_mul_basepoint,
as_bytes, neg, from_bytes_mod_order, from_bytes_mod_order_wide) resolve to
the PROVEN model's definitions by their fully-qualified names. The Result
Try/FromResidual plumbing and the compressed_from_bytes constructor are
given real definitions below.
TIER C — THE DELIBERATE OPAQUE BOUNDARY (the only axioms):
· verifying.sha512_new / sha512_update / sha512_finalize_bytes — SHA-512
· ed25519.Signature.to_bytes — the wire accessor of an opaque type
· signature.error.Error.new — an opaque error value
The apex certificate will carry EXACTLY these axioms beyond the standard
three — the documented hash-oracle boundary.
────────────────────────────────────────────────────────────────────────────── -/
import Aeneas
import CurveSig.TypesExternal
import CurveField.Funs
open Aeneas Aeneas.Std Result ControlFlow Error
set_option linter.dupNamespace false
set_option linter.hashCommand false
set_option linter.unusedVariables false
/-! ### Tier A/B: real definitions -/
/-- `Try::branch` for `core::result::Result` — the `?` operator's dispatch. -/
def core.result.Result.Insts.CoreOpsTry_traitTry.branch
{T : Type} {E : Type} (r : core.result.Result T E) :
Result (core.ops.control_flow.ControlFlow
(core.result.Result core.convert.Infallible E) T) :=
match r with
| .Ok v => ok (.Continue v)
| .Err e => ok (.Break (.Err e))
/-- `FromResidual` for `core::result::Result` — the `?` operator's error
conversion. The `Ok Infallible` branch is uninhabited. -/
def core.result.Result.Insts.CoreOpsTry_traitFromResidualResultInfallibleE.from_residual
(T : Type) {E : Type} {F : Type} (convertFromInst : core.convert.From F E)
(r : core.result.Result core.convert.Infallible E) :
Result (core.result.Result T F) :=
match r with
| .Ok v => nomatch v
| .Err e => do
let f ← convertFromInst.from_ e
ok (.Err f)
/-- The compressed-point constructor: `CompressedEdwardsY` is the 32-byte
array synonym in the proven model. -/
def signature.compressed_from_bytes
(bytes : Array Std.U8 32#usize) :
Result curve25519_dalek.edwards.CompressedEdwardsY :=
ok bytes
/-! ### Tier C: the deliberate opaque boundary -/
/-- SHA-512: fresh hasher state. OPAQUE BY DESIGN. -/
axiom verifying.sha512_new : Result sha2.Sha512
/-- SHA-512: absorb bytes. OPAQUE BY DESIGN. -/
axiom verifying.sha512_update
: sha2.Sha512 → Slice Std.U8 → Result sha2.Sha512
/-- SHA-512: finalize to 64 bytes. OPAQUE BY DESIGN. -/
axiom verifying.sha512_finalize_bytes
: sha2.Sha512 → Result (Array Std.U8 64#usize)
/-- The wire signature's 64 bytes (R ‖ s). Opaque accessor of an opaque
type — the verify spec is stated relative to its result. -/
axiom ed25519.Signature.to_bytes
: ed25519.Signature → Result (Array Std.U8 64#usize)
/-- An opaque error value; the spec only distinguishes ok from err. -/
axiom signature.error.Error.new : Result signature.error.Error