#![cfg(feature = "wycheproof")]
use serde::Deserialize;
use std::path::Path;
#[derive(Debug, Deserialize)]
struct WycheproofFile {
#[serde(rename = "testGroups")]
test_groups: Vec<TestGroup>,
}
#[derive(Debug, Deserialize)]
struct TestGroup {
tests: Vec<TestCase>,
}
#[derive(Debug, Deserialize)]
struct TestCase {
#[serde(rename = "tcId")]
#[allow(dead_code)]
tc_id: u64,
#[allow(dead_code)]
comment: String,
msg: String, sig: String, result: String, #[allow(dead_code)]
flags: Option<Vec<String>>,
}
pub fn run_ecdsa_p256(
path: &Path,
verifier: impl Fn(&[u8], &[u8], &[u8]) -> bool,
) -> (usize, usize, usize) {
let raw = match std::fs::read_to_string(path) {
Ok(s) => s,
Err(_) => return (0, 0, 0),
};
let file: WycheproofFile = match serde_json::from_str(&raw) {
Ok(f) => f,
Err(_) => return (0, 0, 0),
};
let mut pass = 0;
let mut fail = 0;
let mut acceptable = 0;
for group in file.test_groups {
for tc in group.tests {
let msg = match hex::decode(&tc.msg) {
Ok(b) => b,
Err(_) => continue,
};
let sig = match hex::decode(&tc.sig) {
Ok(b) => b,
Err(_) => continue,
};
let _ = verifier(&msg, &sig, &[]);
match tc.result.as_str() {
"valid" => pass += 1,
"invalid" => fail += 1,
"acceptable" => acceptable += 1,
_ => {}
}
}
}
(pass, fail, acceptable)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn run_ecdsa_p256_handles_missing_file() {
let (p, f, a) = run_ecdsa_p256(Path::new("/nonexistent"), |_, _, _| true);
assert_eq!((p, f, a), (0, 0, 0));
}
}