ferric_crypto_lib 0.2.7

A library for Ferric Crypto
Documentation
use crate::crypto_systems::affine::Affine;
use crate::error::AffineError;
use crate::prelude::ALPHABET_LEN;
use crate::utils::{BaseString, EncodedString, StringType};
use crate::Traits::Decrypt;
use rayon::prelude::*;
use rug::Integer;

impl Decrypt<AffineError, BaseString, BaseString> for Affine {
    fn decrypt(&self, input: BaseString) -> Result<BaseString, AffineError> {
        let encoded = input.encode()?;

        let a_inv = Integer::from(self.a)
            .invert(&Integer::from(*ALPHABET_LEN))
            .unwrap()
            .to_usize()
            .ok_or(AffineError::Error("Problem Inverting 'a'".into()))?;

        let encrypted_data: Vec<usize> = encoded
            .iter()
            .map(|&y| {
                let x = a_inv as isize * (y as isize - self.b as isize);
                let mod_x = ((x % *ALPHABET_LEN as isize) + *ALPHABET_LEN as isize)
                    % *ALPHABET_LEN as isize; // this is dumb that we need this but we need it to not get negative numbers from modulos
                mod_x as usize
            })
            .collect();

        let encrypted_input = EncodedString::new(encrypted_data, StringType::Standard);

        Ok(encrypted_input.decode()?)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::crypto_systems::affine::Affine;
    use crate::error::AffineError;
    use crate::Traits::Decrypt;

    #[test]
    fn decrypts_input_correctly() {
        let affine = Affine::new(5, 8);
        let result = affine.decrypt("pahhx".into());
        assert!(result.is_ok());
        assert_eq!(result.unwrap(), "hello".into()); // replace with expected encrypted string
    }

    #[test]
    fn decrypts_empty_string() {
        let affine = Affine::new(5, 8);
        let result = affine.decrypt("".into());
        assert!(result.is_ok());
        assert_eq!(result.unwrap(), "".into()); // assuming encryption of empty string is empty string
    }

    #[test]
    fn decrypts_single_character() {
        let affine = Affine::new(5, 8);
        let result = affine.decrypt("i".into());
        assert!(result.is_ok());
        assert_eq!(result.unwrap(), "a".into()); // replace with expected encrypted char
    }
}