1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::crypto_systems::mix::Mix;
use crate::encrypt::mix::mix_function;
use crate::error::MixError;
use crate::prelude::ALPHABET_LEN;
use crate::utils::{decode_list, BaseString};
use crate::Traits::Decrypt;
impl Decrypt<MixError, String, String> for Mix {
/// This function decrypts a given input string using the Mix cipher.
///
/// The decryption process involves parsing the input string into chunks, initializing `l` and `r` with the first two chunks of the parsed input,
/// performing the decryption rounds, reversing the encryption steps, and finally combining `l` and `r` into a single vector and converting it back into a string.
///
/// # Arguments
///
/// * `input` - The input string to be decrypted.
///
/// # Returns
///
/// * `Result<String, MixError>` - A result containing either the decrypted string, or an error.
fn decrypt(&self, input: String) -> Result<String, MixError> {
// Parse the input string into chunks
let parsed_input = match self.get_split_input(input) {
Ok(input) => input,
Err(e) => return Err(e),
};
// Initialize `l` and `r` with the first two chunks of the parsed input
let mut l = parsed_input[0].clone();
let mut r = parsed_input[1].clone();
// Perform the decryption rounds
for i in (0..self.rounds).rev() {
// Select the key for the current round
let k = self.key.keys[i].clone();
// Reverse the encryption steps
let temp = r.clone();
r = l;
l = temp
.iter()
.zip(mix_function(r.clone(), k).iter())
.map(|(&x, &y)| (*ALPHABET_LEN + x - y) % *ALPHABET_LEN)
.collect();
}
// Combine `l` and `r` into a single vector and convert it back into a string
let combined = l.iter().chain(r.iter()).copied().collect::<Vec<usize>>();
let sve = match decode_list(combined) {
Ok(s) => s,
Err(e) => return Err(MixError::CharacterParseError(e)),
};
Ok(sve)
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::crypto_systems::mix::MixKey;
#[test]
fn test_decrypt() {
let k1 = vec![0, 27, 27, 0];
let k2 = vec![1, 0, 0, 1];
let k3 = vec![15, 15, 15, 15];
let clear_text = "ladugÄrd".to_string();
let key = MixKey::new(k1, k2, k3).expect("Key is invalid");
let mix = Mix::new(key);
let decrypted_text = mix
.decrypt("ZODIAILM".to_string())
.expect("Decryption failed");
assert_eq!(decrypted_text, clear_text);
}
}