use crate::collections::{slice_fast_zeroize, vec_fast_zeroize};
use crate::traits::{FastZeroizable, ZeroizationProbe, ZeroizeMetadata};
const SIZE: usize = (u16::MAX / 4) as usize;
#[derive(Clone)]
struct ComplexType {
data: u64,
}
impl ComplexType {
fn new(data: u64) -> Self {
Self { data }
}
}
impl ZeroizeMetadata for ComplexType {
const CAN_BE_BULK_ZEROIZED: bool = false;
}
impl FastZeroizable for ComplexType {
fn fast_zeroize(&mut self) {
self.data = 0;
}
}
impl ZeroizationProbe for ComplexType {
fn is_zeroized(&self) -> bool {
self.data == 0
}
}
#[test]
fn test_slice() {
let mut slice = [u8::MAX; SIZE];
let slice = slice.as_mut_slice();
assert!(!slice.is_zeroized());
for i in 0..SIZE - 1 {
slice[i].fast_zeroize();
assert!(!slice.is_zeroized());
}
slice.fast_zeroize();
assert!(slice.is_zeroized());
assert!(redoubt_util::is_slice_zeroized(slice));
}
#[test]
fn test_slice_fast_zeroize_fast_true() {
let mut arr = [
ComplexType::new(100),
ComplexType::new(200),
ComplexType::new(300),
];
assert!(!arr.is_zeroized());
slice_fast_zeroize(arr.as_mut_slice(), true);
assert!(arr.is_zeroized());
}
#[test]
fn test_slice_fast_zeroize_fast_false() {
let mut arr = [
ComplexType::new(100),
ComplexType::new(200),
ComplexType::new(300),
];
assert!(!arr.is_zeroized());
slice_fast_zeroize(&mut arr, false);
assert!(arr.is_zeroized());
}
#[test]
fn test_array() {
let mut array = [u8::MAX; SIZE];
assert!(!array.is_zeroized());
for i in 0..SIZE - 1 {
array[i].fast_zeroize();
assert!(!array.is_zeroized());
}
array.fast_zeroize();
assert!(array.is_zeroized());
assert!(redoubt_util::is_slice_zeroized(&array));
}
#[test]
fn test_vec() {
let mut vec = Vec::<u8>::new();
vec.resize_with(SIZE, || u8::MAX);
assert!(!vec.is_zeroized());
for i in 0..SIZE - 1 {
vec[i].fast_zeroize();
assert!(!vec.is_zeroized());
}
vec.fast_zeroize();
assert!(vec.is_zeroized());
assert!(redoubt_util::is_vec_fully_zeroized(&vec));
}
#[test]
fn test_vec_fast_zeroize_fast_true() {
let mut vec = vec![
ComplexType::new(100),
ComplexType::new(200),
ComplexType::new(300),
];
vec.reserve(10);
assert!(!vec.is_zeroized());
vec_fast_zeroize(&mut vec, true);
assert!(vec.is_zeroized());
}
#[test]
fn test_vec_fast_zeroize_fast_false() {
let mut vec = vec![
ComplexType::new(100),
ComplexType::new(200),
ComplexType::new(300),
];
vec.reserve(10);
assert!(!vec.is_zeroized());
vec_fast_zeroize(&mut vec, false);
assert!(vec.is_zeroized());
}
#[test]
fn test_vec_spare_capacity_recursive_zeroize() {
let mut vec = vec![
vec![ComplexType::new(100)],
vec![ComplexType::new(200), ComplexType::new(300)],
vec![
ComplexType::new(400),
ComplexType::new(500),
ComplexType::new(600),
],
];
assert!(!vec.is_zeroized());
vec.fast_zeroize();
assert!(vec.is_zeroized());
}
#[test]
fn test_string() {
let mut s = "A".repeat(SIZE);
assert!(!s.is_zeroized());
s.fast_zeroize();
assert!(s.is_zeroized());
assert!(redoubt_util::is_slice_zeroized(s.as_bytes()));
}