You are on page 1of 31

Information and Network Security(C0427)

Lab File

Submitted By
Kartikay Singh
(2K20/CO/228)

Submitted To
Prof. Shailender Kumar

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING


DELHI TECHNOLOGICAL UNIVERSITY
(Formally Delhi College of Engineering)
Bawana road, Delhi-110042
INDEX

S.No Experiment Date Sign

1. To implement Mono-alphabetic decryption 24/8/23

2. To implement Mono-alphabetic decryption 31/8/23

3. To implement Playfair cipher 4/9/23


encryption-decryption

4. To implement Polyalphabetic cipher encryption 14/9/23


and decryption.

5. To implement Hill-cipher encryption decryption. 21/9/23

6. To implement S-DES subkey generation. 12/10/23

7. To implement the Diffie-Hellman key exchange 19/10/23


algorithm.

8. To implement RSA encryption-decryption. 26/10/23

9. Write a program to generate SHA-1 hash. 2/11/23

10. Implement a Digital Signature algorithm. 12/11/23


EXPERIMENT - 1

Aim : To implement Mono-alphabetic decryption

Theory: The Caesar Cipher technique is one of the earliest and simplest methods of encryption
technique. It’s simply a type of substitution cipher, i.e., each letter of a given text is replaced by a
letter with a fixed number of positions down the alphabet. The method is apparently named after
Julius Caesar, who apparently used it to communicate with his officials.

