0% found this document useful (0 votes)
11 views57 pages

School of Computer Science and Engineering (Scope)

The document is a lab manual for the BCSE309P: Cryptography and Network Security Lab for the Winter Semester 2024, detailing various cryptographic techniques and assignments. It includes instructions for implementing substitution ciphers such as Playfair, Hill, and symmetric encryption methods like DES and AES. The manual provides algorithms, programming examples in Java, and input/output examples for each cipher technique.

Uploaded by

whytujay
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views57 pages

School of Computer Science and Engineering (Scope)

The document is a lab manual for the BCSE309P: Cryptography and Network Security Lab for the Winter Semester 2024, detailing various cryptographic techniques and assignments. It includes instructions for implementing substitution ciphers such as Playfair, Hill, and symmetric encryption methods like DES and AES. The manual provides algorithms, programming examples in Java, and input/output examples for each cipher technique.

Uploaded by

whytujay
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 57

School of Computer Science and Engineering

(SCOPE)

Winter Semester 2024


T BCSE309P:Cryptography and Network Security Lab
VI
LAB MANUAL
(Common to all classes)

1. Prof. Balaji N

2. Prof. Jeevanajyothi Pujari

3. Prof.Siva Sankari

4. Prof. S.Sreethar

Prof……………..
Lab Coordinators HoD, Department of …………….
CHALLENGING ASSIGNMENTS

S.NO TITLE PAGE NO


1 Implement the following substitution cipher techniques without
using standard cryptographic library Functions

i. Playfair Cipher

ii. Hill cipher

iii.Vigenere Cipher

T
2.
Consider a sender and receiver who need to exchange data
confidentially using symmetric encryption. Write program that
implements DES encryption and decryption using a 64 bit key
size and 64 bit block size
VI
Consider a sender and receiver who need to exchange data
confidentially using symmetric encryption. Write program that
3.
implements AES encryption and decryption using a 128 bits key
size and 128 bit block size.
Exp No: 1.1 Playfair Cipher

Aim

To implement a Playfair cipher substitution technique in Java

Concept to be Applied
• 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.
• In Playfair cipher unlike traditional cipher we encrypt a pair of alphabets (digraphs)
instead of a single alphabet.
• Playfair is reasonably fast to use and requires no special equipment
T•

Generate the key Square Matrix(5×5):
The key square is a 5×5 grid of alphabets that acts as the key for encrypting the
plaintext. Each of the 25 alphabets must be unique and one letter of the alphabet
(usually J) is omitted from the table (as the table can hold only 25 alphabets). If the
plaintext contains J, then it is replaced by I.
VI
• The initial alphabets in the key square are the unique alphabets of the key in the order
in which they appear followed by the remaining letters of the alphabet in order.
• Algorithm to encrypt the plain text: The plaintext is split into pairs of two letters
(digraphs). If there is an odd number of letters, a Z is added to the last letter.
• Pair cannot be made with 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.

Algorithm

1. Read the key as input from the user.


2. Then create the key table of 5x5 grids of alphabets.
3. Get the plain text as an input.
4. Then split the plain text message into pairs of two letters(digraphs).
5. Pair cannot be made with same letter. Break the letter in single and add a bogus letter
z to the previous letter
6. If both the letters are in the same column, take the letter below each one.
7. If both letters are in the same row, take the letter to the right of each one.
8. If neither of the preceding two rules are true, form a rectangle with the two letters and
take the letters on the horizontal opposite corner of the rectangle.

Program

package CNS;
import java.util.Scanner;
public class PlayfairCipher
{
T
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
System.out.print("Enter keyword: ");
String key=in.nextLine();
VI
System.out.print("Enter message to encrypt: ");
String msg=in.nextLine();
PFEncryption pfEncryption=new PFEncryption();
pfEncryption.makeArray(key);
msg=pfEncryption.manageMessage(msg);
pfEncryption.doPlayFair(msg, "Encrypt");
String en=pfEncryption.getEncrypted();
System.out.println("Encrypting. .. \n\nThe encrypted text is: " + en);
System.out.println("=============================");
pfEncryption.doPlayFair(en, "Decrypt");
System.out.print("\nDecrypting... \n\nThe encrypted text is: " +
pfEncryption.getDecrypted());
}
}
class PFEncryption
{
private char [][] alphabets= new char[5][5];
private char[] uniqueChar= new char[26];
private String ch="ABCDEFGHIKLMNOPQRSTUVWXYZ"; private String encrypted="";
private String decrypted="";
void makeArray(String keyword)
{
keyword=keyword.toUpperCase().replace("J","I");
boolean present, terminate=false;
int val=0;
int uniqueLen;
for (int i=0; i<keyword.length(); i++)
{
present=false;
uniqueLen=0;
if (keyword.charAt(i)!= ' ')
{
for (int k=0; k<uniqueChar.length; k++)
{
if (Character.toString(uniqueChar[k])==null)
{
T
break;
}
uniqueLen++;
}
for (int j=0; j<uniqueChar.length; j++)
VI
{
if (keyword.charAt(i)==uniqueChar[j])
{
present=true;
}
}
if (!present)
{
uniqueChar[val]=keyword.charAt(i); val++;
}
}
ch=ch.replaceAll(Character.toString(keyword.charAt(i)), "");
}
for (int i=0; i<ch.length(); i++)
{
uniqueChar[val]=ch.charAt(i);
val++;
}
val=0;
for (int i=0; i<5; i++)
{
for (int j=0; j<5; j++)
{
alphabets[i][j]=uniqueChar[val]; val++;
System.out.print(alphabets[i][j] + "\t");
}
System.out.println();
}
}
String manageMessage(String msg)
{
int val=0;
int len=msg.length()-2; String newTxt="";
String intermediate="";
while (len>=0)
{
T
intermediate=msg.substring(val, val+2);
if (intermediate.charAt(0)==intermediate.charAt(1))
{
newTxt=intermediate.charAt(0) + "x" + intermediate.charAt(1);
VI
msg=msg.replaceFirst(intermediate, newTxt);
len++;
}
len-=2;
val+=2;
}
if (msg.length()%2!=0)
{
msg=msg+'x';
}
return msg.toUpperCase().replaceAll("J","I").replaceAll(" ","");
}
void doPlayFair(String msg, String tag)
{
int val=0;
while (val<msg.length())
{
searchAndEncryptOrDecrypt(msg.substring(val,val+2),tag); val+=2;
}
}
void searchAndEncryptOrDecrypt(String doubblyCh, String tag)
{
char ch1=doubblyCh.charAt(0);
char ch2=doubblyCh.charAt(1);
int row1=0, col1=0, row2=0, col2=0; for (int i=0; i<5; i++)
{
for (int j=0; j<5; j++)
{
if (alphabets[i][j]==ch1)
{
row1=i; col1=j;
}
else if (alphabets[i][j]==ch2)
{
row2=i;

}
}
T
col2=j;
}

if (tag=="Encrypt")
VI
encrypt(row1, col1, row2, col2); else if(tag=="Decrypt")
decrypt(row1, col1, row2, col2);
}
void encrypt(int row1, int col1, int row2, int col2)
{
if (row1==row2)
{
col1=col1+1; col2=col2+1; if (col1>4)
col1=0; if (col2>4) col2=0;
encrypted+=(Character.toString(alphabets[row1][col1])+ Character.toString(alphabets[row1]
[col2]));
}
else if(col1==col2)
{
row1=row1+1;
row2=row2+1;
if (row1>4)
row1=0;
if (row2>4)
row2=0;
encrypted+=(Character.toString(alphabets[row1][col1])+ Character.toString(alphabets[row2]
[col1]));
}
else
{
encrypted+=(Character.toString(alphabets[row1][col2])+ Character.toString(alphabets[row2]
[col1]));
}
}
void decrypt(int row1, int col1, int row2, int col2)
{
if (row1==row2)
{
col1=col1-1;
col2=col2-1;
T
if (col1<0)
col1=4;
if (col2<0) col2=4;
decrypted+=(Character.toString(alphabets[row1][col1])+ Character.toString(alphabets[row1]
[col2]));
VI
}
else if(col1==col2)
{
row1=row1-1;
row2=row2-1;
if (row1<0)
row1=4;
if (row2<0) row2=4;
decrypted+=(Character.toString(alphabets[row1][col1])+ Character.toString(alphabets[row2]
[col1]));
}
else
{
decrypted+=(Character.toString(alphabets[row1][col2])+ Character.toString(alphabets[row2]
[col1]));
}
}
String getEncrypted( )
{
return encrypted;
}
String getDecrypted( )
{
return decrypted;
}
}

