shadow_crypt_core/v1/
key.rs

1use crate::profile::SecurityProfile;
2
3/// Argon2id parameters for XChacha20-Poly1305 key derivation.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct KeyDerivationParams {
6    pub memory_cost: u32, // Memory cost in kibibytes (KiB)
7    pub time_cost: u32,   // Number of iterations
8    pub parallelism: u32, // Number of parallel threads
9    pub key_size: u8,     // Output key size in bytes
10}
11
12impl KeyDerivationParams {
13    pub fn new(memory_cost: u32, time_cost: u32, parallelism: u32, key_size: u8) -> Self {
14        Self {
15            memory_cost,
16            time_cost,
17            parallelism,
18            key_size,
19        }
20    }
21
22    /// Production defaults for Argon2id parameters.
23    ///
24    /// - Memory Cost: 4,194,304 KiB (4 GiB)
25    /// - Time Cost: 10 iterations
26    /// - Parallelism: 4 threads
27    /// - Key Size: 32 bytes (256 bits)
28    pub fn production_defaults() -> Self {
29        Self {
30            memory_cost: 4 * 1024 * 1024, // 4,194,304 KiB (4 GiB)
31            time_cost: 10,                // 10 iterations
32            parallelism: 4,               // 4 threads
33            key_size: 32,                 // 32 bytes (256 bits)
34        }
35    }
36
37    /// Test defaults for Argon2id parameters.
38    ///
39    /// - Memory Cost: 1,024 KiB (1 MiB)
40    /// - Time Cost: 1 iteration
41    /// - Parallelism: 1 thread
42    /// - Key Size: 32 bytes (256 bits)
43    pub fn test_defaults() -> Self {
44        Self {
45            memory_cost: 1024, // 1,024 KiB (1 MiB)
46            time_cost: 1,      // 1 iteration
47            parallelism: 1,    // 1 thread
48            key_size: 32,      // 32 bytes (256 bits)
49        }
50    }
51}
52
53impl From<SecurityProfile> for KeyDerivationParams {
54    fn from(profile: SecurityProfile) -> Self {
55        match profile {
56            SecurityProfile::Production => KeyDerivationParams::production_defaults(),
57            SecurityProfile::Test => KeyDerivationParams::test_defaults(),
58        }
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn test_key_derivation_params_defaults() {
68        let prod = KeyDerivationParams::production_defaults();
69        assert_eq!(prod.memory_cost, 4 * 1024 * 1024);
70        assert_eq!(prod.time_cost, 10);
71        assert_eq!(prod.parallelism, 4);
72        assert_eq!(prod.key_size, 32);
73
74        let test = KeyDerivationParams::test_defaults();
75        assert_eq!(test.memory_cost, 1 * 1024);
76        assert_eq!(test.time_cost, 1);
77        assert_eq!(test.parallelism, 1);
78        assert_eq!(test.key_size, 32);
79    }
80
81    #[test]
82    fn test_from_security_profile() {
83        let prod_params: KeyDerivationParams = SecurityProfile::Production.into();
84        let expected_prod = KeyDerivationParams::production_defaults();
85        assert_eq!(prod_params, expected_prod);
86
87        let test_params: KeyDerivationParams = SecurityProfile::Test.into();
88        let expected_test = KeyDerivationParams::test_defaults();
89        assert_eq!(test_params, expected_test);
90    }
91}