Source Code:
class CaesarCipher
{ public:
char letters[26] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
char letters_2[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z'};
int numberOfLetters = sizeof(letters);
string encrypt(string, int);
string decrypt(string, int);
};

string CaesarCipher::encrypt(string txt, int key)


{ char initialCharacter;
char encryptedCharacter;
string encryptedText;
for (int i = 0; i < txt.length(); i++)
{ initialCharacter = txt[i];
if (isLower(initialCharacter))
{ for (int j = 0; j < numberOfLetters; j++)
{ if (initialCharacter == letters[j])
{ if (j + key <= numberOfLetters - 1)
{encryptedCharacter = letters[j + key];
encryptedText += encryptedCharacter;
break;
} else
{encryptedCharacter = letters[j + key - numberOfLetters];
encryptedText += encryptedCharacter;
break;
}}}
else if (isUpper(initialCharacter))
{ for (int j = 0; j < numberOfLetters; j++)
{ if (initialCharacter == letters_2[j])
{ if (j + key <= numberOfLetters - 1)
{encryptedCharacter = letters_2[j + key];
encryptedText += encryptedCharacter;
break;}
else
{ encryptedCharacter = letters_2[j + key - numberOfLetters];
encryptedText += encryptedCharacter;
break;
}}}}
else
encryptedText += initialCharacter;
} return encryptedText;}
string CaesarCipher::decrypt(string txt, int key)
{ char initialCharacter;
char decryptedCharacter;
string decryptedText;
for (int i = 0; i < txt.length(); i++)
{initialCharacter = txt[i];
if (isLower(initialCharacter))
{for (int j = 0; j < numberOfLetters; j++)
{ if (initialCharacter == letters[j])
{if (j - key >= 0)
{ decryptedCharacter = letters[j - key];
decryptedText += decryptedCharacter;
break; }
else
{ decryptedCharacter = letters[j - key + numberOfLetters];
decryptedText += decryptedCharacter;
break;
}}}}
else if (isUpper(initialCharacter))
{for (int j = 0; j < numberOfLetters; j++)
{ if (initialCharacter == letters_2[j])
if (j - key >= 0)
{ decryptedCharacter = letters_2[j - key];
decryptedText += decryptedCharacter;
break;
}
else
{
decryptedCharacter = letters_2[j - key + numberOfLetters];
decryptedText += decryptedCharacter;
break; } } } }
else
decryptedText += initialCharacter; }
return decryptedText;
}

int main()
{ CaesarCipher cc;
string encryptedTxt, decryptedTxt;
int key;
cout << "Enter the text to be encrypted: ";
getline(cin, encryptedTxt);
cin >> key;
if (key >= 0)
{key %= 26;
cout << endl<< "Encrypted: " << cc.encrypt(encryptedTxt, key) << endl;
decryptedTxt = cc.encrypt(encryptedTxt, key);
cout << endl<< "Decrypted: " << cc.decrypt(decryptedTxt, key) << endl;}
else
{key %= 26;
key += 26;
cout << endl<< "Encrypted: " << cc.encrypt(encryptedTxt, key) << endl;
decryptedTxt = cc.encrypt(encryptedTxt, key);
cout << endl<< "Decrypted: " << cc.decrypt(decryptedTxt, key) << endl; }
}
Output:
EXPERIMENT - 2

Aim : To implement Mono-alphabetic decryption

Theory: A monoalphabetic cipher is a type of substitution cipher where each character in the
alphabet is replaced by another character in a one-to-one ratio. For example, if "A" is encrypted
as "D", then "A" will always be encrypted to "D".

Source Code:
Import java.util.Scanner;
public class Mono
{
public static char p[] = { 'aS', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z' };
public static char ch[] = { 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C',
'V', 'B', 'N', 'M' };

public static String doEncryption(String s)


{
char c[] = new char[(s.length())];
for (int i = 0; i <s.length(); i++)
{
for (int j = 0; j < 26; j++)
{
if (p[j] == s.charAt(i))
{
c[i] = ch[j];
break;
}
}
}
return (new String(c));
}

public static String doDecryption(String s)


{
char p1[] = new char[(s.length())];
for (int i = 0; i <s.length(); i++)
{
for (int j = 0; j < 26; j++)
{
if (ch[j] == s.charAt(i))
{
p1[i] = p[j];
break;
}
}
}
return (new String(p1));
}

public static void main(String args[])


{
Scanner sc = new Scanner(System.in);
System.out.println("Enter the message: ");
String en = doEncryption(sc.next().toLowerCase());
System.out.println("Encrypted message: " + en);
System.out.println("Decrypted message: " + doDecryption(en));
sc.close();
}
}

Output:
EXPERIMENT - 3

Aim : To implement Playfair cipher encryption-decryption

Theory:
Playfair cipher is a substitution cipher which encrypts a pair of alphabets called diagrams
instead of a single alphabet. Playfair cipher encrypts the text in two steps:
● It creates a 5x5 matrix in which the key is stored and remaining positions are filled with
remaining alphabets. Since there are 26 alphabets but only 25 positions in the matrix,
the letter i and j are considered the same.
● It encrypts the text by looking in the matrix and performing by following the rules:
○ Pair cannot be made with the same letter. Break the letter in single and add a
bogus letter to the previous letter. If the letter is standing alone in the process of
pairing, then add an extra bogus letter with the alone letter.
○ If both the letters are in the same column: Take the letter below each one (going
back to the top if at the bottom).
○ If both the letters are in the same row: Take the letter to the right of each one
(going back to the leftmost if at the rightmost position).
○ If neither of the above rules is true: Form a rectangle with the two letters and take
the letters on the horizontal opposite corner of the rectangle.
For decryption the above-mentioned rules are followed in reverse manner.

Source Code:
#include <bits/stdc++.h>
using namespace std;
string cmatrix(string keyword) {
char array[24];
int i = 0;
int k = 0;
int value = 0;
int count = 0;
bool unique = true;
int len = keyword.length();
int run = 1;
for (int tmp = 0; tmp < len; tmp++) {
if (keyword[tmp] == 'j') {
keyword[tmp] = 'i';
}
}
for (run = 0; run < len; run++) {
for (k = 0; k < run; k++){
if (keyword[run] == keyword[k]){
unique = false;
}
}
if (unique == true){
array[i] = keyword[run];
i++;
}
unique = true;
}
while (count < 26){
for (k = 0; k < len; k++){
if (value == keyword[k] - 97){
unique = false;
}
}
if (unique == true){
if (value != 9){
array[i] = 97 + value;
i++;
}
}
value++;
count++;
k = 0;
unique = true;
}
return array;
}

void encrypt(string matrix) {


fstream txt, en;

txt.open("textfile.txt", ios::in);
en.open("encrypted.txt", ios::out);

if (txt && en){


while (!txt.eof()) {
string ciphertxt;
string text, s = "";
getline(txt, text);
int i = 0;
int j = 0;
int len = 0;
len = text.length();
for (int tmp = 0; tmp < len; tmp++){
if (text[tmp] == 'j'){
text[tmp] = 'i';
}
}
if (len % 2 != 0){
text = text + "x";
}
len = text.length();
for (i = 0; i < len; i = i + 2){
if (text[i + 1] == text[i]){
text = text + " ";
len = text.length();
for (j = len - 1; j > i; j--){
text[j] = text[j - 1];
}
text[i + 1] = 'x';
}
}
ciphertxt = text;
int loc[2];
int row[2];
int col[2];
int shift = 0;
int original_row = 0;
int n = 0;
int textlen = text.length();
for (n = 0; n < textlen; n = n + 2){
for (int temp = 0; temp < 26; temp++){
if (text[n] == matrix[temp])
loc[0] = temp;
if (text[n + 1] == matrix[temp])
loc[1] = temp;
}
for (int m = 0; m < 2; m++){
if (loc[m] < 5)
row[m] = 1;
else if (loc[m] > 4 && loc[m] < 10)
row[m] = 2;
else if (loc[m] > 9 && loc[m] < 15)
row[m] = 3;
else if (loc[m] > 14 && loc[m] < 20)
row[m] = 4;
else
row[m] = 5;
if (loc[m] == 0 || loc[m] == 5 || loc[m] == 10 || loc[m] == 15 || loc[m] == 20)
col[m] = 1;
else if (loc[m] == 1 || loc[m] == 6 || loc[m] == 11 || loc[m] == 16 || loc[m] == 21)
col[m] = 2;
else if (loc[m] == 2 || loc[m] == 7 || loc[m] == 12 || loc[m] == 17 || loc[m] == 22)
col[m] = 3;
else if (loc[m] == 3 || loc[m] == 8 || loc[m] == 13 || loc[m] == 18 || loc[m] == 23)
col[m] = 4;
else
col[m] = 5;
}
if (row[0] == row[1] || col[0] == col[1]){
if (row[0] == row[1]){
original_row = row[0];
loc[0] = (loc[0] + 1);
loc[1] = (loc[1] + 1);
for (int m = 0; m < 2; m++) {
if (loc[m] < 5)
row[m] = 1;
else if (loc[m] > 4 && loc[m] < 10)
row[m] = 2;
else if (loc[m] > 9 && loc[m] < 15)
row[m] = 3;
else if (loc[m] > 14 && loc[m] < 20)
row[m] = 4;
else
row[m] = 5;
}
if (row[0] != original_row)
loc[0] = loc[0] - 5;
if (row[1] != original_row)
loc[1] = loc[1] - 5;
ciphertxt[n] = matrix[loc[0]];
ciphertxt[n + 1] = matrix[loc[1]];
}
if (col[0] == col[1]){
loc[0] = (loc[0] + 5);
loc[1] = (loc[1] + 5);
if (loc[0] > 24)
loc[0] = loc[0] - 25;
if (loc[1] > 24)
loc[1] = loc[1] - 25;
ciphertxt[n] = matrix[loc[0]];
ciphertxt[n + 1] = matrix[loc[1]];
}
}
else if (col[0] < col[1]){
shift = abs(col[0] - col[1]);
loc[0] = loc[0] + shift;
loc[1] = loc[1] - shift;
ciphertxt[n] = matrix[loc[0]];
ciphertxt[n + 1] = matrix[loc[1]];
}
else if (col[0] > col[1]){
shift = (col[0] - col[1]);
loc[0] = loc[0] - shift;
loc[1] = loc[1] + shift;
ciphertxt[n] = matrix[loc[0]];
ciphertxt[n + 1] = matrix[loc[1]];
}
}
if (!txt.eof())
en << ciphertxt << endl;
else
en << ciphertxt;
}
}
else
cout << "Error!! text file not found" << endl;
txt.close();
en.close();
}

void decrypt(string matrix)


{
fstream dr, en;
dr.open("decrypted.txt", ios::out);
en.open("encrypted.txt", ios::in);
if (dr && en){
while (!en.eof()){
string cipher, s = "";
getline(en, cipher);
string plain = cipher;
int loc[2];
int row[2];
int col[2];
int shift = 0;
int original_row = 0;
int n = 0;
int m = 0;
int textlen = cipher.length();
for (n = 0; n < textlen; n = n + 2) {
loc[0] = 0;
loc[1] = 0;
for (int temp = 0; temp < 26; temp++){
if (plain[n] == matrix[temp])
loc[0] = temp;
if (plain[n + 1] == matrix[temp])
loc[1] = temp;
}
for (m = 0; m < 2; m++)
{
if (loc[m] < 5)
row[m] = 1;
else if (loc[m] > 4 && loc[m] < 10)
row[m] = 2;
else if (loc[m] > 9 && loc[m] < 15)
row[m] = 3;
else if (loc[m] > 14 && loc[m] < 20)
row[m] = 4;
else
row[m] = 5;
if (loc[m] == 0 || loc[m] == 5 || loc[m] == 10 || loc[m] == 15 || loc[m] == 20)
col[m] = 1;
else if (loc[m] == 1 || loc[m] == 6 || loc[m] == 11 || loc[m] == 16 || loc[m] == 21)
col[m] = 2;
else if (loc[m] == 2 || loc[m] == 7 || loc[m] == 12 || loc[m] == 17 || loc[m] == 22)
col[m] = 3;
else if (loc[m] == 3 || loc[m] == 8 || loc[m] == 13 || loc[m] == 18 || loc[m] == 23)
col[m] = 4;
else
col[m] = 5;
}
if (row[0] == row[1] || col[0] == col[1]){
if (row[0] == row[1]){
original_row = row[0];
loc[0] = (loc[0] - 1);
loc[1] = (loc[1] - 1);
for (m = 0; m < 2; m++){
if (loc[m] < 5)
row[m] = 1;
else if (loc[m] > 4 && loc[m] < 10)
row[m] = 2;
else if (loc[m] > 9 && loc[m] < 15)
row[m] = 3;
else if (loc[m] > 14 && loc[m] < 20)
row[m] = 4;
else
row[m] = 5;
}
if (row[0] != original_row || loc[0] < 0)
loc[0] = loc[0] + 5;
if (row[1] != original_row || loc[1] < 0)
loc[1] = loc[1] + 5;
plain[n] = matrix[loc[0]];
plain[n + 1] = matrix[loc[1]];
}
else if (col[0] == col[1]) {
if (loc[0] > loc[1]) {
loc[0] = (loc[0] - 5);
loc[1] = (loc[1] - 5);
if (loc[1] < 0)
loc[1] = (loc[1] + 25);
}
else if (loc[0] < loc[1] && loc[0] < 4) {
loc[0] = (loc[0] + 5);
loc[1] = (loc[1] - 5);
}
else {
if (loc[1] - loc[0] == 20) {
loc[0] = loc[0] + 20;
loc[1] = (loc[1] - 5);
}
else {
loc[0] = (loc[0] - 5);
loc[1] = (loc[1] - 5);
if (loc[0] > 24)
loc[0] = loc[0] - 25;
if (loc[1] > 24)
loc[1] = loc[1] - 25;
}
}
plain[n] = matrix[loc[0]];
plain[n + 1] = matrix[loc[1]];
}
}
else if (col[0] < col[1]) {
shift = abs(col[0] - col[1]);
loc[0] = loc[0] + shift;
loc[1] = loc[1] - shift;
plain[n] = matrix[loc[0]];
plain[n + 1] = matrix[loc[1]];
}
else if (col[0] > col[1]) {
shift = (col[0] - col[1]);
loc[0] = loc[0] - shift;
loc[1] = loc[1] + shift;
plain[n] = matrix[loc[0]];
plain[n + 1] = matrix[loc[1]];
}
}
if (!en.eof())
dr << plain << endl;
else
dr << plain;
}
}
else
cout << "Error!! text file not found" << endl;
dr.close();
en.close();
}

int main() {
string key = "monarchy";
string matrix = cmatrix(key);
encrypt(matrix);
decrypt(matrix);
return 0;
}

Output:
EXPERIMENT - 4

Aim : To implement Polyalphabetic cipher encryption and decryption.

Theory:
A poly-alphabetic cipher is any cipher based on substitution, using several substitution
alphabets. In polyalphabetic substitution ciphers, the plaintext letters are enciphered differently
based upon their installation in the text. Rather than being a one-to-one correspondence, there
is a one-to-many relationship between each letter and its substitutes. To encrypt, a table of
alphabets can be used, termed a tabula recta, Vigenère square or Vigenère table. It has the
alphabet written out 26 times in different rows, each alphabet shifted cyclically to the left
compared to the previous alphabet, corresponding to the 26 possible Caesar ciphers. At
different points in the encryption process, the cipher uses a different alphabet from one of the
rows. The alphabet used at each point depends on a repeating keyword.

Source Code:
#include<bits/stdc++.h>
using namespace std;
void encrypt(string key){
fstream txt, en;
txt.open("textfile.txt", ios::in);
en.open("encrypted.txt", ios::out);
if(txt && en){
while(!txt.eof()){
string st, s = "";
getline(txt, st);
int c = 0;
for(int i = 0 ; i < st.size() ; i++){
if(st[i] == ' ')
s += ' ';
else{
s += (char)((st[i] + key[c] -2*'a') % 26 + 'a');
c++;
c = c%(key.length());
}
}
if(!txt.eof())
en << s << endl;
else
en << s;
}
}else{
cout << "Error";
}
txt.close();
en.close();
}
void decrypt(string key){
fstream dr, en;
dr.open("decrypted.txt", ios::out);
en.open("encrypted.txt", ios::in);
if(dr && en){
while(!en.eof()){
string st, s = "";
getline(en, st);
int c = 0;
for(int i = 0 ; i < st.size() ; i++){
if(st[i] == ' ')
s += ' ';
else{
s += (char)((st[i] - key[c] + 26) % 26 + 'a');
c++;
c %= key.length();
}
}
if(!en.eof())
dr << s << endl;
else
dr << s;
}
}else{
cout << "Error";
}
dr.close();
en.close();
}
int main(){
string key = "welcome";
encrypt(key);
decrypt(key);
return 0;
}

Output:
EXPERIMENT - 5

Aim : To implement Hill-cipher encryption decryption.

Theory:
Hill cipher is a polygraphic substitution cipher based on linear algebra.Each letter is represented
by a number modulo 26. Often the simple scheme A = 0, B = 1, …, Z = 25 is used, but this is not
an essential feature of the cipher. To encrypt a message, each block of n letters (considered as
an n-component vector) is multiplied by an invertible n × n matrix, against modulus 26. To
decrypt the message, each block is multiplied by the inverse of the matrix used for encryption.

Source Code:
#include <iostream>
#include <math.h>
using namespace std;
float encrypt[3][1], decrypt[3][1], a[3][3], b[3][3], mes[3][1], c[3][3];
void encryption();
void decryption();
void getKeyMessage();
void inverse();
int main()
{
getKeyMessage();
encryption();
decryption();
}
void encryption()
{
int i, j, k;
for (i = 0; i < 3; i++)
for (j = 0; j < 1; j++)
for (k = 0; k < 3; k++)
encrypt[i][j] = encrypt[i][j] + a[i][k] * mes[k][j];
cout << "\nEncrypted string is: ";
for (i = 0; i < 3; i++)
cout << (char)(fmod(encrypt[i][0], 26) + 97);
}
void decryption()
{
int i, j, k;
inverse();
for (i = 0; i < 3; i++)
for (j = 0; j < 1; j++)
for (k = 0; k < 3; k++)
decrypt[i][j] = decrypt[i][j] + b[i][k] * encrypt[k][j];
cout << "\nDecrypted string is: ";
for (i = 0; i < 3; i++)
cout << (char)(fmod(decrypt[i][0], 26) + 97);
cout << "\n";
}
void getKeyMessage()
{
int i, j;
char msg[3];
cout << "Enter 3x3 matrix for key (It should be inversible):\n";
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
cin >> a[i][j];
c[i][j] = a[i][j];
}
cout << "\nEnter a 3 letter string: ";
cin >> msg;
for (i = 0; i < 3; i++)
mes[i][0] = msg[i] - 97;
}
void inverse()
{
int i, j, k;
float p, q;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
if (i == j)
b[i][j] = 1;
else
b[i][j] = 0;
}
for (k = 0; k < 3; k++)
{
for (i = 0; i < 3; i++)
{
p = c[i][k];
q = c[k][k];
for (j = 0; j < 3; j++)
{
if (i != k)
{
c[i][j] = c[i][j] * q - p * c[k][j];
b[i][j] = b[i][j] * q - p * b[k][j];
}
}
}
}
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
b[i][j] = b[i][j] / c[i][i];
}
Output:
EXPERIMENT - 6

