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