Professional Documents
Culture Documents
Experim
ent No. Title Remarks
1 Write a Program to implement the Caesar cipher.
2 Write a Program to implement the hill cipher.
3
Write a program to implement Diffie-Hellman key exchange algorithm.
4
Write the case study for Random numbers using PRNG.
Examples :
Experiment 1
#include<stdio.h>
#include<conio.h>
int main()
{
char message[100], ch;
int i, key;
clrscr();
printf("\n****CEASER CYPHER****\nEnter a message to encrypt: ");
gets(message);
printf("\nEnter key: ");
scanf("%d", &key);
//encryption
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
// printf("%c ",ch);
if(islower(ch)){
ch = (ch + key-97)%26+97;
message[i] = ch;
}
else {
ch = (ch + key-65)%26+65;
message[i] = ch;
}
}
printf("\nEncrypted message: %s", message);
//decryption
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
//printf("%c ",ch);
if(islower(ch)){
ch = (ch - key-97)%26+97;
message[i] = ch;
}
else {
ch = (ch - key-65)%26+65;
message[i] = ch;
}
}
printf("\nDecrypted message: %s", message);
getch();
return 0;
}
Theory: Hill cipher is a polygraphic substitution cipher based on linear algebra.Each letter is
represented by a number modulo 26. Often the simple scheme A = 0, B = 1, …, Z = 25 is
used, but this is not an essential feature of the cipher. To encrypt a message, each block of
n letters (considered as an n-component vector) is multiplied by an invertible n × n matrix,
against modulus 26. To decrypt the message, each block is multiplied by the inverse of the
matrix used for encryption.
The matrix used for encryption is the cipher key, and it should be chosen randomly from the
set of invertible n × n matrices (modulo 26).
Examples:
#include<stdio.h>
#include<math.h>
#include<conio.h>
void main()
{
char aa[26] = "abcdefghijklmnopqrstuvwxyz";
char pt[10];
int m=3, d, q = 0, i, j, k[2][2],ki[2][2], p[4], pp[4], t[5], a=26, x,det;
// int k1[2][2], k2[2][2], det;
// clrscr();
printf("*****HILL CYPHER****\nenter the plaintext(3 letters in small) :");
scanf("%s", pt);
printf("\n%s\n",pt);
// m = strlen(pt);
{
if (pt[i] == aa[j])
{
t[q] = j % 26;
++q;
}
}
}
// Encryption
i= p[0] = ((k[0][0] * t[0]) + (k[0][1] * t[1]) +(k[0][2] * t[2]))%26;
j= p[1] = ((k[1][0] * t[0]) + (k[1][1] * t[1])+(k[1][2] * t[2]))%26;
q= p[2] = ((k[2][0] * t[0]) + (k[2][1] * t[1])+(k[2][2] * t[2]))%26;
printf("\n Encrypted string is :%c%c%c", aa[i],aa[j],aa[q]);
// finding determinant
for(i = 0; i < 3; i++)
det = det + (k[0][i] * (k[1][(i+1)%3] * k[2][(i+2)%3] - k[1][(i+2)%3] * k[2][(i+1)%3]));
printf("\n\ndeterminant: %f\n", det);
if (gcd(a,det)==1)
{
x=imod(a,det);
// printf("The Modular Multiplicative Inverse is: %d\n",imod(a,det));
}
//else
// printf("The numbers are not relatively prime.\n");
// DEcryption
pp[0] = ((ki[0][0] * p[0]) + (ki[0][1] * p[1]) +(ki[0][2] * p[2]))%26;
pp[1] = ((ki[1][0] * p[0]) + (ki[1][1] * p[1])+(ki[1][2] * p[2]))%26;
pp[2] = ((ki[2][0] * p[0]) + (ki[2][1] * p[1])+(ki[2][2] * p[2]))%26;
printf("\n cyper text :%s", p);
Theory: The Diffie-Hellman algorithm is being used to establish a shared secret that can be
used for secret
communications while exchanging data over a public network using the elliptic curve to
generate points and get the secret key using the parameters.
For the sake of simplicity and practical implementation of the algorithm, we will consider only
4 variables one prime P and G (a primitive root of P) and two private values a and b.
P and G are both publicly available numbers. Users (say Alice and Bob) pick private values
a and b and they generate a key and exchange it publicly, the opposite person received the
key and from that generates a secret key after which they have the same secret key to
encrypt.
/* This program calculates the Key for two persons using the Diffie-Hellman Key exchange
algorithm */
#include <stdio.h>
#include <stdlib.h>
a=rand();
printf(" \nprivate key for Alice:%d\n",a);
// Calculate Alice's Public Key (Alice will send A to Bob)
A = compute(g, a, p);
// choose secret integer for Bob's Pivate Key (only known to Bob)
b=rand();
printf("\n private key for Bob:%d\n",b);
// Calculate Bob's Public Key (Bob will send B to Alice)
B = compute(g, b, p);
// Alice and Bob Exchanges their Public Key A & B with each other
// Find Secret key
getch();
return 0;
}
Result: Hence Key is generated for two person using Diffie-Hellman key exchange
algorithms as above program.
Aim: Write the case study for Random numbers using PRNG.
Aim: Write a program to print pseudo random numbers in range [0, 100]. So we calculate
rand() % 100 which will return a number in [0, 99] so we add 1 to get the desired range
#include <stdio.h>
#include <stdlib.h>
// Driver program
int main(void)
{
// This program will create same sequence of
// random numbers on every program run
int i;
printf("\n")
for(i = 0; i<5; i++)
printf(" %d ", rand());
return 0;
}
Output
Result: If you rerun this program, you will get the same set of numbers.
To get different numbers every time you can use: srand(unsigned int seed) function; here
seed is an unsigned integer. So you will need a different value of seed every time you run
the program for that you can use current time which will always be different so you will get a
different set of numbers. By default, seed = 1 if you do not use srand function.
Program:
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
int main(void)
{ // This program will create different sequence of random numbers on every program run
Use current time as seed for random generator
int i;
printf("\n");
return 0;
Output
Aim: Write a program to implement encryption and decryption using one time pad cipher
(OTP).
Theory: Invented in 1917 by Gilbert Vernam, an engineer at AT&T Corporation in the USA.
It is Stream cipher with symmetric secret key
Key length = message length
It has been proven that OTP is impossible to crack if it is used correctly. It has the perfect
secrecy property and allows very fast encryption and decryption. However, the secret key
must be at least as long as the message, what makes it quite inconvenient to use while
sending large electronic information.
Both data encryption and decryption by using OTP takes place in the same way. All bytes of
the message (or of the ciphertext) are added XOR to bytes of the secret key.
The bytes are added one by one, and each addition produces one output byte:
mi XOR ki = ci
ci XOR ki = mi
M1 XOR K = C1
M2 XOR K = C2
C1 XOR C2 = M1 XOR K XOR M2 XOR K = M1 XOR M2
Having two original messages summed by XOR, the intruder can try to broke the cipher, by
using attacks based on language and encoding features.
Providing no integrity
It is possible to modify the ciphertext in such a way, that the receiver would not be able to
detect that. What is worse, the changes have a predictable impact on the message. If the
attackers know the structure of the message, they are able to change only the desired parts
of the message.
(m -> enc(m, k) -> m XOR k
(m XOR k) XOR p = m XOR k XOR p
m XOR k XOR p -> dec(m XOR p, k) -> m XOR p
Secret Sharing
OTP allows to share the secret key among a number of people. Then, the encrypted text can
be decoded only when all those parties use their parts of the key. Each person will know
only one subkey.
For example, if a secret key is shared among three parties, it will be required to have all
three subkeys XORed with the ciphertext in order to recover the original message.
Block Diagram:
Mathematical Function:
The only operation during the OTP encryption and decryption is Exclusive Or (XOR). The
key bytes are added XOR to the data bytes, one after another.
Each time, all the 8 bits in the first byte are added XOR to the 8 bits in the second bytes.
Program:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
main()
{
//All the text which ever entered is converted to upper and without spaces
int i,j,len1,len2,numstr[100],numkey[100],numcipher[100];
char str[100],key[100],cipher[100];
for(i=0;i<strlen(str);i++)
{
numcipher[i]=numstr[i]+numkey[i];
}
//To loop the number within 25 i.e if addition of numstr and numkey is 27 then numcipher
should be 1
for(i=0;i<strlen(str);i++)
{
if(numcipher[i]>25)
{
numcipher[i]=numcipher[i]-26;
}
}
printf("One Time Pad Cipher text is\n");
for(i=0;i<strlen(str);i++)
{
printf("%c",(numcipher[i]+'A'));
}
printf("\n");
return 0;
getch();
}
Result: Encryption and decryption using one time pad cipher (OTP) is implemented as
above.
1. A client (for example browser) sends its public key to the server and requests for some
data.
2. The server encrypts the data using client’s public key and sends the encrypted data.
3. Client receives this data and decrypts it.
Since this is asymmetric, nobody else except browser can decrypt the data even if a third
party has public key of browser.
The idea! The idea of RSA is based on the fact that it is difficult to factorize a large integer.
The public key consists of two numbers where one number is multiplication of two large
prime numbers. And private key is also derived from the same two prime numbers. So if
somebody can factorize the large number, the private key is compromised. Therefore
encryption strength totally lies on the key size and if we double or triple the key size, the
strength of encryption increases exponentially. RSA keys can be typically 1024 or 2048 bits
long, but experts believe that 1024 bit keys could be broken in the near future. But till now it
seems to be an infeasible task.
Program:
// C program for RSA asymmetric cryptographic algorithm. For demonstration values are
// relatively small compared to practical application
#include<stdio.h>
#include<math.h>
while (y > 0)
{
// If y is odd, multiply x with result
if (y & 1)
res = (res*x) % p;
int p = 3;
int q = 11;
int e = 3; //e stands for encrypt
int d; //d stands for decrypt
int n, phi; //public key
int msg = 4,c,m; // Message to be encrypted
n = p*q; //public key
phi = (p-1)*(q-1);
// Encryption c = (msg ^ e) % n
c = power(msg, e,n);
// Decryption m = (c ^ d) % n
m = power(c, d,n);
printf("\npower m=%u\n",m);
Experiment No. 7
Theory: The Data Encryption Standard (DES) is a symmetric-key block cipher published by
the National Institute of Standards and Technology (NIST).
DES is an implementation of a Feistel Cipher. It uses 16 round Feistel structure. The block
size is 64-bit. Though, key length is 64-bit, DES has an effective key length of 56 bits, since
8 of the 64 bits of the key are not used by the encryption algorithm (function as check bits
only). General Structure of DES is depicted in the following illustration –
Round function
Key schedule
Any additional processing − Initial and final permutation
Initial and Final Permutation
The initial and final permutations are straight Permutation boxes (P-boxes) that are inverses
of each other. They have no cryptography significance in DES. The initial and final
permutations are shown as follows –
Expansion Permutation Box − Since right input is 32-bit and round key is a 48-bit,
we first need to expand right input to 48 bits. Permutation logic is graphically
depicted in the following illustration –
Substitution Boxes. − The S-boxes carry out the real mixing (confusion). DES uses
8 S-boxes, each with a 6-bit input and a 4-bit output. Refer the following illustration –
#include<stdio.h>
int main()
{
int IPkey[8]={1,6,7,8,5,2,3,4};
int FPkey[8]={1,6,7,8,5,2,3,4};
int i,cnt;
char input[9], output[9],output2[9];
//clrscr();
printf("\n****Implementing DES Intial Permutation and reverse Permutation\nEnter your 8
bits input:");
scanf("%s",input);
input[8]='\0';
printf("Your input is:%s\n", input);
printf("IP key used : ");
output[i]=input[cnt-1];
}
printf("\nAfter Initial Permutation ");
output[8]='\0';
output2[i]=output[cnt-1];
}
printf("\nAfter Final(reverse) Permutation ");
output2[8]='\0';
Result: Hence the algorithm of Data Encryption Standard is implemented as above program.
Program: