randomx/
lib.rs

1const HASH_SIZE: usize = sys::RANDOMX_HASH_SIZE as usize;
2
3pub struct VM {
4    cache_ptr: *mut sys::randomx_cache,
5    ptr: *mut sys::randomx_vm,
6}
7
8impl VM {
9    pub fn new(key: &[u8]) -> Self {
10        let cache_ptr = unsafe {
11            let ptr = sys::randomx_alloc_cache(sys::randomx_flags_RANDOMX_FLAG_DEFAULT);
12            sys::randomx_init_cache(
13                ptr,
14                key.as_ptr() as *const std::ffi::c_void,
15                key.len()
16            );
17
18            ptr
19        };
20
21        let ptr = unsafe {
22            sys::randomx_create_vm(
23                sys::randomx_flags_RANDOMX_FLAG_DEFAULT,
24                cache_ptr,
25                std::ptr::null_mut()
26            )
27        };
28
29        Self { cache_ptr, ptr }
30    }
31
32    pub fn calculate(&mut self, input: &[u8]) -> [u8; HASH_SIZE] {
33        let ret = [0u8; HASH_SIZE];
34
35        unsafe {
36            sys::randomx_calculate_hash(
37                self.ptr,
38                input.as_ptr() as *const std::ffi::c_void,
39                input.len(),
40                ret.as_ptr() as *mut std::ffi::c_void,
41            );
42        }
43
44        ret
45    }
46}
47
48impl Drop for VM {
49    fn drop(&mut self) {
50        unsafe {
51            sys::randomx_release_cache(self.cache_ptr);
52            sys::randomx_destroy_vm(self.ptr);
53        }
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn should_create_vm() {
63        let mut vm = VM::new(&b"RandomX example key"[..]);
64        let hash = vm.calculate(&b"RandomX example input"[..]);
65        assert_eq!(hash, [210, 164, 216, 149, 3, 68, 116, 1, 239, 110, 111, 48, 180, 102, 53, 180, 91, 84, 242, 90, 101, 12, 71, 70, 75, 83, 17, 249, 214, 253, 71, 89]);
66    }
67}