Download as pdf or txt
Download as pdf or txt
You are on page 1of 45

St.

Ann’s College Of Engineering &


Technology
Chirala – 523155

Cryptography and Network Security

Computer Science&
Engineering
EX. NO: 1
IMPLEMENTATION OF CAESAR CIPHER

AIM:

Implementation of Caesar Cipher Technique.

DESCRIPTION:

To encrypt a message with a Caesar cipher, each letter in the message is changed using
a simple rule: shift by three. Each letter is replaced by the letter three letters ahead in the
alphabet. A becomes D, B becomes E, and so on. For the last letters, we can think of the
alphabet as a circle and "wrap around". W becomes Z, X becomes A, Y becm
oes B, and Z
becomes C. To change a message back, each letter is replaced by the one three before it.

EXAMPLE:

ALGORITHM:

STEP-1: Read the plain text from the user.


STEP-2: Read the key value from the user.
STEP-3: If the key is positive then encrypt the text by adding the key with each
character in the plain text.
STEP-4: Else subtract the key from the plain text.
STEP-5: Display the cipher text obtained above.

PROGRAM: (Caesar Cipher)


#include <stdio.h>
#include <string.h>
#include<conio.h>
#include <ctype.h>
void main()
{
char plain[10], cipher[10];
int key,i,length;
int result;
clrscr();
printf("\n Enter the plain text:");
scanf("%s", plain);
printf("\n Enter the key value:");
scanf("%d", &key);
printf("\n \n \t PLAIN TEXt: %s",plain);
printf("\n \n \t ENCRYPTED TEXT: ");
for(i = 0, length = strlen(plain); i < length; i++)
{
cipher[i]=plain[i] + key;
if (isupper(plain[i]) && (cipher[i] > 'Z'))
cipher[i] = cipher[i] - 26;
if (islower(plain[i]) && (cipher[i] > 'z'))
cipher[i] = cipher[i] - 26;
printf("%c", cipher[i]);
}
printf("\n \n \t AFTER DECRYPTION : ");
for(i=0;i<length;i++)
{
plain[i]=cipher[i]-key;
if(isupper(cipher[i])&&(plain[i]<'A'))
plain[i]=plain[i]+26;
if(islower(cipher[i])&&(plain[i]<'a'))
plain[i]=plain[i]+26;
printf("%c",plain[i]);
}
getch();
}

6
OUTPUT:

RESULT:

Thus the implementation of Caesar cipher had been executed successfully.

7
EX. NO: 2

IMPLEMENTATION OF PLAYFAIR CIPHER


AIM:

Implement the Playfair Cipher

DESCRIPTION:

The Playfair cipher starts with creating a key table. The key table is a 5×5 grid of letters
that will act as the key for encrypting your plaintext. Each of the 25 letters must be uniqueand one
letter of the alphabet is omitted from the table (as there are 25 spots and 26 letters in thealphabet).

To encrypt a message, one would break the message into digrams (groups of 2 letters)
such that, for example, "HelloWorld" becomes "HE LL OW OR LD", and map them out on the
key table. The two letters of the diagram are considered as the opposite corners of a rectangle in
the key table. Note the relative position of the corners of this rectangle. Thenapply the following
4 rules, in order, to each pair of letters in the plaintext:

1. If both letters are the same (or only one letter is left), add an "X" after the first letter
2. If the letters appear on the same row of your table, replace them with the letters to their
immediate right respectively
3. If the letters appear on the same column of your table, replace them with the letters
immediately below respectively
4. If the letters are not on the same row or column, replace them with the letters on the same
row respectively but at the other pair of corners of the rectangle defined by the original
pair.

EXAMPLE:

8
ALGORITHM:

STEP-1: Read the plain text from the user.


STEP-2: Read the keyword from the user.
STEP-3: Arrange the keyword without duplicates in a 5*5 matrix in the row order and fill
the remaining cells with missed out letters in alphabetical order. Note that ‘i’ and
‘j’ takes the same cell.
STEP-4: Group theplain text in pairs and match the corresponding corner letters by forming
a rectangular grid.
STEP-5: Display the obtained cipher text.

PROGRAM: (Playfair Cipher)


