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