You are on page 1of 70

CRYPTOGRAPHY & NETWORK SECURITY LAB

PAPER CODE (ETIT-455)

Faculty Name: Ms. Vandana Choudhary Student name: Divy Mohan


Roll No.: 00396403117
Semester: 7th
Group: 7-I-7

Maharaja Agrasen Institute of Technology, PSP Area,


Sector – 22, Rohini, New Delhi – 110086

1|P a ge
CRYPTOGRAPHY AND NETWORK SECURITY LAB
PRACTICAL RECORD

PAPER CODE : ETIT-455


Name of the student : Divy Mohan Rai
University Roll No. : 00396403117
Branch : Information Technology
Section/ Group : 7-I-7

PRACTICAL DETAILS

Exp. No Date of Date of Marks


Experiment Name Remarks
performance checking (10)

Write a program to perform


01 encryption and decryption using 25-Aug-20
Monoalphabetic Cipher Technique.

Write a menu driven program to


02 perform Encryption & Decryption 1-Sep-20
using Caesar Cipher Technique.

Write a menu driven program to


03 perform Encryption & Decryption 8-Sep-20
using Playfair Cipher Technique.

Write a menu driven program to


04 perform Encryption & Decryption 15-Sep-2020
using Hill Cipher Technique.

Write a menu driven program to


05 perform Encryption & Decryption 22-Sep-2020
using Vigenere Cipher Technique.

Write a menu driven program to


perform Encryption & Decryption
06 29-Sep-2020
using One time Pad cipher
Technique.

2|P a ge
Write a menu driven program to
07 perform Encryption & Decryption 06-Oct-2020
using Rail Fence Technique

Write a program to implement Diffie


08 20-Oct-2020
Hellman Key Exchange Algorithm.

Write a program to implement RSA


09 27-Oct-2020
algorithm.

10 Write a program to implement DES. 03-Nov-2020

11 Write a program to implement SHA. 10-Nov-2020

3|P a ge
Tuesday, 25 August 2020

EXPERIMENT-1

AIM : Write a program to perform encryption and decryption using


Monoalphabetic Cipher Technique. .

Theory:
Mono Alphabetic Cipher is another substitution technique, where each character of
the plain text is substituted with another different character. There is no mathematical
relation between the original character and the substituted character. Whenever a
specific character is encountered, it will be always replaced by the character, which is
defined in the substitution table. For example, whenever 'a' is encountered in the plain
text, it will always be replaced by 'q' in the Cipher text. The relation between 'a' and 'q'
is random.

If the substitution table is as follows:

Original Characters - 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
Substituted Characters - 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

The plain text will be converted to:

Plain Text: h e l l o

Cipher Text - i t s s g

4|P a ge
Code:
#include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
// the original table
char pt[52]={'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','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'};

// the replacement table


char ct[52]={'Z','Y','X','W','V','U','T','S','R','Q','P','O',

'N','M','L','K','J','I','H','G','F','E','D','C',

'B','A','z','y','x','w','v','u','t','s','r','q','p','o',

'n','m','l','k','j','i','h','g','f','e','d','c','b','a'};

char p[20]={'\0'},c[20]={'\0'},r[20]={'\0'};

5|P a ge
int i,j;

char ch = 'y';

int value = 0;
do {
printf("Do you want to encode or decode. Press 1 or 2: ");
scanf("%d",&value);
if(value==1){

printf("\n enter the plain text:");


scanf("%s",&p);
for(i=0;i<strlen(p);i++)
{
for(j=0;j<52;j++)

{
if(pt[j]==p[i])
{
c[i]=ct[j];
}

}
}
printf("\n cipher text is: %s",c);
}

else{
printf("\n enter the decoded text:");
scanf("%s",&c);
for(i=0;i<strlen(c);i++)
{
for(j=0;j<52;j++)

6|P a ge
{

if(ct[j]==c[i])

{
r[i]=pt[j];
}
}
}

printf("\n plain text is: %s",r);


}
printf("\n Do you want to continue?");
scanf("%s",&ch);
}while(ch=='y'||ch=='Y');

OUTPUT:

7|P a ge
Tuesday, 01 September 2020

EXPERIMENT-2

AIM : Write a menu driven program to perform Encryption & Decryption using
Caesar Cipher Technique. .

Theory:

The Caesar cipher is one of the earliest known and simplest ciphers. It is a type
of substitution cipher in which each letter in the plaintext is 'shifted' a certain
number of places down the alphabet. For example, with a shift of 1, A would be
replaced by B, B would become C, and so on. The method is named after Julius
Caesar, who apparently used it to communicate with his generals. To pass an
encrypted message from one person to another, it is first necessary that both
parties have the 'key' for the cipher, so that the sender may encrypt it and the
receiver may decrypt it. For the Caesar cipher, the key is the number of
characters to shift the cipher alphabet.

Here is a quick example of the encryption and decryption steps involved with
the Caesar cipher. The text we will encrypt is 'defend the east wall of the castle',
with a shift (key) of 1.

plaintext: defend the east wall of the castle

ciphertext: efgfoe uif fbtu xbmm pg uif dbtumf

8|P a ge
Code:
#include<iostream>
using namespace std;

