stochastic-routing-extended 1.0.2

SRX (Stochastic Routing eXtended) — a next-generation VPN protocol with stochastic routing, DPI evasion, post-quantum cryptography, and multi-transport channel splitting
Documentation
//! Re-key scheduling: periodic key rotation hidden in normal traffic.

use crate::seed::SeedRng;

/// Schedules re-keying events at pseudo-random intervals.
pub struct ReKeyScheduler {
    _rng: SeedRng,
    /// Minimum packets between re-keys.
    min_interval: u64,
    /// Maximum packets between re-keys.
    max_interval: u64,
    /// Packet count at which the next re-key should happen.
    next_rekey_at: u64,
}

impl ReKeyScheduler {
    pub fn new(rng: SeedRng, min_interval: u64, max_interval: u64) -> Self {
        let (min_interval, max_interval) = if min_interval <= max_interval {
            (min_interval, max_interval)
        } else {
            (max_interval, min_interval)
        };
        let mut s = Self {
            _rng: rng,
            min_interval,
            max_interval,
            next_rekey_at: 0,
        };
        s.schedule_next();
        s
    }

    /// Next packet count at which re-key should run (exclusive lower bound on scheduling).
    #[must_use]
    pub fn next_rekey_at(&self) -> u64 {
        self.next_rekey_at
    }

    /// Check if re-keying should happen at the given packet count.
    pub fn should_rekey(&self, packet_count: u64) -> bool {
        packet_count >= self.next_rekey_at
    }

    /// Schedule the next re-key event.
    pub fn schedule_next(&mut self) {
        let hi = self
            .max_interval
            .saturating_add(1)
            .max(self.min_interval.saturating_add(1));
        let span = self._rng.range(self.min_interval, hi);
        self.next_rekey_at = self.next_rekey_at.saturating_add(span);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn rekey_threshold_moves_forward() {
        let mut s = ReKeyScheduler::new(SeedRng::new([7u8; 32]), 10, 20);
        let t = s.next_rekey_at;
        s.schedule_next();
        assert!(s.next_rekey_at > t);
    }

    #[test]
    fn swapped_min_max_normalized() {
        let s = ReKeyScheduler::new(SeedRng::new([1u8; 32]), 100, 50);
        assert!(s.min_interval <= s.max_interval);
    }
}