diff --git a/README.md b/README.md deleted file mode 100644 index d6dbfe7..0000000 --- a/README.md +++ /dev/null @@ -1,72 +0,0 @@ -## Introduction - -This project implements a text encryption and decryption system using a matrix-based encryption technique. This project serves as an educational and practical exploration of matrix-based encryption techniques, demonstrating the fundamental concepts of encryption and decryption in a user-friendly manner. - -## Encryption Algorithm - -### Convert Input String to ASCII Integer - -1. **Initialization**: - - Given an input string $S$ of length $n$, where $S = s_1 s_2 s_3 \ldots s_n$, and each $s_i$ represents a character in the string.\ -Initialize an empty vector $\text{parsed}$ to store the ASCII integer representations of characters extracted from the input string $S$. - - - Consider the input string $S = \text{"Hello World"}$.\ -Initialize $\text{parsed} = []$. - -2. **Token Extraction**: - - Extract tokens (words) from the input string $S$. Let $T_1, T_2, \ldots, T_m$ be the tokens extracted from $S$, where $m$ is the number of tokens. - - - Extract tokens: $T_1 = \text{"Hello"}$ and $T_2 = \text{"World"}$. - -3. **Character Processing for Token $T_i$**: - - For each token $T_i$, consisting of characters $t_{i1}, t_{i2}, \ldots, t_{ik}$, where $k$ is the length of the token: - - Convert each character $t_{ij}$ to its ASCII integer representation $a_{ij}$. - - Add each $a_{ij}$ to end of the $parsed$ vector. - - - Convert 'H' to ASCII integer $72$, 'e' to $101$, 'l' to $108$, 'l' to $108$, 'o' to $111$.\ -Add these integers to $\text{parsed}$: $[72, 101, 108, 108, 111]$. - -4. **Adding Space**: - - After processing each character in a token $T_i$, add a space character ' ' to the $parsed$ vector. - - - Add a space ' ' to $\text{parsed}$. - -5. **End of Token**: - - Repeat steps 3-4 for all tokens $T_1, T_2, \ldots, T_m$. - - - Process characters for $T_2$: - - Convert 'W' to ASCII integer $87$, 'o' to $111$, 'r' to $114$, 'l' to $108$, 'd' to $100$. - - Add these integers to $\text{parsed}$: $[87, 111, 114, 108, 100]$. - - Add a space ' ' to $\text{parsed}$. - -6. **Return Result**: - - The function returns the $\text{parsed}$ vector containing ASCII integer representations of characters in $S$, with spaces after each token. - - - Return $\text{parsed} = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 32]$. - -### Generate Random Key - -1. **Initialization**: - - Let $key$ be a square matrix of size $size \times size$, represented as $key = [key_{ij}]$ where $i, j = 0, 1, \ldots, size - 1$. - - Each element $key_{ij}$ denotes a value in the key matrix. - - - Consider the ASCII representation of the string ${\text{"hi"} + \text{Space (ASCII 32)}}$, where the ASCII values are $[104, 105, 32]$.\ -Let $key$ be a square matrix of size $3 \times 3$ - -2. **Random Number Generation Setup**: - - Initialize a pseudo-random number generator with a random seed. - -3. **Uniform Distribution Setup**: - - Define a uniform distribution to produce random numbers uniformly distributed between -10.0 and 10.0. - -4. **Random Key Generation**: - - For each element $key_{ij}$ of $key$: - - Sample a random value $r_{ij}$ from the uniform distribution. - - Assign $r_{ij}$ as the value of $key_{ij}$ in the key matrix. - - Mathematically, $key_{ij} = r_{ij}$ for $i, j = 0, 1, \ldots, size - 1$. - -5. **Return the Key**: - - Once all elements of the matrix $key$ have been assigned random values, return the resulting key matrix $key$. - -Generated key matrix for $[104, 105, 32]$: - diff --git a/img/decrypted.png b/img/decrypted.png new file mode 100644 index 0000000..450f8d0 Binary files /dev/null and b/img/decrypted.png differ diff --git a/img/encrypt.png b/img/encrypt.png new file mode 100644 index 0000000..c6616d2 Binary files /dev/null and b/img/encrypt.png differ diff --git a/src/InputHandler.cpp b/src/InputHandler.cpp deleted file mode 100644 index a4eb951..0000000 --- a/src/InputHandler.cpp +++ /dev/null @@ -1,402 +0,0 @@ -#include "InputHandler.h" -#include "MatrixEncryptor.h" -#include -#include -#include -#include -#include // For system() function -#include - -void clearScreen() { -#ifdef _WIN32 - std::system("cls"); // Clear screen for Windows -#else - std::system("clear"); // Clear screen for Unix-like systems -#endif -} - -void displayEncryptionOptions() { - std::cout << "Options:" << std::endl; - std::cout << "(1) Show Encrypted Data" << std::endl; - std::cout << "(2) Save Encrypted Data" << std::endl; - std::cout << "(3) Show Key" << std::endl; - std::cout << "(4) Save Key" << std::endl; - std::cout << "(5) Show All Values" << std::endl; - std::cout << "(6) Back to Menu" << std::endl; - std::cout << "(7) Exit" << std::endl; -} - -void displayDecryptionOptions() { - std::cout << "Options:" << std::endl; - std::cout << "(1) Show Decrypted Data" << std::endl; - std::cout << "(2) Save Decrypted Data" << std::endl; - std::cout << "(3) Back to Menu" << std::endl; - std::cout << "(4) Exit" << std::endl; -} - -void InputHandler::encryptText() { - - char textChoice; - std::vector message; - clearScreen(); - std::cout << "Do you want to enter the text manually or load it from a file? (m/f): "; - std::cin >> textChoice; - std::cin.ignore(std::numeric_limits::max(), '\n'); - - if (textChoice == 'm' || textChoice == 'M') { - std::cout << "Enter the text to encrypt: "; - std::string input_text; - std::getline(std::cin, input_text); - message = MatrixEncryptor::parseInput(input_text); - } - else if (textChoice == 'f' || textChoice == 'F') { - std::string filename; - std::cout << "Enter the path to the file containing the data: "; - std::getline(std::cin, filename); - std::vector fileText = readTextFromFile(filename); - - // Check if the file contains valid data - if (fileText.empty()) { - std::cout << "The file does not contain any valid data to encrypt." << std::endl; - return; - } - - // Convert file text to vector of ints if needed - message.clear(); // Clear any existing data - for (char ch : fileText) { - // Convert char to int (ASCII value) - message.push_back(static_cast(ch)); - } - } - else { - clearScreen(); - std::cout << "Invalid choice. Aborting encryption." << std::endl; - return; - } - - int keySize = message.size(); - - char keyChoice; - std::cout << "Do you want to use a custom key or generate it automatically? (c/g): "; - std::cin >> keyChoice; - std::cin.clear(); - std::cin.ignore(std::numeric_limits::max(), '\n'); - - MatrixEncryptor encryptor(keySize); - - if (keyChoice == 'c' || keyChoice == 'C') { - std::cout << "Enter the elements of the key matrix:" << std::endl; - Eigen::MatrixXd customKey = MatrixEncryptor::getCustomKey(keySize); - encryptor = MatrixEncryptor(customKey); - } - else if (keyChoice != 'g' && keyChoice != 'G') { - clearScreen(); - std::cout << "Invalid choice. Aborting encryption." << std::endl; - return; - } - - std::vector encrypted_message = encryptor.encrypt(message); - - // Clear screen and inform the user about encryption completion - clearScreen(); - - // Options after encryption - std::cout << "Encryption is completed." << std::endl; - displayEncryptionOptions(); - - while (true) { - std::cout << "Enter your choice: "; - int choice; - std::cin >> choice; - switch (choice) { - case 1: - clearScreen(); - std::cout << "Encrypted data:\n"; - for (int num : encrypted_message) { - std::cout << num << " "; - } - std::cout << std::endl; - break; - case 2: - { - clearScreen(); - std::string fileloc; - std::cout << "Enter the path and filename to save the encrypted data: "; - std::cin.ignore(); - std::getline(std::cin, fileloc); - saveToFile(encrypted_message, fileloc); - std::cout << "Encrypted data saved." << std::endl; - break; - } - case 3: - clearScreen(); - std::cout << "Key used for encryption:" << std::endl; - std::cout << encryptor.getKey() << std::endl; - break; - case 4: - { - clearScreen(); - std::string fileloc; - std::cout << "Enter the path and filename to save the key matrix: "; - std::cin.ignore(); - std::getline(std::cin, fileloc); - saveKeyToFile(encryptor.getKey(), fileloc); - std::cout << "Key matrix data saved." << std::endl; - break; - } - case 5: - clearScreen(); - std::cout << "Original text: \n"; - for (int num : message) { - std::cout << static_cast(num); - } - std::cout << "\n\nEncrypted data: \n"; - for (int num : encrypted_message) { - std::cout << num << " "; - } - std::cout << "\n\nKey used for encryption:" << std::endl; - std::cout << encryptor.getKey() << std::endl; - break; - case 6: - clearScreen(); - return; // Back to Menu - case 7: - exit(0); - default: - clearScreen(); - std::cout << "Invalid choice. Exiting.." << std::endl; - exit(0); - } - std::cout << "\n(1) Back\n(2) Exit" << std::endl; - std::cout << "Enter your choice: "; - int backChoice; - std::cin >> backChoice; - if (backChoice == 1) { - clearScreen(); - displayEncryptionOptions(); - } - else if (backChoice == 2) { - exit(0); - } - else { - std::cout << "Invalid choice. Please try again." << std::endl; - } - } -} - -void InputHandler::decryptText() { - clearScreen(); - std::cout << "Do you want to enter the encrypted data manually or load it from a file? (m/f): "; - char inputChoice; - std::cin >> inputChoice; - std::cin.ignore(std::numeric_limits::max(), '\n'); - - std::vector input_encrypted_message; - if (inputChoice == 'm' || inputChoice == 'M') { - std::cout << "Enter the encrypted text to decrypt: "; - std::string input_line; - std::getline(std::cin, input_line); - std::istringstream iss(input_line); - int num; - while (iss >> num) { - input_encrypted_message.push_back(num); - } - } - else if (inputChoice == 'f' || inputChoice == 'F') { - std::string filename; - std::cout << "Enter the path to the file containing the encrypted data: "; - std::getline(std::cin, filename); - input_encrypted_message = readEncryptedDataFromFile(filename); - } - else { - clearScreen(); - std::cout << "Invalid choice. Aborting decryption." << std::endl; - return; - } - - if (!input_encrypted_message.empty()) { - int keySize = input_encrypted_message.size() / 2; - clearScreen(); - char keyChoice; - std::cout << "Do you want to enter the key manually or load it from a file? (m/f): "; - std::cin >> keyChoice; - std::cin.ignore(std::numeric_limits::max(), '\n'); - - Eigen::MatrixXd decryptionKey; - - if (keyChoice == 'm' || keyChoice == 'M') { - std::cout << "Enter the elements of the key matrix:" << std::endl; - decryptionKey = MatrixEncryptor::getCustomKey(keySize); - } - else if (keyChoice == 'f' || keyChoice == 'F') { - std::string keyFilename; - std::cout << "Enter the path to the key file: "; - std::getline(std::cin, keyFilename); - decryptionKey = readKeyFromFile(keyFilename); - if (decryptionKey.rows() != keySize || decryptionKey.cols() != keySize) { - clearScreen(); - std::cout << "Invalid key size. Aborting decryption." << std::endl; - return; - } - } - else { - clearScreen(); - std::cout << "Invalid choice. Aborting decryption." << std::endl; - return; - } - clearScreen(); - MatrixEncryptor decryptor(decryptionKey); - std::vector decrypted_message = decryptor.decrypt(input_encrypted_message, keySize); - std::cout << "Decryption is completed.\n"; - displayDecryptionOptions(); - - while (true) { - std::cout << "Enter your choice: "; - int choice; - std::cin >> choice; - switch (choice) { - case 1: - clearScreen(); - std::cout << "Decrypted text: "; - for (int num : decrypted_message) { - std::cout << static_cast(num); - } - std::cout << std::endl; - break; - case 2: - { - clearScreen(); - std::string fileloc; - std::cout << "Enter the path and filename to save the decrypted data: "; - std::cin.ignore(); - std::getline(std::cin, fileloc); - saveToFile(decrypted_message, fileloc); - std::cout << "Decrypted data saved." << std::endl; - break; - } - case 3: - clearScreen(); - return; // Back to Menu - case 4: - exit(0); - default: - clearScreen(); - std::cout << "Invalid choice. Exiting.." << std::endl; - exit(0); - } - std::cout << "\n(1) Back\n(2) Exit" << std::endl; - std::cout << "Enter your choice: "; - int backChoice; - std::cin >> backChoice; - if (backChoice == 1) { - clearScreen(); - displayDecryptionOptions(); - } - else if (backChoice == 2) { - exit(0); - } - else { - std::cout << "Invalid choice. Please try again." << std::endl; - } - } - - // Saving decrypted message - saveToFile(decrypted_message, "decrypted_text.txt"); - std::cout << "Decrypted data saved to 'decrypted_text.txt'" << std::endl; - } - else { - std::cout << "Empty message. Decryption aborted." << std::endl; - } -} - -void InputHandler::saveToFile(const std::vector& data, const std::string& filename) { - std::ofstream file(filename); - if (file.is_open()) { - for (int num : data) { - file << static_cast(num); // Convert ASCII value to character - } - file.close(); - std::cout << "Text saved to '" << filename << "'" << std::endl; - } - else { - std::cerr << "Unable to open file for saving: " << filename << std::endl; - } -} - -void InputHandler::saveKeyToFile(const Eigen::MatrixXd& key, const std::string& filename) { - std::ofstream file(filename); - if (file.is_open()) { - file << key; - file.close(); - std::cout << "Key matrix saved to '" << filename << "'" << std::endl; - } - else { - std::cerr << "Unable to open file for saving: " << filename << std::endl; - } -} - - -Eigen::MatrixXd InputHandler::readKeyFromFile(const std::string& filename) { - std::ifstream file(filename); - Eigen::MatrixXd key; - if (file.is_open()) { - std::vector> matrixData; - std::string line; - while (std::getline(file, line)) { - std::vector row; - std::istringstream iss(line); - double num; - while (iss >> num) { - row.push_back(num); - } - matrixData.push_back(row); - } - - int rows = matrixData.size(); - int cols = (rows > 0) ? matrixData[0].size() : 0; - key.resize(rows, cols); - - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - key(i, j) = matrixData[i][j]; - } - } - file.close(); - } - else { - std::cerr << "Unable to open file for reading: " << filename << std::endl; - } - return key; -} - -std::vector InputHandler::readEncryptedDataFromFile(const std::string& filename) { - std::vector data; - std::ifstream file(filename); - if (file.is_open()) { - int num; - while (file >> num) { - data.push_back(num); - } - file.close(); - } - else { - std::cerr << "Unable to open file for reading: " << filename << std::endl; - } - return data; -} - -std::vector InputHandler::readTextFromFile(const std::string& filename) { - std::vector data; - std::ifstream file(filename); - if (file.is_open()) { - char ch; - while (file.get(ch)) { - data.push_back(ch); - } - file.close(); - } - else { - std::cerr << "Unable to open file for reading: " << filename << std::endl; - } - return data; -} diff --git a/src/InputHandler.h b/src/InputHandler.h deleted file mode 100644 index 2d739d9..0000000 --- a/src/InputHandler.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef INPUTHANDLER_H -#define INPUTHANDLER_H - -#include -#include -#include - -class InputHandler { -public: - static void saveToFile(const std::vector& data, const std::string& filename); - - static void encryptText(); - static void decryptText(); - static void saveKeyToFile(const Eigen::MatrixXd& key, const std::string& filename); - static Eigen::MatrixXd readKeyFromFile(const std::string& filename); - static std::vector readEncryptedDataFromFile(const std::string& filename); - static std::vector readTextFromFile(const std::string& filename); -}; - -#endif diff --git a/src/MatrixEncryptor.cpp b/src/MatrixEncryptor.cpp deleted file mode 100644 index 145630f..0000000 --- a/src/MatrixEncryptor.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "MatrixEncryptor.h" -#include -#include -#include - -Eigen::MatrixXd MatrixEncryptor::generateRandomKey(int size) { - Eigen::MatrixXd key(size, size); - std::random_device rd; - std::mt19937 generator(rd()); - std::uniform_real_distribution distribution(-10.0, 10.0); - - for (int i = 0; i < size; ++i) { - for (int j = 0; j < size; ++j) { - key(i, j) = distribution(generator); - } - } - return key; -} - -MatrixEncryptor::MatrixEncryptor(int size) { - keyMatrix = generateRandomKey(size); -} - -MatrixEncryptor::MatrixEncryptor(const Eigen::MatrixXd& customKey) : keyMatrix(customKey) {} - -std::vector MatrixEncryptor::encrypt(const std::vector& message) const { - int size = keyMatrix.rows(); - int messageSize = message.size(); - std::cout << messageSize << std::endl; - std::cout << size << std::endl; - int remainder = size - (messageSize % size); - std::vector paddedMessage = message; - paddedMessage.insert(paddedMessage.end(), remainder, ' '); // Padding message with spaces to make its size a multiple of the key matrix size - - std::vector encrypted_message; - for (int i = 0; i < paddedMessage.size(); i += size) { - Eigen::VectorXd messageVector(size); - for (int j = 0; j < size; ++j) { - messageVector(j) = paddedMessage[i + j]; - } - Eigen::VectorXd encryptedVector = keyMatrix * messageVector; - for (int j = 0; j < size; ++j) { - encrypted_message.push_back(static_cast(encryptedVector(j))); - } - } - return encrypted_message; -} - -std::vector MatrixEncryptor::decrypt(const std::vector& encrypted_message, int size) const { - std::vector decrypted_message; - for (int i = 0; i < encrypted_message.size(); i += size) { - Eigen::VectorXd encryptedVector(size); - for (int j = 0; j < size; ++j) { - encryptedVector(j) = encrypted_message[i + j]; - } - Eigen::MatrixXd inverseKey = keyMatrix.inverse(); - Eigen::VectorXd decryptedVector = inverseKey * encryptedVector; - for (int j = 0; j < size; ++j) { - // Round to the nearest integer before converting back to int - int decrypted_value = static_cast(decryptedVector(j) + 0.5); - decrypted_message.push_back(decrypted_value); - } - } - return decrypted_message; -} - -const Eigen::MatrixXd& MatrixEncryptor::getKey() const { - return keyMatrix; -} - -std::vector MatrixEncryptor::parseInput(const std::string& input) { - std::vector parsed; - std::istringstream iss(input); - std::string token; - while (iss >> token) { - for (char c : token) { - parsed.push_back(static_cast(c)); - } - parsed.push_back(' '); // Add space after each token - } - return parsed; -} - -Eigen::MatrixXd MatrixEncryptor::getCustomKey(int size) { - Eigen::MatrixXd customKey(size, size); - for (int i = 0; i < size; ++i) { - for (int j = 0; j < size; ++j) { - std::cin >> customKey(i, j); - } - } - return customKey; -} - diff --git a/src/MatrixEncryptor.h b/src/MatrixEncryptor.h deleted file mode 100644 index f5b2eb9..0000000 --- a/src/MatrixEncryptor.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef MATRIXENCRYPTOR_H -#define MATRIXENCRYPTOR_H - -#include -#include -#include - -class MatrixEncryptor { -private: - Eigen::MatrixXd keyMatrix; - - Eigen::MatrixXd generateRandomKey(int size); - -public: - MatrixEncryptor(int size); - MatrixEncryptor(const Eigen::MatrixXd& customKey); - - std::vector encrypt(const std::vector& message) const; - std::vector decrypt(const std::vector& encrypted_message, int size) const; - const Eigen::MatrixXd& getKey() const; - - static std::vector parseInput(const std::string& input); - static Eigen::MatrixXd getCustomKey(int size); - static size_t calculateHash(const std::vector& data); -}; - -#endif // MATRIXENCRYPTOR_H diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 0467fbc..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include "InputHandler.h" - -int main() { - int choice; - do { - std::cout << "(1) Encrypt a text" << std::endl; - std::cout << "(2) Decrypt a text" << std::endl; - std::cout << "(3) Exit" << std::endl; - std::cout << "Enter your choice: "; - std::cin >> choice; - - switch (choice) { - case 1: - InputHandler::encryptText(); - break; - case 2: - InputHandler::decryptText(); - break; - case 3: - std::cout << "Exiting program..." << std::endl; - break; - default: - std::cout << "Invalid choice. Please try again." << std::endl; - } - } while (choice != 3); - - return 0; -}