Aim : To implement S-DES subkey generation.

Theory:
It is a block cipher that takes a block of plaintext and converts it into cipher text. It takes an 8 bit
block. It is a symmetric key cipher i.e. they use the same key for both encryption and decryption.
In the key generation algorithm, we accept the 10-bit key and convert it into two 8 bit keys. This
key is shared between both sender and receiver.

Source Code:
#include <iostream>
using namespace std;
void p10(int key[]){
int out[10]={3,5,2,7,4,10,1,9,8,6};
int temp[10];

for(int i= 0; i< 10; i++)


temp[i]= key[i];
for(int i= 0; i< 10; i++){
key[i]= temp[out[i]-1];
}
}
void p8(int key[]){
int out[8]={6,3,7,4,8,5,10,9};
int temp[10];

for(int i=0;i<10;i++)
temp[i]=key[i];

for(int i=0;i<8;i++){
key[i]=temp[out[i]-1];
}
}
void left_shift(int left_half[], int right_half[], int shift_count)
{
int temp1=left_half[0];
int temp2=right_half[0];

for(int i=0;i<4;i++)
{
left_half[i]=left_half[i+1];
right_half[i]=right_half[i+1];
}
left_half[4]=temp1;
right_half[4]=temp2;

if(shift_count==2)
left_shift(left_half,right_half,1);

}
int* generate_key(int key[],int round)
{
int left_half[5],right_half[5];
int key1[10],key2[8];
p10(key);
for(int i= 0; i< 10; i++){
if(i<5){
left_half[i]= key[i];
}
else{
right_half[i-5]= key[i];
}
}
left_shift(left_half,right_half,1);
for(int i= 0; i< 5; i++) {
key1[i]= left_half[i];
key1[i+5]= right_half[i];
}
if(round==1){
p8(key1);
for(int i= 0; i< 8; ++i)
cout<<key1[i];
return key1;
}
else{
left_shift(left_half, right_half, 2);
for(int i= 0; i< 5; i++){
key2[i]= left_half[i];
key2[i+5]= right_half[i];
}
p8(key2);
for(int i= 0; i< 8; ++i)
cout<<key2[i];
return key2;
}
}
int main()
{
int pt[8],key[10],num;
cout<<"\nEnter the plain text (8-bits) :";
for(int i= 0; i< 8; i++)
cin>>pt[i];
cout<<"\nEnter the key (10-bits) :";
for(int i= 0; i< 10; i++)
cin>>key[i];
cout<<"\nEnter Round No. :";
cin>>num;

int* generated_key= generate_key(key, num);


return 0;
}
Output:
EXPERIMENT - 7

