dalek-ed25519-verified/verification/extract.sh

64 lines
3.1 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# Regenerate the Lean model in gen/ from the Rust sources.
#
# SCOPE: field arithmetic + Edwards point arithmetic
# roots: crate::field, crate::backend::serial::u64::field,
# crate::backend::serial::curve_models, crate::edwards
# (same widening the reference solution used for its Tier-1 addition-law
# theorem; scalar-mul backends and decompress internals stay opaque —
# upstream Aeneas cannot translate them; they are modeled/axiomatized in
# gen/CurveField/FunsExternal.lean OUTSIDE every certificate's cone).
#
# Rust --charon--> CurveField.llbc --aeneas--> gen/CurveField/*.lean
#
# The hand-written gen/CurveField/{TypesExternal,FunsExternal}.lean are NOT
# touched by regeneration (Aeneas only rewrites the *_Template variants).
# After regenerating, diff the templates against the hand-written files:
# diff gen/CurveField/FunsExternal_Template.lean gen/CurveField/FunsExternal.lean
#
# Usage: ./extract.sh
set -euo pipefail
source ~/aeneas-toolchain/env.sh
HERE="$(cd "$(dirname "$0")" && pwd)"
CRATE=~/GitClone/FormalVerification/sources/curve25519-dalek-source/curve25519-dalek
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 16:13:58 +00:00
echo "[1/2] charon: Rust -> LLBC (field + curve_models + edwards + scalar [MERGED GEN])"
cd "$CRATE"
charon cargo --preset=aeneas \
--start-from crate::field \
--start-from crate::backend::serial::u64::field \
--start-from crate::backend::serial::curve_models \
--start-from crate::edwards \
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 16:13:58 +00:00
--start-from 'crate::backend::serial::u64::scalar::_::add' \
--start-from 'crate::backend::serial::u64::scalar::_::sub' \
--start-from 'crate::backend::serial::u64::scalar::_::mul' \
--start-from 'crate::backend::serial::u64::scalar::_::square' \
--start-from 'crate::backend::serial::u64::scalar::_::montgomery_mul' \
--start-from 'crate::backend::serial::u64::scalar::_::montgomery_square' \
--start-from 'crate::backend::serial::u64::scalar::_::montgomery_reduce' \
--start-from 'crate::backend::serial::u64::scalar::_::montgomery_invert' \
--start-from 'crate::backend::serial::u64::scalar::_::as_montgomery' \
--start-from 'crate::backend::serial::u64::scalar::_::from_montgomery' \
--start-from 'crate::backend::serial::u64::scalar::_::from_bytes_wide' \
--start-from 'crate::scalar::_::from_bytes_mod_order' \
--start-from 'crate::scalar::_::from_bytes_mod_order_wide' \
--opaque 'crate::field::_::internal_invert_batch' \
--opaque 'crate::backend::serial::scalar_mul::variable_base' \
--opaque 'crate::backend::serial::scalar_mul::straus' \
--opaque 'crate::backend::serial::scalar_mul::precomputed_straus' \
--opaque 'crate::backend::serial::scalar_mul::pippenger' \
--opaque 'crate::backend::vector' \
--opaque 'crate::backend::get_selected_backend' \
--opaque 'crate::edwards::decompress' \
--opaque 'crate::edwards::_::sum' \
--opaque 'crate::edwards::_::from_slice' \
--dest-file "$HERE/CurveField.llbc" \
-- --no-default-features
echo "[2/2] aeneas: LLBC -> Lean (split files, CurveField.* modules)"
cd "$HERE"
aeneas -backend lean -split-files -subdir CurveField -dest gen CurveField.llbc
echo "Done. Now run ./check.sh to type-check the regenerated model."