Skip to main content

sp1_hypercube/
util.rs

1use slop_algebra::AbstractField;
2use sp1_primitives::{poseidon2_init, SP1Perm};
3
4/// The digest size.
5pub const DIGEST_SIZE: usize = 8;
6
7/// Compute the ceiling of the base-2 logarithm of a number.
8#[must_use]
9pub fn log2_ceil_usize(n: usize) -> usize {
10    // println!("n: {}", n);
11    n.next_power_of_two().ilog2() as usize
12}
13
14/// Get the inner perm
15#[must_use]
16pub fn inner_perm() -> SP1Perm {
17    poseidon2_init()
18}
19
20/// Get an array `xs` such that `xs[i] = i`.
21#[must_use]
22pub const fn indices_arr<const N: usize>() -> [usize; N] {
23    let mut indices_arr = [0; N];
24    let mut i = 0;
25    while i < N {
26        indices_arr[i] = i;
27        i += 1;
28    }
29    indices_arr
30}
31
32/// Pad to the next multiple of 32, with an option to specify the fixed height.
33//
34// The `rows` argument represents the rows of a matrix stored in row-major order. The function will
35// pad the rows using `row_fn` to create the padded rows. The padding will be to the next multiple
36// of 32 if `height` is `None`, or to the specified `height` if it is not `None`. The
37// function will panic of the number of rows is larger than the specified `height`.
38pub fn pad_rows_fixed<R: Clone>(rows: &mut Vec<R>, row_fn: impl Fn() -> R, height: Option<usize>) {
39    let nb_rows = rows.len();
40    let dummy_row = row_fn();
41    rows.resize(next_multiple_of_32(nb_rows, height), dummy_row);
42}
43
44/// Returns the internal value of the option if it is set, otherwise returns the next multiple of
45/// 32.
46#[track_caller]
47#[inline]
48#[allow(clippy::uninlined_format_args)]
49#[must_use]
50pub fn next_multiple_of_32(n: usize, fixed_height: Option<usize>) -> usize {
51    if let Some(height) = fixed_height {
52        if n > height {
53            panic!("fixed height is too small: got height {} for number of rows {}", height, n);
54        }
55        height
56    } else {
57        n.next_multiple_of(32).max(16)
58    }
59}
60
61/// Returns a 48-bit address as three u16 limbs.
62#[must_use]
63pub fn addr_to_limbs<F: AbstractField>(addr: u64) -> [F; 3] {
64    [
65        F::from_canonical_u16((addr & 0xFFFF) as u16),
66        F::from_canonical_u16(((addr >> 16) & 0xFFFF) as u16),
67        F::from_canonical_u16(((addr >> 32) & 0xFFFF) as u16),
68    ]
69}