mirror of
https://github.com/saymrwulf/risc0-ed25519-verified.git
synced 2026-09-05 20:10:36 +00:00
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.
This fork (v4.1.3) inlines a local `black_box` (a volatile read used as an
optimization barrier) inside Scalar52::sub; charon cannot translate the
`&raw const` it lowers to, so it is marked --opaque and modeled below.
- verification/gen/CurveScalar/{Types,Funs}.lean: transpiled model (27 defs)
- verification/gen/CurveScalar/FunsExternal.lean: hand-written model of
Scalar52::sub::black_box as the identity on u64 (a volatile read returns
the value written; the qualifier is only an optimization barrier).
TypesExternal.lean is decl-free — this fork pulls in no external types
(unlike v5 dalek, which routes sub through subtle::Choice).
- 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>
28 lines
1.4 KiB
Text
28 lines
1.4 KiB
Text
-- Hand-written external function models for the Scalar52 arithmetic extraction.
|
|
-- This fork (curve25519-dalek v4.1.3) implements Scalar52::sub's constant-time
|
|
-- conditional add directly with a local `black_box` optimization barrier rather
|
|
-- than routing through subtle::ConditionallySelectable (as the v5 dalek does).
|
|
-- The sole external item is that `black_box`.
|
|
import Aeneas
|
|
import CurveScalar.Types
|
|
open Aeneas Aeneas.Std Result ControlFlow Error
|
|
set_option linter.dupNamespace false
|
|
set_option linter.hashCommand false
|
|
set_option linter.unusedVariables false
|
|
set_option maxHeartbeats 1000000
|
|
set_option maxRecDepth 2048
|
|
open curve25519_dalek
|
|
|
|
/-- [curve25519_dalek::backend::serial::u64::scalar::{curve25519_dalek::backend::serial::u64::scalar::Scalar52}::sub::black_box]:
|
|
Source: 'curve25519-dalek/src/backend/serial/u64/scalar.rs', lines 179:8-183:9
|
|
|
|
MODEL (faithful): the Rust body is
|
|
`unsafe { core::ptr::read_volatile(&value) }`
|
|
— a volatile read of the `u64` `value` living on the stack. The `volatile`
|
|
qualifier only forbids the compiler from eliding/reordering the read (an
|
|
optimization barrier to keep the constant-time path branch-free); the VALUE
|
|
read back is exactly the value written, so semantically this is the identity
|
|
on `u64`. -/
|
|
def backend.serial.u64.scalar.Scalar52.sub.black_box
|
|
(value : Std.U64) : Result Std.U64 :=
|
|
ok value
|