int main()
{
char message[100], ch;
int i, key;
char cha = 'y';

do{
cout << "Enter a message to encrypt: ";
cin.ignore();
gets(message);
cout << "Enter key: ";

cin >> key;


for(i = 0; message[i] != '\0'; ++i){
ch = message[i];

if(ch >= 'a' && ch <= 'z'){

ch = ch + key;

if(ch > 'z'){


ch = ch - 'z' + 'a' - 1;
}

message[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch + key;

9|P a ge
if(ch > 'Z'){
ch = ch - 'Z' + 'A' - 1;
}

message[i] = ch;
}
}

cout << "Encrypted message: " << message<<endl;

for(i = 0; message[i] != '\0'; ++i){


ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){

ch = ch + 'z' - 'a' + 1;
}
message[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){

ch = ch - key;
if(ch > 'a'){
ch = ch + 'Z' - 'A' + 1;
}
message[i] = ch;

}
}
cout << "Decrypted message: " << message<<endl;
cout<<"Do you want to continue (y/n)?"<<endl;
cin>>cha;

10 | P a g e
}while(cha=='y'||cha=='Y');
return 0;
}

Output:

11 | P a g e
08 September 2020

EXPERIMENT-3

AIM : Write a program to perform encryption and decryption using PlayFair


Cypher Technique.

Theory:

The Playfair cipher was the first practical digraph substitution cipher. The
scheme was invented in 1854 by Charles Wheatstone, but was named after Lord
Playfair who promoted the use of the cipher. The technique encrypts pairs of
letters (digraphs), instead of single letters as in the simple substitution cipher.
The Playfair is significantly harder to break since the frequency analysis used for
simple substitution ciphers does not work with it. Frequency analysis can still be
undertaken, but on the 25*25=625 possible digraphs rather than the 25 possible
monographs. Frequency analysis thus requires much more ciphertext in order
to work.

The playfair cipher is more complicated than a substitution cipher, but still easy
to crack using automated approaches. It is known as a digraph substitution
cipher because pairs of letters are replaced by other pairs of letters. This
obliterates any single letter frequency statistics, but the digraph statistics
remain unchanged (frequencies of letter pairs). Unfortunately, letter pairs have
a much 'flatter' distribution than the single letter frequencies, so this
complicates matters for solving the cipher using pen and paper methods.

12 | P a g e
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE 30
// Function to convert the string to lowercase
void toLowerCase(char plain[], int ps)
{
int i;
for (i = 0; i < ps; i++) {
if (plain[i] > 64 && plain[i] < 91)
plain[i] += 32;
}
}

// Function to remove all spaces in a string


int removeSpaces(char* plain, int ps)
{
int i, count = 0;
for (i = 0; i < ps; i++)
if (plain[i] != ' ')
plain[count++] = plain[i];
plain[count] = '\0';
return count;
}

// Function to generate the 5x5 key square


void generateKeyTable(char key[], int ks, char keyT[5][5])

13 | P a g e
{
int i, j, k, flag = 0, *dicty;
// a 26 character hashmap
// to store count of the alphabet
dicty = (int*)calloc(26, sizeof(int));
for (i = 0; i < ks; i++) {
if (key[i] != 'j')
dicty[key[i] - 97] = 2;
}
dicty['j' - 97] = 1;

i = 0;
j = 0;

for (k = 0; k < ks; k++) {


if (dicty[key[k] - 97] == 2) {
dicty[key[k] - 97] -= 1;
keyT[i][j] = key[k];
j++;
if (j == 5) {
i++;
j = 0;
}
}
}

for (k = 0; k < 26; k++) {


if (dicty[k] == 0) {
keyT[i][j] = (char)(k + 97);
j++;
if (j == 5) {

14 | P a g e
i++;
j = 0;
}
}
}
}

// Function to search for the characters of a digraph


// in the key square and return their position
void search(char keyT[5][5], char a, char b, int arr[])
{
int i, j;

if (a == 'j')
a = 'i';
else if (b == 'j')
b = 'i';

for (i = 0; i < 5; i++) {

for (j = 0; j < 5; j++) {

if (keyT[i][j] == a) {
arr[0] = i;
arr[1] = j;
}
else if (keyT[i][j] == b) {
arr[2] = i;
arr[3] = j;
}
}

15 | P a g e
}
}

// Function to find the modulus with 5


int mod5(int a)
{
return (a % 5);
}

// Function to make the plain text length to be even


int prepare(char str[], int ptrs)
{
if (ptrs % 2 != 0) {
str[ptrs++] = 'z';
str[ptrs] = '\0';
}
return ptrs;
}

// Function for performing the encryption


void encrypt(char str[], char keyT[5][5], int ps)
{
int i, a[4];

for (i = 0; i < ps; i += 2) {

search(keyT, str[i], str[i + 1], a);

if (a[0] == a[2]) {
str[i] = keyT[a[0]][mod5(a[1] + 1)];
str[i + 1] = keyT[a[0]][mod5(a[3] + 1)];

16 | P a g e
}
else if (a[1] == a[3]) {
str[i] = keyT[mod5(a[0] + 1)][a[1]];
str[i + 1] = keyT[mod5(a[2] + 1)][a[1]];
}
else {
str[i] = keyT[a[0]][a[3]];
str[i + 1] = keyT[a[2]][a[1]];
}
}
}

// Function to encrypt using Playfair Cipher


