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 add_one_or_zero(n: u32) -> usize {
17    if n == 0 {
18        0
19    } else {
20        n as usize + 1
21    }
22}
23
24#[inline(always)]
25pub fn transmute_field_to_u32<F: PrimeField32>(field: &F) -> u32 {
26    debug_assert_eq!(
27        std::mem::size_of::<F>(),
28        std::mem::size_of::<u32>(),
29        "Field type F must have the same size as u32"
30    );
31    debug_assert_eq!(
32        std::mem::align_of::<F>(),
33        std::mem::align_of::<u32>(),
34        "Field type F must have the same alignment as u32"
35    );
36    // SAFETY: This assumes that F has the same memory layout as u32.
37    // This is only safe for field types that are guaranteed to be represented
38    // as a single u32 internally
39    unsafe { *(field as *const F as *const u32) }
40}
41
42#[inline(always)]
43pub fn transmute_u32_to_field<F: PrimeField32>(value: &u32) -> F {
44    debug_assert_eq!(
45        std::mem::size_of::<F>(),
46        std::mem::size_of::<u32>(),
47        "Field type F must have the same size as u32"
48    );
49    debug_assert_eq!(
50        std::mem::align_of::<F>(),
51        std::mem::align_of::<u32>(),
52        "Field type F must have the same alignment as u32"
53    );
54    // SAFETY: This assumes that F has the same memory layout as u32.
55    // This is only safe for field types that are guaranteed to be represented
56    // as a single u32 internally
57    unsafe { *(value as *const u32 as *const F) }
58}
59
60/// # Safety
61/// The type `T` should be plain old data so there is no worry about [Drop] behavior in the
62/// transmutation.
63#[inline(always)]
64pub unsafe fn slice_as_bytes<T>(slice: &[T]) -> &[u8] {
65    let len = size_of_val(slice);
66    // SAFETY: length and alignment are correct.
67    unsafe { std::slice::from_raw_parts(slice.as_ptr() as *const u8, len) }
68}