1use crate::types::AccountAddress;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct Ed25519PublicKey(pub [u8; 32]);
10
11impl Serialize for Ed25519PublicKey {
12 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
13 serde_bytes::Bytes::new(&self.0).serialize(serializer)
16 }
17}
18
19impl<'de> Deserialize<'de> for Ed25519PublicKey {
20 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
21 let bytes: Vec<u8> = serde_bytes::deserialize(deserializer)?;
23 if bytes.len() != 32 {
24 return Err(serde::de::Error::invalid_length(bytes.len(), &"32 bytes"));
25 }
26 let mut arr = [0u8; 32];
27 arr.copy_from_slice(&bytes);
28 Ok(Ed25519PublicKey(arr))
29 }
30}
31
32impl From<Vec<u8>> for Ed25519PublicKey {
33 fn from(bytes: Vec<u8>) -> Self {
40 assert!(
41 bytes.len() == 32,
42 "Ed25519PublicKey requires exactly 32 bytes, got {}",
43 bytes.len()
44 );
45 let mut arr = [0u8; 32];
46 arr.copy_from_slice(&bytes);
47 Ed25519PublicKey(arr)
48 }
49}
50
51impl Ed25519PublicKey {
52 pub fn try_from_bytes(bytes: &[u8]) -> crate::error::AptosResult<Self> {
60 if bytes.len() != 32 {
61 return Err(crate::error::AptosError::InvalidPublicKey(format!(
62 "Ed25519PublicKey requires exactly 32 bytes, got {}",
63 bytes.len()
64 )));
65 }
66 let mut arr = [0u8; 32];
67 arr.copy_from_slice(bytes);
68 Ok(Ed25519PublicKey(arr))
69 }
70}
71
72#[derive(Clone, Debug, PartialEq, Eq)]
75pub struct Ed25519Signature(pub [u8; 64]);
76
77impl Serialize for Ed25519Signature {
78 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
79 serde_bytes::Bytes::new(&self.0).serialize(serializer)
82 }
83}
84
85impl<'de> Deserialize<'de> for Ed25519Signature {
86 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
87 let bytes: Vec<u8> = serde_bytes::deserialize(deserializer)?;
89 if bytes.len() != 64 {
90 return Err(serde::de::Error::invalid_length(bytes.len(), &"64 bytes"));
91 }
92 let mut arr = [0u8; 64];
93 arr.copy_from_slice(&bytes);
94 Ok(Ed25519Signature(arr))
95 }
96}
97
98impl From<Vec<u8>> for Ed25519Signature {
99 fn from(bytes: Vec<u8>) -> Self {
106 assert!(
107 bytes.len() == 64,
108 "Ed25519Signature requires exactly 64 bytes, got {}",
109 bytes.len()
110 );
111 let mut arr = [0u8; 64];
112 arr.copy_from_slice(&bytes);
113 Ed25519Signature(arr)
114 }
115}
116
117impl Ed25519Signature {
118 pub fn try_from_bytes(bytes: &[u8]) -> crate::error::AptosResult<Self> {
124 if bytes.len() != 64 {
125 return Err(crate::error::AptosError::InvalidSignature(format!(
126 "Ed25519Signature requires exactly 64 bytes, got {}",
127 bytes.len()
128 )));
129 }
130 let mut arr = [0u8; 64];
131 arr.copy_from_slice(bytes);
132 Ok(Ed25519Signature(arr))
133 }
134}
135
136#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
148pub enum TransactionAuthenticator {
149 Ed25519 {
151 public_key: Ed25519PublicKey,
153 signature: Ed25519Signature,
155 },
156 MultiEd25519 {
158 public_key: Vec<u8>,
160 signature: Vec<u8>,
162 },
163 MultiAgent {
165 sender: AccountAuthenticator,
167 secondary_signer_addresses: Vec<AccountAddress>,
169 secondary_signers: Vec<AccountAuthenticator>,
171 },
172 FeePayer {
174 sender: AccountAuthenticator,
176 secondary_signer_addresses: Vec<AccountAddress>,
178 secondary_signers: Vec<AccountAuthenticator>,
180 fee_payer_address: AccountAddress,
182 fee_payer_signer: AccountAuthenticator,
184 },
185 SingleSender {
188 sender: AccountAuthenticator,
190 },
191}
192
193#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
195pub enum AccountAuthenticator {
196 Ed25519 {
198 public_key: Ed25519PublicKey,
200 signature: Ed25519Signature,
202 },
203 MultiEd25519 {
205 public_key: Vec<u8>,
207 signature: Vec<u8>,
209 },
210 SingleKey {
212 public_key: Vec<u8>,
214 signature: Vec<u8>,
216 },
217 MultiKey {
219 public_key: Vec<u8>,
221 signature: Vec<u8>,
223 },
224 NoAccountAuthenticator,
226 #[cfg(feature = "keyless")]
229 #[cfg_attr(docsrs, doc(cfg(feature = "keyless")))]
230 Keyless {
231 public_key: Vec<u8>,
233 signature: Vec<u8>,
235 },
236}
237
238#[derive(Clone, Debug, PartialEq, Eq)]
240pub struct Ed25519Authenticator {
241 pub public_key: Vec<u8>,
243 pub signature: Vec<u8>,
245}
246
247impl Ed25519Authenticator {
248 pub fn new(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
250 Self {
251 public_key,
252 signature,
253 }
254 }
255}
256
257impl From<Ed25519Authenticator> for TransactionAuthenticator {
258 fn from(auth: Ed25519Authenticator) -> Self {
259 TransactionAuthenticator::Ed25519 {
260 public_key: auth.public_key.into(),
261 signature: auth.signature.into(),
262 }
263 }
264}
265
266impl From<Ed25519Authenticator> for AccountAuthenticator {
267 fn from(auth: Ed25519Authenticator) -> Self {
268 AccountAuthenticator::Ed25519 {
269 public_key: auth.public_key.into(),
270 signature: auth.signature.into(),
271 }
272 }
273}
274
275impl TransactionAuthenticator {
276 pub fn ed25519(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
278 Self::Ed25519 {
279 public_key: public_key.into(),
280 signature: signature.into(),
281 }
282 }
283
284 pub fn multi_ed25519(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
286 Self::MultiEd25519 {
287 public_key,
288 signature,
289 }
290 }
291
292 pub fn multi_agent(
294 sender: AccountAuthenticator,
295 secondary_signer_addresses: Vec<AccountAddress>,
296 secondary_signers: Vec<AccountAuthenticator>,
297 ) -> Self {
298 Self::MultiAgent {
299 sender,
300 secondary_signer_addresses,
301 secondary_signers,
302 }
303 }
304
305 pub fn fee_payer(
307 sender: AccountAuthenticator,
308 secondary_signer_addresses: Vec<AccountAddress>,
309 secondary_signers: Vec<AccountAuthenticator>,
310 fee_payer_address: AccountAddress,
311 fee_payer_signer: AccountAuthenticator,
312 ) -> Self {
313 Self::FeePayer {
314 sender,
315 secondary_signer_addresses,
316 secondary_signers,
317 fee_payer_address,
318 fee_payer_signer,
319 }
320 }
321
322 pub fn single_sender(sender: AccountAuthenticator) -> Self {
325 Self::SingleSender { sender }
326 }
327}
328
329impl AccountAuthenticator {
330 pub fn ed25519(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
332 Self::Ed25519 {
333 public_key: public_key.into(),
334 signature: signature.into(),
335 }
336 }
337 pub fn single_key(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
339 Self::SingleKey {
340 public_key,
341 signature,
342 }
343 }
344
345 pub fn multi_key(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
347 Self::MultiKey {
348 public_key,
349 signature,
350 }
351 }
352
353 pub fn no_account_authenticator() -> Self {
355 Self::NoAccountAuthenticator
356 }
357
358 #[cfg(feature = "keyless")]
365 #[cfg_attr(docsrs, doc(cfg(feature = "keyless")))]
366 pub fn keyless(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
367 Self::Keyless {
368 public_key,
369 signature,
370 }
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use super::*;
377
378 #[test]
379 fn test_ed25519_authenticator() {
380 let mut pk = [0u8; 32];
381 pk[0..3].copy_from_slice(&[1, 2, 3]);
382 let mut sig = [0u8; 64];
383 sig[0..3].copy_from_slice(&[4, 5, 6]);
384
385 let auth = Ed25519Authenticator::new(pk.to_vec(), sig.to_vec());
386 let txn_auth: TransactionAuthenticator = auth.into();
387
388 match txn_auth {
389 TransactionAuthenticator::Ed25519 {
390 public_key,
391 signature,
392 } => {
393 assert_eq!(public_key.0[0..3], [1, 2, 3]);
394 assert_eq!(signature.0[0..3], [4, 5, 6]);
395 }
396 _ => panic!("wrong authenticator type"),
397 }
398 }
399
400 #[test]
401 fn test_multi_agent_authenticator() {
402 let sender = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
403 let auth = TransactionAuthenticator::multi_agent(sender, vec![], vec![]);
404
405 match auth {
406 TransactionAuthenticator::MultiAgent { .. } => {}
407 _ => panic!("wrong authenticator type"),
408 }
409 }
410
411 #[test]
412 fn test_ed25519_bcs_format() {
413 let auth = TransactionAuthenticator::Ed25519 {
415 public_key: Ed25519PublicKey([0xab; 32]),
416 signature: Ed25519Signature([0xcd; 64]),
417 };
418 let bcs = aptos_bcs::to_bytes(&auth).unwrap();
419
420 assert_eq!(bcs[0], 0, "Ed25519 variant index should be 0");
422 assert_eq!(bcs[1], 32, "Pubkey length prefix should be 32");
424 assert_eq!(bcs[2], 0xab, "First pubkey byte should be 0xab");
426 assert_eq!(bcs[34], 64, "Signature length prefix should be 64");
428 assert_eq!(bcs[35], 0xcd, "First signature byte should be 0xcd");
430 assert_eq!(bcs.len(), 99, "BCS length should be 99");
432 }
433
434 #[test]
435 fn test_ed25519_authenticator_into_account_authenticator() {
436 let auth = Ed25519Authenticator::new(vec![0xaa; 32], vec![0xbb; 64]);
437 let account_auth: AccountAuthenticator = auth.into();
438
439 match account_auth {
440 AccountAuthenticator::Ed25519 {
441 public_key,
442 signature,
443 } => {
444 assert_eq!(public_key.0[0], 0xaa);
445 assert_eq!(signature.0[0], 0xbb);
446 }
447 _ => panic!("Expected Ed25519 variant"),
448 }
449 }
450
451 #[test]
452 fn test_transaction_authenticator_ed25519() {
453 let auth = TransactionAuthenticator::ed25519(vec![0x11; 32], vec![0x22; 64]);
454 match auth {
455 TransactionAuthenticator::Ed25519 {
456 public_key,
457 signature,
458 } => {
459 assert_eq!(public_key.0[0], 0x11);
460 assert_eq!(signature.0[0], 0x22);
461 }
462 _ => panic!("Expected Ed25519 variant"),
463 }
464 }
465
466 #[test]
467 fn test_transaction_authenticator_multi_ed25519() {
468 let auth = TransactionAuthenticator::multi_ed25519(vec![0x33; 64], vec![0x44; 128]);
469 match auth {
470 TransactionAuthenticator::MultiEd25519 {
471 public_key,
472 signature,
473 } => {
474 assert_eq!(public_key.len(), 64);
475 assert_eq!(signature.len(), 128);
476 }
477 _ => panic!("Expected MultiEd25519 variant"),
478 }
479 }
480
481 #[test]
482 fn test_fee_payer_authenticator() {
483 let sender = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
484 let fee_payer = AccountAuthenticator::ed25519(vec![1; 32], vec![1; 64]);
485 let fee_payer_address = AccountAddress::from_hex("0x123").unwrap();
486
487 let auth = TransactionAuthenticator::fee_payer(
488 sender,
489 vec![],
490 vec![],
491 fee_payer_address,
492 fee_payer,
493 );
494
495 match auth {
496 TransactionAuthenticator::FeePayer {
497 fee_payer_address: addr,
498 ..
499 } => {
500 assert_eq!(addr, fee_payer_address);
501 }
502 _ => panic!("Expected FeePayer variant"),
503 }
504 }
505
506 #[test]
507 fn test_single_sender_authenticator() {
508 let sender = AccountAuthenticator::ed25519(vec![0x55; 32], vec![0x66; 64]);
509 let auth = TransactionAuthenticator::single_sender(sender);
510
511 match auth {
512 TransactionAuthenticator::SingleSender { sender } => match sender {
513 AccountAuthenticator::Ed25519 { public_key, .. } => {
514 assert_eq!(public_key.0[0], 0x55);
515 }
516 _ => panic!("Expected Ed25519 sender"),
517 },
518 _ => panic!("Expected SingleSender variant"),
519 }
520 }
521
522 #[test]
523 fn test_account_authenticator_multi_key() {
524 let auth = AccountAuthenticator::multi_key(vec![0x77; 100], vec![0x88; 200]);
525 match auth {
526 AccountAuthenticator::MultiKey {
527 public_key,
528 signature,
529 } => {
530 assert_eq!(public_key.len(), 100);
531 assert_eq!(signature.len(), 200);
532 }
533 _ => panic!("Expected MultiKey variant"),
534 }
535 }
536
537 #[test]
538 fn test_ed25519_public_key_from_vec() {
539 let pk: Ed25519PublicKey = vec![0x12; 32].into();
540 assert_eq!(pk.0[0], 0x12);
541 assert_eq!(pk.0.len(), 32);
542 }
543
544 #[test]
545 fn test_ed25519_signature_from_vec() {
546 let sig: Ed25519Signature = vec![0x34; 64].into();
547 assert_eq!(sig.0[0], 0x34);
548 assert_eq!(sig.0.len(), 64);
549 }
550
551 #[test]
552 fn test_ed25519_public_key_bcs_roundtrip() {
553 let pk = Ed25519PublicKey([0xef; 32]);
554 let serialized = aptos_bcs::to_bytes(&pk).unwrap();
555 assert_eq!(serialized.len(), 33);
557 assert_eq!(serialized[0], 32); let deserialized: Ed25519PublicKey = aptos_bcs::from_bytes(&serialized).unwrap();
559 assert_eq!(pk, deserialized);
560 }
561
562 #[test]
563 fn test_ed25519_signature_bcs_roundtrip() {
564 let sig = Ed25519Signature([0x99; 64]);
565 let serialized = aptos_bcs::to_bytes(&sig).unwrap();
566 let deserialized: Ed25519Signature = aptos_bcs::from_bytes(&serialized).unwrap();
567 assert_eq!(sig, deserialized);
568 }
569
570 #[test]
571 fn test_multi_agent_with_secondary_signers() {
572 let sender = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
573 let secondary_signer1 = AccountAuthenticator::ed25519(vec![1; 32], vec![1; 64]);
574 let secondary_signer2 = AccountAuthenticator::ed25519(vec![2; 32], vec![2; 64]);
575 let addr1 = AccountAddress::from_hex("0x111").unwrap();
576 let addr2 = AccountAddress::from_hex("0x222").unwrap();
577
578 let auth = TransactionAuthenticator::multi_agent(
579 sender,
580 vec![addr1, addr2],
581 vec![secondary_signer1, secondary_signer2],
582 );
583
584 match auth {
585 TransactionAuthenticator::MultiAgent {
586 secondary_signer_addresses,
587 secondary_signers,
588 ..
589 } => {
590 assert_eq!(secondary_signer_addresses.len(), 2);
591 assert_eq!(secondary_signers.len(), 2);
592 }
593 _ => panic!("Expected MultiAgent variant"),
594 }
595 }
596
597 #[test]
598 fn test_transaction_authenticator_bcs_roundtrip() {
599 let auth = TransactionAuthenticator::Ed25519 {
600 public_key: Ed25519PublicKey([0x11; 32]),
601 signature: Ed25519Signature([0x22; 64]),
602 };
603
604 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
605 let deserialized: TransactionAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
606
607 assert_eq!(auth, deserialized);
608 }
609
610 #[test]
611 fn test_account_authenticator_bcs_roundtrip() {
612 let auth = AccountAuthenticator::Ed25519 {
613 public_key: Ed25519PublicKey([0x33; 32]),
614 signature: Ed25519Signature([0x44; 64]),
615 };
616
617 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
618 let deserialized: AccountAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
619
620 assert_eq!(auth, deserialized);
621 }
622
623 #[test]
624 fn test_account_authenticator_single_key() {
625 let auth = AccountAuthenticator::single_key(vec![0x55; 33], vec![0x66; 65]);
626 match auth {
627 AccountAuthenticator::SingleKey {
628 public_key,
629 signature,
630 } => {
631 assert_eq!(public_key.len(), 33);
632 assert_eq!(signature.len(), 65);
633 }
634 _ => panic!("Expected SingleKey variant"),
635 }
636 }
637
638 #[test]
639 fn test_account_authenticator_single_key_bcs_roundtrip() {
640 let auth = AccountAuthenticator::SingleKey {
641 public_key: vec![0x77; 33],
642 signature: vec![0x88; 65],
643 };
644
645 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
646 assert_eq!(serialized[0], 2, "SingleKey variant index should be 2");
648 let deserialized: AccountAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
649 assert_eq!(auth, deserialized);
650 }
651
652 #[test]
653 fn test_no_account_authenticator() {
654 let auth = AccountAuthenticator::no_account_authenticator();
655 match auth {
656 AccountAuthenticator::NoAccountAuthenticator => {}
657 _ => panic!("Expected NoAccountAuthenticator variant"),
658 }
659 }
660
661 #[test]
662 fn test_no_account_authenticator_bcs_roundtrip() {
663 let auth = AccountAuthenticator::NoAccountAuthenticator;
664
665 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
666 assert_eq!(
668 serialized[0], 4,
669 "NoAccountAuthenticator variant index should be 4"
670 );
671 assert_eq!(
673 serialized.len(),
674 1,
675 "NoAccountAuthenticator should be 1 byte"
676 );
677 let deserialized: AccountAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
678 assert_eq!(auth, deserialized);
679 }
680
681 #[test]
682 fn test_single_sender_with_single_key() {
683 let sender = AccountAuthenticator::single_key(vec![0x99; 33], vec![0xaa; 65]);
684 let auth = TransactionAuthenticator::single_sender(sender);
685
686 match auth {
687 TransactionAuthenticator::SingleSender { sender } => match sender {
688 AccountAuthenticator::SingleKey { public_key, .. } => {
689 assert_eq!(public_key.len(), 33);
690 }
691 _ => panic!("Expected SingleKey sender"),
692 },
693 _ => panic!("Expected SingleSender variant"),
694 }
695 }
696
697 #[test]
698 fn test_account_authenticator_variant_indices() {
699 let ed25519 = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
701 let multi_ed25519 = AccountAuthenticator::MultiEd25519 {
702 public_key: vec![0; 64],
703 signature: vec![0; 128],
704 };
705 let single_key = AccountAuthenticator::single_key(vec![0; 33], vec![0; 65]);
706 let multi_key = AccountAuthenticator::multi_key(vec![0; 100], vec![0; 200]);
707 let no_account = AccountAuthenticator::no_account_authenticator();
708
709 assert_eq!(aptos_bcs::to_bytes(&ed25519).unwrap()[0], 0, "Ed25519 = 0");
710 assert_eq!(
711 aptos_bcs::to_bytes(&multi_ed25519).unwrap()[0],
712 1,
713 "MultiEd25519 = 1"
714 );
715 assert_eq!(
716 aptos_bcs::to_bytes(&single_key).unwrap()[0],
717 2,
718 "SingleKey = 2"
719 );
720 assert_eq!(
721 aptos_bcs::to_bytes(&multi_key).unwrap()[0],
722 3,
723 "MultiKey = 3"
724 );
725 assert_eq!(
726 aptos_bcs::to_bytes(&no_account).unwrap()[0],
727 4,
728 "NoAccountAuthenticator = 4"
729 );
730 }
731
732 #[test]
733 fn test_ed25519_public_key_try_from_bytes_valid() {
734 let bytes = vec![0x12; 32];
735 let pk = Ed25519PublicKey::try_from_bytes(&bytes).unwrap();
736 assert_eq!(pk.0[0], 0x12);
737 }
738
739 #[test]
740 fn test_ed25519_public_key_try_from_bytes_invalid_length() {
741 let bytes = vec![0x12; 16]; let result = Ed25519PublicKey::try_from_bytes(&bytes);
743 assert!(result.is_err());
744 }
745
746 #[test]
747 fn test_ed25519_signature_try_from_bytes_valid() {
748 let bytes = vec![0x34; 64];
749 let sig = Ed25519Signature::try_from_bytes(&bytes).unwrap();
750 assert_eq!(sig.0[0], 0x34);
751 }
752
753 #[test]
754 fn test_ed25519_signature_try_from_bytes_invalid_length() {
755 let bytes = vec![0x34; 32]; let result = Ed25519Signature::try_from_bytes(&bytes);
757 assert!(result.is_err());
758 }
759
760 #[test]
761 fn test_transaction_authenticator_variant_indices() {
762 let ed25519 = TransactionAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
764 let multi_ed25519 = TransactionAuthenticator::multi_ed25519(vec![0; 64], vec![0; 128]);
765 let sender = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
766 let multi_agent = TransactionAuthenticator::multi_agent(sender.clone(), vec![], vec![]);
767 let fee_payer = TransactionAuthenticator::fee_payer(
768 sender.clone(),
769 vec![],
770 vec![],
771 AccountAddress::ONE,
772 sender.clone(),
773 );
774 let single_sender = TransactionAuthenticator::single_sender(sender);
775
776 assert_eq!(aptos_bcs::to_bytes(&ed25519).unwrap()[0], 0, "Ed25519 = 0");
777 assert_eq!(
778 aptos_bcs::to_bytes(&multi_ed25519).unwrap()[0],
779 1,
780 "MultiEd25519 = 1"
781 );
782 assert_eq!(
783 aptos_bcs::to_bytes(&multi_agent).unwrap()[0],
784 2,
785 "MultiAgent = 2"
786 );
787 assert_eq!(
788 aptos_bcs::to_bytes(&fee_payer).unwrap()[0],
789 3,
790 "FeePayer = 3"
791 );
792 assert_eq!(
793 aptos_bcs::to_bytes(&single_sender).unwrap()[0],
794 4,
795 "SingleSender = 4"
796 );
797 }
798
799 #[test]
800 fn test_multi_key_authenticator_bcs_roundtrip() {
801 let auth = AccountAuthenticator::multi_key(vec![0xaa; 100], vec![0xbb; 200]);
802
803 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
804 assert_eq!(serialized[0], 3, "MultiKey variant index should be 3");
806 let deserialized: AccountAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
807 assert_eq!(auth, deserialized);
808 }
809
810 #[test]
811 fn test_multi_ed25519_authenticator_bcs_roundtrip() {
812 let auth = AccountAuthenticator::MultiEd25519 {
813 public_key: vec![0xcc; 64],
814 signature: vec![0xdd; 128],
815 };
816
817 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
818 assert_eq!(serialized[0], 1, "MultiEd25519 variant index should be 1");
820 let deserialized: AccountAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
821 assert_eq!(auth, deserialized);
822 }
823
824 #[test]
825 fn test_ed25519_public_key_deserialize_invalid_length() {
826 let mut bytes = vec![16u8]; bytes.extend_from_slice(&[0xab; 16]); let result: Result<Ed25519PublicKey, _> = aptos_bcs::from_bytes(&bytes);
830 assert!(result.is_err());
831 }
832
833 #[test]
834 fn test_ed25519_signature_deserialize_invalid_length() {
835 let mut bytes = vec![32u8]; bytes.extend_from_slice(&[0xab; 32]); let result: Result<Ed25519Signature, _> = aptos_bcs::from_bytes(&bytes);
839 assert!(result.is_err());
840 }
841}