void encryptByPlayfairCipher(char str[], char key[])
{
char ps, ks, keyT[5][5];

// Key
ks = strlen(key);
ks = removeSpaces(key, ks);
toLowerCase(key, ks);

// Plaintext
ps = strlen(str);
toLowerCase(str, ps);
ps = removeSpaces(str, ps);

ps = prepare(str, ps);

generateKeyTable(key, ks, keyT);

17 | P a g e
encrypt(str, keyT, ps);
}
void decrypt(char str[], char keyT[5][5], int ps)
{
int i, a[4];
for (i = 0; i < ps; i += 2) {
search(keyT, str[i], str[i + 1], a);
if (a[0] == a[2]) {
str[i] = keyT[a[0]][mod5(a[1] - 1)];
str[i + 1] = keyT[a[0]][mod5(a[3] - 1)];
}
else if (a[1] == a[3]) {
str[i] = keyT[mod5(a[0] - 1)][a[1]];
str[i + 1] = keyT[mod5(a[2] - 1)][a[1]];
}
else {
str[i] = keyT[a[0]][a[3]];
str[i + 1] = keyT[a[2]][a[1]];
}
}
}

// Function to call decrypt


void decryptByPlayfairCipher(char str[], char key[])
{
char ps, ks, keyT[5][5];

// Key
ks = strlen(key);
ks = removeSpaces(key, ks);
toLowerCase(key, ks);

18 | P a g e
// ciphertext
ps = strlen(str);
toLowerCase(str, ps);
ps = removeSpaces(str, ps);

generateKeyTable(key, ks, keyT);

decrypt(str, keyT, ps);


}
// Driver code
int main()
{
char str[SIZE], key[SIZE];
char choice;
int num;
// Key to be encrypted
strcpy(key, "information");
printf("Key text: %s\n", key);

do{
printf("\n1. Do you want to encrypt?\n");
printf("2. Do you want to decrypt?\n");
printf("\nEnter your choice: ");
scanf("%d",&num);

if(num==1){

printf("Enter the plain text: ");


scanf("%s",str);
printf("Plain text: %s\n", str);

19 | P a g e
encryptByPlayfairCipher(str, key);
printf("Cipher text: %s\n", str);
}

if(num==2){
printf("Enter the cipher text: ");
scanf("%s",str);
decryptByPlayfairCipher(str, key);
printf("Deciphered text: %s\n", str);
}

printf("\nDo you want to continue(y/n): ");


scanf("%s",&choice);
}while(choice=='y');

return 0;
}

OUTPUT:

20 | P a g e
15 September 2020

EXPERIMENT-4

AIM : Write a menu driven program to perform Encryption & Decryption using
Hill Cipher Technique.

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.

The matrix used for encryption is the cipher key, and it should be chosen
randomly from the set of invertible n × n matrices (modulo 26).

Example:
Input : Plaintext: ACT
Key: GYBNQKURP
Output: Ciphertext: POH

21 | P a g e
Code:

#include<iostream>
#include<math.h>

using namespace std;

float encrypt[4][1], decrypt[4][1], a[4][4], b[4][4], mes[4][1], c[4][4];

void encryption(); //encrypts the message


void decryption(); //decrypts the message

void getKeyMessage(); //gets key and message from user


void inverse(); //finds inverse of key matrix

int main() {
getKeyMessage();

encryption();
decryption();
}

void encryption() {

int i, j, k;

for(i = 0; i < 4; i++)


for(j = 0; j < 1; j++)

for(k = 0; k < 4; k++)


encrypt[i][j] = encrypt[i][j] + a[i][k] * mes[k][j];

cout<<"\nEncrypted string is: ";

22 | P a g e
for(i = 0; i < 4; i++)
cout<<(char)(fmod(encrypt[i][0], 26) + 97);
}

void decryption() {
int i, j, k;

inverse();

for(i = 0; i < 4; i++)


for(j = 0; j < 1; j++)
for(k = 0; k < 4; k++)

decrypt[i][j] = decrypt[i][j] + b[i][k] * encrypt[k][j];

cout<<"\nDecrypted string is: ";


for(i = 0; i < 4; i++)
cout<<(char)(fmod(decrypt[i][0], 26) + 97);

cout<<"\n";
}