Input& Output:

Run1:

Enter keyword: scope

Enter message to encrypt: security

S C O P E

A B D F G

V
T I

W
K

X
L

Y
M

Z
VI
Encrypting. ..

The encrypted text is: CSEQQKYP

=============================

Decrypting...

The encrypted text is: SECURITY

Run2:

Enter keyword: network

Enter message to encrypt: securitylabvit

N E T W O

R K A B C

D F G H I

L M P Q S

U V X Y Z
Encrypting. ..

The encrypted text is: MORZCDWXPRKYGO

=============================

Decrypting...

The encrypted text is: SECURITYLABVIT

T
VI
Exp No: 1.2 Hill Cipher

Aim

To implement a Java program for encryption and decryption using Hill cipher substitution
technique.

Concept to be Applied
• 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).

Algorithm:

1. Obtain a plain text message to encode in Standard English with no spaces.


2. Split the plain text into group of length three. To fill this, add X at the end.
3. Convert each group of letters with length three into plain text vectors.
4. Replace each letter by the number corresponding to its position in the alphabet i.e.
A=1, B=2, C=3…Z=0.
5. Create the key word in a 3*3 matrix.
6. Multiply the two matrices to obtain the cipher text of length three.
T 7.

8.
For decryption, convert each entry in the cipher text vector into its plain text vector
by multiplying the cipher text vector and inverse of a matrix.
Thus plaintext is obtained from the corresponding plaintext vector by corresponding
position in the alphabet.
VI
Program

package CNS;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class hillcipher
{
//the 3x3 key matrix for 3 characters at once
public static int[][] keymat = new int[][]{{ 1, 2, 1 },{ 2, 3, 2 },{ 2, 2, 1 },};
public static int[][] invkeymat = new int[][]{{ -1, 0, 1 },{ 2, -1, 0 },{ -2, 2, -1},};
public static String key = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void main(String[] args)
{
String text,outtext ="",outtext1="";
int ch, n;
Scanner sc=new Scanner(System.in);
System.out.println("Enter the Plain text for Encryption: ");
//String text=new String();
text=sc.next();
text = text.toUpperCase();
text = text.replaceAll("\\s",""); //removing spaces
n = text.length() % 3; if(n!=0)
{
for(int i = 1; i<= (3-n);i++)
{
text+= 'X';
}
}
System.out.println("Padded Text:" + text);
char[] ptextchars = text.toCharArray();
for(int i=0;i< text.length(); i+=3)
{
outtext += encrypt(ptextchars[i],ptextchars[i+1],ptextchars[i+2]);
}
System.out.println("Encrypted Message: " + outtext);
char[] ptextchars1 = outtext.toCharArray(); for(int i=0;i< outtext.length(); i+=3)
{

}
T
outtext1 += decrypt(ptextchars1[i],ptextchars1[i+1],ptextchars1[i+2]);

System.out.println("Decrypted Message: " + outtext1);


}
VI
private static String encrypt(char a, char b, char c)
{
String ret = "";
int x,y, z;
int posa = (int)a - 65;
int posb = (int)b - 65;
int posc = (int)c - 65;
x = posa * keymat[0][0] + posb * keymat[1][0] + posc * keymat[2][0];
y = posa * keymat[0][1] + posb * keymat[1][1] + posc * keymat[2][1];
z = posa * keymat[0][2] + posb * keymat[1][2] + posc * keymat[2][2];
a = key.charAt(x%26);
b = key.charAt(y%26);
c = key.charAt(z%26); ret = "" + a + b + c; return ret;
}
private static String decrypt(char a, char b, char c)
{
String ret = "";
int x,y,z;
int posa = (int)a - 65;
int posb = (int)b - 65;
int posc = (int)c - 65;
x = posa * invkeymat[0][0]+ posb * invkeymat[1][0] + posc * invkeymat[2][0];
y = posa * invkeymat[0][1]+ posb * invkeymat[1][1] + posc * invkeymat[2][1];
z = posa * invkeymat[0][2]+ posb * invkeymat[1][2] + posc * invkeymat[2][2];
a = key.charAt((x%26<0)?(26+x%26):(x%26));
b = key.charAt((y%26<0)?(26+y%26):(y%26));
c = key.charAt((z%26<0)?(26+z%26):(z%26)); ret = "" + a + b + c;
return ret;
}
}
Input & Output:

Run1:

Enter the Plain text for Encryption:

T
Analytics

Padded Text:ANALYTICS

Encrypted Message: ANATCAWGE

Decrypted Message: ANALYTICS


VI
Run2:

Enter the Plain text for Encryption:

velloreinstituteoftechnology

Padded Text:VELLOREINSTITUTEOFTECHNOLOGYXX

Encrypted Message: ZYOVUEUGHUFMTGAQILFCDJDVZYTMHP

Decrypted Message: VELLOREINSTITUTEOFTECHNOLOGYXX

Run3:

Enter the Plain text for Encryption:

cryptography

Padded Text:CRYPTOGRAPHY

Enrcypted Message: GZIDLPOLOZVB

Decrypted Message: CRYPTOGRAPHY

Exp No: 1.3 Vigenere Cipher


Aim

To implement a Java program for encryption and decryption using Vigenere cipher
substitution technique.

