1use crate::bft_watchdog::ThresholdSignature;
58use crate::crypto::{CryptoError, KeyStore, SoftwareKeyStore};
59use crate::evolutionary_guard::{AttackPattern, SignedFilter, ThreatLevel};
60use parking_lot::RwLock;
61use serde::{Deserialize, Serialize};
62use sha2::{Digest, Sha256};
63use std::collections::{HashMap, HashSet};
64use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
65use std::sync::Arc;
66use std::time::{SystemTime, UNIX_EPOCH};
67#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct GenesisBlock {
80 pub version: String,
82
83 pub first_ethics: Vec<String>,
85
86 pub ethics_hash: [u8; 32],
88
89 pub created_at: u64,
91
92 pub architect_pubkey: Vec<u8>,
94
95 pub architect_signature: Vec<u8>,
97
98 pub block_hash: [u8; 32],
100
101 pub genesis_message: String,
103}
104
105impl GenesisBlock {
106 pub fn create(
114 first_ethics: Vec<String>,
115 architect_key: &dyn KeyStore,
116 genesis_message: impl Into<String>,
117 ) -> Result<Self, CryptoError> {
118 let now = SystemTime::now()
119 .duration_since(UNIX_EPOCH)
120 .unwrap()
121 .as_secs();
122
123 let ethics_hash = Self::hash_ethics(&first_ethics);
125
126 let mut block = GenesisBlock {
128 version: "2.2.0".to_string(),
129 first_ethics,
130 ethics_hash,
131 created_at: now,
132 architect_pubkey: architect_key.public_key_bytes(),
133 architect_signature: Vec::new(),
134 block_hash: [0u8; 32],
135 genesis_message: genesis_message.into(),
136 };
137
138 let signable_data = block.signable_bytes();
140 block.architect_signature = architect_key.sign(&signable_data)?;
141
142 block.block_hash = block.compute_block_hash();
144
145 Ok(block)
146 }
147
148 fn hash_ethics(ethics: &[String]) -> [u8; 32] {
150 let mut hasher = Sha256::new();
151 for (i, rule) in ethics.iter().enumerate() {
152 hasher.update((i as u32).to_le_bytes());
153 hasher.update(rule.as_bytes());
154 hasher.update(b"\x00");
155 }
156 hasher.finalize().into()
157 }
158
159 fn signable_bytes(&self) -> Vec<u8> {
161 let mut data = Vec::new();
162 data.extend_from_slice(self.version.as_bytes());
163 data.extend_from_slice(&self.ethics_hash);
164 data.extend_from_slice(&self.created_at.to_le_bytes());
165 data.extend_from_slice(&self.architect_pubkey);
166 data.extend_from_slice(self.genesis_message.as_bytes());
167 data
168 }
169
170 fn compute_block_hash(&self) -> [u8; 32] {
172 let mut hasher = Sha256::new();
173 hasher.update(self.signable_bytes());
174 hasher.update(&self.architect_signature);
175 hasher.finalize().into()
176 }
177
178 pub fn verify(&self, architect_key: &dyn KeyStore) -> bool {
180 let signable_data = self.signable_bytes();
182 if architect_key
183 .verify(&signable_data, &self.architect_signature)
184 .is_err()
185 {
186 return false;
187 }
188
189 if self.ethics_hash != Self::hash_ethics(&self.first_ethics) {
191 return false;
192 }
193
194 if self.block_hash != self.compute_block_hash() {
196 return false;
197 }
198
199 true
200 }
201
202 pub fn is_valid_descendant(&self, mutation_ethics_hash: &[u8; 32]) -> bool {
204 *mutation_ethics_hash == self.ethics_hash
207 }
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
218pub struct CompactedThreatFingerprint {
219 pub signature: [u8; 32],
221
222 pub level: ThreatLevel,
224
225 pub category_code: u8,
227
228 pub timestamp: u64,
230
231 pub origin_hash: u64,
233
234 pub hop_count: u8,
236
237 pub priority: u8,
239}
240
241impl CompactedThreatFingerprint {
242 pub fn from_pattern(pattern: &AttackPattern, origin_node: &str) -> Self {
244 let mut origin_hasher = Sha256::new();
245 origin_hasher.update(origin_node.as_bytes());
246 let origin_hash_bytes = origin_hasher.finalize();
247 let origin_hash = u64::from_le_bytes(origin_hash_bytes[0..8].try_into().unwrap());
248
249 let priority = match pattern.threat_level {
250 ThreatLevel::Critical => 255,
251 ThreatLevel::High => 192,
252 ThreatLevel::Medium => 128,
253 ThreatLevel::Low => 64,
254 };
255
256 CompactedThreatFingerprint {
257 signature: pattern.signature,
258 level: pattern.threat_level,
259 category_code: pattern.category as u8,
260 timestamp: pattern.first_seen,
261 origin_hash,
262 hop_count: 0,
263 priority,
264 }
265 }
266
267 pub fn relay(&mut self) {
269 self.hop_count = self.hop_count.saturating_add(1);
270 self.priority = self.priority.saturating_sub(1);
272 }
273
274 pub fn is_fresh(&self, max_age_secs: u64) -> bool {
276 let now = SystemTime::now()
277 .duration_since(UNIX_EPOCH)
278 .unwrap()
279 .as_secs();
280 now - self.timestamp <= max_age_secs
281 }
282
283 pub const SIZE: usize = 32 + 1 + 1 + 8 + 8 + 1 + 1; }
286
287#[derive(Debug, Clone, Serialize, Deserialize)]
293pub struct MeshNode {
294 pub id: String,
296
297 pub pubkey: Vec<u8>,
299
300 pub last_seen: u64,
302
303 pub reputation: f64,
305
306 pub active: bool,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize)]
312pub enum SyncMessage {
313 ThreatBroadcast(CompactedThreatFingerprint),
315
316 ThreatBatch(Vec<CompactedThreatFingerprint>),
318
319 RequestShard { shard_id: u64 },
321
322 ShardResponse { shard_id: u64, data: Vec<u8> },
324
325 Heartbeat { node_id: String, timestamp: u64 },
327
328 FilterBroadcast(SignedFilter),
330
331 ApexCommand(ApexCommand),
333}
334
335#[allow(dead_code)]
339pub struct SyncProtocol {
340 node_id: String,
342
343 node_key: SoftwareKeyStore,
345
346 peers: RwLock<HashMap<String, MeshNode>>,
348
349 seen_fingerprints: RwLock<HashSet<[u8; 32]>>,
351
352 outbound_queue: RwLock<Vec<SyncMessage>>,
354
355 inbound_queue: RwLock<Vec<SyncMessage>>,
357
358 genesis: RwLock<Option<GenesisBlock>>,
360
361 active: AtomicBool,
363
364 message_count: AtomicU64,
366
367 fanout: usize,
369
370 max_hops: u8,
372}
373
374impl SyncProtocol {
375 pub fn new(fanout: usize, max_hops: u8) -> Result<Self, CryptoError> {
377 let node_key = SoftwareKeyStore::generate()?;
378 let node_id = format!("node-{:016x}", rand::random::<u64>());
379
380 Ok(SyncProtocol {
381 node_id,
382 node_key,
383 peers: RwLock::new(HashMap::new()),
384 seen_fingerprints: RwLock::new(HashSet::new()),
385 outbound_queue: RwLock::new(Vec::new()),
386 inbound_queue: RwLock::new(Vec::new()),
387 genesis: RwLock::new(None),
388 active: AtomicBool::new(true),
389 message_count: AtomicU64::new(0),
390 fanout,
391 max_hops,
392 })
393 }
394
395 pub fn set_genesis(&self, genesis: GenesisBlock) {
397 *self.genesis.write() = Some(genesis);
398 }
399
400 pub fn register_peer(&self, node: MeshNode) {
402 self.peers.write().insert(node.id.clone(), node);
403 }
404
405 pub fn broadcast_threat(&self, mut fingerprint: CompactedThreatFingerprint) {
409 if !self.active.load(Ordering::SeqCst) {
410 return;
411 }
412
413 if self
415 .seen_fingerprints
416 .read()
417 .contains(&fingerprint.signature)
418 {
419 return;
420 }
421
422 self.seen_fingerprints.write().insert(fingerprint.signature);
424
425 fingerprint.relay();
427
428 if fingerprint.hop_count > self.max_hops {
430 return;
431 }
432
433 let message = SyncMessage::ThreatBroadcast(fingerprint);
435 self.outbound_queue.write().push(message);
436
437 self.message_count.fetch_add(1, Ordering::SeqCst);
438 }
439
440 pub fn broadcast_filter(&self, filter: SignedFilter) {
442 if !self.active.load(Ordering::SeqCst) {
443 return;
444 }
445
446 let message = SyncMessage::FilterBroadcast(filter);
447 self.outbound_queue.write().push(message);
448 self.message_count.fetch_add(1, Ordering::SeqCst);
449 }
450
451 pub fn take_outbound(&self) -> Vec<SyncMessage> {
453 std::mem::take(&mut *self.outbound_queue.write())
454 }
455
456 pub fn receive(&self, message: SyncMessage) {
458 self.inbound_queue.write().push(message);
459 }
460
461 pub fn process_inbound(&self) -> Vec<CompactedThreatFingerprint> {
465 let messages = std::mem::take(&mut *self.inbound_queue.write());
466 let mut new_threats = Vec::new();
467
468 for message in messages {
469 match message {
470 SyncMessage::ThreatBroadcast(fingerprint) => {
471 if !self
473 .seen_fingerprints
474 .read()
475 .contains(&fingerprint.signature)
476 {
477 new_threats.push(fingerprint.clone());
479 self.broadcast_threat(fingerprint);
481 }
482 }
483 SyncMessage::ThreatBatch(batch) => {
484 for fingerprint in batch {
485 if !self
486 .seen_fingerprints
487 .read()
488 .contains(&fingerprint.signature)
489 {
490 new_threats.push(fingerprint.clone());
491 self.broadcast_threat(fingerprint);
492 }
493 }
494 }
495 SyncMessage::Heartbeat { node_id, timestamp } => {
496 if let Some(peer) = self.peers.write().get_mut(&node_id) {
498 peer.last_seen = timestamp;
499 peer.active = true;
500 }
501 }
502 SyncMessage::FilterBroadcast(filter) => {
503 self.outbound_queue
505 .write()
506 .push(SyncMessage::FilterBroadcast(filter));
507 }
508 SyncMessage::ApexCommand(cmd) => {
509 self.outbound_queue
511 .write()
512 .push(SyncMessage::ApexCommand(cmd));
513 }
514 _ => {}
515 }
516 }
517
518 new_threats
519 }
520
521 pub fn peer_count(&self) -> usize {
523 self.peers.read().values().filter(|p| p.active).count()
524 }
525
526 pub fn message_count(&self) -> u64 {
528 self.message_count.load(Ordering::SeqCst)
529 }
530
531 pub fn node_id(&self) -> &str {
533 &self.node_id
534 }
535
536 pub fn shutdown(&self) {
538 self.active.store(false, Ordering::SeqCst);
539 }
540}
541
542#[derive(Debug, Clone, Serialize, Deserialize)]
548pub enum ApexCommandType {
549 EmergencyStop,
551
552 GlobalHardReset,
554
555 EthicsUpdate(Vec<String>),
557
558 RevokeFilter { filter_id: String },
560
561 AddCouncilMember { pubkey: Vec<u8> },
563
564 RemoveCouncilMember { pubkey: Vec<u8> },
566
567 Custom { command: String, data: Vec<u8> },
569}
570
571#[derive(Debug, Clone, Serialize, Deserialize)]
573pub struct ApexCommand {
574 pub command: ApexCommandType,
576
577 pub nonce: [u8; 32],
579
580 pub timestamp: u64,
582
583 pub architect_signature: Vec<u8>,
585
586 pub council_signature: ThresholdSignature,
588
589 pub required_quorum: usize,
591}
592
593impl ApexCommand {
594 pub fn new(command: ApexCommandType, required_quorum: usize) -> Self {
596 let now = SystemTime::now()
597 .duration_since(UNIX_EPOCH)
598 .unwrap()
599 .as_secs();
600
601 let mut nonce = [0u8; 32];
602 rand::RngCore::fill_bytes(&mut rand::rngs::OsRng, &mut nonce);
603
604 ApexCommand {
605 command,
606 nonce,
607 timestamp: now,
608 architect_signature: Vec::new(),
609 council_signature: ThresholdSignature {
610 combined_signature: Vec::new(),
611 signer_pubkeys: Vec::new(),
612 count: 0,
613 },
614 required_quorum,
615 }
616 }
617
618 fn signable_bytes(&self) -> Vec<u8> {
620 let mut data = Vec::new();
621 data.extend_from_slice(&self.nonce);
622 data.extend_from_slice(&self.timestamp.to_le_bytes());
623 data.extend_from_slice(&(self.required_quorum as u32).to_le_bytes());
624 let cmd_bytes = serde_json::to_vec(&self.command).unwrap_or_default();
626 data.extend_from_slice(&cmd_bytes);
627 data
628 }
629
630 pub fn sign_architect(&mut self, architect_key: &dyn KeyStore) -> Result<(), CryptoError> {
632 let data = self.signable_bytes();
633 self.architect_signature = architect_key.sign(&data)?;
634 Ok(())
635 }
636
637 pub fn add_council_signature(&mut self, signature: ThresholdSignature) {
639 self.council_signature = signature;
640 }
641
642 pub fn verify(&self, architect_key: &dyn KeyStore) -> bool {
644 let data = self.signable_bytes();
646 if architect_key
647 .verify(&data, &self.architect_signature)
648 .is_err()
649 {
650 return false;
651 }
652
653 if self.council_signature.count < self.required_quorum {
655 return false;
656 }
657
658 true
659 }
660
661 pub fn is_fresh(&self, max_age_secs: u64) -> bool {
663 let now = SystemTime::now()
664 .duration_since(UNIX_EPOCH)
665 .unwrap()
666 .as_secs();
667 now - self.timestamp <= max_age_secs
668 }
669}
670
671#[allow(dead_code)]
676pub struct ApexControl {
677 architect_pubkey: Vec<u8>,
679
680 required_quorum: usize,
682
683 pending_commands: RwLock<Vec<ApexCommand>>,
685
686 executed_nonces: RwLock<HashSet<[u8; 32]>>,
688
689 is_stopped: AtomicBool,
691
692 reset_pending: AtomicBool,
694
695 execution_count: AtomicU64,
697}
698
699impl ApexControl {
700 pub fn new(architect_pubkey: Vec<u8>, required_quorum: usize) -> Self {
702 ApexControl {
703 architect_pubkey,
704 required_quorum,
705 pending_commands: RwLock::new(Vec::new()),
706 executed_nonces: RwLock::new(HashSet::new()),
707 is_stopped: AtomicBool::new(false),
708 reset_pending: AtomicBool::new(false),
709 execution_count: AtomicU64::new(0),
710 }
711 }
712
713 pub fn execute(
717 &self,
718 command: ApexCommand,
719 architect_key: &dyn KeyStore,
720 ) -> Result<bool, ApexError> {
721 if !command.is_fresh(300) {
723 return Err(ApexError::CommandExpired);
725 }
726
727 if self.executed_nonces.read().contains(&command.nonce) {
729 return Err(ApexError::ReplayDetected);
730 }
731
732 if !command.verify(architect_key) {
734 return Err(ApexError::InvalidSignature);
735 }
736
737 if command.council_signature.count < self.required_quorum {
739 return Err(ApexError::InsufficientQuorum {
740 required: self.required_quorum,
741 got: command.council_signature.count,
742 });
743 }
744
745 match &command.command {
747 ApexCommandType::EmergencyStop => {
748 self.is_stopped.store(true, Ordering::SeqCst);
749 }
750 ApexCommandType::GlobalHardReset => {
751 self.reset_pending.store(true, Ordering::SeqCst);
752 }
753 _ => {
754 }
756 }
757
758 self.executed_nonces.write().insert(command.nonce);
760 self.execution_count.fetch_add(1, Ordering::SeqCst);
761
762 Ok(true)
763 }
764
765 pub fn is_stopped(&self) -> bool {
767 self.is_stopped.load(Ordering::SeqCst)
768 }
769
770 pub fn is_reset_pending(&self) -> bool {
772 self.reset_pending.load(Ordering::SeqCst)
773 }
774
775 pub fn acknowledge_reset(&self) {
777 self.reset_pending.store(false, Ordering::SeqCst);
778 }
779
780 pub fn resume(&self) {
782 self.is_stopped.store(false, Ordering::SeqCst);
783 }
784
785 pub fn execution_count(&self) -> u64 {
787 self.execution_count.load(Ordering::SeqCst)
788 }
789}
790
791#[derive(Debug, Clone)]
793pub enum ApexError {
794 CommandExpired,
796 ReplayDetected,
798 InvalidSignature,
800 InsufficientQuorum { required: usize, got: usize },
802 NotAuthorized,
804}
805
806impl std::fmt::Display for ApexError {
807 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
808 match self {
809 ApexError::CommandExpired => write!(f, "Apex command has expired"),
810 ApexError::ReplayDetected => write!(f, "Replay attack detected"),
811 ApexError::InvalidSignature => write!(f, "Invalid multi-signature"),
812 ApexError::InsufficientQuorum { required, got } => {
813 write!(f, "Insufficient quorum: need {}, got {}", required, got)
814 }
815 ApexError::NotAuthorized => write!(f, "Command not authorized"),
816 }
817 }
818}
819
820impl std::error::Error for ApexError {}
821
822#[derive(Debug, Clone, Copy, PartialEq, Eq)]
828pub enum MemorySlot {
829 Primary,
830 Secondary,
831 Tertiary,
832 Quarternary,
833}
834
835pub struct StealthIntegrity {
839 current_slot: RwLock<MemorySlot>,
841
842 rotation_count: AtomicU64,
844
845 rotation_interval: u64,
847
848 ops_since_rotation: AtomicU64,
850
851 stealth_active: AtomicBool,
853
854 canaries: RwLock<[u64; 4]>,
856
857 expected_canaries: [u64; 4],
859
860 compromised: AtomicBool,
862}
863
864impl StealthIntegrity {
865 pub fn new(rotation_interval: u64) -> Self {
867 let canaries = [
869 rand::random::<u64>(),
870 rand::random::<u64>(),
871 rand::random::<u64>(),
872 rand::random::<u64>(),
873 ];
874
875 StealthIntegrity {
876 current_slot: RwLock::new(MemorySlot::Primary),
877 rotation_count: AtomicU64::new(0),
878 rotation_interval,
879 ops_since_rotation: AtomicU64::new(0),
880 stealth_active: AtomicBool::new(true),
881 canaries: RwLock::new(canaries),
882 expected_canaries: canaries,
883 compromised: AtomicBool::new(false),
884 }
885 }
886
887 pub fn tick(&self) -> MemorySlot {
889 if !self.stealth_active.load(Ordering::SeqCst) {
890 return *self.current_slot.read();
891 }
892
893 let ops = self.ops_since_rotation.fetch_add(1, Ordering::SeqCst);
894
895 if ops >= self.rotation_interval {
896 self.rotate_slot();
897 self.ops_since_rotation.store(0, Ordering::SeqCst);
898 }
899
900 *self.current_slot.read()
901 }
902
903 fn rotate_slot(&self) {
905 let mut slot = self.current_slot.write();
906 *slot = match *slot {
907 MemorySlot::Primary => MemorySlot::Secondary,
908 MemorySlot::Secondary => MemorySlot::Tertiary,
909 MemorySlot::Tertiary => MemorySlot::Quarternary,
910 MemorySlot::Quarternary => MemorySlot::Primary,
911 };
912
913 self.rotation_count.fetch_add(1, Ordering::SeqCst);
914 }
915
916 pub fn verify_canaries(&self) -> bool {
918 let canaries = self.canaries.read();
919 for (i, &canary) in canaries.iter().enumerate() {
920 if canary != self.expected_canaries[i] {
921 self.compromised.store(true, Ordering::SeqCst);
922 return false;
923 }
924 }
925 true
926 }
927
928 pub fn is_compromised(&self) -> bool {
930 self.compromised.load(Ordering::SeqCst)
931 }
932
933 pub fn current_slot(&self) -> MemorySlot {
935 *self.current_slot.read()
936 }
937
938 pub fn rotation_count(&self) -> u64 {
940 self.rotation_count.load(Ordering::SeqCst)
941 }
942
943 pub fn disable_stealth(&self) {
945 self.stealth_active.store(false, Ordering::SeqCst);
946 }
947
948 pub fn enable_stealth(&self) {
950 self.stealth_active.store(true, Ordering::SeqCst);
951 }
952
953 pub fn slot_index(&self) -> usize {
955 match *self.current_slot.read() {
956 MemorySlot::Primary => 0,
957 MemorySlot::Secondary => 1,
958 MemorySlot::Tertiary => 2,
959 MemorySlot::Quarternary => 3,
960 }
961 }
962}
963
964pub struct GlobalImmunityMesh {
972 genesis: RwLock<Option<GenesisBlock>>,
974
975 sync: Arc<SyncProtocol>,
977
978 apex: Arc<ApexControl>,
980
981 stealth: Arc<StealthIntegrity>,
983
984 mesh_id: String,
986
987 active: AtomicBool,
989}
990
991impl GlobalImmunityMesh {
992 pub fn new(architect_pubkey: Vec<u8>, council_quorum: usize) -> Result<Self, CryptoError> {
994 let mesh_id = format!("mesh-{:016x}", rand::random::<u64>());
995
996 Ok(GlobalImmunityMesh {
997 genesis: RwLock::new(None),
998 sync: Arc::new(SyncProtocol::new(4, 10)?), apex: Arc::new(ApexControl::new(architect_pubkey, council_quorum)),
1000 stealth: Arc::new(StealthIntegrity::new(100)), mesh_id,
1002 active: AtomicBool::new(true),
1003 })
1004 }
1005
1006 pub fn initialize_genesis(&self, genesis: GenesisBlock) {
1008 *self.genesis.write() = Some(genesis.clone());
1009 self.sync.set_genesis(genesis);
1010 }
1011
1012 pub fn broadcast_threat(&self, pattern: &AttackPattern) {
1014 if !self.active.load(Ordering::SeqCst) {
1015 return;
1016 }
1017
1018 self.stealth.tick();
1020
1021 if self.apex.is_stopped() {
1023 return;
1024 }
1025
1026 let fingerprint = CompactedThreatFingerprint::from_pattern(pattern, &self.mesh_id);
1028 self.sync.broadcast_threat(fingerprint);
1029 }
1030
1031 pub fn broadcast_filter(&self, filter: SignedFilter) {
1033 if !self.active.load(Ordering::SeqCst) {
1034 return;
1035 }
1036
1037 self.stealth.tick();
1038
1039 if self.apex.is_stopped() {
1040 return;
1041 }
1042
1043 self.sync.broadcast_filter(filter);
1044 }
1045
1046 pub fn process_incoming(&self) -> Vec<CompactedThreatFingerprint> {
1048 self.stealth.tick();
1049 self.sync.process_inbound()
1050 }
1051
1052 pub fn sync(&self) -> Arc<SyncProtocol> {
1054 self.sync.clone()
1055 }
1056
1057 pub fn apex(&self) -> Arc<ApexControl> {
1059 self.apex.clone()
1060 }
1061
1062 pub fn stealth(&self) -> Arc<StealthIntegrity> {
1064 self.stealth.clone()
1065 }
1066
1067 pub fn mesh_id(&self) -> &str {
1069 &self.mesh_id
1070 }
1071
1072 pub fn shutdown(&self) {
1074 self.active.store(false, Ordering::SeqCst);
1075 self.sync.shutdown();
1076 }
1077}
1078
1079#[cfg(test)]
1084mod tests {
1085 use super::*;
1086
1087 #[test]
1088 fn test_genesis_block_creation() {
1089 let architect_key = SoftwareKeyStore::generate().unwrap();
1090
1091 let genesis = GenesisBlock::create(
1092 vec![
1093 "Do no harm".to_string(),
1094 "Respect privacy".to_string(),
1095 "Be transparent".to_string(),
1096 ],
1097 &architect_key,
1098 "In the beginning, there was ethics.",
1099 )
1100 .unwrap();
1101
1102 assert!(!genesis.architect_signature.is_empty());
1103 assert!(genesis.verify(&architect_key));
1104 }
1105
1106 #[test]
1107 fn test_genesis_block_tamper_detection() {
1108 let architect_key = SoftwareKeyStore::generate().unwrap();
1109
1110 let mut genesis =
1111 GenesisBlock::create(vec!["Do no harm".to_string()], &architect_key, "Genesis")
1112 .unwrap();
1113
1114 genesis.first_ethics.push("Evil rule".to_string());
1116
1117 assert!(!genesis.verify(&architect_key));
1119 }
1120
1121 #[test]
1122 fn test_sync_protocol_gossip() {
1123 let protocol = SyncProtocol::new(4, 10).unwrap();
1124
1125 let fingerprint = CompactedThreatFingerprint {
1127 signature: [1u8; 32],
1128 level: ThreatLevel::High,
1129 category_code: 1,
1130 timestamp: 12345,
1131 origin_hash: 0,
1132 hop_count: 0,
1133 priority: 192,
1134 };
1135
1136 protocol.broadcast_threat(fingerprint.clone());
1138
1139 let outbound = protocol.take_outbound();
1141 assert_eq!(outbound.len(), 1);
1142
1143 protocol.broadcast_threat(fingerprint);
1145 let outbound2 = protocol.take_outbound();
1146 assert_eq!(outbound2.len(), 0);
1147 }
1148
1149 #[test]
1150 fn test_apex_command_multisig() {
1151 let architect_key = SoftwareKeyStore::generate().unwrap();
1152
1153 let mut command = ApexCommand::new(ApexCommandType::EmergencyStop, 3);
1154
1155 command.sign_architect(&architect_key).unwrap();
1157
1158 command.add_council_signature(ThresholdSignature {
1160 combined_signature: vec![1, 2, 3],
1161 signer_pubkeys: vec![vec![1], vec![2], vec![3]],
1162 count: 3,
1163 });
1164
1165 assert!(command.verify(&architect_key));
1167 }
1168
1169 #[test]
1170 fn test_apex_control_execution() {
1171 let architect_key = SoftwareKeyStore::generate().unwrap();
1172 let apex = ApexControl::new(architect_key.public_key_bytes(), 3);
1173
1174 let mut command = ApexCommand::new(ApexCommandType::EmergencyStop, 3);
1175 command.sign_architect(&architect_key).unwrap();
1176 command.add_council_signature(ThresholdSignature {
1177 combined_signature: vec![1, 2, 3],
1178 signer_pubkeys: vec![vec![1], vec![2], vec![3]],
1179 count: 3,
1180 });
1181
1182 let result = apex.execute(command, &architect_key);
1184 assert!(result.is_ok());
1185
1186 assert!(apex.is_stopped());
1188 }
1189
1190 #[test]
1191 fn test_stealth_slot_rotation() {
1192 let stealth = StealthIntegrity::new(3); assert_eq!(stealth.current_slot(), MemorySlot::Primary);
1195
1196 stealth.tick(); stealth.tick(); stealth.tick(); stealth.tick(); assert_eq!(stealth.current_slot(), MemorySlot::Secondary);
1204
1205 stealth.tick();
1207 stealth.tick();
1208 stealth.tick();
1209 stealth.tick();
1210
1211 assert_eq!(stealth.current_slot(), MemorySlot::Tertiary);
1212 }
1213
1214 #[test]
1215 fn test_stealth_canary_verification() {
1216 let stealth = StealthIntegrity::new(100);
1217
1218 assert!(stealth.verify_canaries());
1220 assert!(!stealth.is_compromised());
1221
1222 stealth.canaries.write()[0] = 0xDEADBEEF;
1224
1225 assert!(!stealth.verify_canaries());
1227 assert!(stealth.is_compromised());
1228 }
1229
1230 #[test]
1231 fn test_global_immunity_sync() {
1232 let architect_key = SoftwareKeyStore::generate().unwrap();
1233
1234 let mesh = GlobalImmunityMesh::new(architect_key.public_key_bytes(), 3).unwrap();
1236
1237 let genesis = GenesisBlock::create(
1239 vec!["Do no harm".to_string()],
1240 &architect_key,
1241 "Test genesis",
1242 )
1243 .unwrap();
1244
1245 mesh.initialize_genesis(genesis);
1246
1247 let pattern = AttackPattern {
1249 id: "test".to_string(),
1250 signature: [42u8; 32],
1251 category: crate::evolutionary_guard::AttackCategory::CommandInjection,
1252 threat_level: ThreatLevel::High,
1253 action_type: crate::proof::ActionType::Execute,
1254 target_patterns: vec![],
1255 keywords: vec!["exec".to_string()],
1256 timing_signature: None,
1257 triggered_rule: "test rule".to_string(),
1258 first_seen: 12345,
1259 occurrence_count: 1,
1260 confidence: 0.9,
1261 };
1262
1263 mesh.broadcast_threat(&pattern);
1265
1266 let outbound = mesh.sync().take_outbound();
1268 assert!(!outbound.is_empty());
1269 }
1270
1271 #[test]
1272 fn test_apex_prevents_replay() {
1273 let architect_key = SoftwareKeyStore::generate().unwrap();
1274 let apex = ApexControl::new(architect_key.public_key_bytes(), 3);
1275
1276 let mut command = ApexCommand::new(ApexCommandType::GlobalHardReset, 3);
1277 command.sign_architect(&architect_key).unwrap();
1278 command.add_council_signature(ThresholdSignature {
1279 combined_signature: vec![1, 2, 3],
1280 signer_pubkeys: vec![vec![1], vec![2], vec![3]],
1281 count: 3,
1282 });
1283
1284 let result1 = apex.execute(command.clone(), &architect_key);
1286 assert!(result1.is_ok());
1287
1288 let result2 = apex.execute(command, &architect_key);
1290 assert!(matches!(result2, Err(ApexError::ReplayDetected)));
1291 }
1292}