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; const SIGNATURE_LENGTH: usize = 1 + BASE_SIGNATURE_LENGTH; #[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 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#[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#[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 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}