cvlib/
spinparams.rs

1/// The parameters for the spin operation
2#[derive(Debug, Clone, Copy)]
3pub struct SpinParams {
4    /// The number of ticks to drop from the UTC timestamp
5    pub spin_counter_interval: SpinCounterInterval,
6    /// The number of bits to use from the UTC timestamp
7    pub spin_counter_periodicity: SpinCounterPeriodicity,
8    /// How many entropy bytes to use
9    pub spin_entropy: SpinEntropy,
10}
11
12/// The number of ticks to drop from the UTC timestamp
13#[derive(Debug, Clone, Copy)]
14pub enum SpinCounterInterval {
15    /// Drop 24 bits
16    Coarse,
17    /// Drop 16 bits
18    Fine,
19}
20
21pub(crate) fn ticks_to_drop(interval: SpinCounterInterval) -> u64 {
22    match interval {
23        SpinCounterInterval::Coarse => 24,
24        SpinCounterInterval::Fine => 16,
25    }
26}
27
28/// The number of bits to use from the UTC timestamp
29#[derive(Debug, Clone, Copy)]
30pub enum SpinCounterPeriodicity {
31    None,
32    /// use 16 bits
33    Short,
34    /// use 24 bits
35    Medium,
36    /// use 32 bits
37    Long,
38}
39
40pub(crate) fn tick_periodicity_bits(params: SpinParams) -> u64 {
41    let counter_bits = match params.spin_counter_periodicity {
42        SpinCounterPeriodicity::None => 0,
43        SpinCounterPeriodicity::Short => 16,
44        SpinCounterPeriodicity::Medium => 24,
45        SpinCounterPeriodicity::Long => 32,
46    };
47
48    counter_bits + entropy_bytes(params.spin_entropy) * 8
49}
50
51/// How many entropy bytes to use
52#[derive(Debug, Clone, Copy)]
53pub enum SpinEntropy {
54    None,
55    One,
56    Two,
57    Three,
58    Four,
59}
60
61pub(crate) fn entropy_bytes(entropy: SpinEntropy) -> u64 {
62    match entropy {
63        SpinEntropy::None => 0,
64        SpinEntropy::One => 1,
65        SpinEntropy::Two => 2,
66        SpinEntropy::Three => 3,
67        SpinEntropy::Four => 4,
68    }
69}
70
71pub(crate) fn generate_entropy(entropy: SpinEntropy) -> Vec<u8> {
72    let bytes_to_generate = entropy_bytes(entropy);
73
74    let mut result = Vec::new();
75    for _ in 0..bytes_to_generate {
76        result.push(rand::random::<u8>());
77    }
78    result
79}