Aim : To implement Diffie-Hellman key exchange algorithm.

Theory:
Diffie-Hellman key exchange raises numbers to a selected power to produce decryption keys.
The two parties use symmetric cryptography to encrypt and decrypt their messages. The
components of the keys are never directly transmitted, making the task of a would-be code
breaker mathematically overwhelming. The method doesn't share information during the key
exchange. The two parties have no prior knowledge of each other, but the two parties create a
key together.

Source Code:
#include <cmath>
#include <iostream>
using namespace std;
long long int power(long long int a, long long int b, long long int P)
{
if (b == 1)
return a;
else
return (((long long int)pow(a, b)) % P);
}
int main()
{
long long int N, G, x, a, y, b, ka, kb;
N = 23;
cout << "The value of N : " << N << endl;
G = 9;
cout << "The value of G : " << G << endl;
a = 4;
cout << "The private key a for Alice : " << a << endl;
x = power(G, a, N);
b = 3;
cout << "The private key b for Bob : " << b << endl;
y = power(G, b, N);
ka = power(y, a, N);
kb = power(x, b, N);
cout << "Secret key for the Alice is : " << ka << endl;
cout << "Secret key for the Bob is : " << kb << endl;
return 0;
}

Output:
EXPERIMENT - 8

Aim : To implement RSA encryption-decryption.

