ferric_crypto_lib 0.2.7

A library for Ferric Crypto
Documentation
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);
    }
}