Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
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

 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. More...
 
void test2 (const std::string &text)
 Self test 2 - using 8x8 randomly generated key. More...
 
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 }
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 }
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 }
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 }
Here is the call graph for this function:
std::srand
T srand(T... args)
std::strlen
T strlen(T... args)
std::string
STL class.
std::pair
std::vector
STL class.
std::vector::size
T size(T... args)
test2
void test2(const std::string &text)
Self test 2 - using 8x8 randomly generated key.
Definition: hill_cipher.cpp:505
std::setfill
T setfill(T... args)
ciphers::STRKEY
static const char * STRKEY
Definition: hill_cipher.cpp:73
std::cout
std::ofstream
STL class.
std::string::compare
T compare(T... args)
ciphers::HillCipher::encrypt_text
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
ciphers::HillCipher::decrypt_text
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
test1
void test1(const std::string &text)
Self test 1 - using 3x3 randomly generated key.
Definition: hill_cipher.cpp:470
ciphers::HillCipher::generate_keys
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
std::endl
T endl(T... args)
std::left
T left(T... args)
std::time
T time(T... args)
std::setw
T setw(T... args)