Theory:
RSA algorithm is an asymmetric cryptography algorithm. Asymmetric actually means that it
works on two different keys i.e. Public Key and Private Key. As the name describes, the Public
Key is given to everyone and the Private key is kept private.
The idea of RSA is based on the fact that it is difficult to factorize a large integer. The public key
consists of two numbers where one number is a multiplication of two large prime numbers. And
private keys are also derived from the same two prime numbers. So if somebody can factorize
the large number, the private key is compromised. Therefore encryption strength totally lies on
the key size and if we double or triple the key size, the strength of encryption increases
exponentially.

Source Code:
#include<bits/stdc++.h>
using namespace std;
long int p, q, n, t, flag, e[100], d[100], temp[100], j, m[100], en[100], i;
char msg[1000];
int prime(long int);
void ce();
long int cd(long int);
void encrypt();
void decrypt();
int prime(long int pr)
{
int i;
j = sqrt(pr);
for (i = 2; i <= j; i++)
{
if (pr % i == 0)
return 0;
}
return 1;
}
int main()
{
cout<< "ENTER FIRST PRIME NUMBER: "<<endl;
cin>> p;
flag = prime(p);
if (flag == 0)
{
cout<< "WRONG INPUT!"<<endl;
exit(1);
}
cout<< "ENTER ANOTHER PRIME NUMBER: "<<endl;
cin>> q;
flag = prime(q);
if (flag == 0 || p == q)
{
cout<< "WRONG INPUT!"<<endl;
exit(1);
}
cout<< "ENTER MESSAGE: "<<endl;
fflush(stdin);
cin>>msg;
for (i = 0; msg[i] != NULL; i++){
m[i] = msg[i];
n = p * q;
t = (p - 1) * (q - 1);
ce();
cout << "POSSIBLE VALUES OF en AND de ARE: " << endl;
for (i = 0; i < j - 1; i++)
cout << e[i] << "\t" << d[i] << "\n";
encrypt();
decrypt();
return 0;
}
void ce()
{
int k;
k = 0;
for (i = 2; i < t; i++)
{
if (t % i == 0)
continue;
flag = prime(i);
if (flag == 1 && i != p && i != q)
{
e[k] = i;
flag = cd(e[k]);
if (flag > 0)
{
d[k] = flag;
k++;
}
if (k == 99)
break;
}
}
}
long int cd(long int x)
{
long int k = 1;
while (1)
{
k = k + t;
if (k % x == 0)
return (k / x);
}
}
void encrypt()
{
long int pt, ct, key = e[0], k, len;
i = 0;
len = strlen(msg);
while (i != len)
{
pt = m[i];
pt = pt - 96;
k = 1;
for (j = 0; j < key; j++)
{
k = k * pt;
k = k % n;
}
temp[i] = k;
ct = k + 96;
en[i] = ct;
i++;
}
en[i] = -1;
cout<< "THE ENCRYPTED MESSAGE IS: "<<endl;
for (i = 0; en[i] != -1; i++)
printf("%c", en[i]);
}
void decrypt()
{
long int pt, ct, key = d[0], k;
i = 0;
while (en[i] != -1)
{
ct = temp[i];
k = 1;
for (j = 0; j < key; j++)
{
k = k * ct;
k = k % n;
}
pt = k + 96;
m[i] = pt;
i++;
}
m[i] = -1;
cout<< "\nTHE DECRYPTED MESSAGE IS: "<<endl;
for (i = 0; m[i] != -1; i++)
printf("%c", m[i]);
}

Output:
EXPERIMENT - 9

Aim : Write a program to generate SHA-1 hash.

Theory:
SHA-1 or Secure Hash Algorithm 1 is a cryptographic algorithm which takes an input and
produces a 160-bit (20-byte) hash value. This hash value is known as a message digest. This
message digest is usually then rendered as a hexadecimal number which is 40 digits long. It is
a U.S. Federal Information Processing Standard and was designed by the United States
National Security Agency. SHA-1 is now considered insecure since 2005.

Source Code:
#include <stdio.h>
#include <openssl/sha.h>

typedef unsigned char byte;

int main(int argc, char *argv[]) {


const int DataLen = 30;
SHA_CTX shactx;
byte digest[SHA_DIGEST_LENGTH];

byte* testdata = new byte[DataLen];


for (int i=0; i<DataLen; i++) testdata[i] = 0;

SHA1_Init(&shactx);
SHA1_Update(&shactx, testdata, DataLen);
SHA1_Final(digest, &shactx);

for (int i=0; i<SHA_DIGEST_LENGTH; i++)


printf("%02x", digest[i]);
putchar('\n');

return 0;
}

Output:
EXPERIMENT - 10

Aim: Implement a Digital Signature algorithm.

Theory:
A digital signature is a mathematical technique used to validate the authenticity and integrity of
a message, software, or digital document.

● Key Generation Algorithms: Digital signature is electronic signatures, which assure that
the message was sent by a particular sender. While performing digital transactions
authenticity and integrity should be assured, otherwise, the data can be altered or
someone can also act as if he was the sender and expect a reply.

● Signing Algorithms: To create a digital signature, signing algorithms like email programs
create a one-way hash of the electronic data which is to be signed. The signing
algorithm then encrypts the hash value using the private key (signature key). This
encrypted hash along with other information like the hashing algorithm is the digital
signature. This digital signature is appended with the data and sent to the verifier. The
reason for encrypting the hash instead of the entire message or document is that a hash
function converts any arbitrary input into a much shorter fixed-length value. This saves
time as now instead of signing a long message a shorter hash value has to be signed
and moreover hashing is much faster than signing.

● Signature Verification Algorithms: Verifier receives Digital Signature along with the data.
It then uses a Verification algorithm to process the digital signature and the public key
(verification key) and generates some value. It also applies the same hash function on
the received data and generates a hash value. Then the hash value and the output of
the verification algorithm are compared. If they both are equal, then the digital signature
is valid else it is invalid.

Source Code:
#include <iostream>
#include <vector>
int euclid(int m, int n) {
if (n == 0) {
return m;
} else {
int r = m % n;
return euclid(n, r);
}
}
std::pair<int, int> exteuclid(int a, int b) {
int r1 = a;
int r2 = b;
int s1 = 1;
int s2 = 0;
int t1 = 0;
int t2 = 1;
while (r2 > 0) {
int q = r1 / r2;
int r = r1 - q * r2;
r1 = r2;
r2 = r;
int s = s1 - q * s2;
s1 = s2;
s2 = s;
int t = t1 - q * t2;
t1 = t2;
t2 = t;
}

if (t1 < 0) {
t1 = t1 % a;
}
return std::make_pair(r1, t1);
}
int main() {
int p = 823;
int q = 953;
int n = p * q;
int Pn = (p - 1) * (q - 1);
std::vector<int> key;
for (int i = 2; i < Pn; ++i) {
int gcd = euclid(Pn, i);

if (gcd == 1) {
key.push_back(i);
}
}
int e = 313;
auto result = exteuclid(Pn, e);
int r = result.first;
int d = result.second;
if (r == 1) {
d = d;
std::cout << "Decryption key is: " << d << std::endl;
} else {
std::cout << "Multiplicative inverse for the given encryption key does not exist. Choose a different
encryption key" << std::endl;
}
int M = 19070;
int S = 1;
for (int i = 0; i < d; ++i) {
S = (S * M) % n;
}
int M1 = 1;
for (int i = 0; i < e; ++i) {
M1 = (M1 * S) % n;
}
if (M == M1) {
std::cout << "As M = M1, Accept the message sent by Alice" << std::endl;
} else {
std::cout << "As M not equal to M1, Do not accept the message sent by Alice" << std::endl;
}
return 0;
}

Output:

You might also like