1use crate::crypto::traits::{PublicKey, Signature, Signer, Verifier};
18use crate::error::{AptosError, AptosResult};
19use k256::ecdsa::{
20 Signature as K256Signature, SigningKey, VerifyingKey, signature::Signer as K256Signer,
21 signature::Verifier as K256Verifier,
22};
23use serde::{Deserialize, Serialize};
24use std::fmt;
25use zeroize::Zeroize;
26
27pub const SECP256K1_PRIVATE_KEY_LENGTH: usize = 32;
29pub const SECP256K1_PUBLIC_KEY_LENGTH: usize = 33;
31#[allow(dead_code)] pub const SECP256K1_PUBLIC_KEY_UNCOMPRESSED_LENGTH: usize = 65;
34pub const SECP256K1_SIGNATURE_LENGTH: usize = 64;
36
37#[derive(Clone, Zeroize)]
41#[zeroize(drop)]
42pub struct Secp256k1PrivateKey {
43 #[zeroize(skip)]
44 #[allow(unused)] inner: SigningKey,
46}
47
48impl Secp256k1PrivateKey {
49 pub fn generate() -> Self {
51 let signing_key = SigningKey::random(&mut rand::rngs::OsRng);
52 Self { inner: signing_key }
53 }
54
55 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
63 if bytes.len() != SECP256K1_PRIVATE_KEY_LENGTH {
64 return Err(AptosError::InvalidPrivateKey(format!(
65 "expected {} bytes, got {}",
66 SECP256K1_PRIVATE_KEY_LENGTH,
67 bytes.len()
68 )));
69 }
70 let signing_key = SigningKey::from_slice(bytes)
71 .map_err(|e| AptosError::InvalidPrivateKey(e.to_string()))?;
72 Ok(Self { inner: signing_key })
73 }
74
75 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
82 let bytes = const_hex::decode(hex_str)?;
83 Self::from_bytes(&bytes)
84 }
85
86 pub fn from_aip80(s: &str) -> AptosResult<Self> {
94 const PREFIX: &str = "secp256k1-priv-";
95 if let Some(hex_part) = s.strip_prefix(PREFIX) {
96 Self::from_hex(hex_part)
97 } else {
98 Err(AptosError::InvalidPrivateKey(format!(
99 "invalid AIP-80 format: expected prefix '{PREFIX}'"
100 )))
101 }
102 }
103
104 pub fn to_bytes(&self) -> [u8; SECP256K1_PRIVATE_KEY_LENGTH] {
106 self.inner.to_bytes().into()
107 }
108
109 pub fn to_hex(&self) -> String {
111 const_hex::encode_prefixed(self.inner.to_bytes())
112 }
113
114 pub fn to_aip80(&self) -> String {
118 format!("secp256k1-priv-{}", self.to_hex())
119 }
120
121 pub fn public_key(&self) -> Secp256k1PublicKey {
123 Secp256k1PublicKey {
124 inner: *self.inner.verifying_key(),
125 }
126 }
127
128 pub fn sign(&self, message: &[u8]) -> Secp256k1Signature {
134 let hash = crate::crypto::sha2_256(message);
136 let signature: K256Signature = self.inner.sign(&hash);
137 let normalized = signature.normalize_s().unwrap_or(signature);
139 Secp256k1Signature { inner: normalized }
140 }
141
142 pub fn sign_prehashed(&self, hash: &[u8; 32]) -> Secp256k1Signature {
147 let signature: K256Signature = self.inner.sign(hash);
148 let normalized = signature.normalize_s().unwrap_or(signature);
150 Secp256k1Signature { inner: normalized }
151 }
152}
153
154impl Signer for Secp256k1PrivateKey {
155 type Signature = Secp256k1Signature;
156
157 fn sign(&self, message: &[u8]) -> Secp256k1Signature {
158 Secp256k1PrivateKey::sign(self, message)
159 }
160
161 fn public_key(&self) -> Secp256k1PublicKey {
162 Secp256k1PrivateKey::public_key(self)
163 }
164}
165
166impl fmt::Debug for Secp256k1PrivateKey {
167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168 write!(f, "Secp256k1PrivateKey([REDACTED])")
169 }
170}
171
172#[derive(Clone, Copy, PartialEq, Eq)]
174pub struct Secp256k1PublicKey {
175 inner: VerifyingKey,
176}
177
178impl Secp256k1PublicKey {
179 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
185 let verifying_key = VerifyingKey::from_sec1_bytes(bytes)
186 .map_err(|e| AptosError::InvalidPublicKey(e.to_string()))?;
187 Ok(Self {
188 inner: verifying_key,
189 })
190 }
191
192 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
199 let bytes = const_hex::decode(hex_str)?;
200 Self::from_bytes(&bytes)
201 }
202
203 pub fn from_aip80(s: &str) -> AptosResult<Self> {
211 const PREFIX: &str = "secp256k1-pub-";
212 if let Some(hex_part) = s.strip_prefix(PREFIX) {
213 Self::from_hex(hex_part)
214 } else {
215 Err(AptosError::InvalidPublicKey(format!(
216 "invalid AIP-80 format: expected prefix '{PREFIX}'"
217 )))
218 }
219 }
220
221 pub fn to_bytes(&self) -> Vec<u8> {
223 self.inner.to_sec1_bytes().to_vec()
224 }
225
226 pub fn to_uncompressed_bytes(&self) -> Vec<u8> {
228 #[allow(unused_imports)]
229 use k256::elliptic_curve::sec1::ToEncodedPoint;
230 self.inner.to_encoded_point(false).as_bytes().to_vec()
231 }
232
233 pub fn to_hex(&self) -> String {
235 const_hex::encode_prefixed(self.to_bytes())
236 }
237
238 pub fn to_aip80(&self) -> String {
242 format!("secp256k1-pub-{}", self.to_hex())
243 }
244
245 pub fn verify(&self, message: &[u8], signature: &Secp256k1Signature) -> AptosResult<()> {
258 if signature.inner.normalize_s().is_some() {
260 return Err(AptosError::SignatureVerificationFailed);
261 }
262 let hash = crate::crypto::sha2_256(message);
263 self.inner
264 .verify(&hash, &signature.inner)
265 .map_err(|_| AptosError::SignatureVerificationFailed)
266 }
267
268 pub fn verify_prehashed(
280 &self,
281 hash: &[u8; 32],
282 signature: &Secp256k1Signature,
283 ) -> AptosResult<()> {
284 if signature.inner.normalize_s().is_some() {
286 return Err(AptosError::SignatureVerificationFailed);
287 }
288 self.inner
289 .verify(hash, &signature.inner)
290 .map_err(|_| AptosError::SignatureVerificationFailed)
291 }
292
293 pub fn to_address(&self) -> crate::types::AccountAddress {
300 let uncompressed = self.to_uncompressed_bytes();
302 let mut bcs_bytes = Vec::with_capacity(1 + 1 + uncompressed.len());
303 bcs_bytes.push(0x01); bcs_bytes.push(65); bcs_bytes.extend_from_slice(&uncompressed);
306 crate::crypto::derive_address(&bcs_bytes, crate::crypto::SINGLE_KEY_SCHEME)
307 }
308}
309
310impl PublicKey for Secp256k1PublicKey {
311 const LENGTH: usize = SECP256K1_PUBLIC_KEY_LENGTH;
312
313 fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
314 Secp256k1PublicKey::from_bytes(bytes)
315 }
316
317 fn to_bytes(&self) -> Vec<u8> {
318 Secp256k1PublicKey::to_bytes(self)
319 }
320}
321
322impl Verifier for Secp256k1PublicKey {
323 type Signature = Secp256k1Signature;
324
325 fn verify(&self, message: &[u8], signature: &Secp256k1Signature) -> AptosResult<()> {
326 Secp256k1PublicKey::verify(self, message, signature)
327 }
328}
329
330impl fmt::Debug for Secp256k1PublicKey {
331 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332 write!(f, "Secp256k1PublicKey({})", self.to_hex())
333 }
334}
335
336impl fmt::Display for Secp256k1PublicKey {
337 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
338 write!(f, "{}", self.to_hex())
339 }
340}
341
342impl Serialize for Secp256k1PublicKey {
343 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
344 where
345 S: serde::Serializer,
346 {
347 if serializer.is_human_readable() {
348 serializer.serialize_str(&self.to_hex())
349 } else {
350 serializer.serialize_bytes(&self.to_bytes())
351 }
352 }
353}
354
355impl<'de> Deserialize<'de> for Secp256k1PublicKey {
356 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
357 where
358 D: serde::Deserializer<'de>,
359 {
360 if deserializer.is_human_readable() {
361 let s = String::deserialize(deserializer)?;
362 Self::from_hex(&s).map_err(serde::de::Error::custom)
363 } else {
364 let bytes = Vec::<u8>::deserialize(deserializer)?;
365 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
366 }
367 }
368}
369
370#[derive(Clone, Copy, PartialEq, Eq)]
372pub struct Secp256k1Signature {
373 inner: K256Signature,
374}
375
376impl Secp256k1Signature {
377 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
392 if bytes.len() != SECP256K1_SIGNATURE_LENGTH {
393 return Err(AptosError::InvalidSignature(format!(
394 "expected {} bytes, got {}",
395 SECP256K1_SIGNATURE_LENGTH,
396 bytes.len()
397 )));
398 }
399 let signature = K256Signature::from_slice(bytes)
400 .map_err(|e| AptosError::InvalidSignature(e.to_string()))?;
401 if signature.normalize_s().is_some() {
405 return Err(AptosError::InvalidSignature(
406 "high-S signature rejected: Aptos requires low-S (canonical) ECDSA signatures"
407 .into(),
408 ));
409 }
410 Ok(Self { inner: signature })
411 }
412
413 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
420 let bytes = const_hex::decode(hex_str)?;
421 Self::from_bytes(&bytes)
422 }
423
424 pub fn to_bytes(&self) -> [u8; SECP256K1_SIGNATURE_LENGTH] {
426 self.inner.to_bytes().into()
427 }
428
429 pub fn to_hex(&self) -> String {
431 const_hex::encode_prefixed(self.to_bytes())
432 }
433}
434
435impl Signature for Secp256k1Signature {
436 type PublicKey = Secp256k1PublicKey;
437 const LENGTH: usize = SECP256K1_SIGNATURE_LENGTH;
438
439 fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
440 Secp256k1Signature::from_bytes(bytes)
441 }
442
443 fn to_bytes(&self) -> Vec<u8> {
444 self.inner.to_bytes().to_vec()
445 }
446}
447
448impl fmt::Debug for Secp256k1Signature {
449 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450 write!(f, "Secp256k1Signature({})", self.to_hex())
451 }
452}
453
454impl fmt::Display for Secp256k1Signature {
455 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456 write!(f, "{}", self.to_hex())
457 }
458}
459
460impl Serialize for Secp256k1Signature {
461 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
462 where
463 S: serde::Serializer,
464 {
465 if serializer.is_human_readable() {
466 serializer.serialize_str(&self.to_hex())
467 } else {
468 serializer.serialize_bytes(&self.to_bytes())
469 }
470 }
471}
472
473impl<'de> Deserialize<'de> for Secp256k1Signature {
474 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
475 where
476 D: serde::Deserializer<'de>,
477 {
478 if deserializer.is_human_readable() {
479 let s = String::deserialize(deserializer)?;
480 Self::from_hex(&s).map_err(serde::de::Error::custom)
481 } else {
482 let bytes = Vec::<u8>::deserialize(deserializer)?;
483 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
484 }
485 }
486}
487
488#[cfg(test)]
489mod tests {
490 use super::*;
491
492 #[test]
493 fn test_generate_and_sign() {
494 let private_key = Secp256k1PrivateKey::generate();
495 let message = b"hello world";
496 let signature = private_key.sign(message);
497
498 let public_key = private_key.public_key();
499 assert!(public_key.verify(message, &signature).is_ok());
500 }
501
502 #[test]
503 fn test_wrong_message_fails() {
504 let private_key = Secp256k1PrivateKey::generate();
505 let message = b"hello world";
506 let wrong_message = b"hello world!";
507 let signature = private_key.sign(message);
508
509 let public_key = private_key.public_key();
510 assert!(public_key.verify(wrong_message, &signature).is_err());
511 }
512
513 #[test]
514 fn test_from_bytes_roundtrip() {
515 let private_key = Secp256k1PrivateKey::generate();
516 let bytes = private_key.to_bytes();
517 let restored = Secp256k1PrivateKey::from_bytes(&bytes).unwrap();
518 assert_eq!(private_key.to_bytes(), restored.to_bytes());
519 }
520
521 #[test]
522 fn test_public_key_compressed() {
523 let private_key = Secp256k1PrivateKey::generate();
524 let public_key = private_key.public_key();
525
526 assert_eq!(public_key.to_bytes().len(), 33);
528
529 assert_eq!(public_key.to_uncompressed_bytes().len(), 65);
531 }
532
533 #[test]
534 fn test_public_key_from_bytes_roundtrip() {
535 let private_key = Secp256k1PrivateKey::generate();
536 let public_key = private_key.public_key();
537 let bytes = public_key.to_bytes();
538 let restored = Secp256k1PublicKey::from_bytes(&bytes).unwrap();
539 assert_eq!(public_key.to_bytes(), restored.to_bytes());
540 }
541
542 #[test]
543 fn test_signature_from_bytes_roundtrip() {
544 let private_key = Secp256k1PrivateKey::generate();
545 let signature = private_key.sign(b"test");
546 let bytes = signature.to_bytes();
547 let restored = Secp256k1Signature::from_bytes(&bytes).unwrap();
548 assert_eq!(signature.to_bytes(), restored.to_bytes());
549 }
550
551 #[test]
552 fn test_hex_roundtrip() {
553 let private_key = Secp256k1PrivateKey::generate();
554 let hex = private_key.to_hex();
555 let restored = Secp256k1PrivateKey::from_hex(&hex).unwrap();
556 assert_eq!(private_key.to_bytes(), restored.to_bytes());
557 }
558
559 #[test]
560 fn test_public_key_hex_roundtrip() {
561 let private_key = Secp256k1PrivateKey::generate();
562 let public_key = private_key.public_key();
563 let hex = public_key.to_hex();
564 let restored = Secp256k1PublicKey::from_hex(&hex).unwrap();
565 assert_eq!(public_key.to_bytes(), restored.to_bytes());
566 }
567
568 #[test]
569 fn test_signature_hex_roundtrip() {
570 let private_key = Secp256k1PrivateKey::generate();
571 let signature = private_key.sign(b"test");
572 let hex = signature.to_hex();
573 let restored = Secp256k1Signature::from_hex(&hex).unwrap();
574 assert_eq!(signature.to_bytes(), restored.to_bytes());
575 }
576
577 #[test]
578 fn test_invalid_private_key_bytes() {
579 let bytes = vec![0u8; 16]; let result = Secp256k1PrivateKey::from_bytes(&bytes);
581 assert!(result.is_err());
582 }
583
584 #[test]
585 fn test_invalid_public_key_bytes() {
586 let bytes = vec![0u8; 16]; let result = Secp256k1PublicKey::from_bytes(&bytes);
588 assert!(result.is_err());
589 }
590
591 #[test]
592 fn test_invalid_signature_bytes() {
593 let bytes = vec![0u8; 16]; let result = Secp256k1Signature::from_bytes(&bytes);
595 assert!(result.is_err());
596 }
597
598 #[test]
599 fn test_high_s_signature_rejected() {
600 use k256::elliptic_curve::ops::Neg;
601
602 let private_key = Secp256k1PrivateKey::generate();
604 let signature = private_key.sign(b"test message");
605
606 let low_s_sig = k256::ecdsa::Signature::from_slice(&signature.to_bytes()).unwrap();
608 let (r, s) = low_s_sig.split_scalars();
609 let neg_s = s.neg();
610 let high_s_sig = k256::ecdsa::Signature::from_scalars(r, neg_s).unwrap();
611 assert!(
613 high_s_sig.normalize_s().is_some(),
614 "constructed signature should be high-S"
615 );
616 let high_s_bytes = high_s_sig.to_bytes();
617
618 let result = Secp256k1Signature::from_bytes(&high_s_bytes);
620 assert!(result.is_err(), "high-S signature should be rejected");
621 assert!(
622 result
623 .unwrap_err()
624 .to_string()
625 .contains("high-S signature rejected"),
626 "error message should mention high-S rejection"
627 );
628
629 let sig_with_high_s = Secp256k1Signature { inner: high_s_sig };
631 let public_key = private_key.public_key();
632 let result = public_key.verify(b"test message", &sig_with_high_s);
633 assert!(result.is_err(), "verify should reject high-S signature");
634 }
635
636 #[test]
637 fn test_signing_always_produces_low_s() {
638 for _ in 0..20 {
640 let private_key = Secp256k1PrivateKey::generate();
641 let signature = private_key.sign(b"test low-s");
642 assert!(
644 signature.inner.normalize_s().is_none(),
645 "signing must always produce low-S signatures"
646 );
647 }
648 }
649
650 #[test]
651 fn test_json_serialization_public_key() {
652 let private_key = Secp256k1PrivateKey::generate();
653 let public_key = private_key.public_key();
654 let json = serde_json::to_string(&public_key).unwrap();
655 let restored: Secp256k1PublicKey = serde_json::from_str(&json).unwrap();
656 assert_eq!(public_key.to_bytes(), restored.to_bytes());
657 }
658
659 #[test]
660 fn test_json_serialization_signature() {
661 let private_key = Secp256k1PrivateKey::generate();
662 let signature = private_key.sign(b"test");
663 let json = serde_json::to_string(&signature).unwrap();
664 let restored: Secp256k1Signature = serde_json::from_str(&json).unwrap();
665 assert_eq!(signature.to_bytes(), restored.to_bytes());
666 }
667
668 #[test]
669 fn test_key_lengths() {
670 assert_eq!(Secp256k1PublicKey::LENGTH, SECP256K1_PUBLIC_KEY_LENGTH);
671 assert_eq!(Secp256k1Signature::LENGTH, SECP256K1_SIGNATURE_LENGTH);
672 }
673
674 #[test]
675 fn test_display_debug() {
676 let private_key = Secp256k1PrivateKey::generate();
677 let public_key = private_key.public_key();
678 let signature = private_key.sign(b"test");
679
680 assert!(format!("{public_key:?}").contains("Secp256k1PublicKey"));
682 assert!(format!("{signature:?}").contains("Secp256k1Signature"));
683
684 assert!(format!("{public_key}").starts_with("0x"));
686 assert!(format!("{signature}").starts_with("0x"));
687 }
688
689 #[test]
690 fn test_private_key_aip80_roundtrip() {
691 let private_key = Secp256k1PrivateKey::generate();
692 let aip80 = private_key.to_aip80();
693
694 assert!(aip80.starts_with("secp256k1-priv-0x"));
696
697 let restored = Secp256k1PrivateKey::from_aip80(&aip80).unwrap();
699 assert_eq!(private_key.to_bytes(), restored.to_bytes());
700 }
701
702 #[test]
703 fn test_private_key_aip80_format() {
704 let bytes = [0x01; 32];
705 let private_key = Secp256k1PrivateKey::from_bytes(&bytes).unwrap();
706 let aip80 = private_key.to_aip80();
707
708 let expected = format!("secp256k1-priv-0x{}", "01".repeat(32));
710 assert_eq!(aip80, expected);
711 }
712
713 #[test]
714 fn test_private_key_aip80_invalid_prefix() {
715 let result = Secp256k1PrivateKey::from_aip80("ed25519-priv-0x01");
716 assert!(result.is_err());
717 }
718
719 #[test]
720 fn test_public_key_aip80_roundtrip() {
721 let private_key = Secp256k1PrivateKey::generate();
722 let public_key = private_key.public_key();
723 let aip80 = public_key.to_aip80();
724
725 assert!(aip80.starts_with("secp256k1-pub-0x"));
727
728 let restored = Secp256k1PublicKey::from_aip80(&aip80).unwrap();
730 assert_eq!(public_key.to_bytes(), restored.to_bytes());
731 }
732
733 #[test]
734 fn test_public_key_aip80_invalid_prefix() {
735 let result = Secp256k1PublicKey::from_aip80("ed25519-pub-0x01");
736 assert!(result.is_err());
737 }
738
739 #[test]
740 fn test_signer_trait() {
741 use crate::crypto::traits::Signer;
742
743 let private_key = Secp256k1PrivateKey::generate();
744 let message = b"trait test";
745
746 let signature = Signer::sign(&private_key, message);
747 let public_key = Signer::public_key(&private_key);
748
749 assert!(public_key.verify(message, &signature).is_ok());
750 }
751
752 #[test]
753 fn test_verifier_trait() {
754 use crate::crypto::traits::Verifier;
755
756 let private_key = Secp256k1PrivateKey::generate();
757 let public_key = private_key.public_key();
758 let message = b"verifier test";
759 let signature = private_key.sign(message);
760
761 assert!(Verifier::verify(&public_key, message, &signature).is_ok());
762 }
763
764 #[test]
765 fn test_public_key_trait() {
766 use crate::crypto::traits::PublicKey;
767
768 let private_key = Secp256k1PrivateKey::generate();
769 let public_key = private_key.public_key();
770 let bytes = PublicKey::to_bytes(&public_key);
771 let restored = Secp256k1PublicKey::from_bytes(&bytes).unwrap();
772 assert_eq!(public_key.to_bytes(), restored.to_bytes());
773 }
774
775 #[test]
776 fn test_signature_trait() {
777 use crate::crypto::traits::Signature;
778
779 let private_key = Secp256k1PrivateKey::generate();
780 let signature = private_key.sign(b"test");
781 let bytes = Signature::to_bytes(&signature);
782 let restored = Secp256k1Signature::from_bytes(&bytes).unwrap();
783 assert_eq!(signature.to_bytes(), restored.to_bytes());
784 }
785
786 #[test]
787 fn test_private_key_debug() {
788 let private_key = Secp256k1PrivateKey::generate();
789 let debug = format!("{private_key:?}");
790 assert!(debug.contains("REDACTED"));
791 assert!(!debug.contains(&private_key.to_hex()));
792 }
793
794 #[test]
795 fn test_address_derivation() {
796 let private_key = Secp256k1PrivateKey::generate();
797 let public_key = private_key.public_key();
798 let address = public_key.to_address();
799
800 assert!(!address.is_zero());
802
803 let address2 = public_key.to_address();
805 assert_eq!(address, address2);
806 }
807
808 #[test]
809 fn test_uncompressed_bytes() {
810 let private_key = Secp256k1PrivateKey::generate();
811 let public_key = private_key.public_key();
812
813 let uncompressed = public_key.to_uncompressed_bytes();
815 assert_eq!(uncompressed.len(), 65);
816 assert_eq!(uncompressed[0], 0x04); }
818
819 #[test]
820 fn test_private_key_clone() {
821 let private_key = Secp256k1PrivateKey::generate();
822 let cloned = private_key.clone();
823 assert_eq!(private_key.to_bytes(), cloned.to_bytes());
824 }
825
826 #[test]
827 fn test_public_key_equality() {
828 let private_key = Secp256k1PrivateKey::generate();
829 let pk1 = private_key.public_key();
830 let pk2 = private_key.public_key();
831 assert_eq!(pk1, pk2);
832
833 let different = Secp256k1PrivateKey::generate().public_key();
834 assert_ne!(pk1, different);
835 }
836
837 #[test]
838 fn test_signature_equality() {
839 let private_key = Secp256k1PrivateKey::generate();
840 let sig1 = private_key.sign(b"test");
841 let sig2 = private_key.sign(b"test");
842 let public_key = private_key.public_key();
845 assert!(public_key.verify(b"test", &sig1).is_ok());
846 assert!(public_key.verify(b"test", &sig2).is_ok());
847 }
848}