Skip to main content

klirr_core/logic/encryption/
salt.rs

1use serde_with::serde_as;
2use zeroize::{Zeroize, ZeroizeOnDrop};
3
4use crate::prelude::*;
5
6/// A cryptographically secure random salt used for key derivation.
7/// It is used to ensure that the derived keys are unique even if the
8/// input key material is the same.
9#[serde_as]
10#[derive(
11    Clone,
12    Debug,
13    PartialEq,
14    Eq,
15    Hash,
16    From,
17    Deref,
18    AsRef,
19    Serialize,
20    Deserialize,
21    Zeroize,
22    ZeroizeOnDrop,
23)]
24#[serde(transparent)]
25pub struct Salt(#[serde_as(as = "serde_with::hex::Hex")] [u8; 16]);
26
27impl Salt {
28    /// Uses CSPRNG (safe) to generate a salt.
29    pub fn generate() -> Self {
30        use rand::RngCore;
31        let mut salt = [0u8; 16];
32        rand::rng().fill_bytes(&mut salt);
33        Self(salt)
34    }
35}
36
37impl HasSample for Salt {
38    fn sample() -> Self {
39        Self([0xab; 16])
40    }
41
42    fn sample_other() -> Self {
43        Self([0xcd; 16])
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    type Sut = Salt;
52
53    #[test]
54    fn equality() {
55        assert_eq!(Sut::sample(), Sut::sample());
56        assert_eq!(Sut::sample_other(), Sut::sample_other());
57    }
58
59    #[test]
60    fn inequality() {
61        assert_ne!(Sut::sample(), Sut::sample_other());
62    }
63
64    #[test]
65    fn test_salt_generate() {
66        let salt1 = Salt::generate();
67        let salt2 = Salt::generate();
68
69        // Generated salts should be different
70        assert_ne!(salt1, salt2);
71
72        // Salt should not be all zeros
73        assert_ne!(*salt1, [0u8; 16]);
74        assert_ne!(*salt2, [0u8; 16]);
75    }
76}