void getKeyMessage() {

int i, j;
char msg[4];

cout<<"Enter 4x4 matrix for key (It should be inversible):\n";

for(i = 0; i < 4; i++)

23 | P a g e
for(j = 0; j < 4; j++) {
cin>>a[i][j];
c[i][j] = a[i][j];

cout<<"\nEnter a 4 letter string: ";


cin>>msg;

for(i = 0; i < 4; i++)


mes[i][0] = msg[i] - 97;
}

void inverse() {

int i, j, k;
float p, q;

for(i = 0; i < 4; i++)


for(j = 0; j < 4; j++) {

if(i == j)
b[i][j]=1;
else
b[i][j]=0;
}

for(k = 0; k < 4; k++) {


for(i = 0; i < 4; i++) {
p = c[i][k];
q = c[k][k];

24 | P a g e
for(j = 0; j < 4; 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 < 4; i++)


for(j = 0; j < 4; j++)
b[i][j] = b[i][j] / c[i][i];

cout<<"\n\nInverse Matrix is:\n";


for(i = 0; i < 4; i++) {
for(j = 0; j < 4; j++)
cout<<b[i][j]<<" ";

cout<<"\n";
}
}

25 | P a g e
OUTPUT:

26 | P a g e
22 September 2020

EXPERIMENT-5

AIM : Write a menu driven program to perform Encryption & Decryption using
Vigenere Cipher Technique.

Theory:
Vigenere Cipher is a kind of polyalphabetic substitution method of encrypting
alphabetic text.

Vigenere Cipher Table is used in which alphabets from A to Z are written in 26


rows, for encryption and decryption in this method.

Encryption

Key: INFORMATION

Message: DIVY

Here we have to obtain a key by repeating the given key till its length becomes
equal to original message length.

For encryption take first letter of message and key i.e. D and I. Take the
alphabet in Vigenere Cipher Table where D row and I column coincides i.e. L.

Repeat the same process for all remaining alphabets in message text.

Finally, the encrypted message text is:

Encrypted Message: LVAM

27 | P a g e
The cipher text can be generated by below equation.

Ei = (Pi + Ki) mod 26

Here P is plain text and K is key.

Decryption

Key: INFORMATION

Encrypted Message: LVAM

Take generated key and first alphabet of encrypted message i.e. I and L.
Analyze Vigenere Cipher Table, look for alphabet I in column L, the
corresponding row will be the first alphabet of original message i.e. D.

Repeat this process for all the alphabets in encrypted message.

Original Message: DIVY

This can be represented in algebraic form by following equation.

Pi = (Ei – Ki + 26) mod 26

28 | P a g e
Code:

#include <iostream>
#include <string>
using namespace std;
class Vig {

public:
string k;
Vig(string k) {
for (int i = 0; i < k.size(); ++i) {
if (k[i] >= 'A' && k[i] <= 'Z')

this->k += k[i];
else if (k[i] >= 'a' && k[i] <= 'z')
this->k += k[i] + 'A' - 'a';
}
}

string encryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')

c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c + k[j] - 2 * 'A') % 26 + 'A'; //added 'A' to bring it in range of ASCII alphabet [
65-90 | A-Z ]
j = (j + 1) % k.length();

}
return output;

29 | P a g e
}
string decryption(string t) {
string output;

for (int i = 0, j = 0; i < t.length(); ++i) {


char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')

continue;
output += (c - k[j] + 26) % 26 + 'A';//added 'A' to bring it in range of ASCII alphabet [ 65-
90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}

};
int main() {
Vig v("INFORMATION");
string ori;
char ch;

int ans;
do {
cout<<"\nDo you want to perform Encryption or Decryption?";
cout<<"\nCHOOSE 1 for ENCRYPTION 2 for DECRYPTION: ";
cin>>ans;

if(ans==1){

cout<<"\nEnter the message you want to encrypt : ";


cin>>ori;

30 | P a g e
string encrypt = v.encryption(ori);
cout << "\nOriginal Message: "<<ori<< endl;
cout << "Encrypted Message: " << encrypt << endl;

}
else{
cout<<"\nEnter the message you want to decrypt : ";
cin>>ori;
string decrypt = v.decryption(ori);

cout << "\nEncrypted Message: " << ori << endl;


cout << "Decrypted Message: " << decrypt << endl;
}

cout<<"\n Do you want to continue(y/n): ";

cin>>ch;

}while(ch=='y');
}

31 | P a g e
OUTPUT:

32 | P a g e
29 September 2020

EXPERIMENT-6

AIM : Write a menu driven program to perform Encryption & Decryption using
One time Pad cipher Technique.

Theory:

In cryptography, the one-time pad (OTP) is an encryption technique that


cannot be cracked if used correctly.

In this technique, a plaintext is paired with a random secret key (also referred
to as a one-time pad). Then, each bit or character of the plaintext is encrypted
by combining it with the corresponding bit or character from the pad
using modular addition. If the key is truly random, is at least as long as the
plaintext, is never reused in whole or in part, and is kept completely secret,
then the resulting ciphertext will be impossible to decrypt or break.

A one-time pad must be truly random data and must be kept secure in order
to be unbreakable. Consider if the one-time pad is used to encode the word
"otter." If an attacker tries to brute force "guess" the contents of the pad, the
message will "decrypt" into every possible combination of 6 characters (e.g.:
"lemur." "badger" etc.) Since the pad is truly random there are no statistical
methods that the attacker can hope to use to infer which combination is
correct.

33 | P a g e
Code:
#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;

void to_upper_case(vector<char>& text, int len)


{
for (int i = 0; i < len; i++)
{
if (text[i] >= 97 && text[i] <= 122)
text[i] -= 32;
}
}
void print_string(vector<char> text, int len)
{
for (int i = 0; i < len; i++)
{
cout << (char) (text[i] + 65);
}
cout << endl;
return;
}
size_t get_input(vector<char>& msg)
{
char a;
while (1)
{
a = getchar();
if (a == '\n')
break;
34 | P a g e
msg.push_back(a);
}
return msg.size();
}