Concept to be Applied

• Vigenere Cipher is a method of encrypting alphabetic text.


• It uses a simple form of polyalphabetic substitution.
• A polyalphabetic cipher is any cipher based on substitution, using multiple
substitution alphabets.
• 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.
• The encryption of the original text is done using the Vigenere square or Vigenere
table.
• The table consists of the alphabets written out 26 times in different rows, each
alphabet shifted cyclically to the left compared to the previous alphabet,
T corresponding to the 26 possible Caesar Ciphers.
VI
• In addition to the plaintext, the Vigenère cipher also requires a keyword, which is
repeated so that the total length is equal to that of the plaintext/
• To encrypt, pick a letter in the plaintext and its corresponding letter in the keyword,
use the keyword letter and the plaintext letter as the row index and column index,
respectively, and the entry at the row-column intersection is the letter in the
ciphertext.
• Repeating this process until all plaintext letters are processed.
• To decrypt, pick a letter in the ciphertext and its corresponding letter in the keyword,
use the keyword letter to find the corresponding row, and the letter heading of the
column that contains the ciphertext letter is the needed plaintext letter.
• An easy implementation could be to visualize Vigenère algebraically by converting
[A-Z] into numbers [0–25].
• Encryption
The plaintext(P) and key(K) are added modulo 26.
Ei = (Pi + Ki) mod 26
• Decryption
Di = (Ei - Ki) mod 26

Algorithm

1. The Vigenere cipher is a method of encrypting alphabetic text by using a


series of different Caesar ciphers based on the letters of a keyword.
2. It is a simple form of polyalphabetic substitution.
3. To encrypt, a table of alphabets can be used, termeda Vigeneresquare, or
Vigenere table.
4. It consists of 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.
5. At different points in the encryption process, the cipher uses a different
alphabet from one of the rows used.
T 6. The alphabet at each point depends on a repeating keyword.

Program

package CNS;
import java.util.Scanner;
VI
public class vigenerecipher

public static String encrypt(String text,final String key)

String res="";

text=text.toUpperCase();

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

char c=text.charAt(i);

if(c<'A'||c>'z')

continue;

res+=(char)((c+key.charAt(j)-2*'A')%26+'A');

j=++j%key.length();

}
return res;

public static String decrypt(String text,final String key)

String res="";

text=text.toUpperCase();

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

char c=text.charAt(i);

if(c<'A'||c>'z')

continue;
T
res+=(char)((c-key.charAt(j)+26)%26+'A');

j=++j%key.length();

return res;
VI
}

public static void main(String[] args) throws NullPointerException

try

Scanner s=new Scanner(System.in);

System.out.println("Enter the key: ");

String key = s.next();

System.out.println("Enter the message for encryption: ");

String message = s.next();

String encryptedMsg=encrypt(message,key);

System.out.println("String :"+message);

System.out.println("Encrypted message:Cipher Text=" +encryptedMsg);

System.out.println("Decrypted message:Plain Text="+decrypt(encryptedMsg,key));


}

catch(Exception e)

System.out.println(e);

}}}

Input & Output:

Run1:

Enter the key:

SCOPE

Enter the message for encryption:

VELLOREINSTITUTE
T
String :VELLOREINSTITUTE

Encrypted message:Cipher Text=NGZASJGWCWLKHJXW

Decrypted message:Plain Text=VELLOREINSTITUTE

Run2:
VI
Enter the key:

VELLORE

Enter the message for encryption:

CRYPTOGRAPHYANDNETWORKSECURITY

String :CRYPTOGRAPHYANDNETWORKSECURITY

Encrypted message:Cipher Text=XVJAHFKMEASMRRYRPEKFVFWPNIIMOC

Decrypted message:Plain Text=CRYPTOGRAPHYANDNETWORKSECURITY

Run3:

Enter the key:

CRYPTOGRAPHY

Enter the message for encryption:

SCHOOLOFCOMPUTERSCIENCEANDENGINEERING

String :SCHOOLOFCOMPUTERSCIENCEANDENGINEERING

Encrypted message:
Cipher Text=UTFDHZUWCDTNWKCGLQOVNRLYPUCCZWTVEGPLI

Decrypted message: Plain Text=SCHOOLOFCOMPUTERSCIENCEANDENGINEERING

Ex.No. : 2 DATA ENCRYPTION STANDARD (DES)


Date :

AIM:
To apply Data Encryption Standard (DES) Algorithm for a practical application like User
Message Encryption.

Algorithm for Encryption:

1. The algorithm takes the 64-bit plain text as input.


T 2. The text is parsed into a function called the Initial Permutation (IP)
function.
3. The initial permutation (IP) function breaks the plain text into the
two halves of the permuted block. These two blocks are known as
Left Plain Text (LPT) and Right Plain Text (RPT).
VI
4. The 16 round encryption process is performed on both blocks LPT
and RPT. The encryption process performs the following:
a. Key Transformation
b. Expansion Permutation
c. S-Box Permutation
d. P-Box Permutation
e. XOR and Swap
After performing the encryption process, the LPT and RPT block are
rejoined. After that, the Final Permutation (FP) is applied to the combined
block.
Finally, we get the 64-bit ciphertext of the plaintext.
Generating Keys
1. First, we compress and transpose the given 64-bit key into a 48-bit keys
by using the table

2. Separate the result into two equal parts i.e. C and D.


3. The part C and D are left-shifted circularly. For encryption, the 1st,
2nd, 9th, and 16th round is responsible that shifts a bit to the left by
1 bit, circularly. All the rest rounds are shifted to the left by 2-bit
circularly.
4. After that, the result is compressed to 48-bits with the help of the
reduction table
5. The result that we get from step 3 becomes the input for the next
round of the key generation.

T
VI
DES Encryption
T
ROUND OPERATION
VI
Key Generation

Program:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <time.h>

int IP[] =
{
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,

};
T59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
VI
int 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
};

int P[] =
{
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
};
int FP[] =
{
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
};

int S1[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,

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

int S2[4][16] =
{
VI
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
};

int S3[4][16] =
{
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
};

int S4[4][16] =
{
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
};

int S5[4][16] =
{
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
};

int S6[4][16] =
{
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
};

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

};
T13, 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
VI
int S8[4][16]=
{
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
};

int PC1[] =
{
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
};

int PC2[] =
{
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
};

int SHIFTS[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };

FILE* out;
int LEFT[17][32], RIGHT[17][32];
int IPtext[64];
int EXPtext[48];
int XORtext[48];
int X[8][6];
int X2[32];
T
int R[32];
int key56bit[56];
int key48bit[17][48];
int CIPHER[64];
int ENCRYPTED[64];
VI
void expansion_function(int pos, int text)
{
for (int i = 0; i < 48; i++)
{
if (E[i] == pos + 1) {
EXPtext[i] = text;
}
}
}

int initialPermutation(int pos, int text)


