use bytes::Bytes;
use shadow_core::{PeerId, PeerInfo, Packet, PacketType};
fn main() {
println!("╔══════════════════════════════════════════════════════╗");
println!("║ Shadow Network — Phase 2 Demo ║");
println!("╚══════════════════════════════════════════════════════╝\n");
demo_transport_config();
demo_dht_replication();
demo_messaging();
demo_stego_transport();
println!("\nAll Phase 2 subsystems operational.");
println!(" 12 crates | 125 tests | P2P + Replication + E2E + Stego");
}
fn demo_transport_config() {
use transport::{P2PConfig, ShadowSwarm};
println!("━━━ 1. P2P Transport (libp2p) ━━━━━━━━━━━━━━━━━━━━━━━━━");
let config = P2PConfig::default();
println!(" Listen addresses: {:?}", config.listen_addresses);
println!(" Bootstrap peers: {:?}", config.bootstrap_peers);
println!(" mDNS enabled: {}", config.enable_mdns);
println!(" Idle timeout: {:?}", config.idle_timeout);
println!(" Gossipsub interval:{:?}", config.gossipsub_heartbeat);
let custom = P2PConfig::with_port(9090)
.add_bootstrap("/ip4/192.168.1.1/tcp/9090")
.add_bootstrap("/ip4/10.0.0.1/tcp/9090");
println!(" Custom config: port=9090, {} bootstrap peers", custom.bootstrap_peers.len());
println!(" ShadowSwarm ready (TCP+Noise+Yamux, Gossipsub, Kademlia, mDNS)\n");
}
fn demo_dht_replication() {
use dht::{DHTNode, NodeConfig, ReplicationManager, ReplicationConfig};
println!("━━━ 2. DHT Replication ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
let local_id = PeerId::random();
let dht = DHTNode::new(local_id, NodeConfig::default());
let peers: Vec<PeerInfo> = (1..=6).map(|i| {
PeerInfo::new(
PeerId::from_bytes([i; 32]),
vec![format!("/ip4/10.0.0.{}/tcp/9000", i)],
[i; 32],
[i; 32],
)
}).collect();
for p in &peers {
let _ = dht.add_peer(p.clone());
}
println!(" Peers in routing table: {}", dht.peer_count());
let key = *crypto::hash::hash_data(b"important-document").as_bytes();
let value = Bytes::from_static(b"classified content");
dht.store_value(key, value.clone(), [0u8; 32]).unwrap();
println!(" Stored value: key={}", hex::encode(&key[..8]));
let mut repl = ReplicationManager::new(ReplicationConfig {
factor: 3,
..Default::default()
});
let tasks = repl.schedule_replication(key, value, &peers);
println!(" Replication tasks: {}", tasks.len());
for task in &tasks {
println!(" → replicate to peer {}", task.target_peer);
}
for task in &tasks {
repl.confirm_replication(key, task.target_peer);
}
let stats = repl.stats();
println!(" Replica count: {}/{}", repl.replica_count(&key), stats.total_keys);
println!(" Fully replicated: {}", stats.fully_replicated);
println!(" Under-replicated: {}", stats.under_replicated);
let lost = tasks[0].target_peer;
let re_tasks = repl.handle_peer_lost(&lost, &dht);
println!(" Peer {} lost → {} re-replication tasks", lost, re_tasks.len());
println!(" DHT replication fully operational\n");
}
fn demo_messaging() {
use messaging::{Message, MessageTarget, MessageContent, SecureChannel, OfflineQueue, Group, GroupManager};
use messaging::queue::QueuePriority;
use crypto::{EncryptionKey, SigningKey};
println!("━━━ 3. E2E Encrypted Messaging ━━━━━━━━━━━━━━━━━━━━━━━");
let alice_id = PeerId::random();
let bob_id = PeerId::random();
let alice_sign = SigningKey::generate();
let bob_sign = SigningKey::generate();
let (alice_state, alice_pub) = SecureChannel::initiate(alice_sign.clone(), alice_id);
let (bob_state, bob_pub) = SecureChannel::initiate(bob_sign.clone(), bob_id);
let alice_ch = SecureChannel::complete(alice_state, &bob_pub, bob_sign.verify_key()).unwrap();
let bob_ch = SecureChannel::complete(bob_state, &alice_pub, alice_sign.verify_key()).unwrap();
println!(" Key exchange: X25519 DH -- ok");
let msg = Message::text(alice_id, MessageTarget::Direct(bob_id), "Top secret intel");
println!(" Original message: \"Top secret intel\"");
let envelope = alice_ch.encrypt_message(&msg).unwrap();
println!(" Encrypted size: {} bytes (ChaCha20-Poly1305)", envelope.ciphertext.len());
println!(" Signature: {} bytes (Ed25519)", envelope.signature.len());
let decrypted = bob_ch.decrypt_message(&envelope).unwrap();
if let MessageContent::Text(t) = &decrypted.content {
println!(" Decrypted: \"{}\" -- ok", t);
}
let mut queue = OfflineQueue::new();
let offline_peer = PeerId::random();
for i in 0..5 {
let env = alice_ch.encrypt_message(
&Message::text(alice_id, MessageTarget::Direct(offline_peer), format!("msg {}", i))
).unwrap();
queue.enqueue(offline_peer, env, QueuePriority::Normal);
}
println!(" Offline queue: {} messages for disconnected peer", queue.count_for(&offline_peer));
let delivered = queue.dequeue_for(&offline_peer);
println!(" Peer reconnected: delivered {} messages", delivered.len());
let mut groups = GroupManager::new();
let gid = groups.create_group("Ops Team", alice_id);
groups.join_group(&gid, bob_id);
let group = groups.get_group(&gid).unwrap();
println!(" Group \"{}\": {} members", group.name, group.member_count());
println!(" Group key: {} (auto-rotated on join/leave)", hex::encode(&group.group_key[..8]));
println!(" E2E messaging fully operational\n");
}
fn demo_stego_transport() {
use stego_transport::{StegoChannel, StegoChannelConfig, CoverTrafficGenerator, StegoPacketPipeline, PipelineConfig};
use stego_transport::cover::CoverStyle;
println!("━━━ 4. Steganographic Data Transfer ━━━━━━━━━━━━━━━━━━━");
let config = StegoChannelConfig {
width: 128,
height: 128,
channels: 4,
bits_per_channel: 1,
adaptive: false,
randomize: false,
seed: 42,
};
let channel = StegoChannel::new(config);
println!(" Cover image: 128×128 RGBA");
println!(" Embedding: 1 bit/channel (LSB)");
println!(" Capacity: {} bytes per image", channel.capacity());
let secret = b"covert message hidden in plain sight";
let stego_image = channel.encode(secret).unwrap();
println!(" Encoded {} bytes into {} byte image", secret.len(), stego_image.len());
let extracted = channel.decode(&stego_image).unwrap();
assert_eq!(&extracted[..secret.len()], secret.as_slice());
println!(" Extracted: \"{}\" -- ok", String::from_utf8_lossy(&extracted[..secret.len()]));
let cover_gen = CoverTrafficGenerator::new(64, 64);
for style in [CoverStyle::NaturalNoise, CoverStyle::Gradient, CoverStyle::BlockPattern] {
let cover = cover_gen.generate(style);
println!(" Cover {:?}: {} bytes", style, cover.len());
}
let pipeline_cfg = PipelineConfig {
stego: StegoChannelConfig {
width: 64,
height: 64,
channels: 4,
bits_per_channel: 2,
adaptive: false,
randomize: false,
seed: 0,
},
encrypt: false, ..Default::default()
};
let mut pipeline = StegoPacketPipeline::unencrypted(pipeline_cfg);
let packet = Packet::new(
PacketType::Data,
Some(PeerId::random()),
Some(PeerId::random()),
Bytes::from_static(b"steganographic payload"),
);
let stego = pipeline.encode_packet(&packet).unwrap();
let decoded = pipeline.decode_packet(&stego).unwrap();
assert_eq!(decoded.payload, Bytes::from_static(b"steganographic payload"));
println!(" Pipeline: Packet->Stego->Packet roundtrip -- ok");
println!(" Capacity: {} bytes/image", pipeline.capacity());
println!(" Encoded packets: {}", pipeline.packets_encoded());
let dummy = pipeline.generate_dummy_packet().unwrap();
println!(" Dummy traffic: {} bytes (indistinguishable)", dummy.len());
println!(" Steganographic transport fully operational");
}