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