{
int i;
for (i = 0; i < 64; i++)
{
if (IP[i] == pos + 1) {
break;
}
}
IPtext[i] = text;
}
int F1(int i)
{
int r, c, b[6];

for (int j = 0; j < 6; j++) {


b[j] = X[i][j];
}

r = b[0] * 2 + b[5];
c = 8 * b[1] + 4 * b[2] + 2 * b[3] + b[4];

if (i == 0) {
return S1[r][c];
}
else if (i == 1) {
return S2[r][c];
}
else if (i == 2) {
T }
return S3[r][c];

else if (i == 3) {

}
return S4[r][c];
VI
else if (i == 4) {
return S5[r][c];
}
else if (i == 5) {
return S6[r][c];
}
else if (i == 6) {
return S7[r][c];
}
else if (i == 7) {
return S8[r][c];
}
}

int XOR(int a, int b) {


return (a ^ b);
}

int ToBits(int value)


{
int k, j, m;
static int i;
if (i % 32 == 0) {
i = 0;
}

for (j = 3; j >= 0; j--)


{
m = 1 << j;
k = value & m;
if (k == 0) {
X2[3 - j + i] = '0' – 48;
}
else {
X2[3 - j + i] = '1' – 48;
}
}

i = i + 4;
}

{
T
int SBox(int XORtext[])

int k = 0;
for (int i = 0; i < 8; i++)
VI
{
for (int j = 0; j < 6; j++) {
X[i][j] = XORtext[k++];
}
}

int value;
for (int i = 0; i < 8; i++)
{
value = F1(i);
ToBits(value);
}
}

int PBox(int pos, int text)


{
int i;
for (i = 0; i < 32; i++)
{
if (P[i] == pos + 1) {
break;
}
}
R[i] = text;
}

void cipher(int Round, int mode)


{
for (int i = 0; i < 32; i++) {
expansion_function(i, RIGHT[Round – 1][i]);
}

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


{
if (mode == 0) {
XORtext[i] = XOR(EXPtext[i], key48bit[Round][i]);
}
else {
XORtext[i] = XOR(EXPtext[i], key48bit[17 – Round][i]);
}
}
T SBox(XORtext);

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


PBox(i, X2[i]);
VI
}

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


RIGHT[Round][i] = XOR(LEFT[Round – 1][i], R[i]);
}
}

void finalPermutation(int pos, int text)


{
int i;
for (i = 0; i < 64; i++)
{
if (FP[i] == pos + 1) {
break;
}
}
ENCRYPTED[i] = text;
}

void convertToBinary(int n)
{
int k, m;
for (int i = 7; i >= 0; i--)
{
m = 1 << i;
k = n & m;

if (k == 0) {
fprintf(out, "0");
}
else {
fprintf(out, "1");
}
}
}

int convertCharToBit(long int n)


{
FILE* inp = fopen("input.txt", "rb");
out = fopen("bits.txt", "wb+");
char ch;
Tint i = n * 8;

while (i)
{
ch = fgetc(inp);
VI
if (ch == -1) {
break;
}
i--;
convertToBinary(ch);
}
fclose(out);
fclose(inp);
}

void Encryption(long int plain[])


{
out = fopen("cipher.txt", "ab+");
for (int i = 0; i < 64; i++) {
initialPermutation(i, plain[i]);
}

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


LEFT[0][i] = IPtext[i];
}

for (int i = 32; i < 64; i++) {


RIGHT[0][i – 32] = IPtext[i];
}

for (int k = 1; k < 17; k++)


{
cipher(k, 0);

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


LEFT[k][i] = RIGHT[k – 1][i];
}

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


{
if (i < 32) {
CIPHER[i] = RIGHT[16][i];
}
else {
CIPHER[i] = LEFT[16][i – 32];
}
T }
finalPermutation(i, CIPHER[i]);

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


fprintf(out, "%d", ENCRYPTED[i]);
VI
}
fclose(out);
}

void Decryption(long int plain[])


{
out = fopen("decrypted.txt", "ab+");
for (int i = 0; i < 64; i++) {
initialPermutation(i, plain[i]);
}

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


LEFT[0][i] = IPtext[i];
}

for (int i = 32; i < 64; i++) {


RIGHT[0][i – 32] = IPtext[i];
}

for (int k = 1; k < 17; k++)


{
cipher(k, 1);
for (int i = 0; i < 32; i++) {
LEFT[k][i] = RIGHT[k – 1][i];
}
}

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


{
if (i < 32) {
CIPHER[i] = RIGHT[16][i];
} else {
CIPHER[i] = LEFT[16][i – 32];
}
finalPermutation(i, CIPHER[i]);
}

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


fprintf(out, "%d", ENCRYPTED[i]);
}

}
T fclose(out);

void convertToBits(int ch[])


VI
{
int value = 0;
for (int i = 7; i >= 0; i--) {
value += (int)pow(2, i) * ch[7 – i];
}
fprintf(out, "%c", value);
}

int bittochar()
{
out = fopen("result.txt", "ab+");
for (int i = 0; i < 64; i = i + 8) {
convertToBits(&ENCRYPTED[i]);
}
fclose(out);
}

void key56to48(int round, int pos, int text)


{
int i;
for (i = 0; i < 56; i++)
{
if (PC2[i] == pos + 1) {
break;
}
}
key48bit[round][i] = text;
}

int key64to56(int pos, int text)


{
int i;
for (i = 0; i < 56; i++)
{
if (PC1[i] == pos + 1) {
break;
}
}
key56bit[i] = text;
}

T
void key64to48(unsigned int key[])
{
int k, backup[17][2];
int CD[17][56];
int C[17][28], D[17][28];
VI
for (int i = 0; i < 64; i++) {
key64to56(i, key[i]);
}

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


{
if (i < 28) {
C[0][i] = key56bit[i];
}
else {
D[0][i – 28] = key56bit[i];
}
}

for (int x = 1; x < 17; x++)


{
int shift = SHIFTS[x – 1];

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


backup[x - 1][i] = C[x – 1][i];
}
for (int i = 0; i < (28 – shift); i++) {
C[x][i] = C[x – 1][i + shift];
}

k = 0;
for (int i = 28 – shift; i < 28; i++) {
C[x][i] = backup[x – 1][k++];
}

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


backup[x - 1][i] = D[x – 1][i];
}

for (int i = 0; i < (28 – shift); i++) {


D[x][i] = D[x – 1][i + shift];
}

k = 0;
T }
for (int i = 28 – shift; i < 28; i++) {

}
D[x][i] = backup[x – 1][k++];
VI
for (int j = 0; j < 17; j++)
{
for (int i = 0; i < 28; i++) {
CD[j][i] = C[j][i];
}

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


CD[j][i] = D[j][i – 28];
}
}

for (int j = 1; j < 17; j++)


{
for (int i = 0; i < 56; i++) {
key56to48(j, i, CD[j][i]);
}
}
}

void decrypt(long int n)


