openvm_circuit/utils/
mod.rs

1#[cfg(any(test, feature = "test-utils"))]
2mod stark_utils;
3#[cfg(any(test, feature = "test-utils"))]
4pub mod test_utils;
5
6use std::mem::size_of_val;
7
8pub use openvm_circuit_primitives::utils::next_power_of_two_or_zero;
9use openvm_stark_backend::p3_field::PrimeField32;
10#[cfg(any(test, feature = "test-utils"))]
11pub use stark_utils::*;
12#[cfg(any(test, feature = "test-utils"))]
13pub use test_utils::*;
14
15#[inline(always)]
16pub fn transmute_field_to_u32<F: PrimeField32>(field: &F) -> u32 {
17    debug_assert_eq!(
18        std::mem::size_of::<F>(),
19        std::mem::size_of::<u32>(),
20        "Field type F must have the same size as u32"
21    );
22    debug_assert_eq!(
23        std::mem::align_of::<F>(),
24        std::mem::align_of::<u32>(),
25        "Field type F must have the same alignment as u32"
26    );
27    // SAFETY: This assumes that F has the same memory layout as u32.
28    // This is only safe for field types that are guaranteed to be represented
29    // as a single u32 internally
30    unsafe { *(field as *const F as *const u32) }
31}
32
33#[inline(always)]
34pub fn transmute_u32_to_field<F: PrimeField32>(value: &u32) -> F {
35    debug_assert_eq!(
36        std::mem::size_of::<F>(),
37        std::mem::size_of::<u32>(),
38        "Field type F must have the same size as u32"
39    );
40    debug_assert_eq!(
41        std::mem::align_of::<F>(),
42        std::mem::align_of::<u32>(),
43        "Field type F must have the same alignment as u32"
44    );
45    // SAFETY: This assumes that F has the same memory layout as u32.
46    // This is only safe for field types that are guaranteed to be represented
47    // as a single u32 internally
48    unsafe { *(value as *const u32 as *const F) }
49}
50
51/// # Safety
52/// The type `T` should be plain old data so there is no worry about [Drop] behavior in the
53/// transmutation.
54#[inline(always)]
55pub unsafe fn slice_as_bytes<T>(slice: &[T]) -> &[u8] {
56    let len = size_of_val(slice);
57    // SAFETY: length and alignment are correct.
58    unsafe { std::slice::from_raw_parts(slice.as_ptr() as *const u8, len) }
59}