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