{
FILE* in = fopen("cipher.txt", "rb");
long int plain[n * 64];
int i = -1;
char ch;

while (!feof(in))
{
ch = getc(in);
plain[++i] = ch – 48;
}

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


{
Decryption(plain + i * 64);
bittochar();
}

fclose(in);
}

{
T
void encrypt(long int n)

FILE* in = fopen("bits.txt", "rb");

long int plain[n * 64];


VI
int i = -1;
char ch;

while (!feof(in))
{
ch = getc(in);
plain[++i] = ch – 48;
}

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


Encryption(plain + 64 * i);
}

fclose(in);
}

void create16Keys()
{
FILE* pt = fopen("key.txt", "rb");
unsigned int key[64];
int i = 0, ch;

while (!feof(pt))
{
ch = getc(pt);
key[i++] = ch – 48;
}

key64to48(key);
fclose(pt);
}

long int findFileSize()


{
FILE* inp = fopen("input.txt", "rb");
long int size;

if (fseek(inp, 0L, SEEK_END)) {


perror("fseek() failed");
}
// size will contain number of chars in the input file.
T else {

}
size = ftell(inp);

fclose(inp);
VI
return size;
}

int main()
{
// destroy contents of these files (from previous runs, if any)

create16Keys();

long int n = findFileSize() / 8;


convertCharToBit(n);

encrypt(n);
decrypt(n);

return 0;
}

input.txt – Will contain our plain text (Max. Limit of plain text is
64kb).
key.txt – Will contain 64-bit key
Input:

Plaintext : 8787878787878787
Key :
0001001100110100010101110111100110011011101111001101111111110001

Cipher Text: 1984534276453454

Plaintext : 8787878787878787

Ex.No. : 3 ADVANCED ENCRYPTION STANDARD (AES)

AIM:
To implement Advanced Encryption Standard (AES) Algorithm using a 128 bits key size and a
128 bits block size algorithm for encryption and decryption
T
Theory:

AES (Advanced Encryption Standard) is a widely adopted symmetric encryption


algorithm. Operating on fixed-size 128-bit blocks, AES supports key sizes of 128,
192, and 256 bits. The encryption process involves rounds of substitution,
VI
permutation, and mixing, offering strong security. AES replaced DES as a NIST
standard in 2001, demonstrating efficiency and resistance to various cryptographic
attacks. It finds extensive use in securing data transmission, file encryption, and
safeguarding sensitive information across diverse applications.

Algorithm for Encryption:

AES Encryption:

Input:
Take a 128-bit plaintext as input.

Initial Round:
AddRoundKey: Combine the plaintext with the initial round key.

Main Rounds (Repeat for 9, 11, or 13 rounds):

SubBytes: Substitute each byte with a corresponding value from the S-box.
ShiftRows: Shift rows of the state matrix.
MixColumns: Mix data within columns of the state matrix.
AddRoundKey: Combine the state with the round key.
Final Round:

SubBytes
ShiftRows
AddRoundKey

Key Expansion:
Generate additional round keys from the original key.
Apply a series of transformations, including SubBytes, RotWord, and XOR
operations.

Ke Generation:
Input:
Take a 128-bit original key.

Key Compression and Transposition:


Compress and transpose the 128-bit key into a 56-bit key using a predefined
T
table.

Round Key Generation (Repeat for 10, 12, or 14 rounds):


Split the key into two halves, C and D.
Perform circular left shifts on C and D. Shifts are 1 bit for the 1st, 2nd, 9th, and
VI
16th rounds;otherwise, 2 bits.
Compress and transpose the result into a 48-bit key using a reduction table.
Result becomes the input for the next round of key generation.

Decryption:
Key Expansion:
Expand the initial key into a set of round keys.
Apply transformations, including SubBytes, RotWord, and XOR
operations.
Decryption Rounds (10, 12, or 14 rounds):
Inverse AddRoundKey: Combine the state with the round key.
Inverse MixColumns: Reverse the mixing of data within columns.
Inverse ShiftRows: Reverse the row shifting.
Inverse SubBytes: Reverse the substitution using the inverse of the S-box.
Final Round:
Inverse AddRoundKey
Inverse ShiftRows
Inverse SubBytes
Output:
The final state matrix represents the decrypted plaintext.
Code:

The following code is given in Java

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Scanner;

public class SimpleAESExample {


public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the message to be encrypted: ");
String originalMessage = scanner.nextLine();
System.out.print("Enter the 16-byte secret key: ");
String keyString = scanner.nextLine();
T
byte[] keyBytes = keyString.getBytes(StandardCharsets.UTF_8);
SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");

String encryptedMessage = encrypt(originalMessage, secretKey);


System.out.println("Original Message: " + originalMessage);
VI
System.out.println("Encrypted Message: " + encryptedMessage);
// Decrypt the message
String decryptedMessage = decrypt(encryptedMessage, secretKey);
System.out.println("Decrypted Message: " + decryptedMessage);
}
private static String encrypt(String message, SecretKey secretKey) throws
Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes =
cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
// Decrypt a message using AESprivate static String decrypt(String
encryptedMessage, SecretKey secretKey) throws
Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes =
cipher.doFinal(Base64.getDecoder().decode(encryptedMessage));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
}
Output:

The following code is given in C++

#include <stdio.h>

