1use crate::types::AccountAddress;
4use serde::ser::{SerializeTuple, SerializeTupleVariant};
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6
7fn serialize_raw_bytes<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
21 let mut tup = serializer.serialize_tuple(bytes.len())?;
24 for byte in bytes {
25 tup.serialize_element(byte)?;
26 }
27 tup.end()
28}
29
30#[derive(Clone, Debug, PartialEq, Eq)]
33pub struct Ed25519PublicKey(pub [u8; 32]);
34
35impl Serialize for Ed25519PublicKey {
36 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
37 serde_bytes::Bytes::new(&self.0).serialize(serializer)
40 }
41}
42
43impl<'de> Deserialize<'de> for Ed25519PublicKey {
44 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
45 let bytes: Vec<u8> = serde_bytes::deserialize(deserializer)?;
47 if bytes.len() != 32 {
48 return Err(serde::de::Error::invalid_length(bytes.len(), &"32 bytes"));
49 }
50 let mut arr = [0u8; 32];
51 arr.copy_from_slice(&bytes);
52 Ok(Ed25519PublicKey(arr))
53 }
54}
55
56impl From<Vec<u8>> for Ed25519PublicKey {
57 fn from(bytes: Vec<u8>) -> Self {
64 assert!(
65 bytes.len() == 32,
66 "Ed25519PublicKey requires exactly 32 bytes, got {}",
67 bytes.len()
68 );
69 let mut arr = [0u8; 32];
70 arr.copy_from_slice(&bytes);
71 Ed25519PublicKey(arr)
72 }
73}
74
75impl Ed25519PublicKey {
76 pub fn try_from_bytes(bytes: &[u8]) -> crate::error::AptosResult<Self> {
84 if bytes.len() != 32 {
85 return Err(crate::error::AptosError::InvalidPublicKey(format!(
86 "Ed25519PublicKey requires exactly 32 bytes, got {}",
87 bytes.len()
88 )));
89 }
90 let mut arr = [0u8; 32];
91 arr.copy_from_slice(bytes);
92 Ok(Ed25519PublicKey(arr))
93 }
94}
95
96#[derive(Clone, Debug, PartialEq, Eq)]
99pub struct Ed25519Signature(pub [u8; 64]);
100
101impl Serialize for Ed25519Signature {
102 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
103 serde_bytes::Bytes::new(&self.0).serialize(serializer)
106 }
107}
108
109impl<'de> Deserialize<'de> for Ed25519Signature {
110 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
111 let bytes: Vec<u8> = serde_bytes::deserialize(deserializer)?;
113 if bytes.len() != 64 {
114 return Err(serde::de::Error::invalid_length(bytes.len(), &"64 bytes"));
115 }
116 let mut arr = [0u8; 64];
117 arr.copy_from_slice(&bytes);
118 Ok(Ed25519Signature(arr))
119 }
120}
121
122impl From<Vec<u8>> for Ed25519Signature {
123 fn from(bytes: Vec<u8>) -> Self {
130 assert!(
131 bytes.len() == 64,
132 "Ed25519Signature requires exactly 64 bytes, got {}",
133 bytes.len()
134 );
135 let mut arr = [0u8; 64];
136 arr.copy_from_slice(&bytes);
137 Ed25519Signature(arr)
138 }
139}
140
141impl Ed25519Signature {
142 pub fn try_from_bytes(bytes: &[u8]) -> crate::error::AptosResult<Self> {
148 if bytes.len() != 64 {
149 return Err(crate::error::AptosError::InvalidSignature(format!(
150 "Ed25519Signature requires exactly 64 bytes, got {}",
151 bytes.len()
152 )));
153 }
154 let mut arr = [0u8; 64];
155 arr.copy_from_slice(bytes);
156 Ok(Ed25519Signature(arr))
157 }
158}
159
160#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
172pub enum TransactionAuthenticator {
173 Ed25519 {
175 public_key: Ed25519PublicKey,
177 signature: Ed25519Signature,
179 },
180 MultiEd25519 {
182 public_key: Vec<u8>,
184 signature: Vec<u8>,
186 },
187 MultiAgent {
189 sender: AccountAuthenticator,
191 secondary_signer_addresses: Vec<AccountAddress>,
193 secondary_signers: Vec<AccountAuthenticator>,
195 },
196 FeePayer {
198 sender: AccountAuthenticator,
200 secondary_signer_addresses: Vec<AccountAddress>,
202 secondary_signers: Vec<AccountAuthenticator>,
204 fee_payer_address: AccountAddress,
206 fee_payer_signer: AccountAuthenticator,
208 },
209 SingleSender {
212 sender: AccountAuthenticator,
214 },
215}
216
217#[derive(Clone, Debug, PartialEq, Eq)]
229pub enum AccountAuthenticator {
230 Ed25519 {
232 public_key: Ed25519PublicKey,
234 signature: Ed25519Signature,
236 },
237 MultiEd25519 {
239 public_key: Vec<u8>,
241 signature: Vec<u8>,
243 },
244 SingleKey {
246 public_key: Vec<u8>,
248 signature: Vec<u8>,
250 },
251 MultiKey {
253 public_key: Vec<u8>,
255 signature: Vec<u8>,
257 },
258 NoAccountAuthenticator,
260}
261
262const ACCOUNT_AUTH_TAG_ED25519: u32 = 0;
264const ACCOUNT_AUTH_TAG_MULTI_ED25519: u32 = 1;
265const ACCOUNT_AUTH_TAG_SINGLE_KEY: u32 = 2;
266const ACCOUNT_AUTH_TAG_MULTI_KEY: u32 = 3;
267const ACCOUNT_AUTH_TAG_NO_ACCOUNT: u32 = 4;
268
269impl Serialize for AccountAuthenticator {
270 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
271 match self {
272 AccountAuthenticator::Ed25519 {
273 public_key,
274 signature,
275 } => {
276 let mut tv = serializer.serialize_tuple_variant(
279 "AccountAuthenticator",
280 ACCOUNT_AUTH_TAG_ED25519,
281 "Ed25519",
282 2,
283 )?;
284 tv.serialize_field(public_key)?;
285 tv.serialize_field(signature)?;
286 tv.end()
287 }
288 AccountAuthenticator::MultiEd25519 {
289 public_key,
290 signature,
291 } => {
292 let mut tv = serializer.serialize_tuple_variant(
296 "AccountAuthenticator",
297 ACCOUNT_AUTH_TAG_MULTI_ED25519,
298 "MultiEd25519",
299 2,
300 )?;
301 tv.serialize_field(public_key)?;
302 tv.serialize_field(signature)?;
303 tv.end()
304 }
305 AccountAuthenticator::SingleKey {
306 public_key,
307 signature,
308 } => {
309 serialize_account_auth_raw_pair(
312 serializer,
313 ACCOUNT_AUTH_TAG_SINGLE_KEY,
314 "SingleKey",
315 public_key,
316 signature,
317 )
318 }
319 AccountAuthenticator::MultiKey {
320 public_key,
321 signature,
322 } => {
323 serialize_account_auth_raw_pair(
326 serializer,
327 ACCOUNT_AUTH_TAG_MULTI_KEY,
328 "MultiKey",
329 public_key,
330 signature,
331 )
332 }
333 AccountAuthenticator::NoAccountAuthenticator => serializer
334 .serialize_tuple_variant(
335 "AccountAuthenticator",
336 ACCOUNT_AUTH_TAG_NO_ACCOUNT,
337 "NoAccountAuthenticator",
338 0,
339 )
340 .and_then(SerializeTupleVariant::end),
341 }
342 }
343}
344
345fn serialize_account_auth_raw_pair<S: Serializer>(
346 serializer: S,
347 tag: u32,
348 name: &'static str,
349 public_key: &[u8],
350 signature: &[u8],
351) -> Result<S::Ok, S::Error> {
352 struct Raw<'a>(&'a [u8]);
359 impl Serialize for Raw<'_> {
360 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
361 serialize_raw_bytes(self.0, s)
362 }
363 }
364
365 let mut tv = serializer.serialize_tuple_variant("AccountAuthenticator", tag, name, 2)?;
366 tv.serialize_field(&Raw(public_key))?;
367 tv.serialize_field(&Raw(signature))?;
368 tv.end()
369}
370
371impl<'de> Deserialize<'de> for AccountAuthenticator {
372 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
373 #[derive(Deserialize)]
388 enum Compat {
389 Ed25519 {
390 public_key: Ed25519PublicKey,
391 signature: Ed25519Signature,
392 },
393 MultiEd25519 {
394 public_key: Vec<u8>,
395 signature: Vec<u8>,
396 },
397 SingleKey {
398 public_key: Vec<u8>,
399 signature: Vec<u8>,
400 },
401 MultiKey {
402 public_key: Vec<u8>,
403 signature: Vec<u8>,
404 },
405 NoAccountAuthenticator,
406 }
407
408 Compat::deserialize(deserializer).map(|c| match c {
409 Compat::Ed25519 {
410 public_key,
411 signature,
412 } => AccountAuthenticator::Ed25519 {
413 public_key,
414 signature,
415 },
416 Compat::MultiEd25519 {
417 public_key,
418 signature,
419 } => AccountAuthenticator::MultiEd25519 {
420 public_key,
421 signature,
422 },
423 Compat::SingleKey {
424 public_key,
425 signature,
426 } => AccountAuthenticator::SingleKey {
427 public_key,
428 signature,
429 },
430 Compat::MultiKey {
431 public_key,
432 signature,
433 } => AccountAuthenticator::MultiKey {
434 public_key,
435 signature,
436 },
437 Compat::NoAccountAuthenticator => AccountAuthenticator::NoAccountAuthenticator,
438 })
439 }
440}
441
442#[derive(Clone, Debug, PartialEq, Eq)]
444pub struct Ed25519Authenticator {
445 pub public_key: Vec<u8>,
447 pub signature: Vec<u8>,
449}
450
451impl Ed25519Authenticator {
452 pub fn new(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
454 Self {
455 public_key,
456 signature,
457 }
458 }
459}
460
461impl From<Ed25519Authenticator> for TransactionAuthenticator {
462 fn from(auth: Ed25519Authenticator) -> Self {
463 TransactionAuthenticator::Ed25519 {
464 public_key: auth.public_key.into(),
465 signature: auth.signature.into(),
466 }
467 }
468}
469
470impl From<Ed25519Authenticator> for AccountAuthenticator {
471 fn from(auth: Ed25519Authenticator) -> Self {
472 AccountAuthenticator::Ed25519 {
473 public_key: auth.public_key.into(),
474 signature: auth.signature.into(),
475 }
476 }
477}
478
479fn zeroed_multi_ed25519_signature(signature: &[u8]) -> Vec<u8> {
494 let mut out = signature.to_vec();
495 match out.len().checked_sub(4) {
496 Some(sig_bytes_len) => {
498 for byte in &mut out[..sig_bytes_len] {
499 *byte = 0;
500 }
501 }
502 None => out.iter_mut().for_each(|byte| *byte = 0),
506 }
507 out
508}
509
510fn zeroed_multi_key_signature(signature: &[u8]) -> Vec<u8> {
523 use crate::crypto::{AnySignature, MultiKeySignature};
524
525 let Ok(parsed) = MultiKeySignature::from_bytes(signature) else {
526 return vec![0u8; signature.len()];
528 };
529 let rebuilt: Vec<(u8, AnySignature)> = parsed
530 .signatures()
531 .iter()
532 .map(|(index, sig)| {
533 (
534 *index,
535 AnySignature::new(sig.variant, vec![0u8; sig.bytes.len()]),
536 )
537 })
538 .collect();
539 MultiKeySignature::new(rebuilt)
540 .map_or_else(|_| vec![0u8; signature.len()], |sig| sig.to_bytes())
541}
542
543impl TransactionAuthenticator {
544 pub fn ed25519(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
546 Self::Ed25519 {
547 public_key: public_key.into(),
548 signature: signature.into(),
549 }
550 }
551
552 pub fn multi_ed25519(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
554 Self::MultiEd25519 {
555 public_key,
556 signature,
557 }
558 }
559
560 pub fn multi_agent(
562 sender: AccountAuthenticator,
563 secondary_signer_addresses: Vec<AccountAddress>,
564 secondary_signers: Vec<AccountAuthenticator>,
565 ) -> Self {
566 Self::MultiAgent {
567 sender,
568 secondary_signer_addresses,
569 secondary_signers,
570 }
571 }
572
573 pub fn fee_payer(
575 sender: AccountAuthenticator,
576 secondary_signer_addresses: Vec<AccountAddress>,
577 secondary_signers: Vec<AccountAuthenticator>,
578 fee_payer_address: AccountAddress,
579 fee_payer_signer: AccountAuthenticator,
580 ) -> Self {
581 Self::FeePayer {
582 sender,
583 secondary_signer_addresses,
584 secondary_signers,
585 fee_payer_address,
586 fee_payer_signer,
587 }
588 }
589
590 pub fn single_sender(sender: AccountAuthenticator) -> Self {
593 Self::SingleSender { sender }
594 }
595
596 #[must_use]
605 pub fn for_simulate_endpoint(self) -> Self {
606 match self {
607 Self::Ed25519 {
608 public_key,
609 signature: _,
610 } => Self::Ed25519 {
611 public_key,
612 signature: Ed25519Signature([0u8; 64]),
613 },
614 Self::MultiEd25519 {
615 public_key,
616 signature,
617 } => Self::MultiEd25519 {
618 public_key,
619 signature: zeroed_multi_ed25519_signature(&signature),
620 },
621 Self::MultiAgent {
622 sender,
623 secondary_signer_addresses,
624 secondary_signers,
625 } => {
626 let secondary: Vec<AccountAuthenticator> = secondary_signers
627 .into_iter()
628 .map(AccountAuthenticator::for_simulate_endpoint)
629 .collect();
630 Self::multi_agent(
631 sender.for_simulate_endpoint(),
632 secondary_signer_addresses,
633 secondary,
634 )
635 }
636 Self::FeePayer {
637 sender,
638 secondary_signer_addresses,
639 secondary_signers,
640 fee_payer_address,
641 fee_payer_signer,
642 } => {
643 let secondary: Vec<AccountAuthenticator> = secondary_signers
644 .into_iter()
645 .map(AccountAuthenticator::for_simulate_endpoint)
646 .collect();
647 Self::fee_payer(
648 sender.for_simulate_endpoint(),
649 secondary_signer_addresses,
650 secondary,
651 fee_payer_address,
652 fee_payer_signer.for_simulate_endpoint(),
653 )
654 }
655 Self::SingleSender { sender } => Self::single_sender(sender.for_simulate_endpoint()),
656 }
657 }
658}
659
660impl AccountAuthenticator {
661 pub fn ed25519(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
663 Self::Ed25519 {
664 public_key: public_key.into(),
665 signature: signature.into(),
666 }
667 }
668 pub fn single_key(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
670 Self::SingleKey {
671 public_key,
672 signature,
673 }
674 }
675
676 pub fn multi_key(public_key: Vec<u8>, signature: Vec<u8>) -> Self {
678 Self::MultiKey {
679 public_key,
680 signature,
681 }
682 }
683
684 pub fn no_account_authenticator() -> Self {
686 Self::NoAccountAuthenticator
687 }
688
689 #[must_use]
706 pub fn for_simulate_endpoint(self) -> Self {
707 match self {
708 Self::NoAccountAuthenticator => Self::NoAccountAuthenticator,
709 Self::Ed25519 {
710 public_key,
711 signature: _,
712 } => Self::Ed25519 {
713 public_key,
714 signature: Ed25519Signature([0u8; 64]),
715 },
716 Self::MultiEd25519 {
717 public_key,
718 signature,
719 } => Self::MultiEd25519 {
720 public_key,
721 signature: zeroed_multi_ed25519_signature(&signature),
722 },
723 Self::SingleKey { .. } => Self::NoAccountAuthenticator,
724 Self::MultiKey {
725 public_key,
726 signature,
727 } => Self::MultiKey {
728 public_key,
729 signature: zeroed_multi_key_signature(&signature),
730 },
731 }
732 }
733
734 pub fn verify(&self, message: &[u8]) -> crate::error::AptosResult<()> {
740 match self {
741 #[cfg(feature = "ed25519")]
742 Self::Ed25519 {
743 public_key,
744 signature,
745 } => {
746 let public_key = crate::crypto::Ed25519PublicKey::from_bytes(&public_key.0)?;
747 let signature = crate::crypto::Ed25519Signature::from_bytes(&signature.0)?;
748 public_key.verify(message, &signature)
749 }
750 #[cfg(not(feature = "ed25519"))]
751 Self::Ed25519 { .. } => Err(crate::error::AptosError::FeatureNotEnabled(
752 "Ed25519 verification".into(),
753 )),
754 #[cfg(feature = "ed25519")]
755 Self::MultiEd25519 {
756 public_key,
757 signature,
758 } => {
759 let public_key = crate::crypto::MultiEd25519PublicKey::from_bytes(public_key)?;
760 let signature = crate::crypto::MultiEd25519Signature::from_bytes(signature)?;
761 public_key.verify(message, &signature)
762 }
763 #[cfg(not(feature = "ed25519"))]
764 Self::MultiEd25519 { .. } => Err(crate::error::AptosError::FeatureNotEnabled(
765 "MultiEd25519 verification".into(),
766 )),
767 Self::SingleKey {
768 public_key,
769 signature,
770 } => {
771 let pk = crate::crypto::AnyPublicKey::from_bcs_bytes(public_key)?;
772 let sig = crate::crypto::AnySignature::from_bcs_bytes(signature)?;
773 pk.verify(message, &sig)
774 }
775 Self::MultiKey {
776 public_key,
777 signature,
778 } => {
779 let pk = crate::crypto::MultiKeyPublicKey::from_bytes(public_key)?;
780 let sig = crate::crypto::MultiKeySignature::from_bytes(signature)?;
781 pk.verify(message, &sig)
782 }
783 Self::NoAccountAuthenticator => Err(crate::error::AptosError::InvalidSignature(
784 "no account authenticator cannot be verified".into(),
785 )),
786 }
787 }
788
789 pub fn derived_address(&self) -> crate::error::AptosResult<AccountAddress> {
795 match self {
796 #[cfg(feature = "ed25519")]
797 Self::Ed25519 { public_key, .. } => {
798 let public_key = crate::crypto::Ed25519PublicKey::from_bytes(&public_key.0)?;
799 Ok(public_key.to_address())
800 }
801 #[cfg(not(feature = "ed25519"))]
802 Self::Ed25519 { .. } => Err(crate::error::AptosError::FeatureNotEnabled(
803 "Ed25519 address derivation".into(),
804 )),
805 #[cfg(feature = "ed25519")]
806 Self::MultiEd25519 { public_key, .. } => {
807 let public_key = crate::crypto::MultiEd25519PublicKey::from_bytes(public_key)?;
808 Ok(public_key.to_address())
809 }
810 #[cfg(not(feature = "ed25519"))]
811 Self::MultiEd25519 { .. } => Err(crate::error::AptosError::FeatureNotEnabled(
812 "MultiEd25519 address derivation".into(),
813 )),
814 Self::SingleKey { public_key, .. } => Ok(AccountAddress::new(
815 crate::crypto::derive_authentication_key(
816 public_key,
817 crate::crypto::SINGLE_KEY_SCHEME,
818 ),
819 )),
820 Self::MultiKey { public_key, .. } => {
821 let pk = crate::crypto::MultiKeyPublicKey::from_bytes(public_key)?;
822 Ok(pk.to_address())
823 }
824 Self::NoAccountAuthenticator => Err(crate::error::AptosError::InvalidSignature(
825 "no account authenticator has no derived address".into(),
826 )),
827 }
828 }
829}
830
831#[cfg(test)]
832mod tests {
833 use super::*;
834 use crate::crypto::{AnyPublicKey, AnySignature, MultiKeyPublicKey, MultiKeySignature};
835
836 #[test]
837 fn test_ed25519_authenticator() {
838 let mut pk = [0u8; 32];
839 pk[0..3].copy_from_slice(&[1, 2, 3]);
840 let mut sig = [0u8; 64];
841 sig[0..3].copy_from_slice(&[4, 5, 6]);
842
843 let auth = Ed25519Authenticator::new(pk.to_vec(), sig.to_vec());
844 let txn_auth: TransactionAuthenticator = auth.into();
845
846 match txn_auth {
847 TransactionAuthenticator::Ed25519 {
848 public_key,
849 signature,
850 } => {
851 assert_eq!(public_key.0[0..3], [1, 2, 3]);
852 assert_eq!(signature.0[0..3], [4, 5, 6]);
853 }
854 _ => panic!("wrong authenticator type"),
855 }
856 }
857
858 #[test]
859 fn test_multi_agent_authenticator() {
860 let sender = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
861 let auth = TransactionAuthenticator::multi_agent(sender, vec![], vec![]);
862
863 match auth {
864 TransactionAuthenticator::MultiAgent { .. } => {}
865 _ => panic!("wrong authenticator type"),
866 }
867 }
868
869 #[test]
870 fn test_ed25519_bcs_format() {
871 let auth = TransactionAuthenticator::Ed25519 {
873 public_key: Ed25519PublicKey([0xab; 32]),
874 signature: Ed25519Signature([0xcd; 64]),
875 };
876 let bcs = aptos_bcs::to_bytes(&auth).unwrap();
877
878 assert_eq!(bcs[0], 0, "Ed25519 variant index should be 0");
880 assert_eq!(bcs[1], 32, "Pubkey length prefix should be 32");
882 assert_eq!(bcs[2], 0xab, "First pubkey byte should be 0xab");
884 assert_eq!(bcs[34], 64, "Signature length prefix should be 64");
886 assert_eq!(bcs[35], 0xcd, "First signature byte should be 0xcd");
888 assert_eq!(bcs.len(), 99, "BCS length should be 99");
890 }
891
892 #[test]
893 fn test_ed25519_authenticator_into_account_authenticator() {
894 let auth = Ed25519Authenticator::new(vec![0xaa; 32], vec![0xbb; 64]);
895 let account_auth: AccountAuthenticator = auth.into();
896
897 match account_auth {
898 AccountAuthenticator::Ed25519 {
899 public_key,
900 signature,
901 } => {
902 assert_eq!(public_key.0[0], 0xaa);
903 assert_eq!(signature.0[0], 0xbb);
904 }
905 _ => panic!("Expected Ed25519 variant"),
906 }
907 }
908
909 #[test]
910 fn test_transaction_authenticator_ed25519() {
911 let auth = TransactionAuthenticator::ed25519(vec![0x11; 32], vec![0x22; 64]);
912 match auth {
913 TransactionAuthenticator::Ed25519 {
914 public_key,
915 signature,
916 } => {
917 assert_eq!(public_key.0[0], 0x11);
918 assert_eq!(signature.0[0], 0x22);
919 }
920 _ => panic!("Expected Ed25519 variant"),
921 }
922 }
923
924 #[test]
925 fn test_transaction_authenticator_multi_ed25519() {
926 let auth = TransactionAuthenticator::multi_ed25519(vec![0x33; 64], vec![0x44; 128]);
927 match auth {
928 TransactionAuthenticator::MultiEd25519 {
929 public_key,
930 signature,
931 } => {
932 assert_eq!(public_key.len(), 64);
933 assert_eq!(signature.len(), 128);
934 }
935 _ => panic!("Expected MultiEd25519 variant"),
936 }
937 }
938
939 #[test]
940 fn test_fee_payer_authenticator() {
941 let sender = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
942 let fee_payer = AccountAuthenticator::ed25519(vec![1; 32], vec![1; 64]);
943 let fee_payer_address = AccountAddress::from_hex("0x123").unwrap();
944
945 let auth = TransactionAuthenticator::fee_payer(
946 sender,
947 vec![],
948 vec![],
949 fee_payer_address,
950 fee_payer,
951 );
952
953 match auth {
954 TransactionAuthenticator::FeePayer {
955 fee_payer_address: addr,
956 ..
957 } => {
958 assert_eq!(addr, fee_payer_address);
959 }
960 _ => panic!("Expected FeePayer variant"),
961 }
962 }
963
964 #[test]
965 fn test_single_sender_authenticator() {
966 let sender = AccountAuthenticator::ed25519(vec![0x55; 32], vec![0x66; 64]);
967 let auth = TransactionAuthenticator::single_sender(sender);
968
969 match auth {
970 TransactionAuthenticator::SingleSender { sender } => match sender {
971 AccountAuthenticator::Ed25519 { public_key, .. } => {
972 assert_eq!(public_key.0[0], 0x55);
973 }
974 _ => panic!("Expected Ed25519 sender"),
975 },
976 _ => panic!("Expected SingleSender variant"),
977 }
978 }
979
980 #[test]
981 fn test_account_authenticator_multi_key() {
982 let auth = AccountAuthenticator::multi_key(vec![0x77; 100], vec![0x88; 200]);
983 match auth {
984 AccountAuthenticator::MultiKey {
985 public_key,
986 signature,
987 } => {
988 assert_eq!(public_key.len(), 100);
989 assert_eq!(signature.len(), 200);
990 }
991 _ => panic!("Expected MultiKey variant"),
992 }
993 }
994
995 #[test]
996 fn test_ed25519_public_key_from_vec() {
997 let pk: Ed25519PublicKey = vec![0x12; 32].into();
998 assert_eq!(pk.0[0], 0x12);
999 assert_eq!(pk.0.len(), 32);
1000 }
1001
1002 #[test]
1003 fn test_ed25519_signature_from_vec() {
1004 let sig: Ed25519Signature = vec![0x34; 64].into();
1005 assert_eq!(sig.0[0], 0x34);
1006 assert_eq!(sig.0.len(), 64);
1007 }
1008
1009 #[test]
1010 fn test_ed25519_public_key_bcs_roundtrip() {
1011 let pk = Ed25519PublicKey([0xef; 32]);
1012 let serialized = aptos_bcs::to_bytes(&pk).unwrap();
1013 assert_eq!(serialized.len(), 33);
1015 assert_eq!(serialized[0], 32); let deserialized: Ed25519PublicKey = aptos_bcs::from_bytes(&serialized).unwrap();
1017 assert_eq!(pk, deserialized);
1018 }
1019
1020 #[test]
1021 fn test_ed25519_signature_bcs_roundtrip() {
1022 let sig = Ed25519Signature([0x99; 64]);
1023 let serialized = aptos_bcs::to_bytes(&sig).unwrap();
1024 let deserialized: Ed25519Signature = aptos_bcs::from_bytes(&serialized).unwrap();
1025 assert_eq!(sig, deserialized);
1026 }
1027
1028 #[test]
1029 fn test_multi_agent_with_secondary_signers() {
1030 let sender = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
1031 let secondary_signer1 = AccountAuthenticator::ed25519(vec![1; 32], vec![1; 64]);
1032 let secondary_signer2 = AccountAuthenticator::ed25519(vec![2; 32], vec![2; 64]);
1033 let addr1 = AccountAddress::from_hex("0x111").unwrap();
1034 let addr2 = AccountAddress::from_hex("0x222").unwrap();
1035
1036 let auth = TransactionAuthenticator::multi_agent(
1037 sender,
1038 vec![addr1, addr2],
1039 vec![secondary_signer1, secondary_signer2],
1040 );
1041
1042 match auth {
1043 TransactionAuthenticator::MultiAgent {
1044 secondary_signer_addresses,
1045 secondary_signers,
1046 ..
1047 } => {
1048 assert_eq!(secondary_signer_addresses.len(), 2);
1049 assert_eq!(secondary_signers.len(), 2);
1050 }
1051 _ => panic!("Expected MultiAgent variant"),
1052 }
1053 }
1054
1055 #[test]
1056 fn test_transaction_authenticator_bcs_roundtrip() {
1057 let auth = TransactionAuthenticator::Ed25519 {
1058 public_key: Ed25519PublicKey([0x11; 32]),
1059 signature: Ed25519Signature([0x22; 64]),
1060 };
1061
1062 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
1063 let deserialized: TransactionAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
1064
1065 assert_eq!(auth, deserialized);
1066 }
1067
1068 #[test]
1069 fn test_account_authenticator_bcs_roundtrip() {
1070 let auth = AccountAuthenticator::Ed25519 {
1071 public_key: Ed25519PublicKey([0x33; 32]),
1072 signature: Ed25519Signature([0x44; 64]),
1073 };
1074
1075 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
1076 let deserialized: AccountAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
1077
1078 assert_eq!(auth, deserialized);
1079 }
1080
1081 #[test]
1082 fn test_account_authenticator_single_key() {
1083 let auth = AccountAuthenticator::single_key(vec![0x55; 33], vec![0x66; 65]);
1084 match auth {
1085 AccountAuthenticator::SingleKey {
1086 public_key,
1087 signature,
1088 } => {
1089 assert_eq!(public_key.len(), 33);
1090 assert_eq!(signature.len(), 65);
1091 }
1092 _ => panic!("Expected SingleKey variant"),
1093 }
1094 }
1095
1096 #[test]
1097 fn test_account_authenticator_single_key_bcs_wire_format() {
1098 let pk = vec![0x77; 33]; let sig = vec![0x88; 65]; let auth = AccountAuthenticator::SingleKey {
1110 public_key: pk.clone(),
1111 signature: sig.clone(),
1112 };
1113
1114 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
1115 let mut expected = Vec::new();
1116 expected.push(2u8); expected.extend_from_slice(&pk);
1118 expected.extend_from_slice(&sig);
1119 assert_eq!(
1120 serialized, expected,
1121 "SingleKey wire format must be variant tag + raw pubkey bytes + raw signature bytes \
1122 (no inner length prefixes)"
1123 );
1124 }
1125
1126 #[cfg(feature = "ed25519")]
1127 #[test]
1128 fn test_account_authenticator_single_key_verify_and_derived_address() {
1129 use crate::crypto::{Ed25519PrivateKey, SINGLE_KEY_SCHEME, derive_authentication_key};
1130
1131 let private_key = Ed25519PrivateKey::generate();
1132 let message = b"single-key verify test";
1133 let public_key = crate::crypto::AnyPublicKey::ed25519(&private_key.public_key());
1134 let signature = crate::crypto::AnySignature::ed25519(&private_key.sign(message));
1135 let auth =
1136 AccountAuthenticator::single_key(public_key.to_bcs_bytes(), signature.to_bcs_bytes());
1137
1138 auth.verify(message).unwrap();
1139 let expected = AccountAddress::new(derive_authentication_key(
1140 &public_key.to_bcs_bytes(),
1141 SINGLE_KEY_SCHEME,
1142 ));
1143 assert_eq!(auth.derived_address().unwrap(), expected);
1144 }
1145
1146 #[cfg(feature = "ed25519")]
1147 #[test]
1148 fn test_account_authenticator_multi_ed25519_verify_and_derived_address() {
1149 use crate::account::{Account, MultiEd25519Account};
1150 use crate::crypto::Ed25519PrivateKey;
1151
1152 let account = MultiEd25519Account::new(
1153 vec![Ed25519PrivateKey::generate(), Ed25519PrivateKey::generate()],
1154 2,
1155 )
1156 .unwrap();
1157 let message = b"multi-ed25519 verify test";
1158 let auth = AccountAuthenticator::MultiEd25519 {
1159 public_key: account.public_key_bytes(),
1160 signature: account.sign(message).unwrap().to_bytes(),
1161 };
1162
1163 auth.verify(message).unwrap();
1164 assert_eq!(auth.derived_address().unwrap(), account.address());
1165 }
1166
1167 #[test]
1168 fn test_no_account_authenticator() {
1169 let auth = AccountAuthenticator::no_account_authenticator();
1170 match auth {
1171 AccountAuthenticator::NoAccountAuthenticator => {}
1172 _ => panic!("Expected NoAccountAuthenticator variant"),
1173 }
1174 }
1175
1176 #[cfg(feature = "ed25519")]
1177 #[test]
1178 fn test_account_authenticator_for_simulate_endpoint_single_key_to_no_account() {
1179 let auth = AccountAuthenticator::single_key(vec![0x01, 0x02], vec![0x03, 0x04]);
1180 let sanitized = auth.for_simulate_endpoint();
1181 assert!(matches!(
1182 sanitized,
1183 AccountAuthenticator::NoAccountAuthenticator
1184 ));
1185 }
1186
1187 #[cfg(feature = "ed25519")]
1188 #[test]
1189 fn test_transaction_authenticator_for_simulate_endpoint_single_sender_strips_single_key() {
1190 let sender = AccountAuthenticator::single_key(vec![0x05, 0x06], vec![0x07, 0x08]);
1191 let auth = TransactionAuthenticator::single_sender(sender);
1192 let sanitized = auth.for_simulate_endpoint();
1193 assert!(matches!(
1194 sanitized,
1195 TransactionAuthenticator::SingleSender { ref sender }
1196 if matches!(sender, AccountAuthenticator::NoAccountAuthenticator)
1197 ));
1198 }
1199
1200 #[cfg(feature = "ed25519")]
1201 #[test]
1202 fn test_transaction_authenticator_for_simulate_endpoint_ed25519_zeros_sig() {
1203 let auth = TransactionAuthenticator::Ed25519 {
1204 public_key: Ed25519PublicKey([7u8; 32]),
1205 signature: Ed25519Signature([9u8; 64]),
1206 };
1207 let sanitized = auth.for_simulate_endpoint();
1208 match sanitized {
1209 TransactionAuthenticator::Ed25519 { signature, .. } => {
1210 assert_eq!(signature.0, [0u8; 64]);
1211 }
1212 _ => panic!("expected Ed25519"),
1213 }
1214 }
1215
1216 #[test]
1217 fn test_no_account_authenticator_verify_and_derived_address_errors() {
1218 let auth = AccountAuthenticator::NoAccountAuthenticator;
1219 assert!(auth.verify(b"no-auth").is_err());
1220 assert!(auth.derived_address().is_err());
1221 }
1222
1223 #[test]
1224 fn test_no_account_authenticator_bcs_roundtrip() {
1225 let auth = AccountAuthenticator::NoAccountAuthenticator;
1226
1227 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
1228 assert_eq!(
1230 serialized[0], 4,
1231 "NoAccountAuthenticator variant index should be 4"
1232 );
1233 assert_eq!(
1235 serialized.len(),
1236 1,
1237 "NoAccountAuthenticator should be 1 byte"
1238 );
1239 let deserialized: AccountAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
1240 assert_eq!(auth, deserialized);
1241 }
1242
1243 #[test]
1244 fn test_single_sender_with_single_key() {
1245 let sender = AccountAuthenticator::single_key(vec![0x99; 33], vec![0xaa; 65]);
1246 let auth = TransactionAuthenticator::single_sender(sender);
1247
1248 match auth {
1249 TransactionAuthenticator::SingleSender { sender } => match sender {
1250 AccountAuthenticator::SingleKey { public_key, .. } => {
1251 assert_eq!(public_key.len(), 33);
1252 }
1253 _ => panic!("Expected SingleKey sender"),
1254 },
1255 _ => panic!("Expected SingleSender variant"),
1256 }
1257 }
1258
1259 #[test]
1260 fn test_account_authenticator_variant_indices() {
1261 let ed25519 = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
1263 let multi_ed25519 = AccountAuthenticator::MultiEd25519 {
1264 public_key: vec![0; 64],
1265 signature: vec![0; 128],
1266 };
1267 let single_key = AccountAuthenticator::single_key(vec![0; 33], vec![0; 65]);
1268 let multi_key = AccountAuthenticator::multi_key(vec![0; 100], vec![0; 200]);
1269 let no_account = AccountAuthenticator::no_account_authenticator();
1270
1271 assert_eq!(aptos_bcs::to_bytes(&ed25519).unwrap()[0], 0, "Ed25519 = 0");
1272 assert_eq!(
1273 aptos_bcs::to_bytes(&multi_ed25519).unwrap()[0],
1274 1,
1275 "MultiEd25519 = 1"
1276 );
1277 assert_eq!(
1278 aptos_bcs::to_bytes(&single_key).unwrap()[0],
1279 2,
1280 "SingleKey = 2"
1281 );
1282 assert_eq!(
1283 aptos_bcs::to_bytes(&multi_key).unwrap()[0],
1284 3,
1285 "MultiKey = 3"
1286 );
1287 assert_eq!(
1288 aptos_bcs::to_bytes(&no_account).unwrap()[0],
1289 4,
1290 "NoAccountAuthenticator = 4"
1291 );
1292 }
1293
1294 #[test]
1295 fn test_ed25519_public_key_try_from_bytes_valid() {
1296 let bytes = vec![0x12; 32];
1297 let pk = Ed25519PublicKey::try_from_bytes(&bytes).unwrap();
1298 assert_eq!(pk.0[0], 0x12);
1299 }
1300
1301 #[test]
1302 fn test_ed25519_public_key_try_from_bytes_invalid_length() {
1303 let bytes = vec![0x12; 16]; let result = Ed25519PublicKey::try_from_bytes(&bytes);
1305 assert!(result.is_err());
1306 }
1307
1308 #[test]
1309 fn test_ed25519_signature_try_from_bytes_valid() {
1310 let bytes = vec![0x34; 64];
1311 let sig = Ed25519Signature::try_from_bytes(&bytes).unwrap();
1312 assert_eq!(sig.0[0], 0x34);
1313 }
1314
1315 #[test]
1316 fn test_ed25519_signature_try_from_bytes_invalid_length() {
1317 let bytes = vec![0x34; 32]; let result = Ed25519Signature::try_from_bytes(&bytes);
1319 assert!(result.is_err());
1320 }
1321
1322 #[test]
1323 fn test_transaction_authenticator_variant_indices() {
1324 let ed25519 = TransactionAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
1326 let multi_ed25519 = TransactionAuthenticator::multi_ed25519(vec![0; 64], vec![0; 128]);
1327 let sender = AccountAuthenticator::ed25519(vec![0; 32], vec![0; 64]);
1328 let multi_agent = TransactionAuthenticator::multi_agent(sender.clone(), vec![], vec![]);
1329 let fee_payer = TransactionAuthenticator::fee_payer(
1330 sender.clone(),
1331 vec![],
1332 vec![],
1333 AccountAddress::ONE,
1334 sender.clone(),
1335 );
1336 let single_sender = TransactionAuthenticator::single_sender(sender);
1337
1338 assert_eq!(aptos_bcs::to_bytes(&ed25519).unwrap()[0], 0, "Ed25519 = 0");
1339 assert_eq!(
1340 aptos_bcs::to_bytes(&multi_ed25519).unwrap()[0],
1341 1,
1342 "MultiEd25519 = 1"
1343 );
1344 assert_eq!(
1345 aptos_bcs::to_bytes(&multi_agent).unwrap()[0],
1346 2,
1347 "MultiAgent = 2"
1348 );
1349 assert_eq!(
1350 aptos_bcs::to_bytes(&fee_payer).unwrap()[0],
1351 3,
1352 "FeePayer = 3"
1353 );
1354 assert_eq!(
1355 aptos_bcs::to_bytes(&single_sender).unwrap()[0],
1356 4,
1357 "SingleSender = 4"
1358 );
1359 }
1360
1361 #[test]
1362 fn test_single_key_single_sender_bcs_wire_format() {
1363 let mut pk = vec![0u8; 67];
1370 pk[0] = 0x02; pk[1] = 65; pk[2] = 0x04; let mut sig = vec![0u8; 66];
1374 sig[0] = 0x02; sig[1] = 64; let auth = AccountAuthenticator::single_key(pk.clone(), sig.clone());
1378 let bytes = aptos_bcs::to_bytes(&auth).unwrap();
1379 let mut expected_inner = Vec::new();
1380 expected_inner.push(2u8); expected_inner.extend_from_slice(&pk); expected_inner.extend_from_slice(&sig); assert_eq!(bytes, expected_inner);
1384
1385 let txn = TransactionAuthenticator::single_sender(auth);
1386 let bytes = aptos_bcs::to_bytes(&txn).unwrap();
1387 let mut expected_outer = Vec::new();
1388 expected_outer.push(4u8); expected_outer.extend_from_slice(&expected_inner);
1390 assert_eq!(bytes, expected_outer);
1391 }
1392
1393 #[test]
1394 fn test_multi_key_authenticator_bcs_wire_format() {
1395 let pk = vec![0xaa; 100];
1402 let sig = vec![0xbb; 200];
1403 let auth = AccountAuthenticator::multi_key(pk.clone(), sig.clone());
1404
1405 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
1406 let mut expected = Vec::new();
1407 expected.push(3u8); expected.extend_from_slice(&pk);
1409 expected.extend_from_slice(&sig);
1410 assert_eq!(
1411 serialized, expected,
1412 "MultiKey wire format must be variant tag + raw pubkey bytes + raw signature bytes"
1413 );
1414 }
1415
1416 #[test]
1417 fn test_multi_key_authenticator_bcs_rejects_keyless_public_key() {
1418 let mk_pk = MultiKeyPublicKey::new(
1419 vec![AnyPublicKey::new(
1420 crate::crypto::AnyPublicKeyVariant::Keyless,
1421 vec![],
1422 )],
1423 1,
1424 )
1425 .unwrap();
1426 let mk_sig = MultiKeySignature::new(vec![(
1427 0,
1428 AnySignature::new(crate::crypto::AnyPublicKeyVariant::Ed25519, vec![0x66; 64]),
1429 )])
1430 .unwrap();
1431 let auth = AccountAuthenticator::multi_key(mk_pk.to_bytes(), mk_sig.to_bytes());
1432
1433 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
1434 let result: Result<AccountAuthenticator, _> = aptos_bcs::from_bytes(&serialized);
1435 assert!(result.is_err());
1436 }
1437
1438 #[test]
1439 fn test_multi_ed25519_authenticator_bcs_roundtrip() {
1440 let auth = AccountAuthenticator::MultiEd25519 {
1441 public_key: vec![0xcc; 64],
1442 signature: vec![0xdd; 128],
1443 };
1444
1445 let serialized = aptos_bcs::to_bytes(&auth).unwrap();
1446 assert_eq!(serialized[0], 1, "MultiEd25519 variant index should be 1");
1448 let deserialized: AccountAuthenticator = aptos_bcs::from_bytes(&serialized).unwrap();
1449 assert_eq!(auth, deserialized);
1450 }
1451
1452 #[test]
1453 fn test_ed25519_public_key_deserialize_invalid_length() {
1454 let mut bytes = vec![16u8]; bytes.extend_from_slice(&[0xab; 16]); let result: Result<Ed25519PublicKey, _> = aptos_bcs::from_bytes(&bytes);
1458 assert!(result.is_err());
1459 }
1460
1461 #[test]
1462 fn test_ed25519_signature_deserialize_invalid_length() {
1463 let mut bytes = vec![32u8]; bytes.extend_from_slice(&[0xab; 32]); let result: Result<Ed25519Signature, _> = aptos_bcs::from_bytes(&bytes);
1467 assert!(result.is_err());
1468 }
1469
1470 #[cfg(feature = "ed25519")]
1471 #[test]
1472 fn test_account_authenticator_for_simulate_endpoint_multi_ed25519_stays_valid() {
1473 use crate::account::{Account, MultiEd25519Account};
1474 use crate::crypto::{Ed25519PrivateKey, MultiEd25519Signature};
1475
1476 let account = MultiEd25519Account::new(
1477 vec![
1478 Ed25519PrivateKey::generate(),
1479 Ed25519PrivateKey::generate(),
1480 Ed25519PrivateKey::generate(),
1481 ],
1482 2,
1483 )
1484 .unwrap();
1485 let message = b"multi-ed25519 simulate test";
1486 let original_sig_bytes = account.sign(message).unwrap().to_bytes();
1487 let original = MultiEd25519Signature::from_bytes(&original_sig_bytes).unwrap();
1488
1489 let auth = AccountAuthenticator::MultiEd25519 {
1490 public_key: account.public_key_bytes(),
1491 signature: original_sig_bytes.clone(),
1492 };
1493
1494 let AccountAuthenticator::MultiEd25519 { signature, .. } = auth.for_simulate_endpoint()
1495 else {
1496 panic!("expected MultiEd25519 after simulate rewrite");
1497 };
1498
1499 assert_eq!(signature.len(), original_sig_bytes.len());
1501
1502 let rewritten = MultiEd25519Signature::from_bytes(&signature).unwrap();
1505 assert_eq!(rewritten.num_signatures(), original.num_signatures());
1506 assert_eq!(rewritten.bitmap(), original.bitmap());
1507
1508 assert!(signature[..signature.len() - 4].iter().all(|b| *b == 0));
1510 for (_, sig) in rewritten.signatures() {
1511 let sig_bytes = sig.to_bytes();
1512 assert_eq!(sig_bytes.len(), 64);
1513 assert!(sig_bytes.iter().all(|b| *b == 0));
1514 }
1515 }
1516
1517 #[cfg(feature = "ed25519")]
1518 #[test]
1519 fn test_account_authenticator_for_simulate_endpoint_multi_key_stays_valid() {
1520 use crate::crypto::{
1521 AnyPublicKey, AnySignature, Ed25519PrivateKey, MultiKeyPublicKey, MultiKeySignature,
1522 };
1523
1524 let sk0 = Ed25519PrivateKey::generate();
1525 let sk1 = Ed25519PrivateKey::generate();
1526 let sk2 = Ed25519PrivateKey::generate();
1527 let pk = MultiKeyPublicKey::new(
1528 vec![
1529 AnyPublicKey::ed25519(&sk0.public_key()),
1530 AnyPublicKey::ed25519(&sk1.public_key()),
1531 AnyPublicKey::ed25519(&sk2.public_key()),
1532 ],
1533 2,
1534 )
1535 .unwrap();
1536 let message = b"multi-key simulate test";
1537 let original = MultiKeySignature::new(vec![
1538 (0, AnySignature::ed25519(&sk0.sign(message))),
1539 (2, AnySignature::ed25519(&sk2.sign(message))),
1540 ])
1541 .unwrap();
1542 let original_sig_bytes = original.to_bytes();
1543
1544 let auth = AccountAuthenticator::multi_key(pk.to_bytes(), original_sig_bytes.clone());
1545 let AccountAuthenticator::MultiKey { signature, .. } = auth.for_simulate_endpoint() else {
1546 panic!("expected MultiKey after simulate rewrite");
1547 };
1548
1549 assert_eq!(signature.len(), original_sig_bytes.len());
1551
1552 let rewritten = MultiKeySignature::from_bytes(&signature).unwrap();
1555 assert_eq!(rewritten.num_signatures(), original.num_signatures());
1556 assert_eq!(rewritten.bitmap(), original.bitmap());
1557 for ((idx_r, sig_r), (idx_o, sig_o)) in
1558 rewritten.signatures().iter().zip(original.signatures())
1559 {
1560 assert_eq!(idx_r, idx_o);
1561 assert_eq!(sig_r.variant, sig_o.variant);
1562 assert_eq!(sig_r.bytes.len(), sig_o.bytes.len());
1563 assert!(sig_r.bytes.iter().all(|b| *b == 0));
1564 }
1565 }
1566
1567 #[test]
1568 fn test_zeroed_multi_ed25519_signature_wire_layout_pinned() {
1569 let mut input = Vec::new();
1572 input.extend_from_slice(&[0x11u8; 64]);
1573 input.extend_from_slice(&[0x22u8; 64]);
1574 input.extend_from_slice(&[0b1010_0000, 0x00, 0x00, 0x00]);
1575
1576 let out = zeroed_multi_ed25519_signature(&input);
1577
1578 let mut expected = vec![0u8; 128];
1580 expected.extend_from_slice(&[0b1010_0000, 0x00, 0x00, 0x00]);
1581 assert_eq!(out, expected);
1582 }
1583
1584 #[test]
1585 fn test_zeroed_multi_key_signature_wire_layout_pinned() {
1586 let mut input = vec![0x02u8]; input.extend_from_slice(&[0x00, 0x40]); input.extend_from_slice(&[0xaa; 64]);
1592 input.extend_from_slice(&[0x00, 0x40]);
1593 input.extend_from_slice(&[0xbb; 64]);
1594 input.push(0x04); input.extend_from_slice(&[0b1100_0000, 0x00, 0x00, 0x00]);
1596
1597 let out = zeroed_multi_key_signature(&input);
1598
1599 let mut expected = vec![0x02u8];
1600 expected.extend_from_slice(&[0x00, 0x40]);
1601 expected.extend_from_slice(&[0u8; 64]);
1602 expected.extend_from_slice(&[0x00, 0x40]);
1603 expected.extend_from_slice(&[0u8; 64]);
1604 expected.push(0x04);
1605 expected.extend_from_slice(&[0b1100_0000, 0x00, 0x00, 0x00]);
1606 assert_eq!(
1607 out, expected,
1608 "simulate-rewritten MultiKey signature wire layout drifted"
1609 );
1610
1611 let parsed = crate::crypto::MultiKeySignature::from_bytes(&out).unwrap();
1613 assert_eq!(parsed.num_signatures(), 2);
1614 assert_eq!(parsed.bitmap(), &[0b1100_0000, 0x00, 0x00, 0x00]);
1615 }
1616}