#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#define MX 5
void playfair(char ch1,char ch2, char key[MX][MX])
{
int i,j,w,x,y,z;
FILE *out;
if((out=fopen("cipher.txt","a+"))==NULL)
{
printf("File Currupted.");
}
for(i=0;i<MX;i++)
{
for(j=0;j<MX;j++)
{
if(ch1==key[i][j])
{
w=i;
x=j;
}
else if(ch2==key[i][j])
{
y=i;
z=j;
}}}

//printf("%d%d %d%d",w,x,y,z);
if(w==y)
{
x=(x+1)%5;z=(z+1)%5;
printf("%c%c",key[w][x],key[y][z]);
fprintf(out, "%c%c",key[w][x],key[y][z]);
}
else if(x==z)
{
9
w=(w+1)%5;y=(y+1)%5;
printf("%c%c",key[w][x],key[y][z]);
fprintf(out, "%c%c",key[w][x],key[y][z]);
}
else
{
printf("%c%c",key[w][z],key[y][x]);
fprintf(out, "%c%c",key[w][z],key[y][x]);
}

fclose(out);
}
void main()
{
int i,j,k=0,l,m=0,n;
char key[MX][MX],keyminus[25],keystr[10],str[25]={0};
char
alpa[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'}
;
clrscr();
printf("\nEnter key:");
gets(keystr);
printf("\nEnter the plain text:");
gets(str);
n=strlen(keystr);
//convert the characters to uppertext
for (i=0; i<n; i++)
{
if(keystr[i]=='j')keystr[i]='i';
else if(keystr[i]=='J')keystr[i]='I';
keystr[i] = toupper(keystr[i]);
}
//convert all the characters of plaintext to uppertext
for (i=0; i<strlen(str); i++)
{
if(str[i]=='j')str[i]='i';
else if(str[i]=='J')str[i]='I';
str[i] = toupper(str[i]);
}
j=0;

for(i=0;i<26;i++)
{
for(k=0;k<n;k++)
{
if(keystr[k]==alpa[i])
break;
else if(alpa[i]=='J')
break;
}
if(k==n)
{
keyminus[j]=alpa[i];j++;
10
}
}

//construct key keymatrix


k=0;
for(i=0;i<MX;i++)
{
for(j=0;j<MX;j++)
{
if(k<n)
{
key[i][j]=keystr[k];
k++;}
else
{
key[i][j]=keyminus[m];m++;
}
printf("%c ",key[i][j]);
}
printf("\n");
}
printf("\n\nEntered text :%s\nCipher Text :",str);
for(i=0;i<strlen(str);i++)
{
if(str[i]=='J')str[i]='I';
if(str[i+1]=='\0')
playfair(str[i],'X',key);
else
{

if(str[i+1]=='J')str[i+1]='I';
if(str[i]==str[i+1])
playfair(str[i],'X',key); else
{
playfair(str[i],str[i+1],key);i++;
}}
}
getch();
}

11
OUTPUT:

RESULT:
Thus the Playfair cipher substitution technique had been implemented successfully.

13
EX. NO: 3

IMPLEMENTATION OF RAIL FENCE – ROW & COLUMN

TRANSFORMATION TECHNIQUE

AIM:

Implementation of Pure Transformation Cipher

DESCRIPTION:

In the rail fence cipher, the plain text is written downwards and diagonally on successive
"rails" of an imaginary fence, then moving up when we reach the bottom rail.When we reach
the top rail, the message is written downwards again until the whole plaintextis written out. The
message is then read off in rows.

EXAMPLE:

ALGORITHM:

STEP-1: Read the Plain text.


STEP-2: Arrange the plain text in row columnar matrix format.
STEP-3: Now read the keyword depending on the number of columns of the plain text.
STEP-4: Arrange the characters of the keyword in sorted order and the corresponding
columns of the plain text.
STEP-5: Read the characters row wise or column wise in the former order to get the
cipher text.
PROGRAM: (Rail Fence)

#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
int i,j,k,l;
char a[20],c[20],d[20];
clrscr();
printf("\n\t\t RAIL FENCE TECHNIQUE");
printf("\n\nEnter the input string : ");
gets(a);
l=strlen(a);

/*Ciphering*/
for(i=0,j=0;i<l;i++)
{
if(i%2==0)
c[j++]=a[i];
}
for(i=0;i<l;i++)
{
if(i%2==1)
c[j++]=a[i];
}
c[j]='\0';
printf("\nCipher text after applying rail fence :");
printf("\n%s",c);

/*Deciphering*/
if(l%2==0)
k=l/2;
else
k=(l/2)+1;
for(i=0,j=0;i<k;i++)
{
d[j]=c[i];
j=j+2;
}
for(i=k,j=1;i<l;i++)
{
d[j]=c[i];
j=j+2;
}
d[l]='\0';
printf("\nText after decryption : ");
printf("%s",d);
getch();
}
OUTPUT:

