ferric_crypto_lib 0.2.7

A library for Ferric Crypto
Documentation
use std::fmt::format;
use std::str::FromStr;
//use num_bigint::BigUint;
//use num_traits::Zero;
use crate::crypto_systems::rsa::RSA;
use crate::error::RSAError;
use crate::prelude::*;
use crate::utils::BaseString;
use crate::Traits::Decrypt;
use rug::Integer;

impl Decrypt<RSAError, String, String> for RSA {
    /// Decrypts a string using the RSA cipher.
    ///
    /// This requires that the private key is present since we need it for decrypting
    ///
    /// # Arguments
    ///
    /// * `cipher_text` - A `String` that holds the text to be decrypted.
    ///
    /// # Returns
    ///
    /// * A `Result<String, RSAError>` which is `Ok` if the decryption is successful, and `Err` otherwise.
    ///   The `Ok` variant contains the decrypted text, and the `Err` variant contains an error type.
    ///
    /// # Example
    ///
    /// TODO: make example
    fn decrypt(&self, cipher_text: String) -> Result<String, RSAError> {
        // since RSA wont always encrypt a string to a new slice of ints that can be decoded we must take in the whole input as a string and interpret it as a number later
        let cipher_num = match Integer::from_str(cipher_text.as_str()) {
            Ok(num) => num,
            Err(e) => return Err(RSAError::Error(e.to_string())),
        };

        if self.d == 0 {
            return Err(RSAError::PrivateKeyNotSet);
        }

        // decrypt the number
        let decrypted_num = cipher_num.secure_pow_mod(&self.d, &self.n);

        Ok(decrypted_num.to_string())
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::utils::EncodedString;
    use crate::Traits::{Decrypt, Encrypt};

    // TODO: make tests for RSA decrypt implementation
    #[test]
    fn test_decrypt() {
        let mut rsa = RSA::from_public(Integer::from(14317u64), Integer::from(7777u64));
        match rsa.factorize_and_set_d() {
            Ok(_) => {}
            Err(e) => println!("{}", e),
        };
        let cipher_text = "1640".to_string();
        let decrypted_text = rsa.decrypt(cipher_text).unwrap();
        assert_eq!(decrypted_text, "2612");
    }

    // broken case 'rsa_sys = ferric_crypto_lib.RSA("4177248169415681", "8650415919381337961")' with cipher_text = '32107833669138743416991214827014308'
    // pub key n: '36134934063919959150141797353966441' and e: '1330643366620853071'

    #[test]
    fn test_decryption() {
        let rsa = RSA::new(
            Integer::from(4177248169415681u64),
            Integer::from(8650415919381337961u64),
        );

        let cipher_text = "32107833669138743416991214827014308".to_string();
        let decrypted_text = rsa.decrypt(cipher_text).unwrap();

        let expected =
            match EncodedString::from("A19160912120914200502281415181401".to_string()).decode() {
                Ok(s) => s,
                Err(e) => panic!("{}", e.to_string()),
            };

        let decrypted = match EncodedString::from("A".to_string() + &decrypted_text).decode() {
            Ok(s) => s,
            Err(e) => panic!("{}", e.to_string()),
        };

        assert_eq!(decrypted, expected);
    }
}