{
T
#include <stdlib.h>
enum errorCode

SUCCESS = 0,
ERROR_AES_UNKNOWN_KEYSIZE,
ERROR_MEMORY_ALLOCATION_FAILED,
VI
};
unsigned char sbox[256] = {
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,
0x , 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64,
0x5d, 0x19,
0x73,
ff
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};
T
unsigned char rsbox[256] =
{0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
0x81, 0xf3, 0xd7,
0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0x , 0x87, 0x34, 0x8e, 0x43, 0x44,
0xc4, 0xde, 0xe9,
0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b,
VI
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,
ff
0x83, 0x53, 0x99,
0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
0x55, 0x21, 0x0c,
0x7d};
unsigned char getSBoxValue(unsigned char num);
unsigned char getSBoxInvert(unsigned char num);
void rotate(unsigned char *word);
unsigned char Rcon[255] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab,
0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25,
0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01,
0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa,
0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
T
0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02,
0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,
VI
0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33,
0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb};
unsigned char getRconValue(unsigned char num);
void core(unsigned char *word, int iteration);
enum keySize
{
SIZE_16 = 16,
SIZE_24 = 24,
SIZE_32 = 32
};
void expandKey(unsigned char *expandedKey, unsigned char *key, enum
keySize, size_t
expandedKeySize);
void subBytes(unsigned char *state);
void shiftRows(unsigned char *state);
void shiftRow(unsigned char *state, unsigned char nbr);
void addRoundKey(unsigned char *state, unsigned char *roundKey);
unsigned char galois_multiplication(unsigned char a, unsigned char b);
void mixColumns(unsigned char *state);
void mixColumn(unsigned char *column);
void aes_round(unsigned char *state, unsigned char *roundKey);
void createRoundKey(unsigned char *expandedKey, unsigned char
*roundKey);
void aes_main(unsigned char *state, unsigned char *expandedKey, int
nbrRounds);
char aes_encrypt(unsigned char *input, unsigned char *output, unsigned char
*key, enum keySize
size);
void invSubBytes(unsigned char *state);
void invShiftRows(unsigned char *state);
void invShiftRow(unsigned char *state, unsigned char nbr);
void invMixColumns(unsigned char *state);
void invMixColumn(unsigned char *column);
void aes_invRound(unsigned char *state, unsigned char *roundKey);
void aes_invMain(unsigned char *state, unsigned char *expandedKey, int
nbrRounds);
char aes_decrypt(unsigned char *input, unsigned char *output, unsigned char
*key, enum keySize
size);
int main(int argc, char *argv[])
{
int expandedKeySize = 176;
T
unsigned char expandedKey[expandedKeySize];
unsigned char key[16] = {'k', 'k', 'k', 'k', 'e', 'e', 'e', 'e', 'y', 'y', 'y', 'y', '.', '.', '.', '.'};
enum keySize size = SIZE_16;
unsigned char plaintext[16] = {'a', 'b', 'c', 'd', 'e', 'f', '1', '2', '3', '4', '5', '6', '7', '8',
'9', '0'};
unsigned char ciphertext[16];
VI
unsigned char decryptedtext[16];
int i;
printf("\nCipher Key (HEX format):\n");
for (i = 0; i < 16; i++)
{
printf("%2.2x%c", key[i], ((i + 1) % 16) ? ' ' : '\n');
}
expandKey(expandedKey, key, size, expandedKeySize);
printf("\nExpanded Key (HEX format):\n");
for (i = 0; i < expandedKeySize; i++)
{
printf("%2.2x%c", expandedKey[i], ((i + 1) % 16) ? ' ' : '\n');
}
printf("\nPlaintext (HEX format):\n");
for (i = 0; i < 16; i++)
{
printf("%2.2x%c", plaintext[i], ((i + 1) % 16) ? ' ' : '\n');
}
aes_encrypt(plaintext, ciphertext, key, SIZE_16);
printf("\nCiphertext (HEX format):\n");
for (i = 0; i < 16; i++)
{
printf("%2.2x%c", ciphertext[i], ((i + 1) % 16) ? ' ' : '\n');
}
aes_decrypt(ciphertext, decryptedtext, key, SIZE_16);
printf("\nDecrypted text (HEX format):\n");
for (i = 0; i < 16; i++)
{
printf("%2.2x%c", decryptedtext[i], ((i + 1) % 16) ? ' ' : '\n');
}
return 0;
}
unsigned char getSBoxValue(unsigned char num)
{
return sbox[num];
}
unsigned char getSBoxInvert(unsigned char num)
{
return rsbox[num];
}
void rotate(unsigned char *word)
{
unsigned char c;
T
int i;
c = word[0];
for (i = 0; i < 3; i++)
word[i] = word[i + 1];
word[3] = c;
}
VI
unsigned char getRconValue(unsigned char num)
{
return Rcon[num];
}
void core(unsigned char *word, int iteration)
{
int i;
rotate(word);
for (i = 0; i < 4; ++i)
{
word[i] = getSBoxValue(word[i]);
}
word[0] = word[0] ^ getRconValue(iteration);
}
void expandKey(unsigned char *expandedKey,
unsigned char *key,
enum keySize size,
size_t expandedKeySize)
{
int currentSize = 0;
int rconIteration = 1;
int i;
unsigned char t[4] = {0};
for (i = 0; i < size; i++)
expandedKey[i] = key[i];
currentSize += size;
while (currentSize < expandedKeySize)
{
for (i = 0; i < 4; i++)
{
t[i] = expandedKey[(currentSize - 4) + i];
}
if (currentSize % size == 0)
{
core(t, rconIteration++);
}
if (size == SIZE_32 && ((currentSize % size) == 16))
{
for (i = 0; i < 4; i++)
t[i] = getSBoxValue(t[i]);
}
for (i = 0; i < 4; i++)
{

}
}
}
T
expandedKey[currentSize] = expandedKey[currentSize - size] ^ t[i];
currentSize++;

void subBytes(unsigned char *state)


VI
{
int i;
for (i = 0; i < 16; i++)
state[i] = getSBoxValue(state[i]);
}
void shiftRows(unsigned char *state)
{
int i;
for (i = 0; i < 4; i++)
shiftRow(state + i * 4, i);
}
void shiftRow(unsigned char *state, unsigned char nbr)
{
int i, j;
unsigned char tmp;
for (i = 0; i < nbr; i++)
{
tmp = state[0];
for (j = 0; j < 3; j++)
state[j] = state[j + 1];
state[3] = tmp;
}
}
void addRoundKey(unsigned char *state, unsigned char *roundKey)
{
int i;
for (i = 0; i < 16; i++)
state[i] = state[i] ^ roundKey[i];
}
unsigned char galois_multiplication(unsigned char a, unsigned char b)
{
unsigned char p = 0;
unsigned char counter;
unsigned char hi_bit_set;
for (counter = 0; counter < 8; counter++)
{
if ((b & 1) == 1)
p ^= a;
hi_bit_set = (a & 0x80);
a <<= 1;
if (hi_bit_set == 0x80)
a ^= 0x1b;
b >>= 1;
}

}
T
return p;

void mixColumns(unsigned char *state)


{
int i, j;
VI
unsigned char column[4];
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
column[j] = state[(j * 4) + i];
}
mixColumn(column);
for (j = 0; j < 4; j++)
{
state[(j * 4) + i] = column[j];
}
}
}
void mixColumn(unsigned char *column)
{
unsigned char cpy[4];
int i;
for (i = 0; i < 4; i++)
{
cpy[i] = column[i];
}
column[0] = galois_multiplication(cpy[0], 2) ^
galois_multiplication(cpy[3], 1) ^
galois_multiplication(cpy[2], 1) ^
galois_multiplication(cpy[1], 3);
column[1] = galois_multiplication(cpy[1], 2) ^
galois_multiplication(cpy[0], 1) ^
galois_multiplication(cpy[3], 1) ^
galois_multiplication(cpy[2], 3);
column[2] = galois_multiplication(cpy[2], 2) ^
galois_multiplication(cpy[1], 1) ^
galois_multiplication(cpy[0], 1) ^
galois_multiplication(cpy[3], 3);
column[3] = galois_multiplication(cpy[3], 2) ^
galois_multiplication(cpy[2], 1) ^
galois_multiplication(cpy[1], 1) ^
galois_multiplication(cpy[0], 3);
}
void aes_round(unsigned char *state, unsigned char *roundKey)
{
subBytes(state);
shiftRows(state);

}
T
mixColumns(state);
addRoundKey(state, roundKey);

void createRoundKey(unsigned char *expandedKey, unsigned char *roundKey)


