webterm_core/cryptography/
iv_counter.rs

1use crate::random::random_in_range;
2use crate::types::Bits96;
3use std::sync::atomic::{AtomicU64, Ordering};
4
5pub struct IvCounter {
6    counter: AtomicU64,
7}
8
9impl IvCounter {
10    pub fn new() -> Self {
11        let mut random_start = random_in_range(0, 1_u64 << 62);
12        if random_start % 2 != 0 {
13            random_start += 1
14        }
15        Self {
16            counter: AtomicU64::new(random_start),
17        }
18    }
19
20    // Agent always uses an "even" IV and frontend always uses an "odd" IV,
21    // guaranteeing that IVs from Agent & Frontend will never overlap.
22    pub fn next(&self) -> Bits96 {
23        self.counter.fetch_add(2, Ordering::SeqCst);
24        self.to_bits96()
25    }
26
27    fn to_bits96(&self) -> Bits96 {
28        let counter_value = self.counter.load(Ordering::SeqCst);
29        Bits96::from(counter_value)
30    }
31}