From 305bad5a0067712634089e2aa948aaf1f75bd023 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 15 Oct 2025 16:35:28 -0700 Subject: [PATCH] ecdsa: re-export blobby (#1082) Re-exporting blobby directly from ecdsa makes version upgrades a tiny bit more resilient to API changes made in blobby. They otherwise have to be carefully managed between ecdsa and its dependencies. If the binary format changes between the blobby upgrade, the blob files will still need to be updated to match. --- Cargo.lock | 7 ++ ecdsa/Cargo.toml | 2 +- ecdsa/src/dev.rs | 70 ++++++++++++++---- .../src/test_vectors/data/wycheproof-mock.blb | Bin 0 -> 2 bytes 4 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 ecdsa/src/test_vectors/data/wycheproof-mock.blb diff --git a/Cargo.lock b/Cargo.lock index 0eb256c..a7d430c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,6 +82,12 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +[[package]] +name = "blobby" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89af0b093cc13baa4e51e64e65ec2422f7e73aea0e612e5ad3872986671622f1" + [[package]] name = "block-buffer" version = "0.11.0-rc.5" @@ -323,6 +329,7 @@ version = "0.11.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6749b668519cd7149ee3d11286a442a8a8bdc3a9d529605f579777bfccc5a4bc" dependencies = [ + "blobby", "block-buffer", "const-oid", "crypto-common", diff --git a/ecdsa/Cargo.toml b/ecdsa/Cargo.toml index 9ee2010..68afb06 100644 --- a/ecdsa/Cargo.toml +++ b/ecdsa/Cargo.toml @@ -40,7 +40,7 @@ alloc = ["elliptic-curve/alloc", "signature/alloc", "spki/alloc"] std = ["alloc", "elliptic-curve/std"] algorithm = ["dep:rfc6979", "digest", "elliptic-curve/arithmetic", "hazmat"] -dev = ["algorithm", "elliptic-curve/dev"] +dev = ["algorithm", "digest/dev", "elliptic-curve/dev"] der = ["dep:der"] digest = ["dep:digest", "elliptic-curve/digest", "signature/digest"] hazmat = [] diff --git a/ecdsa/src/dev.rs b/ecdsa/src/dev.rs index e700a25..7a6c4b2 100644 --- a/ecdsa/src/dev.rs +++ b/ecdsa/src/dev.rs @@ -6,6 +6,8 @@ use crate::EcdsaCurve; use elliptic_curve::dev::MockCurve; +pub use digest::dev::blobby; + impl EcdsaCurve for MockCurve { const NORMALIZE_S: bool = false; } @@ -148,14 +150,13 @@ macro_rules! new_wycheproof_test { ($name:ident, $test_name: expr, $curve:path) => { use $crate::{ Signature, - elliptic_curve::{bigint::Integer, sec1::EncodedPoint}, + elliptic_curve::sec1::EncodedPoint, signature::Verifier, }; #[test] fn $name() { - use blobby::Blob5Iterator; - use elliptic_curve::{array::typenum::Unsigned, bigint::Encoding as _}; + use $crate::elliptic_curve::{self, array::typenum::Unsigned}; // Build a field element but allow for too-short input (left pad with zeros) // or too-long input (check excess leftmost bytes are zeros). @@ -208,16 +209,48 @@ macro_rules! new_wycheproof_test { } } - let data = include_bytes!(concat!("test_vectors/data/", $test_name, ".blb")); + #[derive(Debug,Clone,Copy)] + struct TestVector { + /// X coordinates of the public key + pub wx: &'static [u8], + /// Y coordinates of the public key + pub wy: &'static [u8], + /// Payload to verify + pub msg: &'static [u8], + /// Der encoding of the signature + pub sig: &'static [u8], + /// Whether the signature should verify (`[1]`) or fail (`[0]`) + pub pass_: &'static [u8], + } - for (i, row) in Blob5Iterator::new(data).unwrap().enumerate() { - let [wx, wy, msg, sig, status] = row.unwrap(); - let pass = match status[0] { - 0 => false, - 1 => true, - _ => panic!("invalid value for pass flag"), - }; - if let Some(desc) = run_test(wx, wy, msg, sig, pass) { + impl TestVector { + pub fn pass(&self) -> bool { + match self.pass_ { + &[0] => false, + &[1] => true, + other => panic!( + concat!( + "Unsupported value for pass in `", + $test_name, + "`.\n", + "found=`{other:?}`,\n", + "expected=[0] or [1]" + ), + other=other + ), + } + } + } + + $crate::dev::blobby::parse_into_structs!( + include_bytes!(concat!("test_vectors/data/", $test_name, ".blb")); + static TEST_VECTORS: &[ + TestVector { wx, wy, msg, sig, pass_ } + ]; + ); + + for (i, tv) in TEST_VECTORS.iter().enumerate() { + if let Some(desc) = run_test(tv.wx, tv.wy, tv.msg, tv.sig, tv.pass()) { panic!( "\n\ Failed test №{}: {}\n\ @@ -226,10 +259,21 @@ macro_rules! new_wycheproof_test { msg:\t{:?}\n\ sig:\t{:?}\n\ pass:\t{}\n", - i, desc, wx, wy, msg, sig, pass, + i, desc, tv.wx, tv.wy, tv.msg, tv.sig, tv.pass(), ); } } } }; } + +#[cfg(test)] +mod tests { + use super::*; + + impl crate::hazmat::DigestAlgorithm for MockCurve { + type Digest = sha2::Sha256; + } + + new_wycheproof_test!(wycheproof_mock, "wycheproof-mock", MockCurve); +} diff --git a/ecdsa/src/test_vectors/data/wycheproof-mock.blb b/ecdsa/src/test_vectors/data/wycheproof-mock.blb new file mode 100644 index 0000000000000000000000000000000000000000..09f370e38f498a462e1ca0faa724559b6630c04f GIT binary patch literal 2 JcmZQz0000200961 literal 0 HcmV?d00001