Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
hill_cipher.cpp File Reference

Implementation of Hill cipher algorithm. More...

#include <cassert>
#include <cmath>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include "../numerical_methods/lu_decomposition.h"
Include dependency graph for hill_cipher.cpp:

Classes

class  ciphers::HillCipher
 Implementation of Hill Cipher algorithm. More...
 

Namespaces

namespace  ciphers
 Algorithms for encryption and decryption.
 

Functions

template<typename T >
static std::ostreamoperator<< (std::ostream &out, matrix< T > const &v)
 
void test1 (const std::string &text)
 Self test 1 - using 3x3 randomly generated key.
 
void test2 (const std::string &text)
 Self test 2 - using 8x8 randomly generated key.
 
int main ()
 

Variables

static const char * ciphers::STRKEY
 

Detailed Description

Implementation of Hill cipher algorithm.

Program to generate the encryption-decryption key and perform encryption and decryption of ASCII text using the famous block cipher algorithm. This is a powerful encryption algorithm that is relatively easy to implement with a given key. The strength of the algorithm depends on the size of the block encryption matrix key; the bigger the matrix, the stronger the encryption and more difficult to break it. However, the important requirement for the matrix is that:

  1. matrix should be invertible - all inversion conditions should be satisfied and
  2. its determinant must not have any common factors with the length of character set Due to this restriction, most implementations only implement with small 3x3 encryption keys and a small subset of ASCII alphabets.

In the current implementation, I present to you an implementation for generating larger encryption keys (I have attempted upto 10x10) and an ASCII character set of 97 printable characters. Hence, a typical ASCII text file could be easily encrypted with the module. The larger character set increases the modulo of cipher and hence the matrix determinants can get very large very quickly rendering them ill-defined.

Note
This program uses determinant computation using LU decomposition from the file lu_decomposition.h
The matrix generation algorithm is very rudimentary and does not guarantee an invertible modulus matrix.
Todo
Better matrix generation algorithm.
Author
Krishna Vedala

Function Documentation

◆ main()

int main ( void )

Main function

532 {
533 std::srand(std::time(nullptr));
534 std::cout << "Key dictionary: (" << std::strlen(ciphers::STRKEY) << ")\n\t"
535 << ciphers::STRKEY << "\n";
536
537 std::string text = "This is a simple text with numb3r5 and exclamat!0n.";
538
539 test1(text);
540 test2(text);
541
542 return 0;
543}
static void test2()
Self-implementations, 2nd test.
Definition dsu_path_compression.cpp:186
static void test1()
Self-test implementations, 1st test.
Definition dsu_path_compression.cpp:169
static const char * STRKEY
Definition hill_cipher.cpp:73
T srand(T... args)
T strlen(T... args)
T time(T... args)
Here is the call graph for this function:

◆ operator<<()

template<typename T >
static std::ostream & operator<< ( std::ostream & out,
matrix< T > const & v )
static

operator to print a matrix

54 {
55 const int width = 15;
56 const char separator = ' ';
57
58 for (size_t row = 0; row < v.size(); row++) {
59 for (size_t col = 0; col < v[row].size(); col++)
60 out << std::left << std::setw(width) << std::setfill(separator)
61 << v[row][col];
62 out << std::endl;
63 }
64
65 return out;
66}
T endl(T... args)
T left(T... args)
T setfill(T... args)
T setw(T... args)
T size(T... args)
Here is the call graph for this function:

◆ test1()

void test1 ( const std::string & text)

Self test 1 - using 3x3 randomly generated key.

Parameters
textstring to encrypt and decrypt
470 {
471 // std::string text = "Hello world!";
472 std::cout << "======Test 1 (3x3 key) ======\nOriginal text:\n\t" << text
473 << std::endl;
474
477 matrix<int> ekey = p.first;
478 matrix<int> dkey = p.second;
479
480 // matrix<int> ekey = {{22, 28, 25}, {5, 26, 15}, {14, 18, 9}};
481 // std::cout << "Encryption key: \n" << ekey;
482 std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey);
483 std::cout << "Encrypted text:\n\t" << gibberish << std::endl;
484
485 // matrix<int> dkey = ciphers::HillCipher::generate_decryption_key(ekey);
486 // std::cout << "Decryption key: \n" << dkey;
487 std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey);
488 std::cout << "Reconstruct text:\n\t" << txt_back << std::endl;
489
490 std::ofstream out_file("hill_cipher_test1.txt");
491 out_file << "Block size: " << ekey.size() << "\n";
492 out_file << "Encryption Key:\n" << ekey;
493 out_file << "\nDecryption Key:\n" << dkey;
494 out_file.close();
495
496 assert(txt_back == text);
497 std::cout << "Passed :)\n";
498}
static std::pair< matrix< int >, matrix< int > > generate_keys(size_t size, int limit1=0, int limit2=10)
Generate encryption and decryption key pair.
Definition hill_cipher.cpp:424
static const std::string decrypt_text(const std::string &text, const matrix< int > &decrypt_key)
Decrypt a given text using a given key.
Definition hill_cipher.cpp:457
static const std::string encrypt_text(const std::string &text, const matrix< int > &encrypt_key)
Encrypt a given text using a given key.
Definition hill_cipher.cpp:445
Here is the call graph for this function:

◆ test2()

void test2 ( const std::string & text)

Self test 2 - using 8x8 randomly generated key.

Parameters
textstring to encrypt and decrypt
505 {
506 // std::string text = "Hello world!";
507 std::cout << "======Test 2 (8x8 key) ======\nOriginal text:\n\t" << text
508 << std::endl;
509
512 matrix<int> ekey = p.first;
513 matrix<int> dkey = p.second;
514
515 std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey);
516 std::cout << "Encrypted text:\n\t" << gibberish << std::endl;
517
518 std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey);
519 std::cout << "Reconstruct text:\n\t" << txt_back << std::endl;
520
521 std::ofstream out_file("hill_cipher_test2.txt");
522 out_file << "Block size: " << ekey.size() << "\n";
523 out_file << "Encryption Key:\n" << ekey;
524 out_file << "\nDecryption Key:\n" << dkey;
525 out_file.close();
526
527 assert(txt_back.compare(0, text.size(), text) == 0);
528 std::cout << "Passed :)\n";
529}
T compare(T... args)
Here is the call graph for this function: