1use crate::error::{AptosError, AptosResult};
8use serde::{Deserialize, Serialize};
9use std::fmt;
10
11pub const MAX_NUM_OF_KEYS: usize = 32;
13
14const _: () = assert!(MAX_NUM_OF_KEYS <= u8::MAX as usize);
16
17pub const MIN_THRESHOLD: u8 = 1;
19
20#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
22#[repr(u8)]
23pub enum AnyPublicKeyVariant {
24 Ed25519 = 0,
26 Secp256k1 = 1,
28 Secp256r1 = 2,
30 Keyless = 3,
32}
33
34impl AnyPublicKeyVariant {
35 pub fn from_byte(byte: u8) -> AptosResult<Self> {
41 match byte {
42 0 => Ok(Self::Ed25519),
43 1 => Ok(Self::Secp256k1),
44 2 => Ok(Self::Secp256r1),
45 3 => Ok(Self::Keyless),
46 _ => Err(AptosError::InvalidPublicKey(format!(
47 "unknown public key variant: {byte}"
48 ))),
49 }
50 }
51
52 pub fn as_byte(&self) -> u8 {
54 *self as u8
55 }
56}
57
58#[derive(Clone, PartialEq, Eq)]
60pub struct AnyPublicKey {
61 pub variant: AnyPublicKeyVariant,
63 pub bytes: Vec<u8>,
65}
66
67impl AnyPublicKey {
68 pub fn new(variant: AnyPublicKeyVariant, bytes: Vec<u8>) -> Self {
70 Self { variant, bytes }
71 }
72
73 #[cfg(feature = "ed25519")]
75 pub fn ed25519(public_key: &crate::crypto::Ed25519PublicKey) -> Self {
76 Self {
77 variant: AnyPublicKeyVariant::Ed25519,
78 bytes: public_key.to_bytes().to_vec(),
79 }
80 }
81
82 #[cfg(feature = "secp256k1")]
88 pub fn secp256k1(public_key: &crate::crypto::Secp256k1PublicKey) -> Self {
89 Self {
90 variant: AnyPublicKeyVariant::Secp256k1,
91 bytes: public_key.to_uncompressed_bytes(),
92 }
93 }
94
95 #[cfg(feature = "secp256r1")]
98 pub fn secp256r1(public_key: &crate::crypto::Secp256r1PublicKey) -> Self {
99 Self {
100 variant: AnyPublicKeyVariant::Secp256r1,
101 bytes: public_key.to_uncompressed_bytes(),
102 }
103 }
104
105 pub fn to_bcs_bytes(&self) -> Vec<u8> {
110 let mut result = Vec::with_capacity(1 + 1 + self.bytes.len());
111 result.push(self.variant.as_byte());
112 result.extend(uleb128_encode(self.bytes.len()));
114 result.extend_from_slice(&self.bytes);
115 result
116 }
117
118 pub fn from_bcs_bytes(bytes: &[u8]) -> AptosResult<Self> {
126 if bytes.is_empty() {
127 return Err(AptosError::InvalidPublicKey(
128 "AnyPublicKey BCS empty".into(),
129 ));
130 }
131 let variant = AnyPublicKeyVariant::from_byte(bytes[0])?;
132 let (len, len_bytes) = uleb128_decode(&bytes[1..]).ok_or_else(|| {
133 AptosError::InvalidPublicKey("AnyPublicKey BCS invalid length prefix".into())
134 })?;
135 let start = 1 + len_bytes;
136 let end = start.checked_add(len).ok_or_else(|| {
137 AptosError::InvalidPublicKey("AnyPublicKey BCS length overflow".into())
138 })?;
139 if end > bytes.len() {
140 return Err(AptosError::InvalidPublicKey(
141 "AnyPublicKey BCS truncated payload".into(),
142 ));
143 }
144 if end != bytes.len() {
145 return Err(AptosError::InvalidPublicKey(
146 "AnyPublicKey BCS trailing bytes".into(),
147 ));
148 }
149 Ok(Self::new(variant, bytes[start..end].to_vec()))
150 }
151
152 #[allow(unused_variables)]
163 pub fn verify(&self, message: &[u8], signature: &AnySignature) -> AptosResult<()> {
164 if signature.variant != self.variant {
165 return Err(AptosError::InvalidSignature(format!(
166 "signature variant {:?} doesn't match public key variant {:?}",
167 signature.variant, self.variant
168 )));
169 }
170
171 match self.variant {
172 #[cfg(feature = "ed25519")]
173 AnyPublicKeyVariant::Ed25519 => {
174 let pk = crate::crypto::Ed25519PublicKey::from_bytes(&self.bytes)?;
175 let sig = crate::crypto::Ed25519Signature::from_bytes(&signature.bytes)?;
176 pk.verify(message, &sig)
177 }
178 #[cfg(feature = "secp256k1")]
179 AnyPublicKeyVariant::Secp256k1 => {
180 let pk = crate::crypto::Secp256k1PublicKey::from_bytes(&self.bytes)?;
182 let sig = crate::crypto::Secp256k1Signature::from_bytes(&signature.bytes)?;
183 pk.verify(message, &sig)
184 }
185 #[cfg(feature = "secp256r1")]
186 AnyPublicKeyVariant::Secp256r1 => {
187 let pk = crate::crypto::Secp256r1PublicKey::from_bytes(&self.bytes)?;
189 let sig = crate::crypto::Secp256r1Signature::from_bytes(&signature.bytes)?;
190 pk.verify(message, &sig)
191 }
192 #[allow(unreachable_patterns)]
193 _ => Err(AptosError::InvalidPublicKey(format!(
194 "verification not supported for variant {:?}",
195 self.variant
196 ))),
197 }
198 }
199}
200
201impl fmt::Debug for AnyPublicKey {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 write!(
204 f,
205 "AnyPublicKey({:?}, {})",
206 self.variant,
207 const_hex::encode_prefixed(&self.bytes)
208 )
209 }
210}
211
212impl fmt::Display for AnyPublicKey {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 write!(
215 f,
216 "{:?}:{}",
217 self.variant,
218 const_hex::encode_prefixed(&self.bytes)
219 )
220 }
221}
222
223#[derive(Clone, PartialEq, Eq)]
225pub struct AnySignature {
226 pub variant: AnyPublicKeyVariant,
228 pub bytes: Vec<u8>,
230}
231
232impl AnySignature {
233 pub fn new(variant: AnyPublicKeyVariant, bytes: Vec<u8>) -> Self {
235 Self { variant, bytes }
236 }
237
238 #[cfg(feature = "ed25519")]
240 pub fn ed25519(signature: &crate::crypto::Ed25519Signature) -> Self {
241 Self {
242 variant: AnyPublicKeyVariant::Ed25519,
243 bytes: signature.to_bytes().to_vec(),
244 }
245 }
246
247 #[cfg(feature = "secp256k1")]
249 pub fn secp256k1(signature: &crate::crypto::Secp256k1Signature) -> Self {
250 Self {
251 variant: AnyPublicKeyVariant::Secp256k1,
252 bytes: signature.to_bytes().to_vec(),
253 }
254 }
255
256 #[cfg(feature = "secp256r1")]
258 pub fn secp256r1(signature: &crate::crypto::Secp256r1Signature) -> Self {
259 Self {
260 variant: AnyPublicKeyVariant::Secp256r1,
261 bytes: signature.to_bytes().to_vec(),
262 }
263 }
264
265 pub fn to_bcs_bytes(&self) -> Vec<u8> {
276 if self.variant == AnyPublicKeyVariant::Secp256r1 && self.bytes.len() != 64 {
277 let mut result = Vec::with_capacity(1 + self.bytes.len());
278 result.push(self.variant.as_byte());
279 result.extend_from_slice(&self.bytes);
280 return result;
281 }
282 let mut result = Vec::with_capacity(1 + 1 + self.bytes.len());
283 result.push(self.variant.as_byte());
284 result.extend(uleb128_encode(self.bytes.len()));
286 result.extend_from_slice(&self.bytes);
287 result
288 }
289
290 pub fn from_bcs_bytes(bytes: &[u8]) -> AptosResult<Self> {
309 if bytes.is_empty() {
310 return Err(AptosError::InvalidSignature(
311 "AnySignature BCS empty".into(),
312 ));
313 }
314 let variant = AnyPublicKeyVariant::from_byte(bytes[0]).map_err(|e| {
315 AptosError::InvalidSignature(format!("AnySignature BCS bad variant: {e}"))
316 })?;
317 if variant == AnyPublicKeyVariant::Secp256r1 && bytes.len() > 1 && bytes[1] == 0x00 {
318 return Ok(Self::new(variant, bytes[1..].to_vec()));
319 }
320 let (len, len_bytes) = uleb128_decode(&bytes[1..]).ok_or_else(|| {
321 AptosError::InvalidSignature("AnySignature BCS invalid length prefix".into())
322 })?;
323 let start = 1 + len_bytes;
324 let end = start.checked_add(len).ok_or_else(|| {
325 AptosError::InvalidSignature("AnySignature BCS length overflow".into())
326 })?;
327 if end > bytes.len() {
328 return Err(AptosError::InvalidSignature(
329 "AnySignature BCS truncated payload".into(),
330 ));
331 }
332 if end != bytes.len() {
333 return Err(AptosError::InvalidSignature(
334 "AnySignature BCS trailing bytes".into(),
335 ));
336 }
337 Ok(Self::new(variant, bytes[start..end].to_vec()))
338 }
339}
340
341#[allow(clippy::cast_possible_truncation)] #[inline]
346pub(crate) fn uleb128_encode(mut value: usize) -> Vec<u8> {
347 let mut result = Vec::with_capacity(if value < 128 { 1 } else { 2 });
349 loop {
350 let byte = (value & 0x7F) as u8;
351 value >>= 7;
352 if value == 0 {
353 result.push(byte);
354 break;
355 }
356 result.push(byte | 0x80);
357 }
358 result
359}
360
361fn uleb128_decode(bytes: &[u8]) -> Option<(usize, usize)> {
363 let mut result: usize = 0;
364 let mut shift = 0;
365 for (i, &byte) in bytes.iter().enumerate() {
366 result |= ((byte & 0x7F) as usize) << shift;
367 if byte & 0x80 == 0 {
368 return Some((result, i + 1));
369 }
370 shift += 7;
371 if shift >= 64 {
372 return None; }
374 }
375 None
376}
377
378impl fmt::Debug for AnySignature {
379 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380 write!(
381 f,
382 "AnySignature({:?}, {} bytes)",
383 self.variant,
384 self.bytes.len()
385 )
386 }
387}
388
389#[derive(Clone, PartialEq, Eq)]
393pub struct MultiKeyPublicKey {
394 public_keys: Vec<AnyPublicKey>,
396 threshold: u8,
398}
399
400impl MultiKeyPublicKey {
401 pub fn new(public_keys: Vec<AnyPublicKey>, threshold: u8) -> AptosResult<Self> {
416 if public_keys.is_empty() {
417 return Err(AptosError::InvalidPublicKey(
418 "multi-key requires at least one public key".into(),
419 ));
420 }
421 if public_keys.len() > MAX_NUM_OF_KEYS {
422 return Err(AptosError::InvalidPublicKey(format!(
423 "multi-key supports at most {} keys, got {}",
424 MAX_NUM_OF_KEYS,
425 public_keys.len()
426 )));
427 }
428 if threshold < MIN_THRESHOLD {
429 return Err(AptosError::InvalidPublicKey(
430 "threshold must be at least 1".into(),
431 ));
432 }
433 if threshold as usize > public_keys.len() {
434 return Err(AptosError::InvalidPublicKey(format!(
435 "threshold {} exceeds number of keys {}",
436 threshold,
437 public_keys.len()
438 )));
439 }
440 Ok(Self {
441 public_keys,
442 threshold,
443 })
444 }
445
446 pub fn num_keys(&self) -> usize {
448 self.public_keys.len()
449 }
450
451 pub fn threshold(&self) -> u8 {
453 self.threshold
454 }
455
456 pub fn public_keys(&self) -> &[AnyPublicKey] {
458 &self.public_keys
459 }
460
461 pub fn get(&self, index: usize) -> Option<&AnyPublicKey> {
463 self.public_keys.get(index)
464 }
465
466 #[allow(clippy::cast_possible_truncation)] pub fn to_bytes(&self) -> Vec<u8> {
471 let estimated_size = 2 + self.public_keys.len() * 36;
473 let mut bytes = Vec::with_capacity(estimated_size);
474
475 bytes.push(self.public_keys.len() as u8);
477
478 for pk in &self.public_keys {
480 bytes.extend(pk.to_bcs_bytes());
481 }
482
483 bytes.push(self.threshold);
485
486 bytes
487 }
488
489 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
501 const MAX_KEY_SIZE: usize = 128;
504
505 if bytes.is_empty() {
506 return Err(AptosError::InvalidPublicKey("empty bytes".into()));
507 }
508
509 let num_keys = bytes[0] as usize;
510 if num_keys == 0 || num_keys > MAX_NUM_OF_KEYS {
511 return Err(AptosError::InvalidPublicKey(format!(
512 "invalid number of keys: {num_keys}"
513 )));
514 }
515
516 let mut offset = 1;
517 let mut public_keys = Vec::with_capacity(num_keys);
518
519 for _ in 0..num_keys {
520 if offset >= bytes.len() {
521 return Err(AptosError::InvalidPublicKey("bytes too short".into()));
522 }
523
524 let variant = AnyPublicKeyVariant::from_byte(bytes[offset])?;
525 offset += 1;
526
527 let (len, len_bytes) = uleb128_decode(&bytes[offset..]).ok_or_else(|| {
529 AptosError::InvalidPublicKey("invalid ULEB128 length encoding".into())
530 })?;
531 offset += len_bytes;
532
533 if len > MAX_KEY_SIZE {
534 return Err(AptosError::InvalidPublicKey(format!(
535 "key size {len} exceeds maximum {MAX_KEY_SIZE}"
536 )));
537 }
538
539 if offset + len > bytes.len() {
540 return Err(AptosError::InvalidPublicKey(
541 "bytes too short for key".into(),
542 ));
543 }
544
545 let key_bytes = bytes[offset..offset + len].to_vec();
546 offset += len;
547
548 public_keys.push(AnyPublicKey::new(variant, key_bytes));
549 }
550
551 if offset >= bytes.len() {
552 return Err(AptosError::InvalidPublicKey(
553 "bytes too short for threshold".into(),
554 ));
555 }
556
557 let threshold = bytes[offset];
558
559 Self::new(public_keys, threshold)
560 }
561
562 pub fn to_address(&self) -> crate::types::AccountAddress {
564 crate::crypto::derive_address(&self.to_bytes(), crate::crypto::MULTI_KEY_SCHEME)
565 }
566
567 pub fn to_authentication_key(&self) -> [u8; 32] {
569 crate::crypto::derive_authentication_key(&self.to_bytes(), crate::crypto::MULTI_KEY_SCHEME)
570 }
571
572 pub fn verify(&self, message: &[u8], signature: &MultiKeySignature) -> AptosResult<()> {
581 if signature.num_signatures() < self.threshold as usize {
583 return Err(AptosError::SignatureVerificationFailed);
584 }
585
586 for (index, sig) in signature.signatures() {
588 if *index as usize >= self.public_keys.len() {
589 return Err(AptosError::InvalidSignature(format!(
590 "signer index {} out of bounds (max {})",
591 index,
592 self.public_keys.len() - 1
593 )));
594 }
595 let pk = &self.public_keys[*index as usize];
596 pk.verify(message, sig)?;
597 }
598
599 Ok(())
600 }
601}
602
603impl fmt::Debug for MultiKeyPublicKey {
604 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
605 write!(
606 f,
607 "MultiKeyPublicKey({}-of-{} keys)",
608 self.threshold,
609 self.public_keys.len()
610 )
611 }
612}
613
614impl fmt::Display for MultiKeyPublicKey {
615 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
616 f.write_str(&const_hex::encode_prefixed(self.to_bytes()))
617 }
618}
619
620#[derive(Clone, PartialEq, Eq)]
622pub struct MultiKeySignature {
623 signatures: Vec<(u8, AnySignature)>,
625 bitmap: [u8; 4],
627}
628
629impl MultiKeySignature {
630 pub fn new(mut signatures: Vec<(u8, AnySignature)>) -> AptosResult<Self> {
644 if signatures.is_empty() {
645 return Err(AptosError::InvalidSignature(
646 "multi-key signature requires at least one signature".into(),
647 ));
648 }
649 if signatures.len() > MAX_NUM_OF_KEYS {
650 return Err(AptosError::InvalidSignature(format!(
651 "too many signatures: {} (max {})",
652 signatures.len(),
653 MAX_NUM_OF_KEYS
654 )));
655 }
656
657 signatures.sort_by_key(|(idx, _)| *idx);
659
660 let mut bitmap = [0u8; 4];
662 let mut last_index: Option<u8> = None;
663
664 for (index, _) in &signatures {
665 if *index as usize >= MAX_NUM_OF_KEYS {
666 return Err(AptosError::InvalidSignature(format!(
667 "signer index {} out of bounds (max {})",
668 index,
669 MAX_NUM_OF_KEYS - 1
670 )));
671 }
672 if last_index == Some(*index) {
673 return Err(AptosError::InvalidSignature(format!(
674 "duplicate signer index {index}"
675 )));
676 }
677 last_index = Some(*index);
678
679 let byte_index = (index / 8) as usize;
684 let bit_in_byte = index % 8;
685 bitmap[byte_index] |= 0b1000_0000u8 >> bit_in_byte;
686 }
687
688 Ok(Self { signatures, bitmap })
689 }
690
691 pub fn num_signatures(&self) -> usize {
693 self.signatures.len()
694 }
695
696 pub fn signatures(&self) -> &[(u8, AnySignature)] {
698 &self.signatures
699 }
700
701 pub fn bitmap(&self) -> &[u8; 4] {
703 &self.bitmap
704 }
705
706 pub fn has_signature(&self, index: u8) -> bool {
708 if index as usize >= MAX_NUM_OF_KEYS {
709 return false;
710 }
711 let byte_index = (index / 8) as usize;
712 let bit_in_byte = index % 8;
713 (self.bitmap[byte_index] & (0b1000_0000u8 >> bit_in_byte)) != 0
714 }
715
716 #[allow(clippy::cast_possible_truncation)] pub fn to_bytes(&self) -> Vec<u8> {
723 let estimated_size = 1 + self.signatures.len() * 68 + 1 + 4;
726 let mut bytes = Vec::with_capacity(estimated_size);
727
728 bytes.push(self.signatures.len() as u8);
730
731 for (_, sig) in &self.signatures {
733 bytes.extend(sig.to_bcs_bytes());
734 }
735
736 bytes.push(4);
738 bytes.extend_from_slice(&self.bitmap);
740
741 bytes
742 }
743
744 pub fn from_bytes(bytes: &[u8]) -> AptosResult<Self> {
756 const MAX_SIGNATURE_SIZE: usize = 128;
759
760 if bytes.len() < 6 {
764 return Err(AptosError::InvalidSignature("bytes too short".into()));
765 }
766
767 let num_sigs = bytes[0] as usize;
768 if num_sigs == 0 || num_sigs > MAX_NUM_OF_KEYS {
769 return Err(AptosError::InvalidSignature(format!(
770 "invalid number of signatures: {num_sigs}"
771 )));
772 }
773
774 let bitmap_start = bytes.len() - 4;
777 let mut bitmap = [0u8; 4];
778 bitmap.copy_from_slice(&bytes[bitmap_start..]);
779 let bitvec_prefix_idx = bitmap_start.checked_sub(1).ok_or_else(|| {
780 AptosError::InvalidSignature("MultiKeySignature too short for BitVec prefix".into())
781 })?;
782 if bytes[bitvec_prefix_idx] != 4 {
783 return Err(AptosError::InvalidSignature(
784 "MultiKeySignature: expected BCS BitVec length prefix = 4".into(),
785 ));
786 }
787
788 let mut offset = 1;
790 let mut signatures = Vec::with_capacity(num_sigs);
791
792 let mut signer_indices = Vec::new();
794 #[allow(clippy::cast_possible_truncation)]
795 for bit_pos in 0..(MAX_NUM_OF_KEYS as u8) {
796 let byte_idx = (bit_pos / 8) as usize;
797 let bit_in_byte = bit_pos % 8;
798 if (bitmap[byte_idx] & (0b1000_0000u8 >> bit_in_byte)) != 0 {
799 signer_indices.push(bit_pos);
800 }
801 }
802
803 if signer_indices.len() != num_sigs {
804 return Err(AptosError::InvalidSignature(
805 "bitmap doesn't match number of signatures".into(),
806 ));
807 }
808
809 let sigs_end = bitvec_prefix_idx;
812 for &index in &signer_indices {
813 if offset >= sigs_end {
814 return Err(AptosError::InvalidSignature("bytes too short".into()));
815 }
816
817 let variant = AnyPublicKeyVariant::from_byte(bytes[offset])?;
818 offset += 1;
819
820 let (len, len_bytes) = uleb128_decode(&bytes[offset..sigs_end]).ok_or_else(|| {
822 AptosError::InvalidSignature("invalid ULEB128 length encoding".into())
823 })?;
824 offset += len_bytes;
825
826 if len > MAX_SIGNATURE_SIZE {
827 return Err(AptosError::InvalidSignature(format!(
828 "signature size {len} exceeds maximum {MAX_SIGNATURE_SIZE}"
829 )));
830 }
831
832 if offset + len > sigs_end {
833 return Err(AptosError::InvalidSignature(
834 "bytes too short for signature".into(),
835 ));
836 }
837
838 let sig_bytes = bytes[offset..offset + len].to_vec();
839 offset += len;
840
841 signatures.push((index, AnySignature::new(variant, sig_bytes)));
842 }
843
844 Ok(Self { signatures, bitmap })
845 }
846}
847
848impl fmt::Debug for MultiKeySignature {
849 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
850 write!(
851 f,
852 "MultiKeySignature({} signatures, bitmap={:?})",
853 self.signatures.len(),
854 self.bitmap
855 )
856 }
857}
858
859impl fmt::Display for MultiKeySignature {
860 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
861 f.write_str(&const_hex::encode_prefixed(self.to_bytes()))
862 }
863}
864
865#[cfg(test)]
866mod tests {
867 use super::*;
868
869 #[test]
870 fn test_any_public_key_variant_from_byte() {
871 assert_eq!(
872 AnyPublicKeyVariant::from_byte(0).unwrap(),
873 AnyPublicKeyVariant::Ed25519
874 );
875 assert_eq!(
876 AnyPublicKeyVariant::from_byte(1).unwrap(),
877 AnyPublicKeyVariant::Secp256k1
878 );
879 assert_eq!(
880 AnyPublicKeyVariant::from_byte(2).unwrap(),
881 AnyPublicKeyVariant::Secp256r1
882 );
883 assert_eq!(
884 AnyPublicKeyVariant::from_byte(3).unwrap(),
885 AnyPublicKeyVariant::Keyless
886 );
887 assert!(AnyPublicKeyVariant::from_byte(4).is_err());
888 assert!(AnyPublicKeyVariant::from_byte(255).is_err());
889 }
890
891 #[test]
892 fn test_any_public_key_variant_as_byte() {
893 assert_eq!(AnyPublicKeyVariant::Ed25519.as_byte(), 0);
894 assert_eq!(AnyPublicKeyVariant::Secp256k1.as_byte(), 1);
895 assert_eq!(AnyPublicKeyVariant::Secp256r1.as_byte(), 2);
896 assert_eq!(AnyPublicKeyVariant::Keyless.as_byte(), 3);
897 }
898
899 #[test]
900 fn test_any_public_key_new() {
901 let pk = AnyPublicKey::new(AnyPublicKeyVariant::Ed25519, vec![0x11; 32]);
902 assert_eq!(pk.variant, AnyPublicKeyVariant::Ed25519);
903 assert_eq!(pk.bytes.len(), 32);
904 assert_eq!(pk.bytes[0], 0x11);
905 }
906
907 #[test]
908 fn test_any_public_key_to_bcs_bytes() {
909 let pk = AnyPublicKey::new(AnyPublicKeyVariant::Ed25519, vec![0xaa; 32]);
910 let bcs = pk.to_bcs_bytes();
911
912 assert_eq!(bcs[0], 0); assert_eq!(bcs[1], 32); assert_eq!(bcs[2], 0xaa); assert_eq!(bcs.len(), 1 + 1 + 32); }
918
919 #[test]
920 fn test_any_public_key_debug() {
921 let pk = AnyPublicKey::new(AnyPublicKeyVariant::Secp256k1, vec![0xbb; 33]);
922 let debug = format!("{pk:?}");
923 assert!(debug.contains("Secp256k1"));
924 assert!(debug.contains("0x"));
925 }
926
927 #[test]
928 fn test_any_signature_new() {
929 let sig = AnySignature::new(AnyPublicKeyVariant::Ed25519, vec![0xcc; 64]);
930 assert_eq!(sig.variant, AnyPublicKeyVariant::Ed25519);
931 assert_eq!(sig.bytes.len(), 64);
932 }
933
934 #[test]
935 fn test_any_signature_to_bcs_bytes() {
936 let sig = AnySignature::new(AnyPublicKeyVariant::Ed25519, vec![0xdd; 64]);
937 let bcs = sig.to_bcs_bytes();
938
939 assert_eq!(bcs[0], 0); assert_eq!(bcs[1], 64); assert_eq!(bcs[2], 0xdd); assert_eq!(bcs.len(), 1 + 1 + 64); }
945
946 #[test]
947 fn test_any_signature_secp256r1_bare_bcs_roundtrip() {
948 let inner = vec![0x42u8; 64];
949 let mut wire = vec![0x02, 0x40];
950 wire.extend_from_slice(&inner);
951 let sig = AnySignature::from_bcs_bytes(&wire).expect("parse bare Secp256r1");
952 assert_eq!(sig.variant, AnyPublicKeyVariant::Secp256r1);
953 assert_eq!(sig.bytes, inner);
954 assert_eq!(sig.to_bcs_bytes(), wire);
955 }
956
957 #[test]
958 fn test_any_signature_webauthn_style_bcs_roundtrip() {
959 let mut paar = vec![0x00u8, 0x40];
962 paar.extend(vec![0x11u8; 64]);
963 let mut wire = vec![0x02];
964 wire.extend_from_slice(&paar);
965 let sig = AnySignature::from_bcs_bytes(&wire).expect("parse WebAuthn-style");
966 assert_eq!(sig.variant, AnyPublicKeyVariant::Secp256r1);
967 assert_eq!(sig.bytes, paar);
968 assert_eq!(sig.to_bcs_bytes(), wire);
969 }
970
971 #[test]
972 fn test_any_signature_debug() {
973 let sig = AnySignature::new(AnyPublicKeyVariant::Secp256r1, vec![0xee; 64]);
974 let debug = format!("{sig:?}");
975 assert!(debug.contains("Secp256r1"));
976 assert!(debug.contains("64 bytes"));
977 }
978
979 #[test]
980 fn test_any_public_key_verify_mismatched_variant() {
981 let pk = AnyPublicKey::new(AnyPublicKeyVariant::Ed25519, vec![0; 32]);
982 let sig = AnySignature::new(AnyPublicKeyVariant::Secp256k1, vec![0; 64]);
983
984 let result = pk.verify(b"message", &sig);
985 assert!(result.is_err());
986 assert!(result.unwrap_err().to_string().contains("variant"));
987 }
988
989 #[test]
990 fn test_multi_key_signature_insufficient_sigs() {
991 let result = MultiKeySignature::new(vec![]);
993 assert!(result.is_err());
994 }
995
996 #[test]
997 fn test_multi_key_signature_duplicate_indices() {
998 let sig1 = AnySignature::new(AnyPublicKeyVariant::Ed25519, vec![0; 64]);
999 let sig2 = AnySignature::new(AnyPublicKeyVariant::Ed25519, vec![1; 64]);
1000
1001 let result = MultiKeySignature::new(vec![(0, sig1.clone()), (0, sig2)]);
1003 assert!(result.is_err());
1004 }
1005
1006 #[test]
1007 fn test_multi_key_signature_index_out_of_range() {
1008 let sig = AnySignature::new(AnyPublicKeyVariant::Ed25519, vec![0; 64]);
1009
1010 let result = MultiKeySignature::new(vec![(32, sig)]);
1012 assert!(result.is_err());
1013 }
1014
1015 #[test]
1016 fn test_multi_key_signature_basic() {
1017 let sig1 = AnySignature::new(AnyPublicKeyVariant::Ed25519, vec![0xaa; 64]);
1018 let sig2 = AnySignature::new(AnyPublicKeyVariant::Ed25519, vec![0xbb; 64]);
1019
1020 let multi_sig = MultiKeySignature::new(vec![(0, sig1), (5, sig2)]).unwrap();
1021
1022 assert_eq!(multi_sig.num_signatures(), 2);
1023 assert!(multi_sig.has_signature(0));
1024 assert!(!multi_sig.has_signature(1));
1025 assert!(multi_sig.has_signature(5));
1026 }
1027
1028 #[test]
1029 fn test_multi_key_signature_debug_display() {
1030 let sig = AnySignature::new(AnyPublicKeyVariant::Ed25519, vec![0; 64]);
1031 let multi_sig = MultiKeySignature::new(vec![(0, sig)]).unwrap();
1032
1033 let debug = format!("{multi_sig:?}");
1034 let display = format!("{multi_sig}");
1035
1036 assert!(debug.contains("MultiKeySignature"));
1037 assert!(display.starts_with("0x"));
1038 }
1039
1040 #[test]
1041 #[cfg(feature = "ed25519")]
1042 fn test_multi_key_public_key_creation() {
1043 use crate::crypto::Ed25519PrivateKey;
1044
1045 let keys: Vec<_> = (0..3)
1046 .map(|_| AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key()))
1047 .collect();
1048
1049 let multi_pk = MultiKeyPublicKey::new(keys.clone(), 2).unwrap();
1051 assert_eq!(multi_pk.num_keys(), 3);
1052 assert_eq!(multi_pk.threshold(), 2);
1053
1054 assert!(MultiKeyPublicKey::new(keys.clone(), 4).is_err());
1056
1057 assert!(MultiKeyPublicKey::new(keys.clone(), 0).is_err());
1059
1060 assert!(MultiKeyPublicKey::new(vec![], 1).is_err());
1062 }
1063
1064 #[test]
1065 #[cfg(all(feature = "ed25519", feature = "secp256k1"))]
1066 fn test_multi_key_mixed_types() {
1067 use crate::crypto::{Ed25519PrivateKey, Secp256k1PrivateKey};
1068
1069 let ed_key = AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key());
1071 let secp_key = AnyPublicKey::secp256k1(&Secp256k1PrivateKey::generate().public_key());
1072
1073 let multi_pk = MultiKeyPublicKey::new(vec![ed_key, secp_key], 2).unwrap();
1074 assert_eq!(multi_pk.num_keys(), 2);
1075 assert_eq!(
1076 multi_pk.get(0).unwrap().variant,
1077 AnyPublicKeyVariant::Ed25519
1078 );
1079 assert_eq!(
1080 multi_pk.get(1).unwrap().variant,
1081 AnyPublicKeyVariant::Secp256k1
1082 );
1083 }
1084
1085 #[test]
1086 #[cfg(feature = "ed25519")]
1087 fn test_multi_key_sign_verify() {
1088 use crate::crypto::Ed25519PrivateKey;
1089
1090 let private_keys: Vec<_> = (0..3).map(|_| Ed25519PrivateKey::generate()).collect();
1091 let public_keys: Vec<_> = private_keys
1092 .iter()
1093 .map(|k| AnyPublicKey::ed25519(&k.public_key()))
1094 .collect();
1095
1096 let multi_pk = MultiKeyPublicKey::new(public_keys, 2).unwrap();
1097 let message = b"test message";
1098
1099 let sig0 = AnySignature::ed25519(&private_keys[0].sign(message));
1101 let sig2 = AnySignature::ed25519(&private_keys[2].sign(message));
1102
1103 let multi_sig = MultiKeySignature::new(vec![(0, sig0), (2, sig2)]).unwrap();
1104
1105 assert!(multi_pk.verify(message, &multi_sig).is_ok());
1107
1108 assert!(multi_pk.verify(b"wrong message", &multi_sig).is_err());
1110 }
1111
1112 #[test]
1113 #[cfg(feature = "ed25519")]
1114 fn test_multi_key_bytes_roundtrip() {
1115 use crate::crypto::Ed25519PrivateKey;
1116
1117 let keys: Vec<_> = (0..3)
1118 .map(|_| AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key()))
1119 .collect();
1120 let multi_pk = MultiKeyPublicKey::new(keys, 2).unwrap();
1121
1122 let bytes = multi_pk.to_bytes();
1123 let restored = MultiKeyPublicKey::from_bytes(&bytes).unwrap();
1124
1125 assert_eq!(multi_pk.threshold(), restored.threshold());
1126 assert_eq!(multi_pk.num_keys(), restored.num_keys());
1127 }
1128
1129 #[test]
1130 #[cfg(feature = "ed25519")]
1131 fn test_multi_key_signature_bytes_roundtrip() {
1132 use crate::crypto::Ed25519PrivateKey;
1133
1134 let private_keys: Vec<_> = (0..3).map(|_| Ed25519PrivateKey::generate()).collect();
1135 let message = b"test";
1136
1137 let sig0 = AnySignature::ed25519(&private_keys[0].sign(message));
1138 let sig2 = AnySignature::ed25519(&private_keys[2].sign(message));
1139
1140 let multi_sig = MultiKeySignature::new(vec![(0, sig0), (2, sig2)]).unwrap();
1141
1142 let bytes = multi_sig.to_bytes();
1143 let restored = MultiKeySignature::from_bytes(&bytes).unwrap();
1144
1145 assert_eq!(multi_sig.num_signatures(), restored.num_signatures());
1146 assert_eq!(multi_sig.bitmap(), restored.bitmap());
1147 }
1148
1149 #[test]
1150 #[cfg(feature = "ed25519")]
1151 fn test_signature_bitmap() {
1152 use crate::crypto::Ed25519PrivateKey;
1153
1154 let private_keys: Vec<_> = (0..5).map(|_| Ed25519PrivateKey::generate()).collect();
1155 let message = b"test";
1156
1157 let signatures: Vec<_> = [1, 3, 4]
1159 .iter()
1160 .map(|&i| {
1161 (
1162 i,
1163 AnySignature::ed25519(&private_keys[i as usize].sign(message)),
1164 )
1165 })
1166 .collect();
1167
1168 let multi_sig = MultiKeySignature::new(signatures).unwrap();
1169
1170 assert!(!multi_sig.has_signature(0));
1171 assert!(multi_sig.has_signature(1));
1172 assert!(!multi_sig.has_signature(2));
1173 assert!(multi_sig.has_signature(3));
1174 assert!(multi_sig.has_signature(4));
1175 assert!(!multi_sig.has_signature(5));
1176 }
1177
1178 #[test]
1179 fn test_multi_key_public_key_empty_keys() {
1180 let result = MultiKeyPublicKey::new(vec![], 1);
1181 assert!(result.is_err());
1182 assert!(result.unwrap_err().to_string().contains("at least one"));
1183 }
1184
1185 #[test]
1186 #[cfg(feature = "ed25519")]
1187 fn test_multi_key_public_key_threshold_zero() {
1188 use crate::crypto::Ed25519PrivateKey;
1189
1190 let keys: Vec<_> = (0..2)
1191 .map(|_| AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key()))
1192 .collect();
1193 let result = MultiKeyPublicKey::new(keys, 0);
1194 assert!(result.is_err());
1195 assert!(result.unwrap_err().to_string().contains("at least 1"));
1196 }
1197
1198 #[test]
1199 #[cfg(feature = "ed25519")]
1200 fn test_multi_key_public_key_threshold_exceeds() {
1201 use crate::crypto::Ed25519PrivateKey;
1202
1203 let keys: Vec<_> = (0..2)
1204 .map(|_| AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key()))
1205 .collect();
1206 let result = MultiKeyPublicKey::new(keys, 5);
1207 assert!(result.is_err());
1208 assert!(result.unwrap_err().to_string().contains("exceed"));
1209 }
1210
1211 #[test]
1212 #[cfg(feature = "ed25519")]
1213 fn test_multi_key_signature_empty() {
1214 let result = MultiKeySignature::new(vec![]);
1215 assert!(result.is_err());
1216 assert!(result.unwrap_err().to_string().contains("at least one"));
1217 }
1218
1219 #[test]
1220 #[cfg(feature = "ed25519")]
1221 fn test_multi_key_signature_duplicate_index() {
1222 use crate::crypto::Ed25519PrivateKey;
1223
1224 let private_key = Ed25519PrivateKey::generate();
1225 let sig = AnySignature::ed25519(&private_key.sign(b"test"));
1226
1227 let result = MultiKeySignature::new(vec![(0, sig.clone()), (0, sig)]);
1228 assert!(result.is_err());
1229 assert!(result.unwrap_err().to_string().contains("duplicate"));
1230 }
1231
1232 #[test]
1233 #[cfg(feature = "ed25519")]
1234 fn test_multi_key_public_key_accessors() {
1235 use crate::crypto::Ed25519PrivateKey;
1236
1237 let keys: Vec<_> = (0..3)
1238 .map(|_| AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key()))
1239 .collect();
1240 let multi_pk = MultiKeyPublicKey::new(keys, 2).unwrap();
1241
1242 assert_eq!(multi_pk.threshold(), 2);
1243 assert_eq!(multi_pk.num_keys(), 3);
1244 assert_eq!(multi_pk.public_keys().len(), 3);
1245 }
1246
1247 #[test]
1248 #[cfg(feature = "ed25519")]
1249 fn test_multi_key_signature_accessors() {
1250 use crate::crypto::Ed25519PrivateKey;
1251
1252 let private_key = Ed25519PrivateKey::generate();
1253 let sig0 = AnySignature::ed25519(&private_key.sign(b"test"));
1254 let sig2 = AnySignature::ed25519(&private_key.sign(b"test"));
1255
1256 let multi_sig = MultiKeySignature::new(vec![(0, sig0), (2, sig2)]).unwrap();
1257
1258 assert_eq!(multi_sig.num_signatures(), 2);
1259 assert_eq!(multi_sig.signatures().len(), 2);
1260 }
1261
1262 #[test]
1263 #[cfg(feature = "ed25519")]
1264 fn test_multi_key_public_key_debug() {
1265 use crate::crypto::Ed25519PrivateKey;
1266
1267 let keys: Vec<_> = (0..2)
1268 .map(|_| AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key()))
1269 .collect();
1270 let multi_pk = MultiKeyPublicKey::new(keys, 2).unwrap();
1271
1272 let debug = format!("{multi_pk:?}");
1273 assert!(debug.contains("MultiKeyPublicKey"));
1274 }
1275
1276 #[test]
1277 #[cfg(feature = "ed25519")]
1278 fn test_multi_key_signature_debug() {
1279 use crate::crypto::Ed25519PrivateKey;
1280
1281 let private_key = Ed25519PrivateKey::generate();
1282 let sig = AnySignature::ed25519(&private_key.sign(b"test"));
1283 let multi_sig = MultiKeySignature::new(vec![(0, sig)]).unwrap();
1284
1285 let debug = format!("{multi_sig:?}");
1286 assert!(debug.contains("MultiKeySignature"));
1287 }
1288
1289 #[test]
1290 #[cfg(feature = "ed25519")]
1291 fn test_multi_key_public_key_display() {
1292 use crate::crypto::Ed25519PrivateKey;
1293
1294 let keys: Vec<_> = (0..2)
1295 .map(|_| AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key()))
1296 .collect();
1297 let multi_pk = MultiKeyPublicKey::new(keys, 2).unwrap();
1298
1299 let display = format!("{multi_pk}");
1300 assert!(display.starts_with("0x"));
1301 }
1302
1303 #[test]
1304 #[cfg(feature = "ed25519")]
1305 fn test_multi_key_signature_display() {
1306 use crate::crypto::Ed25519PrivateKey;
1307
1308 let private_key = Ed25519PrivateKey::generate();
1309 let sig = AnySignature::ed25519(&private_key.sign(b"test"));
1310 let multi_sig = MultiKeySignature::new(vec![(0, sig)]).unwrap();
1311
1312 let display = format!("{multi_sig}");
1313 assert!(display.starts_with("0x"));
1314 }
1315
1316 #[test]
1317 #[cfg(feature = "ed25519")]
1318 fn test_multi_key_public_key_to_address() {
1319 use crate::crypto::Ed25519PrivateKey;
1320
1321 let keys: Vec<_> = (0..2)
1322 .map(|_| AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key()))
1323 .collect();
1324 let multi_pk = MultiKeyPublicKey::new(keys, 2).unwrap();
1325
1326 let address = multi_pk.to_address();
1327 assert!(!address.is_zero());
1328 }
1329
1330 #[test]
1331 fn test_any_public_key_variant_debug() {
1332 let variant = AnyPublicKeyVariant::Ed25519;
1333 let debug = format!("{variant:?}");
1334 assert!(debug.contains("Ed25519"));
1335 }
1336
1337 #[test]
1338 #[cfg(feature = "ed25519")]
1339 fn test_any_public_key_ed25519_debug() {
1340 use crate::crypto::Ed25519PrivateKey;
1341
1342 let pk = AnyPublicKey::ed25519(&Ed25519PrivateKey::generate().public_key());
1343 let debug = format!("{pk:?}");
1344 assert!(debug.contains("Ed25519"));
1345 }
1346
1347 #[test]
1348 #[cfg(feature = "ed25519")]
1349 fn test_any_signature_ed25519_debug() {
1350 use crate::crypto::Ed25519PrivateKey;
1351
1352 let private_key = Ed25519PrivateKey::generate();
1353 let sig = AnySignature::ed25519(&private_key.sign(b"test"));
1354 let debug = format!("{sig:?}");
1355 assert!(debug.contains("Ed25519"));
1356 }
1357
1358 #[test]
1359 #[cfg(feature = "ed25519")]
1360 fn test_multi_key_insufficient_signatures() {
1361 use crate::crypto::Ed25519PrivateKey;
1362
1363 let private_keys: Vec<_> = (0..3).map(|_| Ed25519PrivateKey::generate()).collect();
1364 let public_keys: Vec<_> = private_keys
1365 .iter()
1366 .map(|k| AnyPublicKey::ed25519(&k.public_key()))
1367 .collect();
1368
1369 let multi_pk = MultiKeyPublicKey::new(public_keys, 2).unwrap();
1370 let message = b"test message";
1371
1372 let sig0 = AnySignature::ed25519(&private_keys[0].sign(message));
1374 let multi_sig = MultiKeySignature::new(vec![(0, sig0)]).unwrap();
1375
1376 let result = multi_pk.verify(message, &multi_sig);
1378 assert!(result.is_err());
1379 }
1380}