int main()
{
vector<char> msg;
vector<char> enc_msg;
vector<char> dec_msg;
int *p;
int i;
size_t len;
char ch = 'y';
int ans;

do{

cout<<"\nDo you want to perform Encryption or Decryption?";


cout<<"\n\nCHOOSE 1 for ENCRYPTION 2 for DECRYPTION: ";
cin>>ans;
fflush(stdin);

if(ans==1){

cout << "Enter Message to Encrypt: ";


len = get_input(msg);
to_upper_case(msg, len);
p = (int*) malloc(msg.size() * sizeof(int));
for (i = 0; i < len; i++)
{

35 | P a g e
p[i] = rand() % 26;
if (msg[i] >= 65 && msg[i] <= 90)
enc_msg.push_back((char) ((msg[i] - 65 + p[i]) % 26));
else if (msg[i] >= 97 && msg[i] <= 122)
enc_msg.push_back((char) ((msg[i] - 97 + p[i]) % 26));
else
enc_msg.push_back((char) msg[i]);
}
cout << "\nEncoded Message: ";
print_string(enc_msg, len);

}
else{

cout << "\nKey for decryption:\n";


for (i = 0; i < len; i++)
{
cout << (char) (p[i] + 65);
}
cout << endl;

cout << "\nDecrypted Message: ";


for (i = 0; i < len; i++)
{
if ((enc_msg[i] - p[i]) < 0)
dec_msg.push_back((char) (enc_msg[i] - p[i] + 26));
else if ((enc_msg[i] - p[i]) >= 0)
dec_msg.push_back((char) (enc_msg[i] - p[i]));
else
dec_msg.push_back((char) enc_msg[i]);
}

36 | P a g e
print_string(dec_msg, len);

}
cout<<"\n Do you want to continue(y/n): ";
cin>>ch;
}while(ch=='y');

return 0;
}

OUTPUT:

37 | P a g e
06 October 2020

EXPERIMENT-7

AIM : Write a menu driven program to perform Encryption & Decryption using
Rail Fence cipher Technique.

Theory:

The rail fence cipher (also called a zigzag cipher) is a form of transposition
cipher. It derives its name from the way in which it is encoded. In the rail fence
cipher, the plain text is written downwards and diagonally on successive
“rails” of an imaginary fence, then moving up when the bottom rail is reached.
When the top rail is reached, the message is written downwards again until
the whole plaintext is written out. The message is then read off in rows.

For example, if 3 “rails” and the message “HELLOWORLD” is used, the cipher
writes out:

H...O...L.

.E.L.W.R.D

..L...O...

Then reads off to get the ciphertext:

HOLELWRDLO

38 | P a g e
Code:
// C++ program to illustrate Rail Fence Cipher
// Encryption and Decryption

#include <bits/stdc++.h>
using namespace std;

string encryptRailFence(string text, int key)


{
// create the matrix to cipher plain text
// key = rows , length(text) = columns
char rail[key][(text.length())];

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


for (int j = 0; j < text.length(); j++)
rail[i][j] = '\n';

bool dir_down = false;


int row = 0, col = 0;

for (int i=0; i < text.length(); i++)


{
if (row == 0 || row == key-1)
dir_down = !dir_down;

rail[row][col++] = text[i];

dir_down?row++ : row--;
}

//now we can construct the cipher using the rail matrix


string result;

39 | P a g e
for (int i=0; i < key; i++)
for (int j=0; j < text.length(); j++)
if (rail[i][j]!='\n')
result.push_back(rail[i][j]);

return result;
}

string decryptRailFence(string cipher, int key)


