Implementation of Hill Cipher algorithm.
More...
|
template<typename T1 , typename T2 > |
static const T2 | rand_range (T1 a, T1 b) |
| Function to generate a random integer in a given interval. More...
|
|
template<typename T1 , typename T2 > |
static double | rand_range (matrix< T2 > *M, T1 a, T1 b) |
| Function overload to fill a matrix with random integers in a given interval. More...
|
|
template<typename T > |
static const T | gcd (T a, T b) |
| Compute GCD of two integers using Euler's algorithm. More...
|
|
static const std::valarray< uint8_t > | mat_mul (const std::valarray< uint8_t > &vector, const matrix< int > &key) |
| helper function to perform vector multiplication with encryption or decryption matrix More...
|
|
static char | get_idx_char (const uint8_t idx) |
| Get the character at a given index in the STRKEY. More...
|
|
static uint8_t | get_char_idx (const char ch) |
| Get the index of a character in the STRKEY. More...
|
|
static const std::string | codec (const std::string &text, const matrix< int > &key) |
| Convenience function to perform block cipher operations. The operations are identical for both encryption and decryption. More...
|
|
template<typename T > |
static matrix< double > | get_inverse (matrix< T > const &A) |
|
static int | modulo (int a, int b) |
|
Implementation of Hill Cipher algorithm.
◆ codec()
Convenience function to perform block cipher operations. The operations are identical for both encryption and decryption.
- Parameters
-
text | input text to encrypt or decrypt |
key | key for encryption or decryption |
- Returns
- encrypted/decrypted output
212 size_t text_len = text.
length();
213 size_t key_len = key.
size();
217 size_t L2 = text_len % key_len == 0
219 : text_len + key_len - (text_len % key_len);
225 #pragma parallel omp for private(i)
227 for (i = 0; i < L2 - key_len + 1; i += key_len) {
229 for (
size_t j = 0; j < key_len; j++) {
233 batch_int =
mat_mul(batch_int, key);
235 for (
size_t j = 0; j < key_len; j++) {
◆ decrypt_text()
Decrypt a given text using a given key.
- Parameters
-
text | string to decrypt |
decrypt_key | key for decryption |
- Returns
- decrypted text
459 return codec(text, decrypt_key);
◆ encrypt_text()
Encrypt a given text using a given key.
- Parameters
-
text | string to encrypt |
encrypt_key | key for encryption |
- Returns
- encrypted text
447 return codec(text, encrypt_key);
◆ gcd()
template<typename T >
static const T ciphers::HillCipher::gcd |
( |
T |
a, |
|
|
T |
b |
|
) |
| |
|
inlinestaticprivate |
Compute GCD of two integers using Euler's algorithm.
- Parameters
-
a | first number |
b | second number |
- Returns
- GCD of \(a\) and \(b\)
◆ generate_decryption_key()
static matrix<int> ciphers::HillCipher::generate_decryption_key |
( |
matrix< int > const & |
encrypt_key | ) |
|
|
inlinestatic |
Generate decryption matrix from an encryption matrix key.
- Parameters
-
encrypt_key | encryption key for which to create a decrypt key |
- Returns
- Decryption martix
372 size_t size = encrypt_key.
size();
378 int mat_determinant = det_encrypt < 0 ? det_encrypt % L : det_encrypt;
385 for (
int i = 0; i < L; i++) {
386 if (modulo(mat_determinant * i, L) == 1) {
393 std::cerr <<
"Could not find a co-prime for inversion\n";
397 mat_determinant = det_inv * det_encrypt;
402 #pragma parallel omp for private(i)
404 for (i = 0; i < size; i++) {
405 for (
int j = 0; j < size; j++) {
406 int temp =
std::round(tmp_inverse[i][j] * mat_determinant);
407 decrypt_key[i][j] = modulo(temp, L);
◆ generate_encryption_key()
static matrix<int> ciphers::HillCipher::generate_encryption_key |
( |
size_t |
size, |
|
|
int |
limit1 = 0 , |
|
|
int |
limit2 = 10 |
|
) |
| |
|
inlinestatic |
Generate encryption matrix of a given size. Larger size matrices are difficult to generate but provide more security. Important conditions are:
- matrix should be invertible
- determinant must not have any common factors with the length of character key There is no head-fast way to generate hte matrix under the given numerical restrictions of the machine but the conditions added achieve the goals. Bigger the matrix, greater is the probability of the matrix being ill-defined.
- Parameters
-
size | size of matrix (typically \(\text{size}\le10\)) |
limit1 | lower limit of range of random elements (default=0) |
limit2 | upper limit of range of random elements (default=10) |
- Returns
- Encryption martix
343 int mat_determinant = -1;
351 dd =
rand_range(&encrypt_key, limit1, limit2);
352 mat_determinant =
static_cast<int>(dd);
354 if (mat_determinant < 0)
355 mat_determinant = (mat_determinant % L);
356 }
while (std::abs(dd) > 1e3 ||
359 gcd(mat_determinant, L) != 1);
◆ generate_keys()
static std::pair<matrix<int>, matrix<int> > ciphers::HillCipher::generate_keys |
( |
size_t |
size, |
|
|
int |
limit1 = 0 , |
|
|
int |
limit2 = 10 |
|
) |
| |
|
inlinestatic |
Generate encryption and decryption key pair.
- Parameters
-
size | size of matrix key (typically \(\text{size}\le10\)) |
limit1 | lower limit of range of random elements (default=0) |
limit2 | upper limit of range of random elements (default=10) |
- Returns
- std::pair<matrix<int>, matrix<int>> encryption and decryption keys as a pair
- See also
- ::generate_encryption_key
430 while (std::abs(det2) < 0.1 || std::abs(det2) > 1e3) {
◆ get_char_idx()
static uint8_t ciphers::HillCipher::get_char_idx |
( |
const char |
ch | ) |
|
|
inlinestaticprivate |
Get the index of a character in the STRKEY.
- Parameters
-
- Returns
- index of character
193 for (
size_t idx = 0; idx <= L; idx++)
197 std::cerr << __func__ <<
":" << __LINE__ <<
": (" << ch
198 <<
") Should not reach here!\n";
◆ get_idx_char()
static char ciphers::HillCipher::get_idx_char |
( |
const uint8_t |
idx | ) |
|
|
inlinestaticprivate |
Get the character at a given index in the STRKEY.
- Parameters
-
- Returns
- character at the index
◆ get_inverse()
template<typename T >
static matrix<double> ciphers::HillCipher::get_inverse |
( |
matrix< T > const & |
A | ) |
|
|
inlinestaticprivate |
Get matrix inverse using Row-transformations. Given matrix must be a square and non-singular.
- Returns
- inverse matrix
255 for (
size_t row = 0; row < N; row++) {
256 for (
size_t col = 0; col < N; col++) {
258 inverse[row][col] = (row == col) ? 1.f : 0.f;
269 for (
size_t row = 0; row < N; row++) {
270 for (
size_t col = 0; col < N; col++)
271 temp[row][col] =
static_cast<double>(A[row][col]);
275 for (
size_t row = 0; row < N; row++) {
276 for (
size_t row2 = row; row2 < N && temp[row][row] == 0; row2++) {
278 temp[row] = temp[row] + temp[row2];
279 inverse[row] = inverse[row] + inverse[row2];
282 for (
size_t col2 = row; col2 < N && temp[row][row] == 0; col2++) {
284 for (
size_t row2 = 0; row2 < N; row2++) {
285 temp[row2][row] = temp[row2][row] + temp[row2][col2];
287 inverse[row2][row] + inverse[row2][col2];
291 if (temp[row][row] == 0) {
298 double divisor = temp[row][row];
299 temp[row] = temp[row] / divisor;
300 inverse[row] = inverse[row] / divisor;
302 for (
size_t row2 = 0; row2 < N; row2++) {
305 double factor = temp[row2][row];
306 temp[row2] = temp[row2] - factor * temp[row];
307 inverse[row2] = inverse[row2] - factor * inverse[row];
◆ mat_mul()
helper function to perform vector multiplication with encryption or decryption matrix
- Parameters
-
vector | vector to multiply |
key | encryption or decryption key matrix |
- Returns
- corresponding encrypted or decrypted text
165 for (
size_t i = 0; i < key.
size(); i++) {
167 for (
size_t j = 0; j < vector.size(); j++) {
168 tmp += key[i][j] * vector[j];
170 out[i] =
static_cast<uint8_t
>(tmp % L);
◆ rand_range() [1/2]
template<typename T1 , typename T2 >
static double ciphers::HillCipher::rand_range |
( |
matrix< T2 > * |
M, |
|
|
T1 |
a, |
|
|
T1 |
b |
|
) |
| |
|
inlinestaticprivate |
Function overload to fill a matrix with random integers in a given interval.
- Parameters
-
M | pointer to matrix to be filled with random numbers |
a | lower limit of interval |
b | upper limit of interval |
- Template Parameters
-
T1 | type of input range |
T2 | type of matrix |
- Returns
- determinant of generated random matrix
- Warning
- There will need to be a balance between the matrix size and the range of random numbers. If the matrix is large, the range of random numbers must be small to have a well defined keys. Or if the matrix is smaller, the random numbers range can be larger. For an 8x8 matrix, range should be no more than \([0,10]\)
119 for (
size_t i = 0; i < M->
size(); i++) {
120 for (
size_t j = 0; j < M[0][0].
size(); j++) {
121 M[0][i][j] = rand_range<T1, T2>(a, b);
◆ rand_range() [2/2]
template<typename T1 , typename T2 >
static const T2 ciphers::HillCipher::rand_range |
( |
T1 |
a, |
|
|
T1 |
b |
|
) |
| |
|
inlinestaticprivate |
Function to generate a random integer in a given interval.
- Parameters
-
a | lower limit of interval |
b | upper limit of interval |
- Template Parameters
-
- Returns
- random integer in the interval \([a,b)\)
94 long double r =
static_cast<long double>(
std::rand()) / RAND_MAX;
97 return static_cast<T2
>(r * (b - a) + a);
The documentation for this class was generated from the following file: