1use crate::crypto::traits::{PublicKey, Signature, Signer, Verifier};
6use crate::error::{AptosError, AptosResult};
7use ed25519_dalek::{Signer as DalekSigner, Verifier as DalekVerifier};
8use serde::{Deserialize, Serialize};
9use std::fmt;
10use zeroize::Zeroize;
11
12pub const ED25519_PRIVATE_KEY_LENGTH: usize = 32;
14pub const ED25519_PUBLIC_KEY_LENGTH: usize = 32;
16pub const ED25519_SIGNATURE_LENGTH: usize = 64;
18
19#[derive(Clone, Zeroize)]
39#[zeroize(drop)]
40pub struct Ed25519PrivateKey {
41 #[zeroize(skip)]
42 #[allow(unused)] inner: ed25519_dalek::SigningKey,
44}
45
46impl Ed25519PrivateKey {
47 pub fn generate() -> Self {
49 let mut csprng = rand::rngs::OsRng;
50 let signing_key = ed25519_dalek::SigningKey::generate(&mut csprng);
51 Self { inner: signing_key }
52 }
53
54 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
61 if bytes.len() != ED25519_PRIVATE_KEY_LENGTH {
62 return Err(AptosError::InvalidPrivateKey(format!(
63 "expected {} bytes, got {}",
64 ED25519_PRIVATE_KEY_LENGTH,
65 bytes.len()
66 )));
67 }
68 let mut key_bytes = [0u8; ED25519_PRIVATE_KEY_LENGTH];
69 key_bytes.copy_from_slice(bytes);
70 let signing_key = ed25519_dalek::SigningKey::from_bytes(&key_bytes);
71 zeroize::Zeroize::zeroize(&mut key_bytes);
73 Ok(Self { inner: signing_key })
74 }
75
76 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
83 let bytes = const_hex::decode(hex_str)?;
84 Self::from_bytes(&bytes)
85 }
86
87 pub fn from_aip80(s: &str) -> AptosResult<Self> {
105 const PREFIX: &str = "ed25519-priv-";
106 if let Some(hex_part) = s.strip_prefix(PREFIX) {
107 Self::from_hex(hex_part)
108 } else {
109 Err(AptosError::InvalidPrivateKey(format!(
110 "invalid AIP-80 format: expected prefix '{PREFIX}'"
111 )))
112 }
113 }
114
115 pub fn to_bytes(&self) -> [u8; ED25519_PRIVATE_KEY_LENGTH] {
120 self.inner.to_bytes()
121 }
122
123 pub fn to_hex(&self) -> String {
125 const_hex::encode_prefixed(self.inner.to_bytes())
126 }
127
128 pub fn to_aip80(&self) -> String {
142 format!("ed25519-priv-{}", self.to_hex())
143 }
144
145 pub fn public_key(&self) -> Ed25519PublicKey {
147 Ed25519PublicKey {
148 inner: self.inner.verifying_key(),
149 }
150 }
151
152 pub fn sign(&self, message: &[u8]) -> Ed25519Signature {
154 let signature = self.inner.sign(message);
155 Ed25519Signature { inner: signature }
156 }
157}
158
159impl Signer for Ed25519PrivateKey {
160 type Signature = Ed25519Signature;
161
162 fn sign(&self, message: &[u8]) -> Ed25519Signature {
163 Ed25519PrivateKey::sign(self, message)
164 }
165
166 fn public_key(&self) -> Ed25519PublicKey {
167 Ed25519PrivateKey::public_key(self)
168 }
169}
170
171impl fmt::Debug for Ed25519PrivateKey {
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 write!(f, "Ed25519PrivateKey([REDACTED])")
174 }
175}
176
177#[derive(Clone, Copy, PartialEq, Eq)]
193pub struct Ed25519PublicKey {
194 inner: ed25519_dalek::VerifyingKey,
195}
196
197impl Ed25519PublicKey {
198 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
206 if bytes.len() != ED25519_PUBLIC_KEY_LENGTH {
207 return Err(AptosError::InvalidPublicKey(format!(
208 "expected {} bytes, got {}",
209 ED25519_PUBLIC_KEY_LENGTH,
210 bytes.len()
211 )));
212 }
213 let mut key_bytes = [0u8; ED25519_PUBLIC_KEY_LENGTH];
214 key_bytes.copy_from_slice(bytes);
215 let verifying_key = ed25519_dalek::VerifyingKey::from_bytes(&key_bytes)
216 .map_err(|e| AptosError::InvalidPublicKey(e.to_string()))?;
217 Ok(Self {
218 inner: verifying_key,
219 })
220 }
221
222 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
229 let bytes = const_hex::decode(hex_str)?;
230 Self::from_bytes(&bytes)
231 }
232
233 pub fn from_aip80(s: &str) -> AptosResult<Self> {
241 const PREFIX: &str = "ed25519-pub-";
242 if let Some(hex_part) = s.strip_prefix(PREFIX) {
243 Self::from_hex(hex_part)
244 } else {
245 Err(AptosError::InvalidPublicKey(format!(
246 "invalid AIP-80 format: expected prefix '{PREFIX}'"
247 )))
248 }
249 }
250
251 pub fn to_bytes(&self) -> [u8; ED25519_PUBLIC_KEY_LENGTH] {
253 self.inner.to_bytes()
254 }
255
256 pub fn to_hex(&self) -> String {
258 const_hex::encode_prefixed(self.inner.to_bytes())
259 }
260
261 pub fn to_aip80(&self) -> String {
265 format!("ed25519-pub-{}", self.to_hex())
266 }
267
268 pub fn verify(&self, message: &[u8], signature: &Ed25519Signature) -> AptosResult<()> {
274 self.inner
275 .verify(message, &signature.inner)
276 .map_err(|_| AptosError::SignatureVerificationFailed)
277 }
278
279 pub fn to_address(&self) -> crate::types::AccountAddress {
283 crate::crypto::derive_address(&self.to_bytes(), crate::crypto::ED25519_SCHEME)
284 }
285
286 pub fn to_authentication_key(&self) -> [u8; 32] {
288 crate::crypto::derive_authentication_key(&self.to_bytes(), crate::crypto::ED25519_SCHEME)
289 }
290}
291
292impl PublicKey for Ed25519PublicKey {
293 const LENGTH: usize = ED25519_PUBLIC_KEY_LENGTH;
294
295 fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
296 Ed25519PublicKey::from_bytes(bytes)
297 }
298
299 fn to_bytes(&self) -> Vec<u8> {
300 self.inner.to_bytes().to_vec()
301 }
302}
303
304impl Verifier for Ed25519PublicKey {
305 type Signature = Ed25519Signature;
306
307 fn verify(&self, message: &[u8], signature: &Ed25519Signature) -> AptosResult<()> {
308 Ed25519PublicKey::verify(self, message, signature)
309 }
310}
311
312impl fmt::Debug for Ed25519PublicKey {
313 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
314 write!(f, "Ed25519PublicKey({})", self.to_hex())
315 }
316}
317
318impl fmt::Display for Ed25519PublicKey {
319 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
320 write!(f, "{}", self.to_hex())
321 }
322}
323
324impl Serialize for Ed25519PublicKey {
325 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
326 where
327 S: serde::Serializer,
328 {
329 if serializer.is_human_readable() {
330 serializer.serialize_str(&self.to_hex())
331 } else {
332 serializer.serialize_bytes(&self.inner.to_bytes())
333 }
334 }
335}
336
337impl<'de> Deserialize<'de> for Ed25519PublicKey {
338 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
339 where
340 D: serde::Deserializer<'de>,
341 {
342 if deserializer.is_human_readable() {
343 let s = String::deserialize(deserializer)?;
344 Self::from_hex(&s).map_err(serde::de::Error::custom)
345 } else {
346 let bytes = <[u8; ED25519_PUBLIC_KEY_LENGTH]>::deserialize(deserializer)?;
347 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
348 }
349 }
350}
351
352#[derive(Clone, Copy, PartialEq, Eq)]
354pub struct Ed25519Signature {
355 inner: ed25519_dalek::Signature,
356}
357
358impl Ed25519Signature {
359 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
372 if bytes.len() != ED25519_SIGNATURE_LENGTH {
373 return Err(AptosError::InvalidSignature(format!(
374 "expected {} bytes, got {}",
375 ED25519_SIGNATURE_LENGTH,
376 bytes.len()
377 )));
378 }
379 let signature = ed25519_dalek::Signature::from_slice(bytes)
380 .map_err(|e| AptosError::InvalidSignature(e.to_string()))?;
381 Ok(Self { inner: signature })
382 }
383
384 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
393 let bytes = const_hex::decode(hex_str)?;
394 Self::from_bytes(&bytes)
395 }
396
397 pub fn to_bytes(&self) -> [u8; ED25519_SIGNATURE_LENGTH] {
399 self.inner.to_bytes()
400 }
401
402 pub fn to_hex(&self) -> String {
404 const_hex::encode_prefixed(self.inner.to_bytes())
405 }
406}
407
408impl Signature for Ed25519Signature {
409 type PublicKey = Ed25519PublicKey;
410 const LENGTH: usize = ED25519_SIGNATURE_LENGTH;
411
412 fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
413 Ed25519Signature::from_bytes(bytes)
414 }
415
416 fn to_bytes(&self) -> Vec<u8> {
417 self.inner.to_bytes().to_vec()
418 }
419}
420
421impl fmt::Debug for Ed25519Signature {
422 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
423 write!(f, "Ed25519Signature({})", self.to_hex())
424 }
425}
426
427impl fmt::Display for Ed25519Signature {
428 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
429 write!(f, "{}", self.to_hex())
430 }
431}
432
433impl Serialize for Ed25519Signature {
434 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
435 where
436 S: serde::Serializer,
437 {
438 if serializer.is_human_readable() {
439 serializer.serialize_str(&self.to_hex())
440 } else {
441 serializer.serialize_bytes(&self.inner.to_bytes())
442 }
443 }
444}
445
446impl<'de> Deserialize<'de> for Ed25519Signature {
447 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
448 where
449 D: serde::Deserializer<'de>,
450 {
451 if deserializer.is_human_readable() {
452 let s = String::deserialize(deserializer)?;
453 Self::from_hex(&s).map_err(serde::de::Error::custom)
454 } else {
455 let bytes = Vec::<u8>::deserialize(deserializer)?;
456 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
457 }
458 }
459}
460
461#[cfg(test)]
462mod tests {
463 use super::*;
464
465 #[test]
466 fn test_generate_and_sign() {
467 let private_key = Ed25519PrivateKey::generate();
468 let message = b"hello world";
469 let signature = private_key.sign(message);
470
471 let public_key = private_key.public_key();
472 assert!(public_key.verify(message, &signature).is_ok());
473 }
474
475 #[test]
476 fn test_wrong_message_fails() {
477 let private_key = Ed25519PrivateKey::generate();
478 let message = b"hello world";
479 let wrong_message = b"hello world!";
480 let signature = private_key.sign(message);
481
482 let public_key = private_key.public_key();
483 assert!(public_key.verify(wrong_message, &signature).is_err());
484 }
485
486 #[test]
487 fn test_from_bytes_roundtrip() {
488 let private_key = Ed25519PrivateKey::generate();
489 let bytes = private_key.to_bytes();
490 let restored = Ed25519PrivateKey::from_bytes(&bytes).unwrap();
491 assert_eq!(private_key.to_bytes(), restored.to_bytes());
492 }
493
494 #[test]
495 fn test_from_hex_roundtrip() {
496 let private_key = Ed25519PrivateKey::generate();
497 let hex = private_key.to_hex();
498 let restored = Ed25519PrivateKey::from_hex(&hex).unwrap();
499 assert_eq!(private_key.to_bytes(), restored.to_bytes());
500 }
501
502 #[test]
503 fn test_public_key_serialization() {
504 let private_key = Ed25519PrivateKey::generate();
505 let public_key = private_key.public_key();
506
507 let json = serde_json::to_string(&public_key).unwrap();
508 let restored: Ed25519PublicKey = serde_json::from_str(&json).unwrap();
509 assert_eq!(public_key, restored);
510 }
511
512 #[test]
513 fn test_address_derivation() {
514 let private_key = Ed25519PrivateKey::generate();
515 let public_key = private_key.public_key();
516 let address = public_key.to_address();
517
518 assert!(!address.is_zero());
520
521 let address2 = public_key.to_address();
523 assert_eq!(address, address2);
524 }
525
526 #[test]
527 fn test_private_key_aip80_roundtrip() {
528 let private_key = Ed25519PrivateKey::generate();
529 let aip80 = private_key.to_aip80();
530
531 assert!(aip80.starts_with("ed25519-priv-0x"));
533
534 let restored = Ed25519PrivateKey::from_aip80(&aip80).unwrap();
536 assert_eq!(private_key.to_bytes(), restored.to_bytes());
537 }
538
539 #[test]
540 fn test_private_key_aip80_format() {
541 let bytes = [0x01; 32];
542 let private_key = Ed25519PrivateKey::from_bytes(&bytes).unwrap();
543 let aip80 = private_key.to_aip80();
544
545 let expected = format!("ed25519-priv-0x{}", "01".repeat(32));
547 assert_eq!(aip80, expected);
548 }
549
550 #[test]
551 fn test_private_key_aip80_invalid_prefix() {
552 let result = Ed25519PrivateKey::from_aip80("secp256k1-priv-0x01");
553 assert!(result.is_err());
554 }
555
556 #[test]
557 fn test_public_key_aip80_roundtrip() {
558 let private_key = Ed25519PrivateKey::generate();
559 let public_key = private_key.public_key();
560 let aip80 = public_key.to_aip80();
561
562 assert!(aip80.starts_with("ed25519-pub-0x"));
564
565 let restored = Ed25519PublicKey::from_aip80(&aip80).unwrap();
567 assert_eq!(public_key.to_bytes(), restored.to_bytes());
568 }
569
570 #[test]
571 fn test_public_key_aip80_invalid_prefix() {
572 let result = Ed25519PublicKey::from_aip80("secp256k1-pub-0x01");
573 assert!(result.is_err());
574 }
575
576 #[test]
577 fn test_invalid_private_key_bytes_length() {
578 let bytes = vec![0u8; 16]; let result = Ed25519PrivateKey::from_bytes(&bytes);
580 assert!(result.is_err());
581 }
582
583 #[test]
584 fn test_invalid_public_key_bytes_length() {
585 let bytes = vec![0u8; 16]; let result = Ed25519PublicKey::from_bytes(&bytes);
587 assert!(result.is_err());
588 }
589
590 #[test]
591 fn test_invalid_signature_bytes_length() {
592 let bytes = vec![0u8; 32]; let result = Ed25519Signature::from_bytes(&bytes);
594 assert!(result.is_err());
595 }
596
597 #[test]
598 fn test_public_key_from_hex_roundtrip() {
599 let private_key = Ed25519PrivateKey::generate();
600 let public_key = private_key.public_key();
601 let hex = public_key.to_hex();
602 let restored = Ed25519PublicKey::from_hex(&hex).unwrap();
603 assert_eq!(public_key, restored);
604 }
605
606 #[test]
607 fn test_signature_from_hex_roundtrip() {
608 let private_key = Ed25519PrivateKey::generate();
609 let signature = private_key.sign(b"test");
610 let hex = signature.to_hex();
611 let restored = Ed25519Signature::from_hex(&hex).unwrap();
612 assert_eq!(signature.to_bytes(), restored.to_bytes());
613 }
614
615 #[test]
616 fn test_public_key_bytes_roundtrip() {
617 let private_key = Ed25519PrivateKey::generate();
618 let public_key = private_key.public_key();
619 let bytes = public_key.to_bytes();
620 let restored = Ed25519PublicKey::from_bytes(&bytes).unwrap();
621 assert_eq!(public_key, restored);
622 }
623
624 #[test]
625 fn test_signature_bytes_roundtrip() {
626 let private_key = Ed25519PrivateKey::generate();
627 let signature = private_key.sign(b"test");
628 let bytes = signature.to_bytes();
629 let restored = Ed25519Signature::from_bytes(&bytes).unwrap();
630 assert_eq!(signature.to_bytes(), restored.to_bytes());
631 }
632
633 #[test]
634 fn test_private_key_debug() {
635 let private_key = Ed25519PrivateKey::generate();
636 let debug = format!("{private_key:?}");
637 assert!(debug.contains("REDACTED"));
638 assert!(!debug.contains(&private_key.to_hex()));
639 }
640
641 #[test]
642 fn test_public_key_debug() {
643 let private_key = Ed25519PrivateKey::generate();
644 let public_key = private_key.public_key();
645 let debug = format!("{public_key:?}");
646 assert!(debug.contains("Ed25519PublicKey"));
647 }
648
649 #[test]
650 fn test_public_key_display() {
651 let private_key = Ed25519PrivateKey::generate();
652 let public_key = private_key.public_key();
653 let display = format!("{public_key}");
654 assert!(display.starts_with("0x"));
655 }
656
657 #[test]
658 fn test_signature_debug() {
659 let private_key = Ed25519PrivateKey::generate();
660 let signature = private_key.sign(b"test");
661 let debug = format!("{signature:?}");
662 assert!(debug.contains("Ed25519Signature"));
663 }
664
665 #[test]
666 fn test_signature_display() {
667 let private_key = Ed25519PrivateKey::generate();
668 let signature = private_key.sign(b"test");
669 let display = format!("{signature}");
670 assert!(display.starts_with("0x"));
671 }
672
673 #[test]
674 fn test_signer_trait() {
675 use crate::crypto::traits::Signer;
676
677 let private_key = Ed25519PrivateKey::generate();
678 let message = b"trait test";
679
680 let signature = Signer::sign(&private_key, message);
681 let public_key = Signer::public_key(&private_key);
682
683 assert!(public_key.verify(message, &signature).is_ok());
684 }
685
686 #[test]
687 fn test_verifier_trait() {
688 use crate::crypto::traits::Verifier;
689
690 let private_key = Ed25519PrivateKey::generate();
691 let public_key = private_key.public_key();
692 let message = b"verifier test";
693 let signature = private_key.sign(message);
694
695 assert!(Verifier::verify(&public_key, message, &signature).is_ok());
696 }
697
698 #[test]
699 fn test_public_key_trait() {
700 use crate::crypto::traits::PublicKey;
701
702 let private_key = Ed25519PrivateKey::generate();
703 let public_key = private_key.public_key();
704 let bytes = PublicKey::to_bytes(&public_key);
705 let restored = Ed25519PublicKey::from_bytes(&bytes).unwrap();
706 assert_eq!(public_key, restored);
707 }
708
709 #[test]
710 fn test_signature_trait() {
711 use crate::crypto::traits::Signature;
712
713 let private_key = Ed25519PrivateKey::generate();
714 let signature = private_key.sign(b"test");
715 let bytes = Signature::to_bytes(&signature);
716 let restored = Ed25519Signature::from_bytes(&bytes).unwrap();
717 assert_eq!(signature.to_bytes(), restored.to_bytes());
718 }
719
720 #[test]
721 fn test_authentication_key() {
722 let private_key = Ed25519PrivateKey::generate();
723 let public_key = private_key.public_key();
724 let auth_key = public_key.to_authentication_key();
725 assert_eq!(auth_key.len(), 32);
726 }
727
728 #[test]
729 fn test_signature_json_serialization() {
730 let private_key = Ed25519PrivateKey::generate();
731 let signature = private_key.sign(b"test");
732
733 let json = serde_json::to_string(&signature).unwrap();
734 let restored: Ed25519Signature = serde_json::from_str(&json).unwrap();
735 assert_eq!(signature.to_bytes(), restored.to_bytes());
736 }
737
738 #[test]
739 fn test_private_key_clone() {
740 let private_key = Ed25519PrivateKey::generate();
741 let cloned = private_key.clone();
742 assert_eq!(private_key.to_bytes(), cloned.to_bytes());
743 }
744
745 #[test]
746 fn test_public_key_equality() {
747 let private_key = Ed25519PrivateKey::generate();
748 let pk1 = private_key.public_key();
749 let pk2 = private_key.public_key();
750 assert_eq!(pk1, pk2);
751
752 let different = Ed25519PrivateKey::generate().public_key();
753 assert_ne!(pk1, different);
754 }
755
756 #[test]
762 fn test_inner_key_zeroizes_on_drop() {
763 fn assert_zeroize_on_drop<T: zeroize::ZeroizeOnDrop>() {}
764 assert_zeroize_on_drop::<ed25519_dalek::SigningKey>();
765 }
766}