use std::thread;
use std::time::Duration;
use tacet::helpers::InputPair;
use tacet::{AttackerModel, Outcome, TimingOracle};
#[test]
fn library_is_thread_safe() {
let handles: Vec<_> = (0..4)
.map(|i| {
thread::spawn(move || {
let mut fixed = [0u8; 128];
fixed[0] = i as u8;
let inputs = InputPair::new(
move || fixed,
|| {
let mut arr = [0u8; 128];
for byte in &mut arr {
*byte = rand::random();
}
arr
},
);
let outcome = TimingOracle::for_attacker(AttackerModel::AdjacentNetwork)
.time_budget(Duration::from_secs(10))
.test(inputs, |arr| {
let mut acc = 0u32;
for byte in arr {
acc = acc.wrapping_mul(31).wrapping_add(*byte as u32);
}
std::hint::black_box(acc);
});
matches!(
outcome,
Outcome::Pass { .. }
| Outcome::Fail { .. }
| Outcome::Inconclusive { .. }
| Outcome::Unmeasurable { .. }
)
})
})
.collect();
for handle in handles {
assert!(handle.join().unwrap());
}
}
#[test]
#[ignore] fn library_works_with_many_sequential_calls() {
for i in 0..10 {
let mut fixed = [0u8; 128];
fixed[0] = i as u8;
let inputs = InputPair::new(
move || fixed,
|| {
let mut arr = [0u8; 128];
for byte in &mut arr {
*byte = rand::random();
}
arr
},
);
let outcome = TimingOracle::for_attacker(AttackerModel::AdjacentNetwork)
.time_budget(Duration::from_secs(5))
.test(inputs, |arr| {
let mut acc = 0u32;
for byte in arr {
acc = acc.wrapping_mul(31).wrapping_add(*byte as u32);
}
std::hint::black_box(acc);
});
assert!(matches!(
outcome,
Outcome::Pass { .. }
| Outcome::Fail { .. }
| Outcome::Inconclusive { .. }
| Outcome::Unmeasurable { .. }
));
}
}