You are on page 1of 30

Cryptography & Network Security Lab (EIT-751) List of Experiments

1. Implement the encryption and decryption of 8-bit data using Simplified DES Algorithm (created by Prof. Edward Schaefer) in C. 2. Implement Linear Congruential Algorithm to generate 5 pseudo-random numbers in C. 3. Implement Rabin-Miller Primality Testing Algorithm in C. 4. Implement the Euclid Algorithm to generate the GCD of an array of 10 integers in C. 5. Implement RSA algorithm for encryption and decryption in C. 6. Configure a mail agent to support Digital Certificates, send a mail and verify the correctness of this system using the configured parameters. 7. Configure SSH (Secure Shell) and send/receive a file on this connection to verify the correctness of this system using the configured parameters. 8. Configure a firewall to block the following for 5 minutes and verify the correctness of this system using the configured parameters: (a) Two neighborhood IP addresses on your LAN (b) All ICMP requests (c) All TCP SYN Packets

Implement Linear Congruential Algorithm to generate 5 pseudo-random numbers in C. #include<stdio.h> #include<stdint.h> uint16_t rand16(); uint32_t rand32(); uint16_t n, userChosenValue = 0; //Change this for different seed values. uint16_t numberOfValues = 10; //Change this depending on your needs. uint32_t seed; uint32_t mlcg,p,q; uint64_t tmpseed; int main(){ /* Calculate and print a series of 16 bit random numbers */ seed = (uint32_t)(userChosenValue + 1); printf("16 Bit:\n\n"); for (n=0;n<numberOfValues;n++){ printf("%.4x\n",rand16()); } /* Calculate and print a series of 32 bit random numbers */ seed = (uint32_t)(userChosenValue + 1); printf("\n\n32 Bit:\n\n"); for (n=0;n<numberOfValues;n++){ printf("%.8x\t\t\n",rand32()); } return 0; } /* Return the next 32 bit random number */ uint32_t rand32() { tmpseed = (uint64_t)33614U * (uint64_t)seed;

q = tmpseed; /* low */ q = q >> 1; p = tmpseed >> 32 ; /* hi */ mlcg = p + q; if (mlcg & 0x80000000) { mlcg = mlcg & 0x7FFFFFFF; mlcg++; } seed = mlcg; return mlcg; } /* Return low 16 bits of next 32 bit random number */ uint16_t rand16() { return (uint16_t)rand32(); }

Implement the Euclid Algorithm to generate the GCD of an array of 10 integers in C.

#include<stdio.h> #include<conio.h> int gcd(int num1, int num2) { if (num2) return gcd(num2, num1 % num2); else return num1 < 0 ? -num1 : num1; } int main() { int a,b,c; printf("\nEnter two numbers : "); scanf("%d%d",&a,&b); c= gcd(a,b); printf("\nGCD of %d and %d is : %d",a,b,c); getch(); return 0; } Java Code package de.vogella.algorithms.euclid; /** * Calculates the greatest common divisor for two numbers. * <p> * Based on the fact that the gcd from p and q is the same as the gcd from p and * p % q in case p is larger then q * * @author Lars Vogel * */ public class GreatestCommonDivisor {

public static int gcd(int p, int q) { if (q == 0) { return p; } return gcd(q, p % q); } // Test enable assert check via -ea as a VM argument public static void main(String[] args) { assert (gcd(4, 16) == 4); assert (gcd(16, 4) == 4); assert (gcd(15, 60) == 15); assert (gcd(15, 65) == 5); assert (gcd(1052, 52) == 4); } }

/* C program for the Implementation of RSA Algorithm Encrypt the text data and Decrypt the same */ #include<stdio.h> #include<conio.h> int phi,M,n,e,d,C,FLAG; int check() { int i; for(i=3;e%i==0 && phi%i==0;i+2)

