1use crate::crypto::traits::{PublicKey, Signature, Signer, Verifier};
17use crate::error::{AptosError, AptosResult};
18use k256::ecdsa::{
19 Signature as K256Signature, SigningKey, VerifyingKey, signature::Signer as K256Signer,
20 signature::Verifier as K256Verifier,
21};
22use serde::{Deserialize, Serialize};
23use std::fmt;
24use zeroize::Zeroize;
25
26pub const SECP256K1_PRIVATE_KEY_LENGTH: usize = 32;
28pub const SECP256K1_PUBLIC_KEY_LENGTH: usize = 33;
30#[allow(dead_code)] pub const SECP256K1_PUBLIC_KEY_UNCOMPRESSED_LENGTH: usize = 65;
33pub const SECP256K1_SIGNATURE_LENGTH: usize = 64;
35
36#[derive(Clone, Zeroize)]
40#[zeroize(drop)]
41pub struct Secp256k1PrivateKey {
42 #[zeroize(skip)]
43 #[allow(unused)] inner: SigningKey,
45}
46
47impl Secp256k1PrivateKey {
48 pub fn generate() -> Self {
50 let signing_key = SigningKey::random(&mut rand::rngs::OsRng);
51 Self { inner: signing_key }
52 }
53
54 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
62 if bytes.len() != SECP256K1_PRIVATE_KEY_LENGTH {
63 return Err(AptosError::InvalidPrivateKey(format!(
64 "expected {} bytes, got {}",
65 SECP256K1_PRIVATE_KEY_LENGTH,
66 bytes.len()
67 )));
68 }
69 let signing_key = SigningKey::from_slice(bytes)
70 .map_err(|e| AptosError::InvalidPrivateKey(e.to_string()))?;
71 Ok(Self { inner: signing_key })
72 }
73
74 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
81 let hex_str = hex_str.strip_prefix("0x").unwrap_or(hex_str);
82 let bytes = 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 format!("0x{}", hex::encode(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 {
130 let hash = crate::crypto::sha2_256(message);
132 let signature: K256Signature = self.inner.sign(&hash);
133 Secp256k1Signature { inner: signature }
134 }
135
136 pub fn sign_prehashed(&self, hash: &[u8; 32]) -> Secp256k1Signature {
138 let signature: K256Signature = self.inner.sign(hash);
139 Secp256k1Signature { inner: signature }
140 }
141}
142
143impl Signer for Secp256k1PrivateKey {
144 type Signature = Secp256k1Signature;
145
146 fn sign(&self, message: &[u8]) -> Secp256k1Signature {
147 Secp256k1PrivateKey::sign(self, message)
148 }
149
150 fn public_key(&self) -> Secp256k1PublicKey {
151 Secp256k1PrivateKey::public_key(self)
152 }
153}
154
155impl fmt::Debug for Secp256k1PrivateKey {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 write!(f, "Secp256k1PrivateKey([REDACTED])")
158 }
159}
160
161#[derive(Clone, Copy, PartialEq, Eq)]
163pub struct Secp256k1PublicKey {
164 inner: VerifyingKey,
165}
166
167impl Secp256k1PublicKey {
168 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
174 let verifying_key = VerifyingKey::from_sec1_bytes(bytes)
175 .map_err(|e| AptosError::InvalidPublicKey(e.to_string()))?;
176 Ok(Self {
177 inner: verifying_key,
178 })
179 }
180
181 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
188 let hex_str = hex_str.strip_prefix("0x").unwrap_or(hex_str);
189 let bytes = hex::decode(hex_str)?;
190 Self::from_bytes(&bytes)
191 }
192
193 pub fn from_aip80(s: &str) -> AptosResult<Self> {
201 const PREFIX: &str = "secp256k1-pub-";
202 if let Some(hex_part) = s.strip_prefix(PREFIX) {
203 Self::from_hex(hex_part)
204 } else {
205 Err(AptosError::InvalidPublicKey(format!(
206 "invalid AIP-80 format: expected prefix '{PREFIX}'"
207 )))
208 }
209 }
210
211 pub fn to_bytes(&self) -> Vec<u8> {
213 self.inner.to_sec1_bytes().to_vec()
214 }
215
216 pub fn to_uncompressed_bytes(&self) -> Vec<u8> {
218 #[allow(unused_imports)]
219 use k256::elliptic_curve::sec1::ToEncodedPoint;
220 self.inner.to_encoded_point(false).as_bytes().to_vec()
221 }
222
223 pub fn to_hex(&self) -> String {
225 format!("0x{}", hex::encode(self.to_bytes()))
226 }
227
228 pub fn to_aip80(&self) -> String {
232 format!("secp256k1-pub-{}", self.to_hex())
233 }
234
235 pub fn verify(&self, message: &[u8], signature: &Secp256k1Signature) -> AptosResult<()> {
241 let hash = crate::crypto::sha2_256(message);
243 self.inner
244 .verify(&hash, &signature.inner)
245 .map_err(|_| AptosError::SignatureVerificationFailed)
246 }
247
248 pub fn verify_prehashed(
254 &self,
255 hash: &[u8; 32],
256 signature: &Secp256k1Signature,
257 ) -> AptosResult<()> {
258 self.inner
259 .verify(hash, &signature.inner)
260 .map_err(|_| AptosError::SignatureVerificationFailed)
261 }
262
263 pub fn to_address(&self) -> crate::types::AccountAddress {
270 let uncompressed = self.to_uncompressed_bytes();
272 let mut bcs_bytes = Vec::with_capacity(1 + 1 + uncompressed.len());
273 bcs_bytes.push(0x01); bcs_bytes.push(65); bcs_bytes.extend_from_slice(&uncompressed);
276 crate::crypto::derive_address(&bcs_bytes, crate::crypto::SINGLE_KEY_SCHEME)
277 }
278}
279
280impl PublicKey for Secp256k1PublicKey {
281 const LENGTH: usize = SECP256K1_PUBLIC_KEY_LENGTH;
282
283 fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
284 Secp256k1PublicKey::from_bytes(bytes)
285 }
286
287 fn to_bytes(&self) -> Vec<u8> {
288 Secp256k1PublicKey::to_bytes(self)
289 }
290}
291
292impl Verifier for Secp256k1PublicKey {
293 type Signature = Secp256k1Signature;
294
295 fn verify(&self, message: &[u8], signature: &Secp256k1Signature) -> AptosResult<()> {
296 Secp256k1PublicKey::verify(self, message, signature)
297 }
298}
299
300impl fmt::Debug for Secp256k1PublicKey {
301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302 write!(f, "Secp256k1PublicKey({})", self.to_hex())
303 }
304}
305
306impl fmt::Display for Secp256k1PublicKey {
307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
308 write!(f, "{}", self.to_hex())
309 }
310}
311
312impl Serialize for Secp256k1PublicKey {
313 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
314 where
315 S: serde::Serializer,
316 {
317 if serializer.is_human_readable() {
318 serializer.serialize_str(&self.to_hex())
319 } else {
320 serializer.serialize_bytes(&self.to_bytes())
321 }
322 }
323}
324
325impl<'de> Deserialize<'de> for Secp256k1PublicKey {
326 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
327 where
328 D: serde::Deserializer<'de>,
329 {
330 if deserializer.is_human_readable() {
331 let s = String::deserialize(deserializer)?;
332 Self::from_hex(&s).map_err(serde::de::Error::custom)
333 } else {
334 let bytes = Vec::<u8>::deserialize(deserializer)?;
335 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
336 }
337 }
338}
339
340#[derive(Clone, Copy, PartialEq, Eq)]
342pub struct Secp256k1Signature {
343 inner: K256Signature,
344}
345
346impl Secp256k1Signature {
347 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
355 if bytes.len() != SECP256K1_SIGNATURE_LENGTH {
356 return Err(AptosError::InvalidSignature(format!(
357 "expected {} bytes, got {}",
358 SECP256K1_SIGNATURE_LENGTH,
359 bytes.len()
360 )));
361 }
362 let signature = K256Signature::from_slice(bytes)
363 .map_err(|e| AptosError::InvalidSignature(e.to_string()))?;
364 Ok(Self { inner: signature })
365 }
366
367 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
374 let hex_str = hex_str.strip_prefix("0x").unwrap_or(hex_str);
375 let bytes = hex::decode(hex_str)?;
376 Self::from_bytes(&bytes)
377 }
378
379 pub fn to_bytes(&self) -> [u8; SECP256K1_SIGNATURE_LENGTH] {
381 self.inner.to_bytes().into()
382 }
383
384 pub fn to_hex(&self) -> String {
386 format!("0x{}", hex::encode(self.to_bytes()))
387 }
388}
389
390impl Signature for Secp256k1Signature {
391 type PublicKey = Secp256k1PublicKey;
392 const LENGTH: usize = SECP256K1_SIGNATURE_LENGTH;
393
394 fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
395 Secp256k1Signature::from_bytes(bytes)
396 }
397
398 fn to_bytes(&self) -> Vec<u8> {
399 self.inner.to_bytes().to_vec()
400 }
401}
402
403impl fmt::Debug for Secp256k1Signature {
404 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
405 write!(f, "Secp256k1Signature({})", self.to_hex())
406 }
407}
408
409impl fmt::Display for Secp256k1Signature {
410 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
411 write!(f, "{}", self.to_hex())
412 }
413}
414
415impl Serialize for Secp256k1Signature {
416 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
417 where
418 S: serde::Serializer,
419 {
420 if serializer.is_human_readable() {
421 serializer.serialize_str(&self.to_hex())
422 } else {
423 serializer.serialize_bytes(&self.to_bytes())
424 }
425 }
426}
427
428impl<'de> Deserialize<'de> for Secp256k1Signature {
429 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
430 where
431 D: serde::Deserializer<'de>,
432 {
433 if deserializer.is_human_readable() {
434 let s = String::deserialize(deserializer)?;
435 Self::from_hex(&s).map_err(serde::de::Error::custom)
436 } else {
437 let bytes = Vec::<u8>::deserialize(deserializer)?;
438 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
439 }
440 }
441}
442
443#[cfg(test)]
444mod tests {
445 use super::*;
446
447 #[test]
448 fn test_generate_and_sign() {
449 let private_key = Secp256k1PrivateKey::generate();
450 let message = b"hello world";
451 let signature = private_key.sign(message);
452
453 let public_key = private_key.public_key();
454 assert!(public_key.verify(message, &signature).is_ok());
455 }
456
457 #[test]
458 fn test_wrong_message_fails() {
459 let private_key = Secp256k1PrivateKey::generate();
460 let message = b"hello world";
461 let wrong_message = b"hello world!";
462 let signature = private_key.sign(message);
463
464 let public_key = private_key.public_key();
465 assert!(public_key.verify(wrong_message, &signature).is_err());
466 }
467
468 #[test]
469 fn test_from_bytes_roundtrip() {
470 let private_key = Secp256k1PrivateKey::generate();
471 let bytes = private_key.to_bytes();
472 let restored = Secp256k1PrivateKey::from_bytes(&bytes).unwrap();
473 assert_eq!(private_key.to_bytes(), restored.to_bytes());
474 }
475
476 #[test]
477 fn test_public_key_compressed() {
478 let private_key = Secp256k1PrivateKey::generate();
479 let public_key = private_key.public_key();
480
481 assert_eq!(public_key.to_bytes().len(), 33);
483
484 assert_eq!(public_key.to_uncompressed_bytes().len(), 65);
486 }
487
488 #[test]
489 fn test_public_key_from_bytes_roundtrip() {
490 let private_key = Secp256k1PrivateKey::generate();
491 let public_key = private_key.public_key();
492 let bytes = public_key.to_bytes();
493 let restored = Secp256k1PublicKey::from_bytes(&bytes).unwrap();
494 assert_eq!(public_key.to_bytes(), restored.to_bytes());
495 }
496
497 #[test]
498 fn test_signature_from_bytes_roundtrip() {
499 let private_key = Secp256k1PrivateKey::generate();
500 let signature = private_key.sign(b"test");
501 let bytes = signature.to_bytes();
502 let restored = Secp256k1Signature::from_bytes(&bytes).unwrap();
503 assert_eq!(signature.to_bytes(), restored.to_bytes());
504 }
505
506 #[test]
507 fn test_hex_roundtrip() {
508 let private_key = Secp256k1PrivateKey::generate();
509 let hex = private_key.to_hex();
510 let restored = Secp256k1PrivateKey::from_hex(&hex).unwrap();
511 assert_eq!(private_key.to_bytes(), restored.to_bytes());
512 }
513
514 #[test]
515 fn test_public_key_hex_roundtrip() {
516 let private_key = Secp256k1PrivateKey::generate();
517 let public_key = private_key.public_key();
518 let hex = public_key.to_hex();
519 let restored = Secp256k1PublicKey::from_hex(&hex).unwrap();
520 assert_eq!(public_key.to_bytes(), restored.to_bytes());
521 }
522
523 #[test]
524 fn test_signature_hex_roundtrip() {
525 let private_key = Secp256k1PrivateKey::generate();
526 let signature = private_key.sign(b"test");
527 let hex = signature.to_hex();
528 let restored = Secp256k1Signature::from_hex(&hex).unwrap();
529 assert_eq!(signature.to_bytes(), restored.to_bytes());
530 }
531
532 #[test]
533 fn test_invalid_private_key_bytes() {
534 let bytes = vec![0u8; 16]; let result = Secp256k1PrivateKey::from_bytes(&bytes);
536 assert!(result.is_err());
537 }
538
539 #[test]
540 fn test_invalid_public_key_bytes() {
541 let bytes = vec![0u8; 16]; let result = Secp256k1PublicKey::from_bytes(&bytes);
543 assert!(result.is_err());
544 }
545
546 #[test]
547 fn test_invalid_signature_bytes() {
548 let bytes = vec![0u8; 16]; let result = Secp256k1Signature::from_bytes(&bytes);
550 assert!(result.is_err());
551 }
552
553 #[test]
554 fn test_json_serialization_public_key() {
555 let private_key = Secp256k1PrivateKey::generate();
556 let public_key = private_key.public_key();
557 let json = serde_json::to_string(&public_key).unwrap();
558 let restored: Secp256k1PublicKey = serde_json::from_str(&json).unwrap();
559 assert_eq!(public_key.to_bytes(), restored.to_bytes());
560 }
561
562 #[test]
563 fn test_json_serialization_signature() {
564 let private_key = Secp256k1PrivateKey::generate();
565 let signature = private_key.sign(b"test");
566 let json = serde_json::to_string(&signature).unwrap();
567 let restored: Secp256k1Signature = serde_json::from_str(&json).unwrap();
568 assert_eq!(signature.to_bytes(), restored.to_bytes());
569 }
570
571 #[test]
572 fn test_key_lengths() {
573 assert_eq!(Secp256k1PublicKey::LENGTH, SECP256K1_PUBLIC_KEY_LENGTH);
574 assert_eq!(Secp256k1Signature::LENGTH, SECP256K1_SIGNATURE_LENGTH);
575 }
576
577 #[test]
578 fn test_display_debug() {
579 let private_key = Secp256k1PrivateKey::generate();
580 let public_key = private_key.public_key();
581 let signature = private_key.sign(b"test");
582
583 assert!(format!("{public_key:?}").contains("Secp256k1PublicKey"));
585 assert!(format!("{signature:?}").contains("Secp256k1Signature"));
586
587 assert!(format!("{public_key}").starts_with("0x"));
589 assert!(format!("{signature}").starts_with("0x"));
590 }
591
592 #[test]
593 fn test_private_key_aip80_roundtrip() {
594 let private_key = Secp256k1PrivateKey::generate();
595 let aip80 = private_key.to_aip80();
596
597 assert!(aip80.starts_with("secp256k1-priv-0x"));
599
600 let restored = Secp256k1PrivateKey::from_aip80(&aip80).unwrap();
602 assert_eq!(private_key.to_bytes(), restored.to_bytes());
603 }
604
605 #[test]
606 fn test_private_key_aip80_format() {
607 let bytes = [0x01; 32];
608 let private_key = Secp256k1PrivateKey::from_bytes(&bytes).unwrap();
609 let aip80 = private_key.to_aip80();
610
611 let expected = format!("secp256k1-priv-0x{}", "01".repeat(32));
613 assert_eq!(aip80, expected);
614 }
615
616 #[test]
617 fn test_private_key_aip80_invalid_prefix() {
618 let result = Secp256k1PrivateKey::from_aip80("ed25519-priv-0x01");
619 assert!(result.is_err());
620 }
621
622 #[test]
623 fn test_public_key_aip80_roundtrip() {
624 let private_key = Secp256k1PrivateKey::generate();
625 let public_key = private_key.public_key();
626 let aip80 = public_key.to_aip80();
627
628 assert!(aip80.starts_with("secp256k1-pub-0x"));
630
631 let restored = Secp256k1PublicKey::from_aip80(&aip80).unwrap();
633 assert_eq!(public_key.to_bytes(), restored.to_bytes());
634 }
635
636 #[test]
637 fn test_public_key_aip80_invalid_prefix() {
638 let result = Secp256k1PublicKey::from_aip80("ed25519-pub-0x01");
639 assert!(result.is_err());
640 }
641
642 #[test]
643 fn test_signer_trait() {
644 use crate::crypto::traits::Signer;
645
646 let private_key = Secp256k1PrivateKey::generate();
647 let message = b"trait test";
648
649 let signature = Signer::sign(&private_key, message);
650 let public_key = Signer::public_key(&private_key);
651
652 assert!(public_key.verify(message, &signature).is_ok());
653 }
654
655 #[test]
656 fn test_verifier_trait() {
657 use crate::crypto::traits::Verifier;
658
659 let private_key = Secp256k1PrivateKey::generate();
660 let public_key = private_key.public_key();
661 let message = b"verifier test";
662 let signature = private_key.sign(message);
663
664 assert!(Verifier::verify(&public_key, message, &signature).is_ok());
665 }
666
667 #[test]
668 fn test_public_key_trait() {
669 use crate::crypto::traits::PublicKey;
670
671 let private_key = Secp256k1PrivateKey::generate();
672 let public_key = private_key.public_key();
673 let bytes = PublicKey::to_bytes(&public_key);
674 let restored = Secp256k1PublicKey::from_bytes(&bytes).unwrap();
675 assert_eq!(public_key.to_bytes(), restored.to_bytes());
676 }
677
678 #[test]
679 fn test_signature_trait() {
680 use crate::crypto::traits::Signature;
681
682 let private_key = Secp256k1PrivateKey::generate();
683 let signature = private_key.sign(b"test");
684 let bytes = Signature::to_bytes(&signature);
685 let restored = Secp256k1Signature::from_bytes(&bytes).unwrap();
686 assert_eq!(signature.to_bytes(), restored.to_bytes());
687 }
688
689 #[test]
690 fn test_private_key_debug() {
691 let private_key = Secp256k1PrivateKey::generate();
692 let debug = format!("{private_key:?}");
693 assert!(debug.contains("REDACTED"));
694 assert!(!debug.contains(&private_key.to_hex()));
695 }
696
697 #[test]
698 fn test_address_derivation() {
699 let private_key = Secp256k1PrivateKey::generate();
700 let public_key = private_key.public_key();
701 let address = public_key.to_address();
702
703 assert!(!address.is_zero());
705
706 let address2 = public_key.to_address();
708 assert_eq!(address, address2);
709 }
710
711 #[test]
712 fn test_uncompressed_bytes() {
713 let private_key = Secp256k1PrivateKey::generate();
714 let public_key = private_key.public_key();
715
716 let uncompressed = public_key.to_uncompressed_bytes();
718 assert_eq!(uncompressed.len(), 65);
719 assert_eq!(uncompressed[0], 0x04); }
721
722 #[test]
723 fn test_private_key_clone() {
724 let private_key = Secp256k1PrivateKey::generate();
725 let cloned = private_key.clone();
726 assert_eq!(private_key.to_bytes(), cloned.to_bytes());
727 }
728
729 #[test]
730 fn test_public_key_equality() {
731 let private_key = Secp256k1PrivateKey::generate();
732 let pk1 = private_key.public_key();
733 let pk2 = private_key.public_key();
734 assert_eq!(pk1, pk2);
735
736 let different = Secp256k1PrivateKey::generate().public_key();
737 assert_ne!(pk1, different);
738 }
739
740 #[test]
741 fn test_signature_equality() {
742 let private_key = Secp256k1PrivateKey::generate();
743 let sig1 = private_key.sign(b"test");
744 let sig2 = private_key.sign(b"test");
745 let public_key = private_key.public_key();
748 assert!(public_key.verify(b"test", &sig1).is_ok());
749 assert!(public_key.verify(b"test", &sig2).is_ok());
750 }
751}