{
// create the matrix to cipher plain text
// key = rows , length(text) = columns
char rail[key][cipher.length()];

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


for (int j=0; j < cipher.length(); j++)
rail[i][j] = '\n';

bool dir_down;
int row = 0, col = 0;

// mark the places with '*'


for (int i=0; i < cipher.length(); i++)
{
// check the direction of flow
if (row == 0)
dir_down = true;
if (row == key-1)
dir_down = false;
rail[row][col++] = '*';
dir_down?row++ : row--;
}

40 | P a g e
// now we can construct the fill the rail matrix
int index = 0;
for (int i=0; i<key; i++)
for (int j=0; j<cipher.length(); j++)
if (rail[i][j] == '*' && index<cipher.length())
rail[i][j] = cipher[index++];

string result;
row = 0, col = 0;
for (int i=0; i< cipher.length(); i++)
{
// check the direction of flow
if (row == 0)
dir_down = true;
if (row == key-1)
dir_down = false;

// place the marker


if (rail[row][col] != '*')
result.push_back(rail[row][col++]);

// find the next row using direction flag


dir_down?row++: row--;
}
return result;
}
int main()
{
char ch = 'y';
int ans = 1;
string orignal_message;

41 | P a g e
string encrypted;

do{
cout<<"\nDo you want to perform Encryption or Decryption?";
cout<<"\n\nCHOOSE 1 for ENCRYPTION 2 for DECRYPTION: ";
cin>>ans;
fflush(stdin);

if(ans==1){

cout << "Enter Message to Encrypt: ";


cin>>orignal_message;
cout << "The Encrypted text is: "<<encryptRailFence(orignal_message,
3) << endl;
}

if(ans==2){

cout << "Enter Message to Decrypt: ";


cin>>encrypted;
cout << "The Encrypted text is: "<<decryptRailFence(encrypted,3) <<
endl;

cout<<"\n Do you want to continue(y/n): ";


cin>>ch;

}while(ch=='y');
return 0;
}

42 | P a g e
OUTPUT:

43 | P a g e
20 October 2020

EXPERIMENT-8

AIM: Write a program to implement Diffie Hellman Key Exchange Algorithm.

Theory:
Diffie Hellman (DH) key exchange algorithm is a method for securely exchanging
cryptographic keys over a public communications channel. Keys are not actually
exchanged – they are jointly derived. It is named after their inventors Whitfield
Diffie and Martin Hellman.

If Alice and Bob wish to communicate with each other, they first agree between
them a large prime number p, and a generator (or base) g (where 0 < g < p).

Alice chooses a secret integer a (her private key) and then calculates g^a mod p
(which is her public key). Bob chooses his private key b, and calculates his public
key in the same way.

Bob knows b and g^a, so he can calculate (g^a)^b mod p = g^ab mod p.
Therefore both Alice and Bob know a shared secret g^ab mod p. An
eavesdropper Eve who was listening in on the communication knows p, g, Alice’s
public key (g^a mod p) and Bob’s public key (g^b mod p). She is unable to
calculate the shared secret from these values.

In static-static mode, both Alice and Bob retain their private/public keys over
multiple communications. Therefore, the resulting shared secret will be the
same every time. In ephemeral-static mode one party will generate a new
private/public key every time, thus a new shared secret will be generated.

44 | P a g e
CODE:
#include<iostream>
#include<cstdio>

using namespace std;

class DiffieHellman
{

public:
long long int p,g,x,a,y,b,A,B;
DiffieHellman(long long int p1,long long int g1,long long int x1,long long int y1)
{
p = p1;

g = g1;
x = x1;
y = y1;
a=power(g,x,p);
b=power(g,y,p);

A = power(b,x,p);
B = power(a,y,p);
}
long long int power(int a,int b,int mod)
{

long long int t;


if(b==1)
return a;
t=power(a,b/2,mod);
if(b%2==0)
return (t*t)%mod;

45 | P a g e
else
return (((t*t)%mod)*a)%mod;
}

};

int main()
{
long long int p,g,x,a,y,b,A,B;

cout<<"Enter the values of p and g upon which Alice And Bob both will aggree :
"<<endl;
cin>>p>>g;

cout<<"Enter the Secret Integer for Alice : ";


cin>>x;

cout<<"Enter the Secret Integer for Bob : ";


cin>>y;
cout<<endl;
DiffieHellman dh(p,g,x,y);

cout<<"Alice's private key, known only to Alice : "<<dh.a<<endl;


cout<<"Bob's private key known only to Bob : "<<dh.b<<endl;
cout<<endl;
cout<<"Alice's public key, known to Alice and Bob : "<<dh.A<<endl;
cout<<"Bob's public key, known to Alice and Bob : "<<dh.B<<endl;

return 0;
}

46 | P a g e
OUTPUT :

47 | P a g e
27 October 2020

EXPERIMENT-9

AIM: Write a program to implement RSA algorithm.

Theory:

The RSA algorithm is an asymmetric cryptography algorithm; this means that it


uses a public key and a private key (i.e two different, mathematically linked
keys). As their names suggest, a public key is shared publicly, while a private key
is secret and must not be shared with anyone.

The RSA algorithm is named after those who invented it in 1978: Ron Rivest, Adi
Shamir, and Leonard Adleman.

The RSA algorithm ensures that the keys, in the above illustration, are as secure
as possible. The following steps highlight how it works:

Generating the keys

1. Select two large prime numbers, xx and yy. The prime numbers need to
be large so that they will be difficult for someone to figure out.

2. Calculate n = x * yn=x∗y.

3. Calculate the totient function; \phi(n) = (x-1)(y-1)ϕ(n)=(x−1)(y−1).

4. Select an integer ee, such that ee is co-prime to \phi(n)ϕ(n) and 1 < e <
<e<ϕ(n). The pair of numbers (n,e)(n,e) makes up the public key.

Note: Two integers are co-prime if the only positive integer that divides them is
1.

48 | P a g e
Code:
#include<iostream>
#include<math.h>

#include<string.h>
#include<stdlib.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[100];
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 << "\nENTER FIRST PRIME NUMBER\n";

49 | P a g e
cin >> p;
flag = prime(p);
if (flag == 0)

{
cout << "\nWRONG INPUT\n";
exit(1);
}
cout << "\nENTER ANOTHER PRIME NUMBER\n";

cin >> q;
flag = prime(q);
if (flag == 0 || p == q)
{
cout << "\nWRONG INPUT\n";

exit(1);
}
cout << "\nENTER MESSAGE\n";
fflush(stdin);
cin >> msg;

for (i = 0; msg[i] != '\0'; i++)


m[i] = msg[i];
n = p * q;
t = (p - 1) * (q - 1);
ce();

cout << "\nPOSSIBLE VALUES OF e AND d ARE\n";


for (i = 0; i < j - 1; i++)
cout << e[i] << "\t" << d[i] << "\n";
encrypt();
decrypt();
return 0;

50 | P a g e
}
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)
{

51 | P a g e
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 << "\nTHE ENCRYPTED MESSAGE IS\n";
for (i = 0; en[i] != -1; i++)
printf("%c", en[i]);

52 | P a g e
}
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\n";
for (i = 0; m[i] != -1; i++)
printf("%c", m[i]);
}

53 | P a g e
OUTPUT:

54 | P a g e
3 November 2020

EXPERIMENT-10

AIM: Write a program to implement DES.

Theory:

Data Encryption Standard (DES) is a block cipher algorithm that takes plain text
in blocks of 64 bits and converts them to ciphertext using keys of 48 bits. It is a
symmetric key algorithm, which means that the same key is used for encrypting
and decrypting data.

Steps for generating keys

There are 16 rounds of encryption in the algorithm, and a different key is used
for each round. How keys are generated is listed below.

1. Compress and transpose the given 64-bit key into a 48-bit key using the
following table:

2. Divide the result into two equal parts: C and D.

3. C and D are left-shifted circularly. For encryption rounds 1, 2, 9, and 16


they are left shifted circularly by 1 bit; for all of the other rounds, they are
left-circularly shifted by 2.

4. The result is compressed to 48 bits in accordance with the following rule:

5. The result of step 3 is the input for the next round of key generation.

Steps for encryption

1. Transpose the bits in the 64-block according to the following:

2. Divide the result into equal parts: left plain text (1-32 bits) and right plain
text (33-64 bits)

3. The resulting parts undergo 16 rounds of encryption in each round.

The right plain text is expanded using the following expansion table:

55 | P a g e
4. The expanded right plain text now consists of 48 bits and is XORed with
the 48-bit key.

5. The result of the previous step is divided into 8 boxes. Each box contains
6 bits. After going through the eight substitution boxes, each box is
reduced from 8 bits to 6 bits. The first and last bit of each box provides
the row index, and the remaining bits provide the column index. These
indices are used to look-up values in a substitution box. A substitution box
has 4 rows, 16 columns, and contains numbers from 0 to 15.

6. The result is transposed in accordance with the following rule:

7. XOR the left half with the result from the above step. Store this in the right
plain text.

8. Store the initial right plain text in the left plain text.

9. These halves are inputs for the next round. Remember that there are
different keys for each round.

10. After the 16 rounds of encryption, swap the left plain text and the right
plain text.

11. Finally, apply the inverse permutation (inverse of the initial permutation),
and the ciphertext will be generated.

Steps for decryption

The order of the 16 48-bit keys is reversed such that key 16 becomes key 1, and
so on. Then, the steps for encryption are applied to the ciphertext.

56 | P a g e
CODE:
// Including dependancies
#include <iostream>

#include <string>
#include <cmath>
using namespace std;
// Array to hold 16 keys
string round_keys[16];

// String to hold the plain text


string pt;
// Function to convert a number in decimal to binary
string convertDecimalToBinary(int decimal)
{

string binary;
while(decimal != 0) {
binary = (decimal % 2 == 0 ? "0" : "1") + binary;
decimal = decimal/2;
}

while(binary.length() < 4){


binary = "0" + binary;
}
return binary;
}

// Function to convert a number in binary to decimal


int convertBinaryToDecimal(string binary)
{
int decimal = 0;
int counter = 0;
int size = binary.length();

57 | P a g e
for(int i = size-1; i >= 0; i--)
{
if(binary[i] == '1'){

decimal += pow(2, counter);


}
counter++;
}
return decimal;

}
// Function to do a circular left shift by 1
string shift_left_once(string key_chunk){
string shifted="";
for(int i = 1; i < 28; i++){

shifted += key_chunk[i];
}
shifted += key_chunk[0];
return shifted;
}

// Function to do a circular left shift by 2


string shift_left_twice(string key_chunk){
string shifted="";
for(int i = 0; i < 2; i++){
for(int j = 1; j < 28; j++){

shifted += key_chunk[j];
}
shifted += key_chunk[0];
key_chunk= shifted;
shifted ="";
}

58 | P a g e
return key_chunk;
}
// Function to compute xor between two strings