{ FLAG = 1; return; } FLAG = 0; } void encrypt() { int i; C = 1; for(i=0;i< e;i++) C=C*M%n; C = C%n; printf(\n\tEncrypted keyword : %d,C); } void decrypt() { int i; M = 1; for(i=0;i< d;i++) M=M*C%n; M = M%n; printf(\n\tDecrypted keyword : %d,M); } void main() { int p,q,s; clrscr(); printf(Enter Two Relatively Prime Numbers\t: ); scanf(%d%d,&p,&q); n = p*q; phi=(p-1)*(q-1); printf(\n\tF(n) phi value\t= %d,phi); do { printf(\n\nEnter e which is prime number and less than phi \t: ,n); scanf(%d,&e); check(); }while(FLAG==1); d = 1; do { s = (d*e)%phi;

d++; }while(s!=1); d = d-1; printf(\n\tPublic Key\t: {%d,%d},e,n); printf(\n\tPrivate Key\t: {%d,%d},d,n); printf(\n\nEnter The Plain Text\t: ); scanf(%d,&M); encrypt(); printf(\n\nEnter the Cipher text\t: ); scanf(%d,&C); decrypt(); getch(); }

<<miller-rabin.c>>= #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "integer.h" Miller-Rabin results

modular exponentiation function Miller-Rabin pass random integer Miller-Rabin int main(int argc, char* argv[]) { srand(time(NULL)); if (strcmp(argv[1], "test") == 0) { integer n = string_to_integer(argv[2]); puts(miller_rabin(n) == PRIME ? "PRIME" : "COMPOSITE"); } else if (strcmp(argv[1], "genprime") == 0) { integer max = create_integer(atoi(argv[2])/COMPONENT_BITS); integer p = create_integer(max.num_components); set_zero_integer(max); max.c[max.num_components-1] = MAX_COMPONENT; do { random_integer(max, p); test for small factors } while (miller_rabin(p) == COMPOSITE); puts(integer_to_string(p)); } return 0; }

/* This is a program for Encryption and Decryption This program uses the Simple Data Encryption Standard (SDES) Algorithm. This Algo takes 8-bits of plaintext at a time and produces 8-bits of ciphertext. It uses 10-bits of key for Encryption and Decryption. */

#include<iostream.h> #include<stdio.h> #include<conio.h> #include<string.h> #include<stdlib.h> #include<assert.h> void mainmenu(int *); void menuEn(); void menuDe(); int DoEnDe(int); class SDES { private: char KEY[11],K1[9],K2[9],IPOutput[9],InvIPOutput[9]; char F1Output[9],F2Output[9]; char INPUT_BIT[9],OUTPUT_BIT[9]; public: unsigned char INPUT,OUTPUT; SDES(char *key); ~SDES(); void GenerateKeys(); char *Left_Shift(char *,int ); void conv_to_bits(unsigned char ); void IP(char *); void InvIP(char *); void DES_Encryption(unsigned char ); void DES_Decryption(unsigned char ); void Function_F(char *,char *,int );

char *EX_OR(char *,int ); char *SBOX0(char *); char *SBOX1(char *); void SDES::GetChar(); }; SDES::SDES(char *key) //Initializes the object with 10-bits key { int i; if (strlen(key)!=10) //Checks for valid length key { printf("\nInValid Key-Length %s %d",key,strlen(key)); getch(); exit(1); } for (i=0;i<10;i++) //Assigning the key privatly { KEY[i]=key[i]; } KEY[10]='\0'; GenerateKeys(); //Key Genaration Starts. Output: (K1/K2) } void SDES::GenerateKeys() { int P10[10]={3,5,2,7,4,10,1,9,8,6}; char P10_OP[11]; int P8[8]={6,3,7,4,8,5,10,9}; int i; //P10 permutation-array //P8 permutation-array //Output of P10 is to be stored here

char *P10LEFT,*pl,*pl1,*P10RIGHT,*pr,*pr1,*plpr;

/*P10 operation is done on main key*/ for (i=0;i<10;i++) P10_OP[i]=KEY[P10[i]-1]; P10_OP[10]='\0'; /*Dividing 10-bit output of P10 operation into two parts*/ for (i=0;i<5;i++) { P10LEFT[i]=P10_OP[i]; P10RIGHT[i]=P10_OP[i+5]; } P10LEFT[5]='\0'; P10RIGHT[5]='\0'; pl=new char[6]; pr=new char[6]; /*Perform Left-Circular shift by 1 bit on the two parts of P10 output*/ pl=Left_Shift(P10LEFT,1); pr=Left_Shift(P10RIGHT,1); /*Combine the above two parts after the left-cicular operation into 'plpr' string*/ for (i=0;i<5;i++) { plpr[i]=pl[i]; plpr[i+5]=pr[i]; }

