use super::{QuantumFrame, FrameType};
use crate::QsslResult;
use rand::{Rng, RngCore};
use std::collections::VecDeque;
use std::time::{Duration, Instant};
pub struct StealthController {
level: u8,
dummy_generator: DummyTrafficGenerator,
traffic_shaper: TrafficShaper,
pattern_breaker: PatternBreaker,
}
impl StealthController {
pub fn new(level: u8) -> Self {
Self {
level: level.min(10),
dummy_generator: DummyTrafficGenerator::new(level),
traffic_shaper: TrafficShaper::new(level),
pattern_breaker: PatternBreaker::new(),
}
}
pub async fn process_outgoing(
&mut self,
frame: QuantumFrame,
) -> QsslResult<Vec<QuantumFrame>> {
let mut frames = Vec::new();
let dummy_count = self.dummy_generator.get_dummy_count();
for _ in 0..dummy_count {
frames.push(self.dummy_generator.generate());
}
let position = self.pattern_breaker.get_insertion_position(frames.len());
frames.insert(position, frame);
self.traffic_shaper.shape_timing(&mut frames).await;
Ok(frames)
}
pub fn process_incoming(
&mut self,
frames: Vec<QuantumFrame>,
) -> Vec<QuantumFrame> {
frames
.into_iter()
.filter(|f| f.header.frame_type != FrameType::Noise as u8)
.collect()
}
pub fn increase_stealth(&mut self) {
if self.level < 10 {
self.level += 1;
self.dummy_generator.set_level(self.level);
self.traffic_shaper.set_level(self.level);
}
}
pub fn decrease_stealth(&mut self) {
if self.level > 0 {
self.level -= 1;
self.dummy_generator.set_level(self.level);
self.traffic_shaper.set_level(self.level);
}
}
}
struct DummyTrafficGenerator {
level: u8,
entropy_pool: Vec<u8>,
pool_index: usize,
}
impl DummyTrafficGenerator {
fn new(level: u8) -> Self {
let mut entropy_pool = vec![0u8; 4096];
rand::thread_rng().fill_bytes(&mut entropy_pool);
Self {
level,
entropy_pool,
pool_index: 0,
}
}
fn set_level(&mut self, level: u8) {
self.level = level;
}
fn get_dummy_count(&self) -> usize {
match self.level {
0 => 0,
1..=3 => rand::thread_rng().gen_range(0..2),
4..=6 => rand::thread_rng().gen_range(1..4),
7..=9 => rand::thread_rng().gen_range(2..6),
10 => rand::thread_rng().gen_range(3..8),
_ => 0,
}
}
fn generate(&mut self) -> QuantumFrame {
let mut frame = QuantumFrame {
header: super::EncryptedHeader {
sequence: rand::random(),
timestamp: self.get_fake_timestamp(),
frame_type: FrameType::Noise as u8,
},
payload: [0; 719],
mac: [0; 32],
};
for chunk in frame.payload.chunks_mut(32) {
let start = self.pool_index;
let end = (start + chunk.len()).min(self.entropy_pool.len());
chunk.copy_from_slice(&self.entropy_pool[start..end]);
self.pool_index = (self.pool_index + chunk.len()) % self.entropy_pool.len();
}
if self.pool_index == 0 {
rand::thread_rng().fill_bytes(&mut self.entropy_pool);
}
frame
}
fn get_fake_timestamp(&self) -> [u8; 8] {
use std::time::{SystemTime, UNIX_EPOCH};
let mut timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_micros() as u64;
let jitter = rand::thread_rng().gen_range(0..1000 * self.level as u64);
timestamp = timestamp.wrapping_add(jitter);
timestamp.to_be_bytes()
}
}
struct TrafficShaper {
level: u8,
last_send: Instant,
target_rate: Duration,
burst_buffer: VecDeque<QuantumFrame>,
}
impl TrafficShaper {
fn new(level: u8) -> Self {
Self {
level,
last_send: Instant::now(),
target_rate: Self::calculate_rate(level),
burst_buffer: VecDeque::new(),
}
}
fn set_level(&mut self, level: u8) {
self.level = level;
self.target_rate = Self::calculate_rate(level);
}
fn calculate_rate(level: u8) -> Duration {
match level {
0 => Duration::from_micros(100), 1..=3 => Duration::from_micros(500), 4..=6 => Duration::from_millis(1), 7..=9 => Duration::from_millis(5), 10 => Duration::from_millis(10), _ => Duration::from_millis(1),
}
}
async fn shape_timing(&mut self, frames: &mut Vec<QuantumFrame>) {
if self.level == 0 {
return; }
let now = Instant::now();
let elapsed = now.duration_since(self.last_send);
if elapsed < self.target_rate {
let delay = self.target_rate - elapsed;
tokio::time::sleep(delay).await;
}
self.last_send = Instant::now();
if self.level >= 7 {
self.burst_mode(frames).await;
}
}
async fn burst_mode(&mut self, frames: &mut Vec<QuantumFrame>) {
for frame in frames.drain(..) {
self.burst_buffer.push_back(frame);
}
if self.burst_buffer.len() >= 10 || self.last_send.elapsed() > Duration::from_millis(100) {
frames.extend(self.burst_buffer.drain(..));
}
}
}
struct PatternBreaker {
history: Vec<usize>,
counter: usize,
}
impl PatternBreaker {
fn new() -> Self {
Self {
history: Vec::with_capacity(100),
counter: 0,
}
}
fn get_insertion_position(&mut self, max: usize) -> usize {
if max == 0 {
return 0;
}
let position = if self.counter % 7 == 0 {
0
} else if self.counter % 11 == 0 {
max
} else {
let mut pos = rand::thread_rng().gen_range(0..=max);
if self.history.len() > 10 {
let recent = &self.history[self.history.len() - 10..];
if recent.contains(&pos) {
pos = (pos + max / 2) % (max + 1);
}
}
pos
};
self.history.push(position);
if self.history.len() > 100 {
self.history.remove(0);
}
self.counter = self.counter.wrapping_add(1);
position
}
}
pub struct QuantumRng {
source: QuantumEntropySource,
fallback: rand::rngs::ThreadRng,
}
#[derive(Debug)]
enum QuantumEntropySource {
Hardware, Network, Simulated, }
impl QuantumRng {
pub fn new() -> Self {
let source = Self::detect_quantum_source();
Self {
source,
fallback: rand::thread_rng(),
}
}
fn detect_quantum_source() -> QuantumEntropySource {
if std::path::Path::new("/dev/qrng").exists() {
return QuantumEntropySource::Hardware;
}
if std::env::var("QRNG_ENDPOINT").is_ok() {
return QuantumEntropySource::Network;
}
QuantumEntropySource::Simulated
}
pub fn get_bytes(&mut self, buffer: &mut [u8]) {
match self.source {
QuantumEntropySource::Hardware => {
if let Ok(mut file) = std::fs::File::open("/dev/qrng") {
use std::io::Read;
let _ = file.read_exact(buffer);
} else {
self.fallback.fill_bytes(buffer);
}
}
QuantumEntropySource::Network => {
self.fallback.fill_bytes(buffer);
}
QuantumEntropySource::Simulated => {
self.fallback.fill_bytes(buffer);
for byte in buffer.iter_mut() {
*byte ^= (*byte).rotate_left(3);
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_stealth_controller() {
let mut controller = StealthController::new(5);
let frame = QuantumFrame {
header: super::super::EncryptedHeader {
sequence: [0; 8],
timestamp: [0; 8],
frame_type: FrameType::Data as u8,
},
payload: [0; 719],
mac: [0; 32],
};
let frames = controller.process_outgoing(frame).await.unwrap();
assert!(!frames.is_empty());
}
#[test]
fn test_dummy_generator() {
let mut generator = DummyTrafficGenerator::new(5);
let count = generator.get_dummy_count();
assert!(count > 0);
let frame = generator.generate();
assert_eq!(frame.header.frame_type, FrameType::Noise as u8);
}
#[test]
fn test_pattern_breaker() {
let mut breaker = PatternBreaker::new();
let positions: Vec<usize> = (0..20)
.map(|_| breaker.get_insertion_position(10))
.collect();
let unique_count = positions.iter().collect::<std::collections::HashSet<_>>().len();
assert!(unique_count > 1);
}
}