Skip to content

FYI: Support raw-pointer casts to non-literal pointee types (SHA-NI extraction)#976

Open
fournet wants to merge 3 commits into
mainfrom
fournet/raw-ptr-cast-non-literal-pointee
Open

FYI: Support raw-pointer casts to non-literal pointee types (SHA-NI extraction)#976
fournet wants to merge 3 commits into
mainfrom
fournet/raw-ptr-cast-non-literal-pointee

Conversation

@fournet
Copy link
Copy Markdown
Collaborator

@fournet fournet commented May 5, 2026

FYI — sharing for visibility / discussion. Not requesting merge.

Three small commits surfaced while preparing the SymCrypt SHA-2 SHA-NI
verification target.

1. Add @[step] theorem for Array.to_slice_mut with curried postcondition

Adds a @[step] theorem so that step can decompose
Array.to_slice_mut. Uses the curried ⦃ s lib => ... ⦄ postcondition
form so callers don't need to destructure a tuple.

2. Curried postconditions for all index_mut/to_slice_mut step specs

Sweep across Array/ArraySlice.lean, Slice.lean, Vec.lean to convert
the existing index_mut / to_slice_mut step theorems to the curried
form. One Bst test updated.

3. Support raw-pointer casts to non-literal pointee types

Generalize CastRawPtr's source/target pointee from literal_type to
ty, so casts whose pointee is an opaque builtin (e.g. *const __m128i,
*const __m256i) or any other non-scalar type are translated rather than
raising a fatal error.

On the Lean backend this is emitted as a generic RawPtr.cast that
leaves the source and target pointee types implicit (Lean infers them
from the surrounding context, e.g. the argument type of
_mm_loadu_si128). On other backends we still restrict to literal
scalar pointees as before.

This fixes the OOM observed when extracting SymCrypt's SHA-NI fast path
(sha2::sha2_impl::append_blocks_256_shani), which contains many
*const u8 as *const __m128i casts via primitives like:

unsafe fn loadu_u32xn<const N: usize>(arr: &[u32; N], at: usize)
    -> __m128i {
    _mm_loadu_si128(arr.as_ptr().add(at) as *const __m128i)
}

Validated end-to-end: extraction of the full SymCrypt SHA-2 module
including the SHA-NI fast path now produces clean Lean (defs for the
load/store primitives, axiomatised intrinsics for _mm_sha256rnds2_epu32
etc.).

Conflict resolution

The cherry-pick of #3 onto current origin/main produced a single
trivial conflict against the recent Charon update (d9d473d0 Update Charon): both branches independently renamed
Charon.Print.cast_kind_to_stringCharon.PrintExpressions.cast_kind_to_string
in the same error site. Resolution: kept this PR's version, which also
updates the surrounding code path.

fournet and others added 3 commits May 5, 2026 18:35
The new Aeneas translation generates destructuring binds:
  let (s, back) ← lift (Array.to_slice_mut a)
The old @[step_pure_def] left an opaque pair that couldn't be reduced.
The new @[step] theorem introduces s and back as separate variables.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changed tuple postconditions ⦃ (s, back) => ... ⦄ to curried
⦃ (s : Slice α) (back : Slice α → ...) => ... ⦄ in:

- Slice.lean: SliceIndexRangeUsizeSlice.index_mut
- Slice.lean: SliceIndexRangeToUsizeSlice.index_mut
- Slice.lean: SliceIndexRangeFromUsizeSlice.index_mut
- Vec.lean: Vec.index_mut_RangeTo/RangeFrom/Range_spec
- ArraySlice.lean: Array.index_mut_SliceIndexRangeTo/From

This handles the new Aeneas translation pattern where let (s, back) ← f
destructures the result pair. With curried postconditions, step introduces
s and back as separate variables matching the destructuring.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Generalize CastRawPtr's source/target pointee from literal_type to ty,
so that casts whose pointee is an opaque builtin (e.g. *const __m128i,
*const __m256i) or any other non-scalar type are translated rather
than raising a fatal error.

On the Lean backend this is emitted as a generic RawPtr.cast that
leaves the source and target pointee types implicit (Lean infers them
from the surrounding context, e.g. the argument type of
_mm_loadu_si128). On other backends we still restrict to literal
scalar pointees as before.

Fixes the OOM observed when extracting SymCrypt's SHA-NI fast path
(sha2::sha2_impl::append_blocks_256_shani), which contains many
*const u8 -> *const __m128i casts.
@remix7531
Copy link
Copy Markdown
Contributor

Hi! Heads-up that our work likely overlaps. I've formally verified RustCrypto's SHA-256, see my fork, against a literate translation of the FIPS-180-4 spec. Happy to collaborate. Contact: remix7531@mailbox.org.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants