fips_core/noise/
replay.rs1use super::REPLAY_WINDOW_SIZE;
2use std::fmt;
3
4#[derive(Clone)]
12pub struct ReplayWindow {
13 highest: u64,
15 bitmap: [u64; REPLAY_WINDOW_SIZE / 64],
19}
20
21impl ReplayWindow {
22 pub fn new() -> Self {
24 Self {
25 highest: 0,
26 bitmap: [0; REPLAY_WINDOW_SIZE / 64],
27 }
28 }
29
30 pub fn check(&self, counter: u64) -> bool {
35 if counter > self.highest {
36 return true;
38 }
39
40 let diff = self.highest - counter;
42 if diff as usize >= REPLAY_WINDOW_SIZE {
43 return false;
45 }
46
47 let (word_idx, mask) = Self::bit_position(counter);
48 (self.bitmap[word_idx] & mask) == 0
49 }
50
51 pub fn accept(&mut self, counter: u64) {
56 if counter > self.highest {
57 let shift = counter - self.highest;
60 if shift as usize >= REPLAY_WINDOW_SIZE {
61 self.bitmap = [0; REPLAY_WINDOW_SIZE / 64];
62 } else {
63 self.clear_counter_range(self.highest + 1, counter);
64 }
65 self.highest = counter;
66 }
67
68 let (word_idx, mask) = Self::bit_position(counter);
69 self.bitmap[word_idx] |= mask;
70 }
71
72 fn clear_counter_range(&mut self, start: u64, end: u64) {
73 debug_assert!(start <= end);
74 for counter in start..=end {
75 let (word_idx, mask) = Self::bit_position(counter);
76 self.bitmap[word_idx] &= !mask;
77 }
78 }
79
80 #[inline]
81 fn bit_position(counter: u64) -> (usize, u64) {
82 let bit = (counter as usize) % REPLAY_WINDOW_SIZE;
83 (bit / 64, 1u64 << (bit % 64))
84 }
85
86 pub fn highest(&self) -> u64 {
88 self.highest
89 }
90
91 pub fn reset(&mut self) {
93 self.highest = 0;
94 self.bitmap = [0; REPLAY_WINDOW_SIZE / 64];
95 }
96}
97
98impl Default for ReplayWindow {
99 fn default() -> Self {
100 Self::new()
101 }
102}
103
104impl fmt::Debug for ReplayWindow {
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 f.debug_struct("ReplayWindow")
107 .field("highest", &self.highest)
108 .field("window_size", &REPLAY_WINDOW_SIZE)
109 .finish()
110 }
111}