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 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> {
104 const PREFIX: &str = "ed25519-priv-";
105 if let Some(hex_part) = s.strip_prefix(PREFIX) {
106 Self::from_hex(hex_part)
107 } else {
108 Err(AptosError::InvalidPrivateKey(format!(
109 "invalid AIP-80 format: expected prefix '{PREFIX}'"
110 )))
111 }
112 }
113
114 pub fn to_bytes(&self) -> [u8; ED25519_PRIVATE_KEY_LENGTH] {
119 self.inner.to_bytes()
120 }
121
122 pub fn to_hex(&self) -> String {
124 format!("0x{}", hex::encode(self.inner.to_bytes()))
125 }
126
127 pub fn to_aip80(&self) -> String {
141 format!("ed25519-priv-{}", self.to_hex())
142 }
143
144 pub fn public_key(&self) -> Ed25519PublicKey {
146 Ed25519PublicKey {
147 inner: self.inner.verifying_key(),
148 }
149 }
150
151 pub fn sign(&self, message: &[u8]) -> Ed25519Signature {
153 let signature = self.inner.sign(message);
154 Ed25519Signature { inner: signature }
155 }
156}
157
158impl Signer for Ed25519PrivateKey {
159 type Signature = Ed25519Signature;
160
161 fn sign(&self, message: &[u8]) -> Ed25519Signature {
162 Ed25519PrivateKey::sign(self, message)
163 }
164
165 fn public_key(&self) -> Ed25519PublicKey {
166 Ed25519PrivateKey::public_key(self)
167 }
168}
169
170impl fmt::Debug for Ed25519PrivateKey {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 write!(f, "Ed25519PrivateKey([REDACTED])")
173 }
174}
175
176#[derive(Clone, Copy, PartialEq, Eq)]
192pub struct Ed25519PublicKey {
193 inner: ed25519_dalek::VerifyingKey,
194}
195
196impl Ed25519PublicKey {
197 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
205 if bytes.len() != ED25519_PUBLIC_KEY_LENGTH {
206 return Err(AptosError::InvalidPublicKey(format!(
207 "expected {} bytes, got {}",
208 ED25519_PUBLIC_KEY_LENGTH,
209 bytes.len()
210 )));
211 }
212 let mut key_bytes = [0u8; ED25519_PUBLIC_KEY_LENGTH];
213 key_bytes.copy_from_slice(bytes);
214 let verifying_key = ed25519_dalek::VerifyingKey::from_bytes(&key_bytes)
215 .map_err(|e| AptosError::InvalidPublicKey(e.to_string()))?;
216 Ok(Self {
217 inner: verifying_key,
218 })
219 }
220
221 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
228 let hex_str = hex_str.strip_prefix("0x").unwrap_or(hex_str);
229 let bytes = 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 format!("0x{}", hex::encode(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> {
367 if bytes.len() != ED25519_SIGNATURE_LENGTH {
368 return Err(AptosError::InvalidSignature(format!(
369 "expected {} bytes, got {}",
370 ED25519_SIGNATURE_LENGTH,
371 bytes.len()
372 )));
373 }
374 let signature = ed25519_dalek::Signature::from_slice(bytes)
375 .map_err(|e| AptosError::InvalidSignature(e.to_string()))?;
376 Ok(Self { inner: signature })
377 }
378
379 pub fn from_hex(hex_str: &str) -> AptosResult<Self> {
386 let hex_str = hex_str.strip_prefix("0x").unwrap_or(hex_str);
387 let bytes = hex::decode(hex_str)?;
388 Self::from_bytes(&bytes)
389 }
390
391 pub fn to_bytes(&self) -> [u8; ED25519_SIGNATURE_LENGTH] {
393 self.inner.to_bytes()
394 }
395
396 pub fn to_hex(&self) -> String {
398 format!("0x{}", hex::encode(self.inner.to_bytes()))
399 }
400}
401
402impl Signature for Ed25519Signature {
403 type PublicKey = Ed25519PublicKey;
404 const LENGTH: usize = ED25519_SIGNATURE_LENGTH;
405
406 fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
407 Ed25519Signature::from_bytes(bytes)
408 }
409
410 fn to_bytes(&self) -> Vec<u8> {
411 self.inner.to_bytes().to_vec()
412 }
413}
414
415impl fmt::Debug for Ed25519Signature {
416 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
417 write!(f, "Ed25519Signature({})", self.to_hex())
418 }
419}
420
421impl fmt::Display for Ed25519Signature {
422 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
423 write!(f, "{}", self.to_hex())
424 }
425}
426
427impl Serialize for Ed25519Signature {
428 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
429 where
430 S: serde::Serializer,
431 {
432 if serializer.is_human_readable() {
433 serializer.serialize_str(&self.to_hex())
434 } else {
435 serializer.serialize_bytes(&self.inner.to_bytes())
436 }
437 }
438}
439
440impl<'de> Deserialize<'de> for Ed25519Signature {
441 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
442 where
443 D: serde::Deserializer<'de>,
444 {
445 if deserializer.is_human_readable() {
446 let s = String::deserialize(deserializer)?;
447 Self::from_hex(&s).map_err(serde::de::Error::custom)
448 } else {
449 let bytes = Vec::<u8>::deserialize(deserializer)?;
450 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
451 }
452 }
453}
454
455#[cfg(test)]
456mod tests {
457 use super::*;
458
459 #[test]
460 fn test_generate_and_sign() {
461 let private_key = Ed25519PrivateKey::generate();
462 let message = b"hello world";
463 let signature = private_key.sign(message);
464
465 let public_key = private_key.public_key();
466 assert!(public_key.verify(message, &signature).is_ok());
467 }
468
469 #[test]
470 fn test_wrong_message_fails() {
471 let private_key = Ed25519PrivateKey::generate();
472 let message = b"hello world";
473 let wrong_message = b"hello world!";
474 let signature = private_key.sign(message);
475
476 let public_key = private_key.public_key();
477 assert!(public_key.verify(wrong_message, &signature).is_err());
478 }
479
480 #[test]
481 fn test_from_bytes_roundtrip() {
482 let private_key = Ed25519PrivateKey::generate();
483 let bytes = private_key.to_bytes();
484 let restored = Ed25519PrivateKey::from_bytes(&bytes).unwrap();
485 assert_eq!(private_key.to_bytes(), restored.to_bytes());
486 }
487
488 #[test]
489 fn test_from_hex_roundtrip() {
490 let private_key = Ed25519PrivateKey::generate();
491 let hex = private_key.to_hex();
492 let restored = Ed25519PrivateKey::from_hex(&hex).unwrap();
493 assert_eq!(private_key.to_bytes(), restored.to_bytes());
494 }
495
496 #[test]
497 fn test_public_key_serialization() {
498 let private_key = Ed25519PrivateKey::generate();
499 let public_key = private_key.public_key();
500
501 let json = serde_json::to_string(&public_key).unwrap();
502 let restored: Ed25519PublicKey = serde_json::from_str(&json).unwrap();
503 assert_eq!(public_key, restored);
504 }
505
506 #[test]
507 fn test_address_derivation() {
508 let private_key = Ed25519PrivateKey::generate();
509 let public_key = private_key.public_key();
510 let address = public_key.to_address();
511
512 assert!(!address.is_zero());
514
515 let address2 = public_key.to_address();
517 assert_eq!(address, address2);
518 }
519
520 #[test]
521 fn test_private_key_aip80_roundtrip() {
522 let private_key = Ed25519PrivateKey::generate();
523 let aip80 = private_key.to_aip80();
524
525 assert!(aip80.starts_with("ed25519-priv-0x"));
527
528 let restored = Ed25519PrivateKey::from_aip80(&aip80).unwrap();
530 assert_eq!(private_key.to_bytes(), restored.to_bytes());
531 }
532
533 #[test]
534 fn test_private_key_aip80_format() {
535 let bytes = [0x01; 32];
536 let private_key = Ed25519PrivateKey::from_bytes(&bytes).unwrap();
537 let aip80 = private_key.to_aip80();
538
539 let expected = format!("ed25519-priv-0x{}", "01".repeat(32));
541 assert_eq!(aip80, expected);
542 }
543
544 #[test]
545 fn test_private_key_aip80_invalid_prefix() {
546 let result = Ed25519PrivateKey::from_aip80("secp256k1-priv-0x01");
547 assert!(result.is_err());
548 }
549
550 #[test]
551 fn test_public_key_aip80_roundtrip() {
552 let private_key = Ed25519PrivateKey::generate();
553 let public_key = private_key.public_key();
554 let aip80 = public_key.to_aip80();
555
556 assert!(aip80.starts_with("ed25519-pub-0x"));
558
559 let restored = Ed25519PublicKey::from_aip80(&aip80).unwrap();
561 assert_eq!(public_key.to_bytes(), restored.to_bytes());
562 }
563
564 #[test]
565 fn test_public_key_aip80_invalid_prefix() {
566 let result = Ed25519PublicKey::from_aip80("secp256k1-pub-0x01");
567 assert!(result.is_err());
568 }
569
570 #[test]
571 fn test_invalid_private_key_bytes_length() {
572 let bytes = vec![0u8; 16]; let result = Ed25519PrivateKey::from_bytes(&bytes);
574 assert!(result.is_err());
575 }
576
577 #[test]
578 fn test_invalid_public_key_bytes_length() {
579 let bytes = vec![0u8; 16]; let result = Ed25519PublicKey::from_bytes(&bytes);
581 assert!(result.is_err());
582 }
583
584 #[test]
585 fn test_invalid_signature_bytes_length() {
586 let bytes = vec![0u8; 32]; let result = Ed25519Signature::from_bytes(&bytes);
588 assert!(result.is_err());
589 }
590
591 #[test]
592 fn test_public_key_from_hex_roundtrip() {
593 let private_key = Ed25519PrivateKey::generate();
594 let public_key = private_key.public_key();
595 let hex = public_key.to_hex();
596 let restored = Ed25519PublicKey::from_hex(&hex).unwrap();
597 assert_eq!(public_key, restored);
598 }
599
600 #[test]
601 fn test_signature_from_hex_roundtrip() {
602 let private_key = Ed25519PrivateKey::generate();
603 let signature = private_key.sign(b"test");
604 let hex = signature.to_hex();
605 let restored = Ed25519Signature::from_hex(&hex).unwrap();
606 assert_eq!(signature.to_bytes(), restored.to_bytes());
607 }
608
609 #[test]
610 fn test_public_key_bytes_roundtrip() {
611 let private_key = Ed25519PrivateKey::generate();
612 let public_key = private_key.public_key();
613 let bytes = public_key.to_bytes();
614 let restored = Ed25519PublicKey::from_bytes(&bytes).unwrap();
615 assert_eq!(public_key, restored);
616 }
617
618 #[test]
619 fn test_signature_bytes_roundtrip() {
620 let private_key = Ed25519PrivateKey::generate();
621 let signature = private_key.sign(b"test");
622 let bytes = signature.to_bytes();
623 let restored = Ed25519Signature::from_bytes(&bytes).unwrap();
624 assert_eq!(signature.to_bytes(), restored.to_bytes());
625 }
626
627 #[test]
628 fn test_private_key_debug() {
629 let private_key = Ed25519PrivateKey::generate();
630 let debug = format!("{private_key:?}");
631 assert!(debug.contains("REDACTED"));
632 assert!(!debug.contains(&private_key.to_hex()));
633 }
634
635 #[test]
636 fn test_public_key_debug() {
637 let private_key = Ed25519PrivateKey::generate();
638 let public_key = private_key.public_key();
639 let debug = format!("{public_key:?}");
640 assert!(debug.contains("Ed25519PublicKey"));
641 }
642
643 #[test]
644 fn test_public_key_display() {
645 let private_key = Ed25519PrivateKey::generate();
646 let public_key = private_key.public_key();
647 let display = format!("{public_key}");
648 assert!(display.starts_with("0x"));
649 }
650
651 #[test]
652 fn test_signature_debug() {
653 let private_key = Ed25519PrivateKey::generate();
654 let signature = private_key.sign(b"test");
655 let debug = format!("{signature:?}");
656 assert!(debug.contains("Ed25519Signature"));
657 }
658
659 #[test]
660 fn test_signature_display() {
661 let private_key = Ed25519PrivateKey::generate();
662 let signature = private_key.sign(b"test");
663 let display = format!("{signature}");
664 assert!(display.starts_with("0x"));
665 }
666
667 #[test]
668 fn test_signer_trait() {
669 use crate::crypto::traits::Signer;
670
671 let private_key = Ed25519PrivateKey::generate();
672 let message = b"trait test";
673
674 let signature = Signer::sign(&private_key, message);
675 let public_key = Signer::public_key(&private_key);
676
677 assert!(public_key.verify(message, &signature).is_ok());
678 }
679
680 #[test]
681 fn test_verifier_trait() {
682 use crate::crypto::traits::Verifier;
683
684 let private_key = Ed25519PrivateKey::generate();
685 let public_key = private_key.public_key();
686 let message = b"verifier test";
687 let signature = private_key.sign(message);
688
689 assert!(Verifier::verify(&public_key, message, &signature).is_ok());
690 }
691
692 #[test]
693 fn test_public_key_trait() {
694 use crate::crypto::traits::PublicKey;
695
696 let private_key = Ed25519PrivateKey::generate();
697 let public_key = private_key.public_key();
698 let bytes = PublicKey::to_bytes(&public_key);
699 let restored = Ed25519PublicKey::from_bytes(&bytes).unwrap();
700 assert_eq!(public_key, restored);
701 }
702
703 #[test]
704 fn test_signature_trait() {
705 use crate::crypto::traits::Signature;
706
707 let private_key = Ed25519PrivateKey::generate();
708 let signature = private_key.sign(b"test");
709 let bytes = Signature::to_bytes(&signature);
710 let restored = Ed25519Signature::from_bytes(&bytes).unwrap();
711 assert_eq!(signature.to_bytes(), restored.to_bytes());
712 }
713
714 #[test]
715 fn test_authentication_key() {
716 let private_key = Ed25519PrivateKey::generate();
717 let public_key = private_key.public_key();
718 let auth_key = public_key.to_authentication_key();
719 assert_eq!(auth_key.len(), 32);
720 }
721
722 #[test]
723 fn test_signature_json_serialization() {
724 let private_key = Ed25519PrivateKey::generate();
725 let signature = private_key.sign(b"test");
726
727 let json = serde_json::to_string(&signature).unwrap();
728 let restored: Ed25519Signature = serde_json::from_str(&json).unwrap();
729 assert_eq!(signature.to_bytes(), restored.to_bytes());
730 }
731
732 #[test]
733 fn test_private_key_clone() {
734 let private_key = Ed25519PrivateKey::generate();
735 let cloned = private_key.clone();
736 assert_eq!(private_key.to_bytes(), cloned.to_bytes());
737 }
738
739 #[test]
740 fn test_public_key_equality() {
741 let private_key = Ed25519PrivateKey::generate();
742 let pk1 = private_key.public_key();
743 let pk2 = private_key.public_key();
744 assert_eq!(pk1, pk2);
745
746 let different = Ed25519PrivateKey::generate().public_key();
747 assert_ne!(pk1, different);
748 }
749}