binius_math/
test_utils.rs1use std::iter::repeat_with;
4
5use binius_field::{Field, Ghash128b, PackedField, PackedGhash4x128b};
6use rand::prelude::*;
7
8use crate::FieldBuffer;
9
10pub type B128 = Ghash128b;
12
13pub type Packed128b = PackedGhash4x128b;
15
16pub fn random_scalars<F: Field>(mut rng: impl Rng, n: usize) -> Vec<F> {
27 repeat_with(|| F::random(&mut rng)).take(n).collect()
28}
29
30pub fn random_field_buffer<P: PackedField>(mut rng: impl Rng, log_n: usize) -> FieldBuffer<P> {
41 FieldBuffer::<P>::new(
42 log_n,
43 repeat_with(|| P::random(&mut rng))
44 .take(1 << log_n.saturating_sub(P::LOG_WIDTH))
45 .collect(),
46 )
47}
48
49pub fn index_to_hypercube_point<F: Field>(n_vars: usize, index: usize) -> Vec<F> {
74 debug_assert!(
75 index < (1 << n_vars),
76 "Index {index} out of bounds for {n_vars}-variable hypercube"
77 );
78 (0..n_vars)
79 .map(|i| {
80 if (index >> i) & 1 == 1 {
81 F::ONE
82 } else {
83 F::ZERO
84 }
85 })
86 .collect()
87}
88
89#[cfg(test)]
90mod tests {
91 use binius_field::Ghash128b as B128;
92 use proptest::prelude::*;
93
94 use super::*;
95
96 proptest! {
97 #[test]
98 fn same_seed_produces_identical_results(
99 seed: u64,
100 n in 0..100usize
101 ) {
102 let mut rng1 = StdRng::seed_from_u64(seed);
103 let mut rng2 = StdRng::seed_from_u64(seed);
104
105 let scalars1 = random_scalars::<B128>(&mut rng1, n);
106 let scalars2 = random_scalars::<B128>(&mut rng2, n);
107
108 prop_assert_eq!(scalars1, scalars2);
109 }
110
111 #[test]
112 fn different_seeds_produce_different_results(seed1: u64, seed2: u64) {
113 prop_assume!(seed1 != seed2);
114
115 let n = 10;
117
118 let mut rng1 = StdRng::seed_from_u64(seed1);
119 let mut rng2 = StdRng::seed_from_u64(seed2);
120
121 let scalars1 = random_scalars::<B128>(&mut rng1, n);
122 let scalars2 = random_scalars::<B128>(&mut rng2, n);
123
124 prop_assert_ne!(scalars1, scalars2);
125 }
126 }
127}