{
int i, j;
VI
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
roundKey[(i + (j * 4))] = expandedKey[(i * 4) + j];
}
}
void aes_main(unsigned char *state, unsigned char *expandedKey, int
nbrRounds)
{
int i = 0;
unsigned char roundKey[16];
createRoundKey(expandedKey, roundKey);
addRoundKey(state, roundKey);
for (i = 1; i < nbrRounds; i++)
{
createRoundKey(expandedKey + 16 * i, roundKey);
aes_round(state, roundKey);
}
createRoundKey(expandedKey + 16 * nbrRounds, roundKey);
subBytes(state);
shiftRows(state);
addRoundKey(state, roundKey);
}
char aes_encrypt(unsigned char *input,
unsigned char *output,
unsigned char *key,
enum keySize size)
{
int expandedKeySize;
int nbrRounds;
unsigned char *expandedKey;
unsigned char block[16];
int i, j;
switch (size)
{
case SIZE_16:
nbrRounds = 10;
break;
case SIZE_24:
nbrRounds = 12;
break;
case SIZE_32:
nbrRounds = 14;
T
break;
default:
return ERROR_AES_UNKNOWN_KEYSIZE;
break;
}
expandedKeySize = (16 * (nbrRounds + 1));
VI
expandedKey = (unsigned char *)malloc(expandedKeySize * sizeof(unsigned
char));
if (expandedKey == NULL)
{
return ERROR_MEMORY_ALLOCATION_FAILED;
}
else
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
block[(i + (j * 4))] = input[(i * 4) + j];
}
expandKey(expandedKey, key, size, expandedKeySize);
aes_main(block, expandedKey, nbrRounds);
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
output[(i * 4) + j] = block[(i + (j * 4))];
}
free(expandedKey);
expandedKey = NULL;
}
return SUCCESS;
}
void invSubBytes(unsigned char *state)
{
int i;
for (i = 0; i < 16; i++)
state[i] = getSBoxInvert(state[i]);
}
void invShiftRows(unsigned char *state)
{
int i;
for (i = 0; i < 4; i++)
invShiftRow(state + i * 4, i);
}
void invShiftRow(unsigned char *state, unsigned char nbr)
{
int i, j;
unsigned char tmp;
for (i = 0; i < nbr; i++)
{
T
tmp = state[3];
for (j = 3; j > 0; j--)
state[j] = state[j - 1];
state[0] = tmp;
}
}
VI
void invMixColumns(unsigned char *state)
{
int i, j;
unsigned char column[4];
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
column[j] = state[(j * 4) + i];
}
invMixColumn(column);
for (j = 0; j < 4; j++)
{
state[(j * 4) + i] = column[j];
}
}
}
void invMixColumn(unsigned char *column)
{
unsigned char cpy[4];
int i;
for (i = 0; i < 4; i++)
{
cpy[i] = column[i];
}
column[0] = galois_multiplication(cpy[0], 14) ^
galois_multiplication(cpy[3], 9) ^
galois_multiplication(cpy[2], 13) ^
galois_multiplication(cpy[1], 11);
column[1] = galois_multiplication(cpy[1], 14) ^
galois_multiplication(cpy[0], 9) ^
galois_multiplication(cpy[3], 13) ^
galois_multiplication(cpy[2], 11);
column[2] = galois_multiplication(cpy[2], 14) ^
galois_multiplication(cpy[1], 9) ^
galois_multiplication(cpy[0], 13) ^
galois_multiplication(cpy[3], 11);
column[3] = galois_multiplication(cpy[3], 14) ^
galois_multiplication(cpy[2], 9) ^
galois_multiplication(cpy[1], 13) ^
galois_multiplication(cpy[0], 11);
}
void aes_invRound(unsigned char *state, unsigned
T
char *roundKey)
{
invShiftRows(state);
invSubBytes(state);
addRoundKey(state, roundKey);
invMixColumns(state);
VI
}
void aes_invMain(unsigned char *state, unsigned char *expandedKey, int
nbrRounds)
{
int i = 0;
unsigned char roundKey[16];
createRoundKey(expandedKey + 16 * nbrRounds, roundKey);
addRoundKey(state, roundKey);
for (i = nbrRounds - 1; i > 0; i--)
{
createRoundKey(expandedKey + 16 * i, roundKey);
aes_invRound(state, roundKey);
}
createRoundKey(expandedKey, roundKey);
invShiftRows(state);
invSubBytes(state);
addRoundKey(state, roundKey);
}
char aes_decrypt(unsigned char *input,
unsigned char *output,
unsigned char *key,
enum keySize size)
{
int expandedKeySize;
int nbrRounds;
unsigned char *expandedKey;
unsigned char block[16];
int i, j;
switch (size)
{
case SIZE_16:
nbrRounds = 10;
break;
case SIZE_24:
nbrRounds = 12;
break;
case SIZE_32:
nbrRounds = 14;
break;
default:
return ERROR_AES_UNKNOWN_KEYSIZE;
break;
}
T
expandedKeySize = (16 * (nbrRounds + 1));
expandedKey = (unsigned char *)malloc(expandedKeySize * sizeof(unsigned
char));
if (expandedKey == NULL)
{
return ERROR_MEMORY_ALLOCATION_FAILED;
VI
}
else
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
block[(i + (j * 4))] = input[(i * 4) + j];
}
expandKey(expandedKey, key, size, expandedKeySize);
aes_invMain(block, expandedKey, nbrRounds);
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
output[(i * 4) + j] = block[(i + (j * 4))];
}
free(expandedKey);
expandedKey = NULL;
}
return SUCCESS;
}
Output :

T
VI
Exp No:4 RSA Algorithm

Aim:
To develop a chipper scheme by using RSA ( Rivest–Shamir–Adleman)

Theory:
The RSA algorithm is used to encrypt and decrypt messages. It is an assymetric cyptographic
algorithm, i.e there are two different keys. This is also called as public key cryptography, since one of
the keys can be given to anyone.
Rules for Generating a Public Key:
1) Select two prime numbers p and q
2) Let n = p * q
3) Now , we select a number e such that e is 1 < e < φ (p) * φ ( q) and gcd(e, φ (p) * φ ( q) ) = 1

T
4) The public key is { e,n }
Rules for finding the Private Key:
1) Find a number d such that e * d mod φ (p) * φ ( q) = 1 , as we can see d is the multiplicate inverse
2) The private key is { d, n}
VI
Encryption:

Cipher = C = p e m od(n) , where p is the plaintext message to be encrypted


Decryption:

p = Cd m od(n), where C is the cipher text to be decrypted

Algorithm:
1) Initialize private key as 0
2) Initilize p and q as firstPrime and secondPrime with suitable prime numbers
3) Calculate N = p * q , phiN = ( p – 1) * ( q – 1)
4) Iterate from 2 to phiN to find a suitable for e such that the gcd of e and phiN is 1
5) Find the private key d which is the modular muliplicate inverse of e with respect to phiN