string Xor(string a, string b){


string result = "";
int size = b.size();
for(int i = 0; i < size; i++){
if(a[i] != b[i]){

result += "1";
}
else{
result += "0";
}

}
return result;
}
// Function to generate the 16 keys.
void generate_keys(string key){

// The PC1 table


int pc1[56] = {
57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,

19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4
};

59 | P a g e
// The PC2 table
int pc2[48] = {
14,17,11,24,1,5,

3,28,15,6,21,10,
23,19,12,4,26,8,
16,7,27,20,13,2,
41,52,31,37,47,55,
30,40,51,45,33,48,

44,49,39,56,34,53,
46,42,50,36,29,32
};
// 1. Compressing the key using the PC1 table
string perm_key ="";

for(int i = 0; i < 56; i++){


perm_key+= key[pc1[i]-1];
}
// 2. Dividing the key into two equal halves
string left= perm_key.substr(0, 28);

string right= perm_key.substr(28, 28);


for(int i=0; i<16; i++){
// 3.1. For rounds 1, 2, 9, 16 the key_chunks
// are shifted by one.
if(i == 0 || i == 1 || i==8 || i==15 ){

left= shift_left_once(left);
right= shift_left_once(right);
}
// 3.2. For other rounds, the key_chunks
// are shifted by two
else{

60 | P a g e
left= shift_left_twice(left);
right= shift_left_twice(right);
}

// Combining the two chunks


string combined_key = left + right;
string round_key = "";
// Finally, using the PC2 table to transpose the key bits
for(int i = 0; i < 48; i++){

round_key += combined_key[pc2[i]-1];
}
round_keys[i] = round_key;
}

}
// Implementing the algorithm
string DES(){
// The initial permutation table
int initial_permutation[64] = {

58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,

59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7
};
// The expansion table
int expansion_table[48] = {

61 | P a g e
32,1,2,3,4,5,4,5,
6,7,8,9,8,9,10,11,
12,13,12,13,14,15,16,17,

16,17,18,19,20,21,20,21,
22,23,24,25,24,25,26,27,
28,29,28,29,30,31,32,1
};
// The substitution boxes. The should contain values

// from 0 to 15 in any order.


int substition_boxes[8][4][16]=
{{
14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,

4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13
},
{
15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,

3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9
},
{

10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12
},
{

62 | P a g e
7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,

3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14
},
{
2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,

4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3
},
{
12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,

10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13
},
{

4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12
},

{
13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
}};

63 | P a g e
// The permutation table
int permutation_tab[32] = {
16,7,20,21,29,12,28,17,

1,15,23,26,5,18,31,10,
2,8,24,14,32,27,3,9,
19,13,30,6,22,11,4,25
};
// The inverse permutation table

int inverse_permutation[64]= {
40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,

36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41,9,49,17,57,25
};

//1. Applying the initial permutation


string perm = "";
for(int i = 0; i < 64; i++){
perm += pt[initial_permutation[i]-1];
}

// 2. Dividing the result into two equal halves


string left = perm.substr(0, 32);
string right = perm.substr(32, 32);
// The plain text is encrypted 16 times
for(int i=0; i<16; i++) {
string right_expanded = "";

64 | P a g e
// 3.1. The right half of the plain text is expanded
for(int i = 0; i < 48; i++) {
right_expanded += right[expansion_table[i]-1];

}; // 3.3. The result is xored with a key


string xored = Xor(round_keys[i], right_expanded);
string res = "";
// 3.4. The result is divided into 8 equal parts and passed
// through 8 substitution boxes. After passing through a

// substituion box, each box is reduces from 6 to 4 bits.


for(int i=0;i<8; i++){
// Finding row and column indices to lookup the
// substituition box
string row1= xored.substr(i*6,1) + xored.substr(i*6 + 5,1);

int row = convertBinaryToDecimal(row1);


string col1 = xored.substr(i*6 + 1,1) + xored.substr(i*6 + 2,1) + xored.substr(i*6
+ 3,1) + xored.substr(i*6 + 4,1);;
int col = convertBinaryToDecimal(col1);
int val = substition_boxes[i][row][col];
res += convertDecimalToBinary(val);
}

// 3.5. Another permutation is applied


string perm2 ="";
for(int i = 0; i < 32; i++){
perm2 += res[permutation_tab[i]-1];
}

// 3.6. The result is xored with the left half


xored = Xor(perm2, left);
// 3.7. The left and the right parts of the plain text are swapped
left = xored;
if(i < 15){

65 | P a g e
string temp = right;
right = xored;
left = temp;

}
}
// 4. The halves of the plain text are applied
string combined_text = left + right;
string ciphertext ="";

// The inverse of the initial permuttaion is applied


for(int i = 0; i < 64; i++){
ciphertext+= combined_text[inverse_permutation[i]-1];
}
//And we finally get the cipher text

return ciphertext;
}
int main(){
// A 64 bit key
string key=
"1010101010111011000010010001100000100111001101101100110011011101";
// A block of plain text of 64 bits

pt=
"1010101111001101111001101010101111001101000100110010010100110110";
string apt = pt;
// Calling the function to generate 16 keys
generate_keys(key);
cout<<"Plain text: "<<pt<<endl;

// Applying the algo


string ct= DES();
cout<<"Ciphertext: "<<ct<<endl;
// Reversing the round_keys array for decryption

66 | P a g e
int i = 15;
int j = 0;
while(i > j)

{
string temp = round_keys[i];
round_keys[i] = round_keys[j];
round_keys[j] = temp;
i--;

j++;
}
pt = ct;
string decrypted = DES();
cout<<"Decrypted text:"<<decrypted<<endl;

// Comapring the initial plain text with the decrypted text


if (decrypted == apt){
cout<<"Plain text encrypted and decrypted successfully."<<endl;
}
}

OUTPUT:

67 | P a g e
10 November 2020

EXPERIMENT-11

AIM: Write a program to implement SHA.

Theory:
SHA algorithm is Secure Hash algorithm developed by National Institute of
Standards and Technology along with NSA, previously released as a Federal
Information Processing Standard, later in 1995, it was named as SHA algorithm,
design to modify the MD4, in other words, we can say that the SHA algorithm is
the modified version of MD4. SHA is designed to obtain the original message,
given its message digest and to find the message producing the same message
digest.

What is SHA Algorithm?

In the field of cryptography and crypt analytics, the SHA-1 algorithm is a crypt-
formatted hash function that is used to take a smaller input and produces a
string which is 160 bits also known as 20-byte hash value long. The hash value
therefore generated is known as a message digest which is typically rendered
and produced as a hexadecimal number which is specifically 40 digits long. The
cryptographic hash functions are utilized and used in order to keep and store the
secured form of data by providing specifically three different kinds of
characteristics such as pre-image resistance which is also known as the first level
of image resistance, the second level of pre-image resistance and collision
resistance.

68 | P a g e
CODE:
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class GFG {


public static String encryptThisString(String input)
{
try {
// getInstance() method is called with algorithm SHA-1
MessageDigest md = MessageDigest.getInstance("SHA-1");

// digest() method is called


// to calculate message digest of the input string
// returned as array of byte
byte[] messageDigest = md.digest(input.getBytes());

// Convert byte array into signum representation


BigInteger no = new BigInteger(1, messageDigest);

// Convert message digest into hex value


String hashtext = no.toString(16);

// Add preceding 0s to make it 32 bit


while (hashtext.length() < 32) {
hashtext = "0" + hashtext;
}

// return the HashText


return hashtext;
}

// For specifying wrong message digest algorithms


catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}

// Driver code
public static void main(String args[]) throws

69 | P a g e
{

System.out.println("HashCode Generated by SHA-1 for: ");

String s1 = "GeeksForGeeks";
System.out.println("\n" + s1 + " : " + encryptThisString(s1));

String s2 = "hello world";


System.out.println("\n" + s2 + " : " + encryptThisString(s2));
}
}

OUTPUT:

70 | P a g e

You might also like