0xMiden / 0xMiden/miden-signature

bug: `flatten_ef`/`unflatten_ef` use unsafe transmute with unverified memory layout assumption

Open
#1 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2
Forks
1
PR merge metrics
No merged PRs in 30d

Description

## Summary

`flatten_ef` and `unflatten_ef` in `src/internal/proof.rs` cast between `&[EF]` and `&[Goldilocks]` via raw pointer transmute, relying on the assumption that `BinomialExtensionField` has the same memory layout as `[Goldilocks; D]`. This assumption is not verified at compile time and is not guaranteed by Rust's type system.

## Code

```rust
fn flatten_ef>(ef_slice: &[EF]) -> &[Goldilocks] {
let len = ef_slice.len() * EF::DIMENSION;
// Safety: relies on BinomialExtensionField being layout-compatible with [Goldilocks; D]
unsafe { core::slice::from_raw_parts(ef_slice.as_ptr() as *const Goldilocks, len) }
}

fn unflatten_ef>(base_slice: &[Goldilocks]) -> &[EF] {
let len = base_slice.len() / EF::DIMENSION;
unsafe { core::slice::from_raw_parts(base_slice.as_ptr() as *const EF, len) }
}
```

## Why this is unsound

In Rust, `repr(transparent)` only applies to single-field newtype structs. A struct wrapping `[F; D]` can have additional padding or alignment requirements (e.g. from `PhantomData` fields) that differ from `[Goldilocks; D]`. Without a compile-time layout assertion, this is unsound undefined behavior if the layouts differ by even one byte.

These functions are called on every `sign` and `verify` invocation.

## Suggested fix

Use `bytemuck` with a compile-time `Pod` + `Zeroable` bound and a `cast_slice` call, which enforces layout compatibility at compile time:

```rust
fn flatten_ef>(ef_slice: &[EF]) -> &[Goldilocks] {
bytemuck::cast_slice(ef_slice)
}
```

Or add an explicit compile-time size assertion:

```rust
const _: () = assert!(
core::mem::size_of::>()
== core::mem::size_of::<[Goldilocks; 2]>()
);
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.