RESULT:

Thus the rail fence algorithm had been executed successfully.


EX. NO: 4 IMPLEMENTATION OF DES

AIM:

To write a C program to implement Data Encryption Standard (DES) using C


Language.

DESCRIPTION:

DES is a symmetric encryption system that uses 64-bit blocks, 8 bits of which areused
for parity checks. The key therefore has a "useful" length of 56 bits, which means thatonly
56 bits are actually used in the algorithm. The algorithm involves carrying out combinations,
substitutions and permutations between the text to be encrypted and the key, while making sure
the operations can be performed in both directions. The key is ciphered on64 bits and made of 16
blocks of 4 bits, generally denoted k1 to k16. Given that "only" 56 bits are actually used for
encrypting, there can be 256 different keys.

The main parts of the algorithm are as follows:


➢ Fractioning of the text into 64-bit blocks
➢ Initial permutation of blocks
➢ Breakdown of the blocks into two parts: left and right, named L and R
➢ Permutation and substitution steps repeated 16 times
➢ Re-joining of the left and right parts then inverse initial permutation

EXAMPLE:
ALGORITHM:

STEP-1: Read the 64-bit plain text.


STEP-2: Split it into two 32-bit blocks and store it in two different arrays.
STEP-3: Perform XOR operation between these two arrays.
STEP-4: The output obtained is stored as the second 32-bit sequence and the original
second 32-bit sequence forms the first part.
STEP-5: Thus the encrypted 64-bit cipher text is obtained in this way. Repeat the same
process for the remaining plain text characters.

PROGRAM:

// 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();
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 ="";
}
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
};
// 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{
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] = {
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
},
{
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
}};
// 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 = "";
// 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){
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
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:

RESULT:

Thus the data encryption standard algorithm had been implemented successfully
using C language.
EX. NO: 5

IMPLEMENTATION OF AES

AIM:

To write a C program to implement Advanced Encryption Standard (AES) using C


Language.

ALGORITHM:

1. AES is based on a design principle known as a substitution–permutation.

2.AES does not use a Feistel network like DES, it uses variant of Rijndael.

3. It has a fixed block size of128 bits, and a key size of 128, 192, or 256 bits.

4. AES operates on a 4 × 4 column-major order array of bytes, termed the state

PROGRAM:

#include <iostream>

#include <string>

#include <vector>

#include <bitset>

#include <algorithm>