plpr[10]='\0'; /*Performing P8 Operation on plpr and assigning to K1*/ for (i=0;i<8;i++) K1[i]=plpr[P8[i]-1]; K1[8]='\0'; //This is our first sub-key K1 /*Again performing Left-Circular-Shift(LCS) by 2 bits on the output of previous Left-Cicular-Shift(LCS)*/ pl1=Left_Shift(pl,2); pr1=Left_Shift(pr,2); /*Combining the output of above LCS2 into 1 string*/ for (i=0;i<5;i++) { plpr[i]=pl1[i]; plpr[i+5]=pr1[i]; } plpr[10]='\0'; /*Again performing P8 operation on the above combined string*/ for (i=0;i<8;i++) { K2[i]=plpr[P8[i]-1]; } K2[8]='\0'; //This is our second sub-key K2 }

/*Method to perform Left-Circular-Shift on bit-string*/ char *SDES::Left_Shift(char *bs,int n) { int length=strlen(bs); char *char_ptr,firstbit,*str; char_ptr = new char[length +1]; str=new char[length+1]; char_ptr=bs; int i,j; for (j=0;j<n;j++) { firstbit=char_ptr[0]; for (i=0;i<length-1;i++) { str[i]=char_ptr[i+1]; } str[length-1]=firstbit; char_ptr[length]='\0'; char_ptr=str; } char_ptr[length]='\0'; return(str); } /*Method to convert unsigned char to bit-string For Ex. 1="00000001"*/ void SDES::conv_to_bits(unsigned char ch) {

int i,bit; INPUT_BIT[8]='\0'; for (i=7;i>=0;i--) { bit=ch%2; ch=ch/2; if (bit!=0) INPUT_BIT[i]='1'; else INPUT_BIT[i]='0'; } } /*Method to perform Initial-Permutation*/ void SDES::IP(char *input) { int IPArray[8]={2,6,3,1,4,8,5,7}; int i; IPOutput[8]='\0'; for (i=0;i<8;i++) { IPOutput[i]=input[IPArray[i]-1]; } } /*Method to perform Inverse of Initial-Permutation*/ void SDES::InvIP(char *input) { int InvIPArray[8]={4,1,3,5,7,2,8,6};

int i; InvIPOutput[8]='\0'; for (i=0;i<8;i++) { InvIPOutput[i]=input[InvIPArray[i]-1]; } } /*Method to perform SDES-Encryption on 8-bit 'input'*/ void SDES::DES_Encryption(unsigned char input) { char LIP[5],RIP[5],L1[5],R1[5]; int i; INPUT=input; conv_to_bits(INPUT); //Converts the input to bit-string IP(INPUT_BIT); //gotoxy(1,1); printf("\nEncrpyting........."); /*Dividing the output of IP into 2 parts*/ for (i=0;i<4;i++) { LIP[i]=IPOutput[i]; RIP[i]=IPOutput[i+4]; } LIP[4]='\0'; RIP[4]='\0'; /*Sending the above divided parts to Function_F and sub-key K1*/ //Initial-Permutation

Function_F(LIP,RIP,1); /*Dividing the output of the Function_F into 2 parts*/ for (i=0;i<4;i++) { L1[i]=F1Output[i]; R1[i]=F1Output[4+i]; } L1[4]='\0'; R1[4]='\0'; /*This time the string-parameters swaped and uses sub-key K2*/ Function_F(R1,L1,2); /*Performing the Inverse IP on the output of the Funtion_F*/ InvIP(F1Output); //The output of the function will give us //Cipher-string /*Cipher string is converted back to unsigned char and stored in private-variable OUTPUT of this class*/ GetChar(); }

/*Decryption is just inverse of Encryption Here IP, InvIP, E/P, SBOX1 and SBOX2 are same But Function_F first operats on sub-key K2 and then on sub-key K1*/ void SDES::DES_Decryption(unsigned char input) { char LIP[5],RIP[5],L1[5],R1[5];

int i; INPUT=input; conv_to_bits(INPUT); IP(INPUT_BIT); //gotoxy(1,1); printf("\nDecrpyting........."); for (i=0;i<4;i++) { LIP[i]=IPOutput[i]; RIP[i]=IPOutput[i+4]; } LIP[4]='\0'; RIP[4]='\0'; Function_F(LIP,RIP,2); for (i=0;i<4;i++) { L1[i]=F1Output[i]; R1[i]=F1Output[4+i]; } L1[4]='\0'; R1[4]='\0'; Function_F(R1,L1,1); InvIP(F1Output); GetChar(); } //Initial-Permutation

void SDES::Function_F(char *linput,char *rinput,int key) { int E_P[8]={4,1,2,3,2,3,4,1}; //E/P Operation-Array int P4[4]={2,4,3,1}; int i; char E_POutput[9],*EXOR_Output,*LEXOR,*REXOR; char *SBOX0_Output,*SBOX1_Output; char SBOX_Output[5]; char P4_Output[5]; char fk_Output[5]; char Main_Output[9]; /*E/P Operaion is performed here*/ for (i=0;i<8;i++) { E_POutput[i]=rinput[E_P[i]-1]; } E_POutput[8]='\0'; /*Bitwise-EXOR is done on E/P Output and sub-key(K1/K2)*/ EXOR_Output=EX_OR(E_POutput,key); /*Divide the output of Exor in 2 parts*/ LEXOR=new char[strlen(EXOR_Output)/2+1]; REXOR=new char[strlen(EXOR_Output)/2+1]; for (i=0;i<strlen(EXOR_Output)/2;i++) { LEXOR[i]=EXOR_Output[i]; REXOR[i]=EXOR_Output[i+4]; //P4 Operation-Array

} LEXOR[4]=REXOR[4]='\0';

/*Peforming SBOX0 Operation on left 4 bits*/ SBOX0_Output=SBOX0(LEXOR); /*Peforming SBOX1 Operation on right 4 bits*/ SBOX1_Output=SBOX1(REXOR); /*Combining the 2-bits output of both SBOXES in one string*/ for (i=0;i<2;i++) { SBOX_Output[i]=SBOX0_Output[i]; SBOX_Output[i+2]=SBOX1_Output[i]; } SBOX_Output[4]='\0'; /*Performing the P4 operation on SBOX output*/ for (i=0;i<4;i++) { P4_Output[i]=SBOX_Output[P4[i]-1]; } P4_Output[4]='\0'; /*Performing the EXOR operation on 4-bits P4-output and 4-bits Leftinput of Funtion_F*/ for (i=0;i<4;i++) { if (P4_Output[i]==linput[i]) fk_Output[i]='0';

else fk_Output[i]='1'; } fk_Output[4]='\0'; /*Cancating the 4-bits output of above EXOR-operation and 4-bits Right-input of Function_F*/ for (i=0;i<4;i++) { Main_Output[i]=fk_Output[i]; Main_Output[i+4]=rinput[i]; } Main_Output[8]='\0'; /*Assigning this Cucaneted string to Private variable 'F1Output'*/ strcpy(F1Output,Main_Output); } /*This method EXORS the output ofE/P and sub-keys depending on the parameter k. k=1:subkey K1 k=2:subkey K2*/ char *SDES::EX_OR(char *ep,int k) { char *output,*key; int i,klen; output=new char[strlen(ep)+1]; key=new char[strlen(K1)+1]; if (k==1) { strcpy(key,K1); } else

{ if (k==2) { strcpy(key,K2); } else { printf("\n\nWrong Choice in the key parameter(1/2)"); getch(); exit(1); } } klen=strlen(K1); if (strlen(ep)!=klen) { printf("\ninput=%d is not equal to K=%d",strlen(ep),klen); printf("\n\nError in the Output of E/P (Length)..Press any key"); getch(); exit(1); } for (i=0;i<strlen(ep);i++) { if (ep[i]==key[i]) output[i]='0'; else output[i]='1'; } output[strlen(ep)]='\0'; return(output); } /*SBOX0 Operation is defined here*/

char *SDES::SBOX0(char *l) { int S0[4][4]={1,0,3,2, //S0 Matrix 3,2,1,0, 0,2,1,3, 3,1,3,2 }; char *bits[]={"00","01","10","11"}; char lrow[3],lcol[3]; char *SO; int i,lr,lc,b; SO=new char[3]; lrow[0]=l[0]; lrow[1]=l[3]; lcol[0]=l[1]; lcol[1]=l[2]; lrow[2]='\0'; lcol[2]='\0';

for (i=0;i<4;i++) { if (strcmp(lrow,bits[i])==0) lr=i; if (strcmp(lcol,bits[i])==0) lc=i; }

b=S0[lr][lc]; for (i=0;i<3;i++) SO[i]=bits[b][i]; SO[3]='\0'; return(SO); } /*SBOX1 Operation is defined here*/ char *SDES::SBOX1(char *l) { int S0[4][4]={0,1,2,3, //S1 Matrix 2,0,1,3, 3,0,1,0, 2,1,0,3 }; char *bits[]={"00","01","10","11"}; char lrow[3],lcol[3]; char *SO; int i,lr,lc,b; SO=new char[3]; lrow[0]=l[0]; lrow[1]=l[3]; lcol[0]=l[1]; lcol[1]=l[2]; lrow[2]='\0'; lcol[2]='\0';

for (i=0;i<4;i++) { if (strcmp(lrow,bits[i])==0) lr=i; if (strcmp(lcol,bits[i])==0) lc=i; } b=S0[lr][lc]; for (i=0;i<3;i++) SO[i]=bits[b][i]; SO[3]='\0'; return(SO); } /*Method to get back unsigned char from bit-string*/ void SDES::GetChar() { int i,j,in; unsigned char ch=0; char *bs; bs=new char[9]; bs=InvIPOutput; if (strlen(bs)>8) { printf("\nWRONG LENGTH STRING"); exit(0); } for (i=0;i<8;i++) { if (bs[i]=='1')

{ in=1; for (j=1;j<8-i;j++) { in=in*2; } ch=ch+in; } } OUTPUT=ch; } /*Destructor*/ SDES::~SDES() { }

char *sfname,*tfname; char *key;//="1010000010"; void main(void) { //clrscr(); unsigned char ch,ch1; int i,n=10,choice; while (1) { key = new char[11]; sfname = new char[20]; tfname = new char[20];

mainmenu(&choice); fflush(stdin); switch (choice) { case 1: menuEn(); DoEnDe(choice); break; case 2: menuDe(); DoEnDe(choice); break; case 3: exit(0); default: printf("\nWrong Choice Enter again\nPress any key to return to Main Menu.."); getch(); break; } } } void mainmenu(int *c) { //clrscr(); printf("\nWhat do you want to do.."); printf("\n1. Encryption"); printf("\n2. Decryption"); printf("\n3. Exit"); printf("\n\nEnter the choice? "); scanf("%d",c);

} void menuEn() { //clrscr(); sfname=new char[20]; tfname=new char[20]; key=new char[11]; printf("\nEncryption Menu\n\n"); printf("\nEnter the filename to be Encrypted: "); gets(sfname); printf("\nEnter the Target file name: "); gets(tfname); printf("\nEnter the 10-bits KEY: "); gets(key); printf("\n\nNotedown this key, as same key is used for Decryption"); //getch(); } void menuDe() { //clrscr(); sfname=new char[20]; tfname=new char[20]; key=new char[11]; printf("\nDecryption Menu\n\n"); printf("\nEnter the filename to be Decrypted: "); gets(sfname); printf("\nEnter the Target file name: "); gets(tfname); printf("\nEnter the 10-bits KEY: "); gets(key);

} int DoEnDe(int c) { SDES S(key); int i,n; n=10; //Number of Rounds unsigned char ch; FILE *fp; FILE *ft; fp=fopen(tfname,"w"); ft=fopen(sfname,"r"); if (fp==NULL) { printf("\nTarget File not opened SORRY"); getch(); fclose(fp); return(0); } if (ft==NULL) { printf("\nSource File not opened SORRY"); getch(); fclose(ft); return(0); } while (fread(&ch,1,1,ft)==1) { S.OUTPUT=ch; for (i=0;i<n;i++)

{ if (c==1) S.DES_Encryption(S.OUTPUT); if (c==2) S.DES_Decryption(S.OUTPUT); } fwrite(&S.OUTPUT,1,1,fp); } printf("\nCompleted!!!!!"); getch(); fclose(fp); fclose(ft); return(1); }

You might also like