use crate::{RandomXCache, RandomXDataset, RandomXFlag, RandomXVM};
#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_alloc_cache(data: Vec<u8>) -> bool {
let flags = if data.is_empty() {
RandomXFlag::default()
} else {
match data[0] % 10 {
0 => RandomXFlag::get_recommended_flags(),
1 => RandomXFlag::FLAG_DEFAULT,
2 => RandomXFlag::FLAG_LARGE_PAGES,
3 => RandomXFlag::FLAG_HARD_AES,
4 => RandomXFlag::FLAG_FULL_MEM,
5 => RandomXFlag::FLAG_JIT,
6 => RandomXFlag::FLAG_SECURE,
7 => RandomXFlag::FLAG_ARGON2_SSSE3,
8 => RandomXFlag::FLAG_ARGON2_AVX2,
_ => RandomXFlag::FLAG_ARGON2,
}
};
let _unused = RandomXCache::new(flags, &data);
true
}
#[allow(clippy::needless_pass_by_value)]
pub fn fuzz_randomx_create_vm_with_cache_only(data: Vec<u8>) -> bool {
let flags = RandomXFlag::get_recommended_flags();
if let Ok(cache) = RandomXCache::new(flags, &data) {
if let Ok(mut vm) = RandomXVM::new(flags, Some(cache.clone()), None) {
let _unused = vm.reinit_cache(cache);
}
}
true
}
#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_create_vm_with_cache_and_dataset(data: Vec<u8>) -> bool {
let flags = RandomXFlag::get_recommended_flags();
if let Ok(cache) = RandomXCache::new(flags, &data) {
let start = if data.is_empty() { 0u32 } else { u32::from(data[0] % 3) };
if let Ok(dataset) = RandomXDataset::new(flags, cache.clone(), start) {
let _unused = dataset.get_data();
if let Ok(mut vm) = RandomXVM::new(flags, Some(cache.clone()), Some(dataset.clone())) {
let _unused = vm.reinit_cache(cache);
let _unused = vm.reinit_dataset(dataset);
}
}
}
true
}
fn calculate_hashes(hash_data: &[u8], vm: &mut RandomXVM, iterations: u8) {
let mut hash_data = hash_data.to_vec();
for _ in 0..iterations {
if hash_data.len() > 1 {
let hash_set_len = 12;
let mut hash_set = Vec::with_capacity(hash_set_len);
for _ in 0..hash_set_len {
let mut scratch_data = hash_data.clone();
let last = scratch_data.pop().unwrap();
scratch_data.insert(0, last);
hash_set.push(scratch_data);
}
let hash_set_ref = hash_set.iter().map(|v| v.as_slice()).collect::<Vec<&[u8]>>();
let _unused = vm.calculate_hash(&hash_data);
let _unused = vm.calculate_hash_set(&hash_set_ref);
hash_data.pop();
} else {
let _unused = vm.calculate_hash(&hash_data);
let _unused = vm.calculate_hash_set(&[&hash_data]);
}
}
}
#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_vm_calculate_hash_with_cache_only(data: Vec<u8>) -> bool {
let flags = RandomXFlag::get_recommended_flags();
if let Ok(cache) = RandomXCache::new(flags, &data) {
let vm = RandomXVM::new(flags, Some(cache), None);
if let Ok(mut vm) = vm {
calculate_hashes(&data, &mut vm, 100);
}
}
true
}
#[allow(clippy::needless_pass_by_value)] pub fn fuzz_randomx_vm_calculate_hash_with_cache_and_dataset(data: Vec<u8>) -> bool {
let flags = RandomXFlag::get_recommended_flags();
if let Ok(cache) = RandomXCache::new(flags, &data) {
if let Ok(dataset) = RandomXDataset::new(flags, cache.clone(), 0) {
let vm = RandomXVM::new(flags, Some(cache), Some(dataset.clone()));
if let Ok(mut vm) = vm {
calculate_hashes(&data, &mut vm, 100);
}
}
}
true
}
#[cfg(test)]
mod tests {
use quickcheck::QuickCheck;
use crate::test_utils::{
fuzz_randomx_alloc_cache,
fuzz_randomx_create_vm_with_cache_and_dataset,
fuzz_randomx_create_vm_with_cache_only,
fuzz_randomx_vm_calculate_hash_with_cache_and_dataset,
fuzz_randomx_vm_calculate_hash_with_cache_only,
};
#[test]
fn test_fuzz_lib_alloc_cache() {
fuzz_randomx_alloc_cache(vec![]);
const TESTS: u64 = 25;
QuickCheck::new()
.min_tests_passed(TESTS)
.tests(TESTS)
.max_tests(TESTS)
.quickcheck(fuzz_randomx_alloc_cache as fn(Vec<u8>) -> bool);
}
#[test]
fn test_fuzz_randomx_create_vm_with_cache_only() {
fuzz_randomx_create_vm_with_cache_only(vec![]);
const TESTS: u64 = 25;
QuickCheck::new()
.min_tests_passed(TESTS)
.tests(TESTS)
.max_tests(TESTS)
.quickcheck(fuzz_randomx_create_vm_with_cache_only as fn(Vec<u8>) -> bool);
}
#[test]
fn test_fuzz_randomx_create_vm_with_cache_and_dataset() {
fuzz_randomx_create_vm_with_cache_and_dataset(vec![]);
const TESTS: u64 = 1;
QuickCheck::new()
.min_tests_passed(TESTS)
.tests(TESTS)
.max_tests(TESTS)
.quickcheck(fuzz_randomx_create_vm_with_cache_and_dataset as fn(Vec<u8>) -> bool);
}
#[test]
fn test_fuzz_randomx_vm_calculate_hash_with_cache_only() {
fuzz_randomx_vm_calculate_hash_with_cache_only(vec![]);
const TESTS: u64 = 3;
QuickCheck::new()
.min_tests_passed(TESTS)
.tests(TESTS)
.max_tests(TESTS)
.quickcheck(fuzz_randomx_vm_calculate_hash_with_cache_only as fn(Vec<u8>) -> bool);
}
#[test]
fn test_fuzz_randomx_vm_calculate_hash_with_cache_and_dataset() {
fuzz_randomx_vm_calculate_hash_with_cache_and_dataset(vec![]);
const TESTS: u64 = 1;
QuickCheck::new()
.min_tests_passed(TESTS)
.tests(TESTS)
.max_tests(TESTS)
.quickcheck(fuzz_randomx_vm_calculate_hash_with_cache_and_dataset as fn(Vec<u8>) -> bool);
}
}