Skip to main content

commonware_cryptography/secp256r1/
recoverable.rs

1cfg_if::cfg_if! {
2    if #[cfg(feature = "std")] {
3        use std::borrow::Cow;
4    } else {
5        use alloc::borrow::Cow;
6    }
7}
8use super::common::{
9    impl_private_key_wrapper, impl_public_key_wrapper, PrivateKeyInner, PublicKeyInner, CURVE_NAME,
10    PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH,
11};
12use bytes::{Buf, BufMut};
13use commonware_codec::{Error as CodecError, FixedSize, Read, ReadExt, Write};
14use commonware_formatting::Hex;
15use commonware_utils::{union_unique, Array, Span};
16use core::{
17    fmt::{Debug, Display},
18    hash::{Hash, Hasher},
19    ops::Deref,
20};
21use ecdsa::RecoveryId;
22use p256::{ecdsa::VerifyingKey, elliptic_curve::scalar::IsHigh};
23
24const BASE_SIGNATURE_LENGTH: usize = 64; // R || S
25const SIGNATURE_LENGTH: usize = 1 + BASE_SIGNATURE_LENGTH; // RecoveryId || R || S
26
27/// Secp256r1 Private Key.
28#[derive(Clone, Eq, PartialEq)]
29pub struct PrivateKey(PrivateKeyInner);
30
31impl_private_key_wrapper!(PrivateKey);
32
33impl crate::Signer for PrivateKey {
34    type Signature = Signature;
35    type PublicKey = PublicKey;
36
37    fn sign(&self, namespace: &[u8], msg: &[u8]) -> Self::Signature {
38        self.sign_inner(Some(namespace), msg)
39    }
40
41    fn public_key(&self) -> Self::PublicKey {
42        PublicKey(PublicKeyInner::from_private_key(&self.0))
43    }
44}
45
46impl PrivateKey {
47    #[inline(always)]
48    fn sign_inner(&self, namespace: Option<&[u8]>, msg: &[u8]) -> Signature {
49        let payload = namespace.map_or(Cow::Borrowed(msg), |namespace| {
50            Cow::Owned(union_unique(namespace, msg))
51        });
52        let (mut signature, mut recovery_id) = self
53            .0
54            .key
55            .expose(|key| key.sign_recoverable(&payload))
56            .expect("signing must succeed");
57
58        // The signing algorithm generates k, then calculates r <- x(k * G). Normalizing s by negating it is equivalent
59        // to negating k. This has no effect on x(k * G) but y(-k * G) = -y(k * G), hence the need to flip the bit if
60        // we move s into the lower half of the curve order.
61        if let Some(normalized) = signature.normalize_s() {
62            signature = normalized;
63            recovery_id = RecoveryId::new(!recovery_id.is_y_odd(), recovery_id.is_x_reduced());
64        }
65
66        Signature::new(signature, recovery_id)
67    }
68}
69
70impl From<PrivateKey> for PublicKey {
71    fn from(value: PrivateKey) -> Self {
72        Self(PublicKeyInner::from_private_key(&value.0))
73    }
74}
75
76/// Secp256r1 Public Key.
77#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
78#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
79pub struct PublicKey(PublicKeyInner);
80
81impl_public_key_wrapper!(PublicKey);
82
83impl crate::Verifier for PublicKey {
84    type Signature = Signature;
85
86    fn verify(&self, namespace: &[u8], msg: &[u8], sig: &Self::Signature) -> bool {
87        self.verify_inner(Some(namespace), msg, sig)
88    }
89}
90
91impl PublicKey {
92    #[inline(always)]
93    fn verify_inner(&self, namespace: Option<&[u8]>, msg: &[u8], sig: &Signature) -> bool {
94        let Some(recovered_signer) = sig.recover_signer_inner(namespace, msg) else {
95            return false;
96        };
97        &recovered_signer == self
98    }
99}
100
101/// Secp256r1 Signature with recovery ID.
102#[derive(Clone, Eq, PartialEq)]
103pub struct Signature {
104    raw: [u8; SIGNATURE_LENGTH],
105    recovery_id: RecoveryId,
106    signature: p256::ecdsa::Signature,
107}
108
109impl Signature {
110    fn new(signature: p256::ecdsa::Signature, recovery_id: RecoveryId) -> Self {
111        let mut raw = [0u8; SIGNATURE_LENGTH];
112        raw[0] = recovery_id.to_byte();
113        raw[1..].copy_from_slice(signature.to_bytes().as_slice());
114
115        Self {
116            raw,
117            recovery_id,
118            signature,
119        }
120    }
121}
122
123impl crate::Signature for Signature {}
124
125impl crate::Recoverable for Signature {
126    type PublicKey = PublicKey;
127
128    fn recover_signer(&self, namespace: &[u8], msg: &[u8]) -> Option<Self::PublicKey> {
129        self.recover_signer_inner(Some(namespace), msg)
130    }
131}
132
133impl Signature {
134    #[inline(always)]
135    fn recover_signer_inner(&self, namespace: Option<&[u8]>, msg: &[u8]) -> Option<PublicKey> {
136        let payload = namespace.map_or(Cow::Borrowed(msg), |namespace| {
137            Cow::Owned(union_unique(namespace, msg))
138        });
139
140        VerifyingKey::recover_from_msg(payload.as_ref(), &self.signature, self.recovery_id)
141            .ok()
142            .map(|k| PublicKey(PublicKeyInner::from(k)))
143    }
144}
145
146impl Write for Signature {
147    fn write(&self, buf: &mut impl BufMut) {
148        self.raw.write(buf);
149    }
150}
151
152impl Read for Signature {
153    type Cfg = ();
154
155    fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, CodecError> {
156        let raw = <[u8; Self::SIZE]>::read(buf)?;
157        let recovery_id = RecoveryId::from_byte(raw[0])
158            .ok_or_else(|| CodecError::Invalid(CURVE_NAME, "RecoveryId out of range"))?;
159        let result = p256::ecdsa::Signature::from_slice(&raw[1..]);
160        #[cfg(feature = "std")]
161        let signature = result.map_err(|e| CodecError::Wrapped(CURVE_NAME, e.into()))?;
162        #[cfg(not(feature = "std"))]
163        let signature = result
164            .map_err(|e| CodecError::Wrapped(CURVE_NAME, alloc::format!("{:?}", e).into()))?;
165        // Reject any signatures with a `s` value in the upper half of the curve order.
166        if signature.s().is_high().into() {
167            return Err(CodecError::Invalid(CURVE_NAME, "Signature S is high"));
168        }
169        Ok(Self {
170            raw,
171            signature,
172            recovery_id,
173        })
174    }
175}
176
177impl FixedSize for Signature {
178    const SIZE: usize = SIGNATURE_LENGTH;
179}
180
181impl Span for Signature {}
182
183impl Array for Signature {}
184
185impl Hash for Signature {
186    fn hash<H: Hasher>(&self, state: &mut H) {
187        self.raw.hash(state);
188    }
189}
190
191impl Ord for Signature {
192    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
193        self.raw.cmp(&other.raw)
194    }
195}
196
197impl PartialOrd for Signature {
198    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
199        Some(self.cmp(other))
200    }
201}
202
203impl AsRef<[u8]> for Signature {
204    fn as_ref(&self) -> &[u8] {
205        &self.raw
206    }
207}
208
209impl Deref for Signature {
210    type Target = [u8];
211    fn deref(&self) -> &[u8] {
212        &self.raw
213    }
214}
215
216impl Debug for Signature {
217    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
218        write!(f, "{}", Hex(&self.raw))
219    }
220}
221
222impl Display for Signature {
223    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
224        write!(f, "{}", Hex(&self.raw))
225    }
226}
227
228#[cfg(feature = "arbitrary")]
229impl arbitrary::Arbitrary<'_> for Signature {
230    fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
231        use crate::Signer;
232        use commonware_math::algebra::Random;
233        use rand::{rngs::StdRng, SeedableRng};
234
235        let mut rand = StdRng::from_seed(u.arbitrary::<[u8; 32]>()?);
236        let private_key = PrivateKey(PrivateKeyInner::random(&mut rand));
237        let len = u.arbitrary::<usize>()? % 256;
238        let message = u
239            .arbitrary_iter()?
240            .take(len)
241            .collect::<Result<Vec<_>, _>>()?;
242
243        Ok(private_key.sign(&[], &message))
244    }
245}
246
247#[cfg(test)]
248mod tests {
249    use super::*;
250    use crate::{secp256r1::common::tests::*, Recoverable, Signer as _, Verifier as _};
251    use bytes::Bytes;
252    use commonware_codec::{DecodeExt, Encode};
253    use ecdsa::RecoveryId;
254    use p256::elliptic_curve::scalar::IsHigh;
255    use rstest::rstest;
256
257    const NAMESPACE: &[u8] = b"test-namespace";
258
259    fn encode_signature_with_recovery(
260        verifying_key: &VerifyingKey,
261        message: &[u8],
262        signature: &p256::ecdsa::Signature,
263    ) -> Vec<u8> {
264        let recovery_id = RecoveryId::trial_recovery_from_msg(verifying_key, message, signature)
265            .unwrap_or_else(|_| RecoveryId::new(false, false));
266        Signature::new(*signature, recovery_id).encode().to_vec()
267    }
268
269    #[test]
270    fn test_recover_signer_flipped_y_parity_fails() {
271        let private_key = PrivateKey(create_private_key());
272        let expected_public_key = private_key.public_key();
273        let message = b"recover with no namespace";
274
275        let mut signature = private_key.sign(NAMESPACE, message);
276
277        signature.recovery_id = RecoveryId::new(
278            !signature.recovery_id.is_y_odd(),
279            signature.recovery_id.is_x_reduced(),
280        );
281
282        let recovered = signature.recover_signer(NAMESPACE, message);
283
284        assert_ne!(
285            recovered,
286            Some(expected_public_key),
287            "flipped y-parity must fail recovery"
288        );
289
290        assert!(!private_key
291            .public_key()
292            .verify(NAMESPACE, message, &signature));
293    }
294
295    #[test]
296    fn test_recover_signer_with_namespace() {
297        let private_key = PrivateKey(create_private_key());
298        let expected_public_key = private_key.public_key();
299        let message = b"recover with namespace";
300
301        let signature = private_key.sign(NAMESPACE, message);
302        let recovered = signature.recover_signer(NAMESPACE, message);
303        assert_eq!(recovered, Some(expected_public_key));
304    }
305
306    #[test]
307    fn test_recover_signer_mismatched_message_does_not_match_public_key() {
308        let private_key = PrivateKey(create_private_key());
309        let original_message = b"recover with namespace";
310        let expected_public_key = private_key.public_key();
311        let signature = private_key.sign(NAMESPACE, original_message);
312
313        let recovered = signature.recover_signer(NAMESPACE, b"different message");
314        assert_ne!(
315            recovered,
316            Some(expected_public_key),
317            "mismatched message must not recover the original public key"
318        );
319    }
320
321    #[test]
322    fn test_codec_private_key() {
323        let original = PrivateKey(create_private_key());
324        let encoded = original.encode();
325        assert_eq!(encoded.len(), PRIVATE_KEY_LENGTH);
326
327        let decoded = PrivateKey::decode(encoded).unwrap();
328        assert_eq!(original, decoded);
329    }
330
331    #[test]
332    fn test_codec_public_key() {
333        let private_key = PrivateKey(create_private_key());
334        let original = PublicKey::from(private_key);
335
336        let encoded = original.encode();
337        assert_eq!(encoded.len(), PUBLIC_KEY_LENGTH);
338
339        let decoded = PublicKey::decode(encoded).unwrap();
340        assert_eq!(original, decoded);
341    }
342
343    #[test]
344    fn test_codec_signature() {
345        let private_key = PrivateKey(create_private_key());
346        let original = private_key.sign(NAMESPACE, "Hello World".as_bytes());
347
348        let encoded = original.encode();
349        assert_eq!(encoded.len(), SIGNATURE_LENGTH);
350
351        let decoded = Signature::decode(encoded).unwrap();
352        assert_eq!(original, decoded);
353    }
354
355    #[test]
356    fn test_codec_signature_invalid() {
357        let (_, sig, ..) = vector_sig_verification_5();
358        let result = Signature::decode(Bytes::from(sig));
359        assert!(result.is_err());
360    }
361
362    #[test]
363    fn test_scheme_sign() {
364        let private_key: PrivateKey = PrivateKey::decode(
365            commonware_formatting::from_hex(
366                "519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464",
367            )
368            .unwrap()
369            .as_ref(),
370        )
371        .unwrap();
372        let public_key: PublicKey = private_key.clone().into();
373        let message = commonware_formatting::from_hex(
374            "5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045e
375            e2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf
376            9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8",
377        )
378        .unwrap();
379        let signature = private_key.sign(NAMESPACE, &message);
380        assert_eq!(SIGNATURE_LENGTH, signature.len());
381        assert!(public_key.verify(NAMESPACE, &message, &signature));
382    }
383
384    #[test]
385    fn test_decode_zero_signature_fails() {
386        let result = Signature::decode(vec![0u8; SIGNATURE_LENGTH].as_ref());
387        assert!(result.is_err());
388    }
389
390    #[test]
391    fn test_decode_high_s_signature_fails() {
392        let (inner, _) = vector_keypair_1();
393        let private_key = PrivateKey(inner);
394        let message = b"edge";
395        let signature = private_key.sign(NAMESPACE, message);
396        let mut bad_signature = signature.to_vec();
397        bad_signature[33] |= 0x80;
398        assert!(Signature::decode(bad_signature.as_ref()).is_err());
399    }
400
401    #[test]
402    fn test_decode_zero_r_signature_fails() {
403        let (inner, _) = vector_keypair_1();
404        let private_key = PrivateKey(inner);
405        let message = b"edge";
406        let signature = private_key.sign(NAMESPACE, message);
407        let mut bad_signature = signature.to_vec();
408        for b in bad_signature.iter_mut().skip(1).take(32) {
409            *b = 0x00;
410        }
411        bad_signature[33] = 1;
412        assert!(Signature::decode(bad_signature.as_ref()).is_err());
413    }
414
415    #[test]
416    fn test_rfc6979() {
417        let private_key: PrivateKey = PrivateKey::decode(
418            commonware_formatting::from_hex(
419                "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721",
420            )
421            .unwrap()
422            .as_ref(),
423        )
424        .unwrap();
425
426        let (message, exp_sig) = (
427            b"sample",
428            p256::ecdsa::Signature::from_slice(
429                &commonware_formatting::from_hex(
430                    "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716
431                    f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8",
432                )
433                .unwrap(),
434            )
435            .unwrap(),
436        );
437        let signature = private_key.sign_inner(None, message);
438        assert_eq!(
439            signature.signature.to_bytes().to_vec(),
440            exp_sig.normalize_s().unwrap().to_bytes().to_vec()
441        );
442
443        let (message, exp_sig) = (
444            b"test",
445            p256::ecdsa::Signature::from_slice(
446                &commonware_formatting::from_hex(
447                    "f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d38367
448                    019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083",
449                )
450                .unwrap(),
451            )
452            .unwrap(),
453        );
454
455        let signature = private_key.sign_inner(None, message);
456        assert_eq!(
457            signature.signature.to_bytes().to_vec(),
458            exp_sig.to_bytes().to_vec()
459        );
460    }
461
462    #[test]
463    fn test_scheme_validate_public_key_too_long() {
464        let qx_hex = "d0720dc691aa80096ba32fed1cb97c2b620690d06de0317b8618d5ce65eb728f";
465        let qy_hex = "d0720dc691aa80096ba32fed1cb97c2b620690d06de0317b8618d5ce65eb728f";
466
467        let uncompressed_public_key = parse_public_key_as_uncompressed_vector(qx_hex, qy_hex);
468        let public_key = PublicKey::decode(uncompressed_public_key.as_ref());
469        assert!(matches!(public_key, Err(CodecError::Invalid(_, _))));
470
471        let mut compressed_public_key = parse_public_key_as_compressed_vector(qx_hex, qy_hex);
472        compressed_public_key.push(0u8);
473        let public_key = PublicKey::decode(compressed_public_key.as_ref());
474        assert!(matches!(public_key, Err(CodecError::ExtraData(1))));
475
476        let compressed_public_key = parse_public_key_as_compressed_vector(qx_hex, qy_hex);
477        let public_key = PublicKey::decode(compressed_public_key.as_ref());
478        assert!(public_key.is_ok());
479    }
480
481    #[test]
482    fn test_scheme_verify_signature_r0() {
483        let private_key: PrivateKey = PrivateKey::decode(
484            commonware_formatting::from_hex(
485                "c9806898a0334916c860748880a541f093b579a9b1f32934d86c363c39800357",
486            )
487            .unwrap()
488            .as_ref(),
489        )
490        .unwrap();
491        let message = b"sample";
492        let signature = private_key.sign(NAMESPACE, message);
493        let mut signature = signature.to_vec();
494        signature[1..33].fill(0);
495
496        assert!(Signature::decode(signature.as_ref()).is_err());
497    }
498
499    #[test]
500    fn test_scheme_verify_signature_s0() {
501        let private_key: PrivateKey = PrivateKey::decode(
502            commonware_formatting::from_hex(
503                "c9806898a0334916c860748880a541f093b579a9b1f32934d86c363c39800357",
504            )
505            .unwrap()
506            .as_ref(),
507        )
508        .unwrap();
509        let message = b"sample";
510        let signature = private_key.sign(NAMESPACE, message);
511        let mut signature = signature.to_vec();
512        signature[33..].fill(0);
513
514        assert!(Signature::decode(signature.as_ref()).is_err());
515    }
516
517    #[rstest]
518    #[case(vector_keypair_1())]
519    #[case(vector_keypair_2())]
520    #[case(vector_keypair_3())]
521    #[case(vector_keypair_4())]
522    #[case(vector_keypair_5())]
523    #[case(vector_keypair_6())]
524    #[case(vector_keypair_7())]
525    #[case(vector_keypair_8())]
526    #[case(vector_keypair_9())]
527    #[case(vector_keypair_10())]
528    fn test_keypairs(#[case] (inner_priv, inner_pub): (PrivateKeyInner, PublicKeyInner)) {
529        let private_key = PrivateKey(inner_priv);
530        let public_key = PublicKey::from(private_key);
531        let exp_public_key = PublicKey(inner_pub);
532        assert_eq!(exp_public_key, public_key);
533        assert!(public_key.len() == PUBLIC_KEY_LENGTH);
534    }
535
536    #[rstest]
537    #[case(1, vector_public_key_validation_1())]
538    #[case(3, vector_public_key_validation_3())]
539    #[case(4, vector_public_key_validation_4())]
540    #[case(5, vector_public_key_validation_5())]
541    #[case(6, vector_public_key_validation_6())]
542    #[case(7, vector_public_key_validation_7())]
543    #[case(8, vector_public_key_validation_8())]
544    #[case(9, vector_public_key_validation_9())]
545    #[case(10, vector_public_key_validation_10())]
546    #[case(12, vector_public_key_validation_12())]
547    fn test_public_key_validation(
548        #[case] n: usize,
549        #[case] (public_key, exp_valid): (Vec<u8>, bool),
550    ) {
551        let res = PublicKey::decode(public_key.as_ref());
552        assert_eq!(exp_valid, res.is_ok(), "vector_public_key_validation_{n}");
553    }
554
555    fn vector_sig_verification_1() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
556        let (public_key, sig, message, expected) = vector_sig_verification_1_raw();
557        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
558        (PublicKey(public_key), encoded, message, expected)
559    }
560
561    fn vector_sig_verification_2() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
562        let (public_key, sig, message, expected) = vector_sig_verification_2_raw();
563        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
564        (PublicKey(public_key), encoded, message, expected)
565    }
566
567    fn vector_sig_verification_3() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
568        let (public_key, sig, message, expected) = vector_sig_verification_3_raw();
569        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
570        (PublicKey(public_key), encoded, message, expected)
571    }
572
573    fn vector_sig_verification_4() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
574        let (public_key, sig, message, expected) = vector_sig_verification_4_raw();
575        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
576        (PublicKey(public_key), encoded, message, expected)
577    }
578
579    fn vector_sig_verification_5() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
580        let (public_key, sig, message, expected) = vector_sig_verification_5_raw();
581        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
582        (PublicKey(public_key), encoded, message, expected)
583    }
584
585    fn vector_sig_verification_6() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
586        let (public_key, sig, message, expected) = vector_sig_verification_6_raw();
587        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
588        (PublicKey(public_key), encoded, message, expected)
589    }
590
591    fn vector_sig_verification_7() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
592        let (public_key, sig, message, expected) = vector_sig_verification_7_raw();
593        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
594        (PublicKey(public_key), encoded, message, expected)
595    }
596
597    fn vector_sig_verification_8() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
598        let (public_key, sig, message, expected) = vector_sig_verification_8_raw();
599        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
600        (PublicKey(public_key), encoded, message, expected)
601    }
602
603    fn vector_sig_verification_9() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
604        let (public_key, sig, message, expected) = vector_sig_verification_9_raw();
605        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
606        (PublicKey(public_key), encoded, message, expected)
607    }
608
609    fn vector_sig_verification_10() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
610        let (public_key, sig, message, expected) = vector_sig_verification_10_raw();
611        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
612        (PublicKey(public_key), encoded, message, expected)
613    }
614
615    fn vector_sig_verification_11() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
616        let (public_key, sig, message, expected) = vector_sig_verification_11_raw();
617        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
618        (PublicKey(public_key), encoded, message, expected)
619    }
620
621    fn vector_sig_verification_12() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
622        let (public_key, sig, message, expected) = vector_sig_verification_12_raw();
623        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
624        (PublicKey(public_key), encoded, message, expected)
625    }
626
627    fn vector_sig_verification_13() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
628        let (public_key, sig, message, expected) = vector_sig_verification_13_raw();
629        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
630        (PublicKey(public_key), encoded, message, expected)
631    }
632
633    fn vector_sig_verification_14() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
634        let (public_key, sig, message, expected) = vector_sig_verification_14_raw();
635        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
636        (PublicKey(public_key), encoded, message, expected)
637    }
638
639    fn vector_sig_verification_15() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
640        let (public_key, sig, message, expected) = vector_sig_verification_15_raw();
641        let encoded = encode_signature_with_recovery(&public_key.key, &message, &sig);
642        (PublicKey(public_key), encoded, message, expected)
643    }
644
645    #[rstest]
646    #[case(vector_sig_verification_1())]
647    #[case(vector_sig_verification_2())]
648    #[case(vector_sig_verification_3())]
649    #[case(vector_sig_verification_4())]
650    #[case(vector_sig_verification_5())]
651    #[case(vector_sig_verification_6())]
652    #[case(vector_sig_verification_7())]
653    #[case(vector_sig_verification_8())]
654    #[case(vector_sig_verification_9())]
655    #[case(vector_sig_verification_10())]
656    #[case(vector_sig_verification_11())]
657    #[case(vector_sig_verification_12())]
658    #[case(vector_sig_verification_13())]
659    #[case(vector_sig_verification_14())]
660    #[case(vector_sig_verification_15())]
661    fn test_signature_verification(
662        #[case] (public_key, sig, message, expected): (PublicKey, Vec<u8>, Vec<u8>, bool),
663    ) {
664        let expected = if expected {
665            let mut ecdsa_signature = p256::ecdsa::Signature::from_slice(&sig[1..]).unwrap();
666            if ecdsa_signature.s().is_high().into() {
667                assert!(Signature::decode(sig.as_ref()).is_err());
668                assert!(Signature::decode(Bytes::from(sig)).is_err());
669
670                if let Some(normalized_sig) = ecdsa_signature.normalize_s() {
671                    ecdsa_signature = normalized_sig;
672                }
673            }
674            let recovery_id =
675                RecoveryId::trial_recovery_from_msg(&public_key.0.key, &message, &ecdsa_signature)
676                    .expect("recovery id");
677            let signature = Signature::new(ecdsa_signature, recovery_id);
678            public_key.verify_inner(None, &message, &signature)
679        } else {
680            let tf_res = Signature::decode(sig.as_ref());
681            let dc_res = Signature::decode(Bytes::from(sig));
682            if tf_res.is_err() && dc_res.is_err() {
683                true
684            } else {
685                let f1 = !public_key.verify_inner(None, &message, &tf_res.unwrap());
686                let f2 = !public_key.verify_inner(None, &message, &dc_res.unwrap());
687                f1 && f2
688            }
689        };
690        assert!(expected);
691    }
692
693    #[cfg(feature = "arbitrary")]
694    mod conformance {
695        use super::*;
696        use commonware_codec::conformance::CodecConformance;
697
698        commonware_conformance::conformance_tests! {
699            CodecConformance<Signature> => 1024,
700        }
701    }
702}