1use crate::{RandomXCache, RandomXDataset, RandomXFlag, RandomXVM};
24
25#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_alloc_cache(data: Vec<u8>) -> bool {
32 let flags = if data.is_empty() {
33 RandomXFlag::default()
34 } else {
35 match data[0] % 10 {
36 0 => RandomXFlag::get_recommended_flags(),
37 1 => RandomXFlag::FLAG_DEFAULT,
38 2 => RandomXFlag::FLAG_LARGE_PAGES,
39 3 => RandomXFlag::FLAG_HARD_AES,
40 4 => RandomXFlag::FLAG_FULL_MEM,
41 5 => RandomXFlag::FLAG_JIT,
42 6 => RandomXFlag::FLAG_SECURE,
43 7 => RandomXFlag::FLAG_ARGON2_SSSE3,
44 8 => RandomXFlag::FLAG_ARGON2_AVX2,
45 _ => RandomXFlag::FLAG_ARGON2,
46 }
47 };
48 let _unused = RandomXCache::new(flags, &data);
49 true
50}
51
52#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_create_vm_with_cache_only(data: Vec<u8>) -> bool {
63 let flags = RandomXFlag::get_recommended_flags();
64 if let Ok(cache) = RandomXCache::new(flags, &data) {
65 if let Ok(mut vm) = RandomXVM::new(flags, Some(cache.clone()), None) {
66 let _unused = vm.reinit_cache(cache);
67 }
68 }
69 true
70}
71
72#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_create_vm_with_cache_and_dataset(data: Vec<u8>) -> bool {
89 let flags = RandomXFlag::get_recommended_flags();
90 if let Ok(cache) = RandomXCache::new(flags, &data) {
91 let start = if data.is_empty() { 0u32 } else { u32::from(data[0] % 3) };
92 if let Ok(dataset) = RandomXDataset::new(flags, cache.clone(), start) {
93 for _ in 0..100 {
94 let _unused = dataset.get_data();
95 }
96 if let Ok(mut vm) = RandomXVM::new(flags, Some(cache.clone()), Some(dataset.clone())) {
97 let _unused = vm.reinit_cache(cache);
98 let _unused = vm.reinit_dataset(dataset);
99 }
100 }
101 }
102 true
103}
104
105fn calculate_hashes(hash_data: &[u8], vm: &mut RandomXVM, iterations: u8) {
107 let mut hash_data = hash_data.to_vec();
108 for _ in 0..iterations {
109 if hash_data.len() > 1 {
110 let hash_set_len = 12;
112 let mut hash_set = Vec::with_capacity(hash_set_len);
113 for _ in 0..hash_set_len {
114 let mut scratch_data = hash_data.clone();
115 let last = scratch_data.pop().unwrap();
116 scratch_data.insert(0, last);
117 hash_set.push(scratch_data);
118 }
119 let hash_set_ref = hash_set.iter().map(|v| v.as_slice()).collect::<Vec<&[u8]>>();
120 let _unused = vm.calculate_hash(&hash_data);
122 let _unused = vm.calculate_hash_set(&hash_set_ref);
123 hash_data.pop();
125 } else {
126 let _unused = vm.calculate_hash(&hash_data);
127 let _unused = vm.calculate_hash_set(&[&hash_data]);
128 }
129 }
130}
131
132#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_vm_calculate_hash_with_cache_only(data: Vec<u8>) -> bool {
146 let flags = RandomXFlag::get_recommended_flags();
147 if let Ok(cache) = RandomXCache::new(flags, &data) {
148 let vm = RandomXVM::new(flags, Some(cache), None);
149 if let Ok(mut vm) = vm {
150 calculate_hashes(&data, &mut vm, 100);
151 }
152 }
153 true
154}
155
156#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_vm_calculate_hash_with_cache_and_dataset(data: Vec<u8>) -> bool {
175 let flags = RandomXFlag::get_recommended_flags();
176 if let Ok(cache) = RandomXCache::new(flags, &data) {
177 if let Ok(dataset) = RandomXDataset::new(flags, cache.clone(), 0) {
178 let vm = RandomXVM::new(flags, Some(cache), Some(dataset.clone()));
179 if let Ok(mut vm) = vm {
180 calculate_hashes(&data, &mut vm, 100);
181 }
182 }
183 }
184 true
185}
186
187#[cfg(test)]
188mod tests {
189 use quickcheck::QuickCheck;
190
191 use crate::test_utils::{
192 fuzz_randomx_alloc_cache,
193 fuzz_randomx_create_vm_with_cache_and_dataset,
194 fuzz_randomx_create_vm_with_cache_only,
195 fuzz_randomx_vm_calculate_hash_with_cache_and_dataset,
196 fuzz_randomx_vm_calculate_hash_with_cache_only,
197 };
198
199 #[test]
200 fn test_fuzz_lib_alloc_cache() {
201 fuzz_randomx_alloc_cache(vec![]);
202 const TESTS: u64 = 25;
203 QuickCheck::new()
204 .min_tests_passed(TESTS)
205 .tests(TESTS)
206 .max_tests(TESTS)
207 .quickcheck(fuzz_randomx_alloc_cache as fn(Vec<u8>) -> bool);
208 }
209
210 #[test]
211 fn test_fuzz_randomx_create_vm_with_cache_only() {
212 fuzz_randomx_create_vm_with_cache_only(vec![]);
213 const TESTS: u64 = 25;
214 QuickCheck::new()
215 .min_tests_passed(TESTS)
216 .tests(TESTS)
217 .max_tests(TESTS)
218 .quickcheck(fuzz_randomx_create_vm_with_cache_only as fn(Vec<u8>) -> bool);
219 }
220
221 #[test]
222 fn test_fuzz_randomx_create_vm_with_cache_and_dataset() {
223 fuzz_randomx_create_vm_with_cache_and_dataset(vec![]);
224 const TESTS: u64 = 1;
225 QuickCheck::new()
226 .min_tests_passed(TESTS)
227 .tests(TESTS)
228 .max_tests(TESTS)
229 .quickcheck(fuzz_randomx_create_vm_with_cache_and_dataset as fn(Vec<u8>) -> bool);
230 }
231
232 #[test]
233 fn test_fuzz_randomx_vm_calculate_hash_with_cache_only() {
234 fuzz_randomx_vm_calculate_hash_with_cache_only(vec![]);
235 const TESTS: u64 = 3;
236 QuickCheck::new()
237 .min_tests_passed(TESTS)
238 .tests(TESTS)
239 .max_tests(TESTS)
240 .quickcheck(fuzz_randomx_vm_calculate_hash_with_cache_only as fn(Vec<u8>) -> bool);
241 }
242
243 #[test]
244 fn test_fuzz_randomx_vm_calculate_hash_with_cache_and_dataset() {
245 fuzz_randomx_vm_calculate_hash_with_cache_and_dataset(vec![]);
246 const TESTS: u64 = 1;
247 QuickCheck::new()
248 .min_tests_passed(TESTS)
249 .tests(TESTS)
250 .max_tests(TESTS)
251 .quickcheck(fuzz_randomx_vm_calculate_hash_with_cache_and_dataset as fn(Vec<u8>) -> bool);
252 }
253}