timing_test!() { /* proc-macro */ }Expand description
Create a timing test that returns Outcome for pattern matching.
This macro provides a declarative syntax for timing tests that prevents
common mistakes through compile-time checks. Returns Outcome which can be
Pass, Fail, Inconclusive, or Unmeasurable.
§Returns
Returns Outcome which is one of:
Outcome::Pass { leak_probability, effect, samples_used, quality, diagnostics }Outcome::Fail { leak_probability, effect, exploitability, samples_used, quality, diagnostics }Outcome::Inconclusive { reason, leak_probability, effect, samples_used, quality, diagnostics }Outcome::Unmeasurable { operation_ns, timer_resolution_ns, platform, recommendation }
§Syntax
ⓘ
timing_test! {
// Optional: custom oracle configuration (defaults to AdjacentNetwork attacker model)
oracle: TimingOracle::for_attacker(AttackerModel::AdjacentNetwork),
// Required: baseline input generator (closure returning the fixed/baseline value)
baseline: || [0u8; 32],
// Required: sample input generator (closure returning random values)
sample: || rand::random::<[u8; 32]>(),
// Required: measurement body (closure that receives input and performs the operation)
measure: |input| {
encrypt(&input);
},
}§Example
ⓘ
use tacet::{timing_test, Outcome};
fn main() {
let outcome = timing_test! {
baseline: || [0u8; 32],
sample: || rand::random::<[u8; 32]>(),
measure: |input| {
let _ = std::hint::black_box(&input);
},
};
match outcome {
Outcome::Pass { leak_probability, .. } => {
println!("No leak detected (P={:.1}%)", leak_probability * 100.0);
}
Outcome::Fail { leak_probability, exploitability, .. } => {
println!("Leak detected! P={:.1}%, {:?}", leak_probability * 100.0, exploitability);
}
Outcome::Inconclusive { reason, .. } => {
println!("Inconclusive: {:?}", reason);
}
Outcome::Unmeasurable { recommendation, .. } => {
println!("Operation too fast: {}", recommendation);
}
}
}