DATA ENCRYPTION STANDARD PROGRAM in C++ for both Encryption and Decryption :-
/*=====================================================|
| AUTHOR :- RAVI SHANKAR KUMAR |
| FROM :- SITAMARHI(BIHAR),INDIA |
| Email :- ravisk.cs.14@gmail.com |
| NIT JALANDHAR, CSE PRE-FINAL YEAR |
|====================================================*/
/*PROGRAM CHECKER INPUT
19 52 87 121 155 188 223 241
1 35 69 103 137 171 205 239
*/
#include<bits/stdc++.h>
using namespace std;
//IP is Initial Permutation Block for Plain Text
//============================INPUT BLOCK============================
static const int IP[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};
//IIP is inverse of initial permutation block.
//Note :- It can be generated by IP also.
static const int IIP[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};
//C0 and D0 for 64bit key to 56bit key generation and rotation to get
//the permuted key of 48 bit using Compression Block of permutation.
static const int c0[28]={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};
static const int d0[28]={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};
static const int compression[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};
//EXPANSION BOX used to expand 32 bit Plain text to 48 bit for Xor operation
//with key for the current round
static const int expansion[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};
//8 S-box will be used in Each round of encryption and decryption.
static const int sbx[8][4][16]={//S1 BOX
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,
//S2 BOX
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,
//S3 BOX
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,
//S4 BOX
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,
//S5 BOX
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,
//S6 BOX
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,
//S7 BOX
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,
//S8 BOX
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};
static const int straightPer[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};
//================================HELPER FUNCTION=======================
/*
Here Function char_to_binary takes input as integer
equivalent of character and returns the number equivalent
in base b; Generally we needed b=2 in DES.
*/
char *char_to_binary(int num,int b)
{
char *bin=new char[9]; int k=7;
while(k>=0)
{
bin[k--]=num%b+'0';
num/=b;
}
bin[8]='\0';
return bin;
}
/*
Here Function binary_to_char takes character array as input,
convert them into decimal ascii value and return corresponding character
*/
char binary_to_char(char a[])
{
int num=0;
for(int i=0;i<8;i++)
num=(num*2)+(a[i]-'0');
char ans=num;
return ans;
}
/*
Here function Initial_Permute will permute the 2d char array
input according to Initial_Permutation block IP and will return
Permuted 2d char array output.
*/
char **Initial_Permute(char **input)
{
//Declaration of 2d char array.
char **output=new char*[8];
for(int i=0;i<8;i++) output[i]=new char[9];
//Mapping of input to output using IP
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
{
int row=(IP[i*8+j]-1)/8,col=(IP[i*8+j]-1)%8;
output[i][j]=input[row][col];
}
return output;
}
/*
Here function Initial_Permute will permute the 2d char array
input according to Initial_Permutation block IP and will return
Permuted 2d char array output.
*/
char **Inv_Initial_Permute(char **input)
{
//Declaration of 2d char array.
char **output=new char*[8];
for(int i=0;i<8;i++) output[i]=new char[9];
//Mapping of input to output using IP
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
{
int row=(IIP[i*8+j]-1)/8,col=(IIP[i*8+j]-1)%8;
output[i][j]=input[row][col];
}
return output;
}
//This function is very simple.
char xors(char a,char b)
{
if(a==b) return '0';
else return '1';
}
//================================KEY GENERATION=======================
/*
Here function will convert 64 bit character of key to 56 bit char key
using C0 and D0 block.
*/
void convert_64_to_56(char **input,char **output)
{
//Maping using C0 and D0 block.
for(int i=0;i<28;i++)
{
int row=(c0[i]-1)/8,col=(c0[i]-1)%8;
output[0][i]=input[row][col];
row=(d0[i]-1)/8,col=(d0[i]-1)%8;
output[1][i]=input[row][col];
}
output[0][28]=output[1][28]='\0';
return;
}
/*
Here function left_shift will shift 56bit key by one bit.
You need to call it twice if you want to shift left by 2 bit.
*/
void left_shift(char **input)
{
char temp1=input[0][0],temp2=input[1][0];
for(int i=0;i<27;i++)
{
input[0][i]=input[0][i+1];
input[1][i]=input[1][i+1];
}
input[0][27]=temp1; input[1][27]=temp2;
return;
}
void key_generation(char key[],char **keys)
{
//Declare a 2d character array to store 64bit keys
char **binary=new char*[8];
for(int i=0;i<8;i++) binary[i]=new char[9];
//Initialize 64bit key by calling char_to_binary converter.
for(int i=0;i<8;i++)
binary[i]=char_to_binary(key[i],2);
//Call Initial Permutation of 64-bit Key.
//binary=Initial_Permute(binary);
//Call convert_64_to_56
char **output=new char*[2];
output[0]=new char[29];
output[1]=new char[29];
convert_64_to_56(binary,output);
//16 round key generation.
for(int i=0;i<16;i++)
{
//Call one time shift if round=1,2,9 or 16
//Else call twice.
if(i==0||i==1||i==8||i==15) left_shift(output);
else left_shift(output),left_shift(output);
//MAP shifted 2d array to round key using fin block
for(int k=0;k<48;k++)
{
int row=(compression[k]-1)/28,col=(compression[k]-1)%28;
keys[i][k]=output[row][col];
}
keys[i][48]='\0';
}
return;
}
//================================ENCRYPTION=======================
char *use_SBox(char inp[])
{
char *ans=new char[33];
char *temp=new char[9];
int row,col,indx=0,pos;
//USE all S-Box to compress each 6-bit into 4bit
for(int i=0;i<8;i++)
{
pos=i*6;
row=(inp[pos]-'0')*2+(inp[pos+5]-'0'); //First and last bit for row index
//Second,Third,Fourth and fifth bits for column index
col=(inp[pos+1]-'0')*8+(inp[pos+2]-'0')*4+(inp[pos+3]-'0')*2+(inp[pos+4]-'0');
temp=char_to_binary(sbx[i][row][col],2);
ans[indx++]=temp[4],ans[indx++]=temp[5],ans[indx++]=temp[6],ans[indx++]=temp[7];
}
return ans;
}
char *Encryption(char pt[],char **keys)
{
//Declare a 2d character array to store 64bit PlainText
char **binary=new char*[8];
for(int i=0;i<8;i++) binary[i]=new char[9];
//Initialize 64bit array by calling char_to_binary converter.
for(int i=0;i<8;i++)
binary[i]=char_to_binary(pt[i],2);
//Call Initial Permutation of 64-bit Key.
binary=Initial_Permute(binary);
//Break 64bit block into left and right block of 32bit each
char *left=new char[33];
char *right=new char[33];
char *temp=new char[33];
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
{
left[i*8+j]=binary[i][j];
right[i*8+j]=binary[i+4][j];
}
left[32]=right[32]='\0';
//Apply all 16 rounds to get final output.
for(int k=0;k<16;k++)
{
//Take copy of right part.
for(int i=0;i<32;i++) temp[i]=right[i];
temp[32]='\0';
//Expand 32bit right part to 48bit using expansion box
char *expands=new char[49];
for(int i=0;i<48;i++) expands[i]=temp[expansion[i]-1];
expands[48]='\0';
//XOR it with kth key block of 48 bit.
for(int i=0;i<48;i++) expands[i]=xors(expands[i],keys[k][i]);
//Apply all 8 S-box upon it to get 32bit output.
temp=use_SBox(expands);
//Apply stright permutation box
for(int i=0;i<32;i++) expands[i]=temp[straightPer[i]-1];
//XOR this output with left 32bit
for(int i=0;i<32;i++) left[i]=xors(left[i],expands[i]);
//SWAPS between left and right
for(int i=0;i<32;i++)
temp[i]=left[i],left[i]=right[i],right[i]=temp[i];
}
//SWAPS left and right because we don't have to swap in the last
//round but we have got the swapped value.
for(int i=0;i<32;i++)
temp[i]=left[i],left[i]=right[i],right[i]=temp[i];
//Make this 64 bit 1D to 2D array
for(int i=0;i<32;i++)
binary[i/8][i%8]=left[i],binary[(i+32)/8][(i+32)%8]=right[i];
//Apply inverse permutation box by calling Inv_Initial_Permute function
binary=Inv_Initial_Permute(binary);
//Convert this binary 64bit to 8 charactes.
for(int i=0;i<8;i++)
pt[i]=binary_to_char(binary[i]);
return pt;
}
//================================DECRYPTION=========================
char *Decryption(char pt[],char **keys)
{
//Declare a 2d character array to store 64bit PlainText
char **binary=new char*[8];
for(int i=0;i<8;i++) binary[i]=new char[9];
//Initialize 64bit array by calling char_to_binary converter.
for(int i=0;i<8;i++)
binary[i]=char_to_binary(pt[i],2);
//Call Initial Permutation of 64-bit Key.
binary=Initial_Permute(binary);
//Break 64bit block into left and right block of 32bit each
char *left=new char[33];
char *right=new char[33];
char *temp=new char[33];
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
{
left[i*8+j]=binary[i][j];
right[i*8+j]=binary[i+4][j];
}
left[32]=right[32]='\0';
//Apply all 16 rounds to get final output.
for(int k=0;k<16;k++)
{
//Take copy of right part.
for(int i=0;i<32;i++) temp[i]=right[i];
temp[32]='\0';
//Expand 32bit right part to 48bit using expansion box
char *expands=new char[49];
for(int i=0;i<48;i++) expands[i]=temp[expansion[i]-1];
expands[48]='\0';
//XOR it with kth key block of 48 bit.
for(int i=0;i<48;i++) expands[i]=xors(expands[i],keys[15-k][i]);
//Apply all 8 S-box upon it to get 32bit output.
temp=use_SBox(expands);
//Apply stright permutation box
for(int i=0;i<32;i++) expands[i]=temp[straightPer[i]-1];
//XOR this output with left 32bit
for(int i=0;i<32;i++) left[i]=xors(left[i],expands[i]);
//SWAPS between left and right
for(int i=0;i<32;i++)
temp[i]=left[i],left[i]=right[i],right[i]=temp[i];
}
//SWAPS left and right because we don't have to swap in the last
//round but we have got the swapped value.
for(int i=0;i<32;i++)
temp[i]=left[i],left[i]=right[i],right[i]=temp[i];
//Make this 64 bit 1D to 2D array
for(int i=0;i<32;i++)
binary[i/8][i%8]=left[i],binary[(i+32)/8][(i+32)%8]=right[i];
//Apply inverse permutation box by calling Inv_Initial_Permute function
binary=Inv_Initial_Permute(binary);
//Convert this binary 64bit to 8 charactes.
for(int i=0;i<8;i++)
pt[i]=binary_to_char(binary[i]);
return pt;
}
//================================MAIN FUNCTION=======================
int main()
{
//Declare and take input key string of 8 characters
char *key=new char[9];
cout<<"Enter a key string : ";
cin>>key;
//Declare 2d keys array to store all 16 round keys
char **keys=new char*[16];
for(int i=0;i<16;i++) keys[i]=new char[49];
//Call key Generation function
key_generation(key,keys);
for(int i=0;i<16;i++)
printf("Key for round %2d : %s\n",i+1,keys[i]);
//Declare and take input plain text string of 8 characters
char *pt=new char[9];
cout<<"Enter plain text of 8 character : ";
cin>>pt;
//Call Encryption function to encrypt the plain text
pt=Encryption(pt,keys);
cout<<"Encrypted text = "<<pt<<endl;
//Call Decryption function to decrypt the encrypted text
pt=Decryption(pt,keys);
cout<<"Decrypted text = "<<pt<<endl;
return 0;
}
| AUTHOR :- RAVI SHANKAR KUMAR |
| FROM :- SITAMARHI(BIHAR),INDIA |
| Email :- ravisk.cs.14@gmail.com |
| NIT JALANDHAR, CSE PRE-FINAL YEAR |
|====================================================*/
/*PROGRAM CHECKER INPUT
19 52 87 121 155 188 223 241
1 35 69 103 137 171 205 239
*/
#include<bits/stdc++.h>
using namespace std;
//IP is Initial Permutation Block for Plain Text
//============================INPUT BLOCK============================
static const int IP[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};
//IIP is inverse of initial permutation block.
//Note :- It can be generated by IP also.
static const int IIP[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};
//C0 and D0 for 64bit key to 56bit key generation and rotation to get
//the permuted key of 48 bit using Compression Block of permutation.
static const int c0[28]={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};
static const int d0[28]={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};
static const int compression[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};
//EXPANSION BOX used to expand 32 bit Plain text to 48 bit for Xor operation
//with key for the current round
static const int expansion[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};
//8 S-box will be used in Each round of encryption and decryption.
static const int sbx[8][4][16]={//S1 BOX
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,
//S2 BOX
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,
//S3 BOX
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,
//S4 BOX
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,
//S5 BOX
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,
//S6 BOX
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,
//S7 BOX
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,
//S8 BOX
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};
static const int straightPer[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};
//================================HELPER FUNCTION=======================
/*
Here Function char_to_binary takes input as integer
equivalent of character and returns the number equivalent
in base b; Generally we needed b=2 in DES.
*/
char *char_to_binary(int num,int b)
{
char *bin=new char[9]; int k=7;
while(k>=0)
{
bin[k--]=num%b+'0';
num/=b;
}
bin[8]='\0';
return bin;
}
/*
Here Function binary_to_char takes character array as input,
convert them into decimal ascii value and return corresponding character
*/
char binary_to_char(char a[])
{
int num=0;
for(int i=0;i<8;i++)
num=(num*2)+(a[i]-'0');
char ans=num;
return ans;
}
/*
Here function Initial_Permute will permute the 2d char array
input according to Initial_Permutation block IP and will return
Permuted 2d char array output.
*/
char **Initial_Permute(char **input)
{
//Declaration of 2d char array.
char **output=new char*[8];
for(int i=0;i<8;i++) output[i]=new char[9];
//Mapping of input to output using IP
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
{
int row=(IP[i*8+j]-1)/8,col=(IP[i*8+j]-1)%8;
output[i][j]=input[row][col];
}
return output;
}
/*
Here function Initial_Permute will permute the 2d char array
input according to Initial_Permutation block IP and will return
Permuted 2d char array output.
*/
char **Inv_Initial_Permute(char **input)
{
//Declaration of 2d char array.
char **output=new char*[8];
for(int i=0;i<8;i++) output[i]=new char[9];
//Mapping of input to output using IP
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
{
int row=(IIP[i*8+j]-1)/8,col=(IIP[i*8+j]-1)%8;
output[i][j]=input[row][col];
}
return output;
}
//This function is very simple.
char xors(char a,char b)
{
if(a==b) return '0';
else return '1';
}
//================================KEY GENERATION=======================
/*
Here function will convert 64 bit character of key to 56 bit char key
using C0 and D0 block.
*/
void convert_64_to_56(char **input,char **output)
{
//Maping using C0 and D0 block.
for(int i=0;i<28;i++)
{
int row=(c0[i]-1)/8,col=(c0[i]-1)%8;
output[0][i]=input[row][col];
row=(d0[i]-1)/8,col=(d0[i]-1)%8;
output[1][i]=input[row][col];
}
output[0][28]=output[1][28]='\0';
return;
}
/*
Here function left_shift will shift 56bit key by one bit.
You need to call it twice if you want to shift left by 2 bit.
*/
void left_shift(char **input)
{
char temp1=input[0][0],temp2=input[1][0];
for(int i=0;i<27;i++)
{
input[0][i]=input[0][i+1];
input[1][i]=input[1][i+1];
}
input[0][27]=temp1; input[1][27]=temp2;
return;
}
void key_generation(char key[],char **keys)
{
//Declare a 2d character array to store 64bit keys
char **binary=new char*[8];
for(int i=0;i<8;i++) binary[i]=new char[9];
//Initialize 64bit key by calling char_to_binary converter.
for(int i=0;i<8;i++)
binary[i]=char_to_binary(key[i],2);
//Call Initial Permutation of 64-bit Key.
//binary=Initial_Permute(binary);
//Call convert_64_to_56
char **output=new char*[2];
output[0]=new char[29];
output[1]=new char[29];
convert_64_to_56(binary,output);
//16 round key generation.
for(int i=0;i<16;i++)
{
//Call one time shift if round=1,2,9 or 16
//Else call twice.
if(i==0||i==1||i==8||i==15) left_shift(output);
else left_shift(output),left_shift(output);
//MAP shifted 2d array to round key using fin block
for(int k=0;k<48;k++)
{
int row=(compression[k]-1)/28,col=(compression[k]-1)%28;
keys[i][k]=output[row][col];
}
keys[i][48]='\0';
}
return;
}
//================================ENCRYPTION=======================
char *use_SBox(char inp[])
{
char *ans=new char[33];
char *temp=new char[9];
int row,col,indx=0,pos;
//USE all S-Box to compress each 6-bit into 4bit
for(int i=0;i<8;i++)
{
pos=i*6;
row=(inp[pos]-'0')*2+(inp[pos+5]-'0'); //First and last bit for row index
//Second,Third,Fourth and fifth bits for column index
col=(inp[pos+1]-'0')*8+(inp[pos+2]-'0')*4+(inp[pos+3]-'0')*2+(inp[pos+4]-'0');
temp=char_to_binary(sbx[i][row][col],2);
ans[indx++]=temp[4],ans[indx++]=temp[5],ans[indx++]=temp[6],ans[indx++]=temp[7];
}
return ans;
}
char *Encryption(char pt[],char **keys)
{
//Declare a 2d character array to store 64bit PlainText
char **binary=new char*[8];
for(int i=0;i<8;i++) binary[i]=new char[9];
//Initialize 64bit array by calling char_to_binary converter.
for(int i=0;i<8;i++)
binary[i]=char_to_binary(pt[i],2);
//Call Initial Permutation of 64-bit Key.
binary=Initial_Permute(binary);
//Break 64bit block into left and right block of 32bit each
char *left=new char[33];
char *right=new char[33];
char *temp=new char[33];
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
{
left[i*8+j]=binary[i][j];
right[i*8+j]=binary[i+4][j];
}
left[32]=right[32]='\0';
//Apply all 16 rounds to get final output.
for(int k=0;k<16;k++)
{
//Take copy of right part.
for(int i=0;i<32;i++) temp[i]=right[i];
temp[32]='\0';
//Expand 32bit right part to 48bit using expansion box
char *expands=new char[49];
for(int i=0;i<48;i++) expands[i]=temp[expansion[i]-1];
expands[48]='\0';
//XOR it with kth key block of 48 bit.
for(int i=0;i<48;i++) expands[i]=xors(expands[i],keys[k][i]);
//Apply all 8 S-box upon it to get 32bit output.
temp=use_SBox(expands);
//Apply stright permutation box
for(int i=0;i<32;i++) expands[i]=temp[straightPer[i]-1];
//XOR this output with left 32bit
for(int i=0;i<32;i++) left[i]=xors(left[i],expands[i]);
//SWAPS between left and right
for(int i=0;i<32;i++)
temp[i]=left[i],left[i]=right[i],right[i]=temp[i];
}
//SWAPS left and right because we don't have to swap in the last
//round but we have got the swapped value.
for(int i=0;i<32;i++)
temp[i]=left[i],left[i]=right[i],right[i]=temp[i];
//Make this 64 bit 1D to 2D array
for(int i=0;i<32;i++)
binary[i/8][i%8]=left[i],binary[(i+32)/8][(i+32)%8]=right[i];
//Apply inverse permutation box by calling Inv_Initial_Permute function
binary=Inv_Initial_Permute(binary);
//Convert this binary 64bit to 8 charactes.
for(int i=0;i<8;i++)
pt[i]=binary_to_char(binary[i]);
return pt;
}
//================================DECRYPTION=========================
char *Decryption(char pt[],char **keys)
{
//Declare a 2d character array to store 64bit PlainText
char **binary=new char*[8];
for(int i=0;i<8;i++) binary[i]=new char[9];
//Initialize 64bit array by calling char_to_binary converter.
for(int i=0;i<8;i++)
binary[i]=char_to_binary(pt[i],2);
//Call Initial Permutation of 64-bit Key.
binary=Initial_Permute(binary);
//Break 64bit block into left and right block of 32bit each
char *left=new char[33];
char *right=new char[33];
char *temp=new char[33];
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
{
left[i*8+j]=binary[i][j];
right[i*8+j]=binary[i+4][j];
}
left[32]=right[32]='\0';
//Apply all 16 rounds to get final output.
for(int k=0;k<16;k++)
{
//Take copy of right part.
for(int i=0;i<32;i++) temp[i]=right[i];
temp[32]='\0';
//Expand 32bit right part to 48bit using expansion box
char *expands=new char[49];
for(int i=0;i<48;i++) expands[i]=temp[expansion[i]-1];
expands[48]='\0';
//XOR it with kth key block of 48 bit.
for(int i=0;i<48;i++) expands[i]=xors(expands[i],keys[15-k][i]);
//Apply all 8 S-box upon it to get 32bit output.
temp=use_SBox(expands);
//Apply stright permutation box
for(int i=0;i<32;i++) expands[i]=temp[straightPer[i]-1];
//XOR this output with left 32bit
for(int i=0;i<32;i++) left[i]=xors(left[i],expands[i]);
//SWAPS between left and right
for(int i=0;i<32;i++)
temp[i]=left[i],left[i]=right[i],right[i]=temp[i];
}
//SWAPS left and right because we don't have to swap in the last
//round but we have got the swapped value.
for(int i=0;i<32;i++)
temp[i]=left[i],left[i]=right[i],right[i]=temp[i];
//Make this 64 bit 1D to 2D array
for(int i=0;i<32;i++)
binary[i/8][i%8]=left[i],binary[(i+32)/8][(i+32)%8]=right[i];
//Apply inverse permutation box by calling Inv_Initial_Permute function
binary=Inv_Initial_Permute(binary);
//Convert this binary 64bit to 8 charactes.
for(int i=0;i<8;i++)
pt[i]=binary_to_char(binary[i]);
return pt;
}
//================================MAIN FUNCTION=======================
int main()
{
//Declare and take input key string of 8 characters
char *key=new char[9];
cout<<"Enter a key string : ";
cin>>key;
//Declare 2d keys array to store all 16 round keys
char **keys=new char*[16];
for(int i=0;i<16;i++) keys[i]=new char[49];
//Call key Generation function
key_generation(key,keys);
for(int i=0;i<16;i++)
printf("Key for round %2d : %s\n",i+1,keys[i]);
//Declare and take input plain text string of 8 characters
char *pt=new char[9];
cout<<"Enter plain text of 8 character : ";
cin>>pt;
//Call Encryption function to encrypt the plain text
pt=Encryption(pt,keys);
cout<<"Encrypted text = "<<pt<<endl;
//Call Decryption function to decrypt the encrypted text
pt=Decryption(pt,keys);
cout<<"Decrypted text = "<<pt<<endl;
return 0;
}