6) Find the cipher text C = p e m od(N) with the help of Math.pov() function
7) Find the decrypted text p = C d m od(N ) with the help of the Math.pov() function

Code:
import java.math.BigInteger;
import java.math.BigDecimal;

public class RSAExample {

public static int computeGCD(int smaller, int larger) {


if (smaller == 0)
return larger;
else
return computeGCD(larger % smaller, smaller);
}
public static void main(String[] args) {
int privateKey = 0, publicKeyExponent;
int originalMessage = 32;
int firstPrime = 5; // First prime number (p)
int secondPrime = 7; // Second prime number (q)
int N = firstPrime * secondPrime; // n = p*q
int phiN = (firstPrime - 1) * (secondPrime - 1); // phi(n) = (p-1)*(q-1)
System.out.println("phiN is equal to : " + phiN + "\n");

// Find a valid public key exponent e


T
+) {
for (publicKeyExponent = 2; publicKeyExponent < phiN; publicKeyExponent+

}
if (computeGCD(publicKeyExponent, phiN) == 1) {

}
break; // Found a valid e
VI
System.out.println("Public key exponent e is = " + publicKeyExponent);

// Calculate the private key exponent d


for (int multiplier = 0; multiplier <= 9; multiplier++) {
int temp = 1 + (multiplier * phiN);
if (temp % publicKeyExponent == 0) {
privateKey = temp / publicKeyExponent;
break; // Found a valid d
}
}
System.out.println("Private key d is : " + privateKey);

double cipherText;
BigInteger decryptedMessage;
cipherText = Math.pow(originalMessage, publicKeyExponent) % N;
System.out.println("Cipher text is : " + cipherText);

BigInteger bigModulusN = BigInteger.valueOf(N);


BigInteger bigCipherText = BigDecimal.valueOf(cipherText).toBigInteger();

// Decrypting the message


decryptedMessage = bigCipherText.pow(privateKey).mod(bigModulusN);

System.out.println("Decrypted text is : " + decryptedMessage);


}
}
Input:

p = 5, q = 7
message = 32

Output:

T
VI
Exp No: 5 Man in the Middle Attack in Diffie-Hellman Key Exhange

Aim:
To design a diffie hellman multiple key exchange protocol and perform man in thr middle attack

Theory:
Purpose of Diffie-Hellman Key exchannge algorithm is exchanging public keys and calculating secret
keys using public keys. The subsequent messages (further communications) are encrypted using secret
keys.
How Man-in-the-middle-attack takes place in Diffie-Hellman Key Exchange
In man-in- the-middle attack, the attacker exists in the public channel, the attacker receives
the public key of both sender and receiver and sends public keys to sender and receiver which is
T
generated by his own.

Algorithm:
1. Selected public numbers p and g, p is a prime number, called the “modulus” and g is called the
VI
base.

2. Selecting private numbers.

let Alice pick a private random number a and let Bob pick a private random number b, Eve picks
2 random numbers c and d.

3. Intercepting public values,


Eve intercepts Alice’s public value (ga(mod p)), block it from reaching Bob, and instead sends
Bob her own public value (gc(modp)) and Eve intercepts Bob’s public value (gb(mod p)), block it
from reaching Alice, and instead sends Alice her own public value (gd (modp))
4. Computing secret key
Alice will compute a key S1=gda(mod p), and Bob will compute a different key, S2=gcb(mod p)
5. If Alice uses S1 as a key to encrypt a later message to Bob, Eve can decrypt it, re-encrypt it using
S2, and send it to Bob. Bob and Alice won’t notice any problem and may assume their
communication is encrypted, but in reality, Eve can decrypt, read, modify, and then re-encrypt all
their conversations.
Code:
import java.math.BigInteger;
import java.util.Random;
import java.util.*;

class A {
private BigInteger n;

public A(BigInteger p) {
// Generating a random private number selected by Alice
Random random = new Random();
this.n = new BigInteger(p.bitLength() - 1, random).add(BigInteger.ONE);
}

public BigInteger getPrivateKey() {


return n;
}

public BigInteger publish(BigInteger g, BigInteger p) {


// Generating public values
return g.modPow(n, p);

}
T }

public BigInteger computeSecret(BigInteger gb, BigInteger p) {

}
// Computing secret key
return gb.modPow(n, p);
VI
class B {
private BigInteger a, b;

public B(BigInteger p) {
// Generating a random private number selected for Alice
// Generating a random private number selected for Bob
Random random = new Random();
this.a = new BigInteger(p.bitLength() - 1, random).add(BigInteger.ONE);
this.b = new BigInteger(p.bitLength() - 1, random).add(BigInteger.ONE);
}

public BigInteger[] getPrivateNumbers() {


return new BigInteger[]{a, b};
}

public BigInteger publish(BigInteger g, BigInteger p, int i) {


// Generating public values
return g.modPow(i == 0 ? a : b, p);
}

public BigInteger computeSecret(BigInteger ga, BigInteger p, int i) {


// Computing secret key
return ga.modPow(i == 0 ? a : b, p);
}
}

public class Main {


public static void main(String[] args) {
// Taking input for prime number (p) and generator (g)
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a prime number (p): ");
BigInteger p = scanner.nextBigInteger();
System.out.print("Enter a number (g): ");
BigInteger g = scanner.nextBigInteger();

// Creating instances for Alice, Bob, and Eve


A alice = new A(p);
A bob = new A(p);
B eve = new B(p);

// Printing out the private selected number by Alice and Bob


System.out.println("Alice selected (a): " + alice.getPrivateKey());
System.out.println("Bob selected (b): " + bob.getPrivateKey());
System.out.println("Eve selected private number for Alice (c): " +
eve.getPrivateNumbers()[0]);
System.out.println("Eve selected private number for Bob (d): " +
eve.getPrivateNumbers()[1]);

// Generating public values


BigInteger ga = alice.publish(g, p);
T BigInteger gb = bob.publish(g, p);
BigInteger[] ge = eve.getPrivateNumbers();

// Printing public values


System.out.println("Alice published (ga): " + ga);
System.out.println("Bob published (gb): " + gb);
System.out.println("Eve published value for Alice (gc): " + eve.publish(g, p, 0));
VI
System.out.println("Eve published value for Bob (gd): " + eve.publish(g, p, 1));

// Computing the secret keys


BigInteger sa = alice.computeSecret(ge[0], p);
BigInteger sea = eve.computeSecret(ga, p, 0);
BigInteger sb = bob.computeSecret(ge[1], p);
BigInteger seb = eve.computeSecret(gb, p, 1);

// Printing computed secret keys


System.out.println("Alice computed (S1) : " + sa);
System.out.println("Eve computed key for Alice (S1) : " + sea);
System.out.println("Bob computed (S2) : " + sb);
System.out.println("Eve computed key for Bob (S2) : " + seb);
}
}
Output:

T
VI

You might also like