class AES {

private:

static constexpr size_t Nb = 4;

static constexpr size_t Nk = 4;

static constexpr size_t Nr = 10;

using byte = unsigned char;

using word = std::bitset<8>;

static const byte Sbox[256];

static const byte invSbox[256];

static const byte Rcon[11];

public:
static std::string encrypt(std::string plaintext, std::string key) {

std::vector<byte> expandedKey = expandKey(key);

std::vector<byte> state(plaintext.begin(), plaintext.end());

addRoundKey(state, expandedKey, 0);

for (size_t round = 1; round <= Nr; ++round) {

subBytes(state);

shiftRows(state);

if (round < Nr) mixColumns(state);

addRoundKey(state, expandedKey, round);

return std::string(state.begin(), state.end());

static std::string decrypt(std::string ciphertext, std::string key)


{

std::vector<byte> expandedKey = expandKey(key);

std::vector<byte> state(ciphertext.begin(), ciphertext.end());

addRoundKey(state, expandedKey, Nr);

for (size_t round = Nr - 1; round > 0; --round) {

invShiftRows(state);

invSubBytes(state);

addRoundKey(state, expandedKey, round);

if (round > 1) invMixColumns(state);

return std::string(state.begin(), state.end());

private:

static std::vector<byte> expandKey(std::string key) {

std::vector<byte> expandedKey(key.begin(), key.end());


for (size_t i = Nk; i < Nb * (Nr + 1); ++i) {

byte temp[4];

std::copy(expandedKey.begin() + (i - 1) * 4,
expandedKey.begin() + i * 4, temp);

if (i % Nk == 0) {

std::rotate(std::begin(temp), std::begin(temp) + 1,
std::end(temp));

for (auto& byte : temp) byte = Sbox[byte];

temp[0] ^= Rcon[i / Nk];

} else if (Nk > 6 && i % Nk == 4) {

for (auto& byte : temp) byte = Sbox[byte];

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


expandedKey.push_back(expandedKey[(i - Nk) * 4 + j] ^ temp[j]);

return expandedKey;

static void subBytes(std::vector<byte>& state) {

for (auto& byte : state) byte = Sbox[byte];

static void shiftRows(std::vector<byte>& state) {

for (size_t i = 1; i < 4; ++i) std::rotate(state.begin() + i *


Nb, state.begin() + i * Nb + i, state.begin() + i * Nb + Nb);

static void mixColumns(std::vector<byte>& state) {

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

byte a[4], b[4], c, h;

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

a[j] = state[i + j * 4];

h = state[i + j * 4] & 0x80;

b[j] = state[i + j * 4] << 1;

if (h == 0x80) b[j] ^= 0x1b;


c ^= a[j];

state[i] = b[0] ^ c ^ a[1] ^ b[1] ^ a[2] ^ a[3];

state[i + 4] = a[0] ^ b[1] ^ c ^ a[2] ^ b[2] ^ a[3];

state[i + 8] = a[0] ^ a[1] ^ b[2] ^ c ^ a[3] ^ b[3];

state[i + 12] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3] ^ c;

static void addRoundKey(std::vector<byte>& state, const


std::vector<byte>& expandedKey, size_t round) {

for (size_t i = 0; i < 4 * Nb; ++i) state[i] ^=


expandedKey[round * 4 * Nb + i];

static void invSubBytes(std::vector<byte>& state) {

for (auto& byte : state) byte = invSbox[byte];

static void invShiftRows(std::vector<byte>& state) {

for (size_t i = 1; i < 4; ++i) std::rotate(state.begin() + i *


Nb, state.begin() + i * Nb + Nb - i, state.begin() + i * Nb + Nb);

static void invMixColumns(std::vector<byte>& state) {

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

byte a[4], b[4], c, h;

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

a[j] = state[i + j * 4];

h = state[i + j * 4] & 0x80;

b[j] = state[i + j * 4] << 1;

if (h == 0x80) b[j] ^= 0x1b;

c ^= a[j];

}
state[i] = b[0] ^ c ^ a[1] ^ b[1] ^ a[2] ^ a[3];

state[i + 4] = a[0] ^ b[1] ^ c ^ a[2] ^ b[2] ^ a[3];

state[i + 8] = a[0] ^ a[1] ^ b[2] ^ c ^ a[3] ^ b[3];

state[i + 12] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3] ^ c;

};

const AES::byte AES::Sbox[256] = {

// S-box

0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67,
0x2b, 0xfe, 0xd7, 0xab, 0x76,

0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2,
0xaf, 0x9c, 0xa4, 0x72, 0xc0,

0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5,
0xf1, 0x71, 0xd8, 0x31, 0x15,

0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80,
0xe2, 0xeb, 0x27, 0xb2, 0x75,

0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6,
0xb3, 0x29, 0xe3, 0x2f, 0x84,

0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe,
0x39, 0x4a, 0x4c, 0x58, 0xcf,

0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02,
0x7f, 0x50, 0x3c, 0x9f, 0xa8,

0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda,
0x21, 0x10, 0xff, 0xf3, 0xd2,

0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e,
0x3d, 0x64, 0x5d, 0x19, 0x73,

0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8,
0x14, 0xde, 0x5e, 0x0b, 0xdb,

0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac,
0x62, 0x91, 0x95, 0xe4, 0x79,

0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4,
0xea, 0x65, 0x7a, 0xae, 0x08,

0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74,
0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57,
0xb9, 0x86, 0xc1, 0x1d, 0x9e,

0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87,
0xe9, 0xce, 0x55, 0x28, 0xdf,

0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d,
0x0f, 0xb0, 0x54, 0xbb, 0x16

};

const AES::byte AES::invSbox[256] = {

// Inverse S-box

0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3,
0x9e, 0x81, 0xf3, 0xd7, 0xfb,

0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43,
0x44, 0xc4, 0xde, 0xe9, 0xcb,

0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95,
0x0b, 0x42, 0xfa, 0xc3, 0x4e,

0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2,
0x49, 0x6d, 0x8b, 0xd1, 0x25,

0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c,
0xcc, 0x5d, 0x65, 0xb6, 0x92,

0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46,
0x57, 0xa7, 0x8d, 0x9d, 0x84,

0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58,
0x05, 0xb8, 0xb3, 0x45, 0x06,

0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd,
0x03, 0x01, 0x13, 0x8a, 0x6b,

0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf,
0xce, 0xf0, 0xb4, 0xe6, 0x73,

0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37,
0xe8, 0x1c, 0x75, 0xdf, 0x6e,

0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62,
0x0e, 0xaa, 0x18, 0xbe, 0x1b,

0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0,
0xfe, 0x78, 0xcd, 0x5a, 0xf4,

0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10,
0x59, 0x27, 0x80, 0xec, 0x5f,

0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a,
0x9f, 0x93, 0xc9, 0x9c, 0xef,

0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb,
0x3c, 0x83, 0x53, 0x99, 0x61,

0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14,
0x63, 0x55, 0x21, 0x0c, 0x7d

};

const AES::byte AES::Rcon[11] = {

// Rcon

0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36

};

int main() {

std::string secretKey;

std::cout << "Enter the secret key: ";

std::cin >> secretKey;

std::string originalString;

std::cout << "Enter the original URL: ";

std::cin >> originalString;

std::string encryptedString = AES::encrypt(originalString,


secretKey);

std::string decryptedString = AES::decrypt(encryptedString,


secretKey);

std::cout << "URL Encryption Using AES Algorithm\n ----------" <<


std::endl;

std::cout << "Original URL : " << originalString << std::endl;

std::cout << "Encrypted URL : " << encryptedString << std::endl;

std::cout << "Decrypted URL : " << decryptedString << std::endl;

return 0;

}
OUTPUT:

RESULT:

Thus the advanced encryption standard algorithm had been implemented


successfully using C language
EX. NO: 6 IMPLEMENTATION OF RSA

AIM:

To write a C program to implement the RSA encryption algorithm.

DESCRIPTION:

RSA is an algorithm used by modern computers to encrypt and decrypt messages. It


is an asymmetric cryptographic algorithm. Asymmetric means that there are two different keys.
This is also called public key cryptography, because one of them can be given toeveryone. A
basic principle behind RSA is the observation that it is practical to find threevery large positive
integers e, d and n such that with modular exponentiation for all integer m:

(me)d = m (mod n)

The public key is represented by the integers n and e; and, the private key, by the integer
d. m represents the message. RSA involves a public key and a private key. The public key can be
known by everyone and is used for encrypting messages. The intention is that messages encrypted
with the public key can only be decrypted in a reasonable amount oftime using the private
key.

EXAMPLE:
ALGORITHM:

STEP-1: Select two co-prime numbers as p and q.


STEP-2: Compute n as the product of p and q.
STEP-3: Compute (p-1)*(q-1) and store it in z.
STEP-4: Select a random prime number e that is less than that of z.
STEP-5: Compute the private key, d as e * mod-1(z).
STEP-6: The cipher text is computed as messagee * mod n.
STEP-7: Decryption is done as cipherdmod n.

PROGRAM: (RSA)

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
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();
void main()
{
clrscr();
printf("\nENTER FIRST PRIME NUMBER\n");
scanf("%d",&p);
flag=prime(p);
if(flag==0)
{
printf("\nWRONG INPUT\n");
getch();
}
printf("\nENTER ANOTHER PRIME NUMBER\n");
scanf("%d",&q);
flag=prime(q);
if(flag==0||p==q)
{
printf("\nWRONG INPUT\n");
getch();
}
printf("\nENTER MESSAGE\n");
fflush(stdin);
scanf("%s",msg);
for(i=0;msg[i]!=NULL;i++)
m[i]=msg[i];
n=p*q;
t=(p-1)*(q-1);
ce();
printf("\nPOSSIBLE VALUES OF e AND d ARE\n");
for(i=0;i<j-1;i++)
printf("\n%ld\t%ld",e[i],d[i]);
encrypt();
decrypt();
getch();
}
int prime(long int pr)
{
int i;
j=sqrt(pr);
for(i=2;i<=j;i++)
{
if(pr%i==0)
return 0;
}
return 1;
}
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;
printf("\nTHE ENCRYPTED MESSAGE IS\n");
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;
printf("\nTHE DECRYPTED MESSAGE IS\n");
for(i=0;m[i]!=-1;i++)
printf("%c",m[i]);
}
OUTPUT:

RESULT:

Thus the C program to implement RSA encryption technique had been implemented
successfully
EX. NO: 7(A)

IMPLEMENTATION OF HASH FUNCTIONS

AIM:

To implement the SHA-I hashing technique using C program.

DESCRIPTION:

In cryptography, SHA-1 (Secure Hash Algorithm 1) is a cryptographic hash function.


SHA-1 produces a 160-bit hash value known as a message digest. The waythis algorithm
works is that for a message of size < 264 bits it computes a 160-bit condensed output called a
message digest. The SHA-1 algorithm is designed so that it is practicallyinfeasible to find two
input messages that hash to the same output message. A hash function such as SHA-1 is used to
calculate an alphanumeric string that serves as the cryptographic representation of a file or a piece
of data. This is called a digest and can serve as a digital signature. It is supposed to be unique and
non-reversible.

EXAMPLE:

ALGORITHM:
STEP-1: Read the 256-bit key values.
STEP-2: Divide into five equal-sized blocks named A, B, C, D and E.
STEP-3: The blocks B, C and D are passed to the function F.
STEP-4: The resultant value is permuted with block E.
STEP-5: The block A is shifted right by ‘s’ times and permuted with the result of step-4.
STEP-6: Then it is permuted with a weight value and then with some other key pair andtaken as
the first block.
STEP-7: Block A is taken as the second block and the block B is shifted by ‘s’ times andtaken as
the third block.
STEP-8: The blocks C and D are taken as the block D and E for the final output.

PROGRAM: (Secure Hash Algorithm)

#include <iostream>
#include <string>
#include <cstring>

// Rotate bits to the left


#define ROTLEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))

// SHA-1 constants
#define SHA1_BLOCK_SIZE 64
#define SHA1_DIGEST_LENGTH 20

// SHA-1 functions
uint32_t sha1_f(uint32_t b, uint32_t c, uint32_t d, int t) {
if (t < 20)
return (b & c) | ((~b) & d);
else if (t < 40)
return b ^ c ^ d;
else if (t < 60)
return (b & c) | (b & d) | (c & d);
else
return b ^ c ^ d;
}

void sha1_transform(uint32_t state[5], const unsigned char buffer[SHA1_BLOCK_SIZE]) {


uint32_t a, b, c, d, e, temp;
uint32_t w[80];

// Copy buffer to W[0..15]


for (int i = 0; i < 16; ++i)
w[i] = (buffer[i * 4] << 24) | (buffer[i * 4 + 1] << 16) | (buffer[i * 4 + 2] << 8) | (buffer[i * 4 + 3]);

// Extend W[16..79]
for (int i = 16; i < 80; ++i)
w[i] = ROTLEFT(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);

a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];

// Main loop
for (int i = 0; i < 80; ++i) {
temp = ROTLEFT(a, 5) + sha1_f(b, c, d, i) + e + w[i] + 0x5A827999;
e = d;
d = c;
c = ROTLEFT(b, 30);
b = a;
a = temp;
}

// Add this chunk's hash to result so far


state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
}

void sha1(const unsigned char *message, size_t len, uint32_t hash[5]) {


uint32_t state[5] = {
0x67452301,
0xEFCDAB89,
0x98BADCFE,
0x10325476,
0xC3D2E1F0
};

size_t i;
size_t padded_len = len + 1 + 8;
unsigned char *padded_message = new unsigned char[padded_len];
std::memcpy(padded_message, message, len);
padded_message[len] = 0x80; // Padding with a single bit at the end

// Pad with zeros


for (i = len + 1; i < padded_len - 8; ++i)
padded_message[i] = 0;

// Append length
uint64_t bit_len = len * 8;
std::memcpy(padded_message + padded_len - 8, &bit_len, sizeof(bit_len));

// Process each 512-bit chunk


for (i = 0; i < padded_len; i += SHA1_BLOCK_SIZE)
sha1_transform(state, padded_message + i);

delete[] padded_message;

// Output hash
for (i = 0; i < 5; ++i)
hash[i] = state[i];
}

std::string bytesToHex(uint32_t hash[5]) {


std::string hex;
char hexDigit[] = "0123456789ABCDEF";
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 4; ++j) {
unsigned char byte = (hash[i] >> (24 - j * 8)) & 0xFF;
hex += hexDigit[(byte >> 4) & 0x0F];
hex += hexDigit[byte & 0x0F];
}
}
return hex;
}

int main() {
try {
std::cout << "Message digest object info: " << std::endl;
std::cout << " Algorithm = SHA1" << std::endl;
std::cout << " Provider = Manual implementation" << std::endl;
std::cout << " ToString = SHA1 hash function" << std::endl;

std::string input = "";


uint32_t hash[5];
sha1(reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), hash);
std::cout << std::endl << "SHA1(\"" << input << "\") = " << bytesToHex(hash) << std::endl;

input = "abc";
sha1(reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), hash);
std::cout << std::endl << "SHA1(\"" << input << "\") = " << bytesToHex(hash) << std::endl;

input = "abcdefghijklmnopqrstuvwxyz";
sha1(reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), hash);
std::cout << std::endl << "SHA1(\"" << input << "\") = " << bytesToHex(hash) << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}

return 0;
}
OUTPUT:

RESULT:

Thus the SHA-1 hashing technique had been implemented successfully.


EX. NO: 7(B)

AIM:

To write a C program to implement the MD5 hashing technique.

DESCRIPTION:

MD5 processes a variable-length message into a fixed-length output of 128 bits. The input
message is broken up into chunks of 512-bit blocks. The message is pa dded so that its length is
divisible by 512. The padding works as follows: first a single bit, 1, is appended to the end of
the message. This is followed by as many zeros as are required to bring the lengthof the message
up to 64 bits less than a multiple of 512. The remaining bits are filled up with
64 bits representing the length of the original message, modulo 264.The main MD5 algorithm

operates on a 128-bit state, divided into four 32-bit words, denoted A, B, C, and D. These are
initialized to certain fixed constants. The main algorithm then uses each 512-bit message block
in turn to modify the stat e.

EXAMPLE:

ALGORITHM:

STEP-1: Read the 128-bit plain text.


STEP-2: Divide into four blocks of 32-bits named as A, B, C and D.
STEP-3: Compute the functions f, g, h and i with operations such as, rotations,
permutations, etc,.
STEP-4: The output of these functions are combined together as F and performed
circular shifting and then given to key round.
STEP-5: Finally, right shift of ‘s’ times are performed and the results are combined
together to produce the final output.

PROGRAM:( MD5)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include<conio.h>
typedef union uwb
{
unsigned w;
unsigned char b[4];
} MD5union;
typedef unsigned DigestArray[4];
unsigned func0( unsigned abcd[] ){
return ( abcd[1] & abcd[2]) | (~abcd[1] & abcd[3]);}
unsigned func1( unsigned abcd[] ){
return ( abcd[3] & abcd[1]) | (~abcd[3] & abcd[2]);}
unsigned func2( unsigned abcd[] ){
return abcd[1] ^ abcd[2] ^ abcd[3];}
unsigned func3( unsigned abcd[] ){
return abcd[2] ^ (abcd[1] |~ abcd[3]);}
typedef unsigned (*DgstFctn)(unsigned a[]);
unsigned *calctable( unsigned *k)
{
double s, pwr;
int i;
pwr = pow( 2, 32);
for (i=0; i<64; i++)
{
s = fabs(sin(1+i));
k[i] = (unsigned)( s * pwr );
}
return k;
}
unsigned rol( unsigned r, short N )
{
unsigned mask1 = (1<<N) -1;
return ((r>>(32-N)) & mask1) | ((r<<N) & ~mask1);
}
unsigned *md5( const char *msg, int mlen)
{
static DigestArray h0 = { 0x67452301, 0xEFCDAB89,
0x98BADCFE, 0x10325476 };
static DgstFctn ff[] = { &func0, &func1, &func2, &func3};
static short M[] = { 1, 5, 3, 7 };
static short O[] = { 0, 1, 5, 0 };
static short rot0[] = { 7,12,17,22};
static short rot1[] = { 5, 9,14,20};
static short rot2[] = { 4,11,16,23};
static short rot3[] = { 6,10,15,21};
static short *rots[] = {rot0, rot1, rot2, rot3 };
static unsigned kspace[64];
static unsigned *k;
static DigestArray h;
DigestArray abcd;
DgstFctn fctn;
short m, o, g;
unsigned f;
short *rotn;
union
{
unsigned w[16];
char b[64];
}mm;
int os = 0;
int grp, grps, q, p;
unsigned char *msg2;
if (k==NULL) k= calctable(kspace);
for (q=0; q<4; q++) h[q] = h0[q]; // initialize
{
grps = 1 + (mlen+8)/64;
msg2 = malloc( 64*grps);
memcpy( msg2, msg, mlen);
msg2[mlen] = (unsigned char)0x80;
q = mlen + 1;
while (q < 64*grps){ msg2[q] = 0; q++ ; }
{
MD5union u;
u.w = 8*mlen;
q -= 8;
memcpy(msg2+q, &u.w, 4 );
}
}
for (grp=0; grp<grps; grp++)
{
memcpy( mm.b, msg2+os, 64);
for(q=0;q<4;q++) abcd[q] = h[q];
for (p = 0; p<4; p++)
{
fctn = ff[p];
rotn = rots[p];
m = M[p]; o= O[p];
for (q=0; q<16; q++)
{
g = (m*q + o) % 16;
f = abcd[1] + rol( abcd[0]+ fctn(abcd)+k[q+16*p]
+ mm.w[g], rotn[q%4]);
abcd[0] = abcd[3];
abcd[3] = abcd[2];
abcd[2] = abcd[1];
abcd[1] = f;
}}
for (p=0; p<4; p++)
h[p] += abcd[p];
os += 64;
}
return h;}
void main()
{
int j,k;
const char *msg = "The quick brown fox jumps over
the lazy dog";
unsigned *d = md5(msg, strlen(msg));
MD5union u;
clrscr();
printf("\t MD5 ENCRYPTION ALGORITHM IN C \n\n");
printf("Input String to be Encrypted using MD5 :
\n\t%s",msg);
printf("\n\nThe MD5 code for input string is: \n");
printf("\t= 0x");
for (j=0;j<4; j++){
u.w = d[j];
for (k=0;k<4;k++) printf("%02x",u.b[k]);
}
printf("\n");
printf("\n\t MD5 Encyption Successfully
Completed!!!\n\n");
getch();
system("pause");
getch();}
OUTPUT:

RESULT:

Thus the implementation of MD5 hashing algorithm had been implemented


successfully using C
Additional Program

IMPLEMENTATION OF HILL CIPHER


AIM:

To write a C program to implement the hill cipher substitution techniques.

DESCRIPTION:

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 is multiplied by an invertible n × n matrix, against modulus 26. To decrypt the
message, each block is multiplied by the inverse of the m trix used for encryption.
a The matrix
used for encryption is the cipher key, and it sho ld be chosen u

randomly from the set of invertible n × n matrices (modulo 26).

EXAMPLE:

ALGORITHM:

STEP-1: Read the plain text and key from the user.
STEP-2: Split the plain text into groups of length three.
STEP-3: Arrange the keyword in a 3*3 matrix.
STEP-4: Multiply the two matrices to obtain the cipher text of length three.
STEP-5: Combine all these groups to get the complete cipher text.

PROGRAM: (Hill Cipher)


#include<stdio.h>
#include<conio.h>
#include<string.h>
int main(){
unsigned int a[3][3]={{6,24,1},{13,16,10},{20,17,15}};
unsigned int b[3][3]={{8,5,10},{21,8,21},{21,12,8}};
int i,j, t=0;
unsigned int c[20],d[20];
char msg[20];
clrscr();
printf("Enter plain text\n ");
scanf("%s",msg);
for(i=0;i<strlen(msg);i++)

{ c[i]=msg[i]-65;
printf("%d ",c[i]);
}
for(i=0;i<3;i++)
{ t=0;
for(j=0;j<3;j++)
{
t=t+(a[i][j]*c[j]);
}
d[i]=t%26;
}
printf("\nEncrypted Cipher Text :");
for(i=0;i<3;i++)
printf(" %c",d[i]+65);
for(i=0;i<3;i++)
{
t=0;
for(j=0;j<3;j++)
{
t=t+(b[i][j]*d[j]);
}
c[i]=t%26;
}
printf("\nDecrypted Cipher Text :");
for(i=0;i<3;i++)
printf(" %c",c[i]+65);
getch();
return 0;
}

OUTPUT:

RESULT:

Thus the hill cipher substitution technique had been implemented successfully in C.

You might also like