sp1_core_machine/utils/
mod.rs1pub mod concurrency;
2mod logger;
3mod prove;
4mod span;
5#[cfg(test)]
6mod test;
7mod zerocheck_unit_test;
8
9pub use logger::*;
10pub use prove::*;
11use slop_algebra::{AbstractField, Field};
12pub use span::*;
13#[cfg(test)]
14pub use test::*;
15pub use zerocheck_unit_test::*;
16
17use sp1_hypercube::{air::SP1AirBuilder, Word};
18pub use sp1_primitives::consts::{
19 bytes_to_words_le, bytes_to_words_le_vec, num_to_comma_separated, words_to_bytes_le,
20 words_to_bytes_le_vec,
21};
22use sp1_primitives::{consts::WORD_BYTE_SIZE, utils::reverse_bits_len};
23
24pub use sp1_hypercube::{indices_arr, next_multiple_of_32, pad_rows_fixed};
25
26pub fn limbs_to_words<AB: SP1AirBuilder>(limbs: Vec<AB::Var>) -> Vec<Word<AB::Expr>> {
27 let base = AB::Expr::from_canonical_u32(1 << 8);
28 let result_words: Vec<Word<AB::Expr>> = limbs
29 .chunks_exact(WORD_BYTE_SIZE)
30 .map(|l| {
31 Word([
32 l[0] + l[1] * base.clone(),
33 l[2] + l[3] * base.clone(),
34 l[4] + l[5] * base.clone(),
35 l[6] + l[7] * base.clone(),
36 ])
37 })
38 .collect();
39 result_words
40}
41
42pub fn u32_to_half_word<F: Field>(value: u32) -> [F; 2] {
43 [F::from_canonical_u16((value & 0xFFFF) as u16), F::from_canonical_u16((value >> 16) as u16)]
44}
45
46#[inline]
47pub fn log2_strict_usize(n: usize) -> usize {
48 let res = n.trailing_zeros();
49 assert_eq!(n.wrapping_shr(res), 1, "Not a power of two: {n}");
50 res as usize
51}
52
53pub fn zeroed_f_vec<F: Field>(len: usize) -> Vec<F> {
58 debug_assert!(std::mem::size_of::<F>() == 4);
59
60 let vec = vec![0u32; len];
61 unsafe { std::mem::transmute::<Vec<u32>, Vec<F>>(vec) }
62}
63
64pub fn reverse_slice_index_bits<T>(slice: &mut [T]) {
69 let n = slice.len();
70 assert!(n.is_power_of_two(), "Slice length must be a power of two");
71 let log_n = log2_strict_usize(n);
72
73 for i in 0..n {
74 let j = reverse_bits_len(i, log_n);
75 if i < j {
76 slice.swap(i, j);
77 }
78 }
79}