DES Encryption and Decryption (Data Encryption Standard)

//main.cpp
////////////////////////////////////////////////////////////////////////
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
 
#include "DES.h"
 
char* Convert2Bin(char[]);
char* Binary(char);
void InsertInArray(char*,char[]);
char* Convert2Hex(char*);
char Hexa(char,char,char,char);
 
void main()
{
	char ed;
	char *data = new char[DATA_LENGTH];
	char *key = new char[KEY_TOTAL_LENGTH];
	data[0] = '';
	key[0] = '';
 
	char *tData = new char[64];
	char *tKey = new char[64];
 
	cout << endl << "Encryption/Decryption? E/D: ";
	cin >> ed;
 
	if (tolower(ed) == 'e')
	{
		//perform encryption
		cout << endl << "Starting Encryption..." << endl;
 
		cout << endl << "Enter Data to encrypt: ";
		cin >> tData;
		cout << endl << "Enter Encryption Key: ";
		cin >> tKey;
 
#ifdef SDES
		strcpy(data,tData);
		strcpy(key,tKey);
#else
		strcpy(data,Convert2Bin(tData));
		strcpy(key,Convert2Bin(tKey));
#endif
		CDES *des = new CDES(data,key);
		char* cipher = des->Encrypt();
 
#ifdef DES
		cipher = Convert2Hex(cipher);
#endif
 
		cout << endl << "Encrypted Text: " << cipher << endl;
	}
	else if (tolower(ed) == 'd')
	{
		//perform decryption
		cout << endl << "Starting Decryption..." << endl;
 
		cout << endl << "Enter Data to Decrypt: ";
		cin >> tData;
		cout << endl << "Enter Decryption Key: ";
		cin >> tKey;
 
#ifdef SDES
		strcpy(data,tData);
		strcpy(key,tKey);
#else
		strcpy(data,Convert2Bin(tData));
		strcpy(key,Convert2Bin(tKey));
#endif
		CDES *des = new CDES(data,key);
		char *plain = des->Decrypt();
 
#ifdef DES
		plain = Convert2Hex(plain);
#endif
 
		cout << endl << "Decrypted Text: " << plain << endl;
	}
	else
	{
		//invalid choice... neither e nor d
		cout << endl << "We support only e and d..." << endl;
	}
}
 
char* Convert2Hex(char* out)
{
	int i,j;
	char hexchar;
	char *put = new char[DATA_LENGTH/4];
 
	for (i = 0,j = 0 ; i < DATA_LENGTH ; j++, i += 4)
	{
		hexchar = Hexa(out[i],out[i+1],out[i+2],out[i+3]);
		put[j] = hexchar;
	}
 
	put[j] = '';
 
	return put;
}
 
char Hexa(char a, char b, char c, char d)
{
	if		(a == '0' && b == '0' && c == '0' && d == '0')
		return '0';
	else if (a == '0' && b == '0' && c == '0' && d == '1')
		return '1';
	else if (a == '0' && b == '0' && c == '1' && d == '0')
		return '2';
	else if (a == '0' && b == '0' && c == '1' && d == '1')
		return '3';
	else if (a == '0' && b == '1' && c == '0' && d == '0')
		return '4';
	else if (a == '0' && b == '1' && c == '0' && d == '1')
		return '5';
	else if (a == '0' && b == '1' && c == '1' && d == '0')
		return '6';
	else if (a == '0' && b == '1' && c == '1' && d == '1')
		return '7';
	else if (a == '1' && b == '0' && c == '0' && d == '0')
		return '8';
	else if (a == '1' && b == '0' && c == '0' && d == '1')
		return '9';
	else if (a == '1' && b == '0' && c == '1' && d == '0')
		return 'A';
	else if (a == '1' && b == '0' && c == '1' && d == '1')
		return 'B';
	else if (a == '1' && b == '1' && c == '0' && d == '0')
		return 'C';
	else if (a == '1' && b == '1' && c == '0' && d == '1')
		return 'D';
	else if (a == '1' && b == '1' && c == '1' && d == '0')
		return 'E';
	else
		return 'F';
}
 
char* Convert2Bin(char data[])
{
	unsigned int i;
	char *bins;
	char *array = new char[DATA_LENGTH];
	array[0] = '';
 
//	cout << endl << "Data to Convert : " << data;
 
	for (i = 0 ; i < strlen(data) ; i++)
	{
		bins = Binary(data[i]);
//		cout << endl << bins;
		InsertInArray(bins,array);
//		cout << endl << "Array : " << array;
	}
 
	return array;
}
 
void InsertInArray(char* b,char* arr)
{
	int i,j;
 
	for (i = strlen(arr),j = 0 ; j < 4 ; i++,j++)
	{
		arr[i] = b[j];
	}
 
	arr[i] = '';
}
 
char* Binary(char c)
{
	switch(c)
	{
	case '0':
		return "0000";
	case '1':
		return "0001";
	case '2':
		return "0010";
	case '3':
		return "0011";
	case '4':
		return "0100";
	case '5':
		return "0101";
	case '6':
		return "0110";
	case '7':
		return "0111";
	case '8':
		return "1000";
	case '9':
		return "1001";
	case 'A':
		return "1010";
	case 'B':
		return "1011";
	case 'C':
		return "1100";
	case 'D':
		return "1101";
	case 'E':
		return "1110";
	case 'F':
		return "1111";
	default:
		return "";
	}
}
 
////////////////////////////////////////////////////////////////////////
//DES.h
// DES.h: interface for the CDES class.
//
//////////////////////////////////////////////////////////////////////
 
#if !defined(AFX_DES_H__73DFD70F_BB37_4FD4_942C_54906CE719A1__INCLUDED_)
#define AFX_DES_H__73DFD70F_BB37_4FD4_942C_54906CE719A1__INCLUDED_
 
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
 
#define DES
 
#ifdef SDES
	#define KEY_TOTAL_LENGTH 10
	#define KEY_USED_BITS 10
	#define NO_OF_KEYS 2
	#define KEY_P_LENGTH 8
	#define DATA_LENGTH 8
	#define SROWS 4
	#define SCOLS 4
	#define NO_OF_S 2
#else if defined DES
	#define KEY_TOTAL_LENGTH 64
	#define KEY_USED_BITS 56
	#define NO_OF_KEYS 16
	#define KEY_P_LENGTH 48
	#define DATA_LENGTH 64
	#define SROWS 4
	#define SCOLS 16
	#define NO_OF_S 8
#endif
 
 
class CDES  
{
public:
	char* Decrypt();
	char* Encrypt();
	CDES(char* data, char* key);
	virtual ~CDES();
 
private:
	void GenKeys();
	char* PermuteSres_DES(char*);
	char* JoinSres_DES(char*,char*,char*,char*,char*,char*,char*,char*);
	void FillS7_DES();
	void FillS6_DES();
	void FillS5_DES();
	void FillS4_DES();
	void FillS3_DES();
	void FillS2_DES();
	void FillS1_DES();
	void FillS0_DES();
	void FillAllS();
	char* IPInverse(char*);
	char* Switch(char*);
	char* FKFunction(char*,int);
	char* FKFinal(char*,char*);
	char* XORLandP(char*,char*);
	void print(char*,int);
	void SampleKeys();
	char* PermuteSres(char*);
	char* JoinSres(char*,char*);
	char* Bin2bit(int);
	char* Bin4bit(int);
	int Dec2bit(char,char);
	int Dec4bit(char,char,char,char);
	int GetValue(int,int,int);
	char* GetSValue(char*,int);
	void FillS1_SDES();
	void FillS0_SDES();
	char XOR(char,char);
	char* XORwithKey(char*,int);
	char* ExtendedPermutation(char*);
	char* DataIP();
	char* DataIP_DES();
	void keyPermutationA(char*,int);
	char* JoinShifted(char*,char*);
	char* LeftShift(char*, char, int);
	char* keyIPermutation();
	char data[DATA_LENGTH];
	char Compkey[KEY_TOTAL_LENGTH];
 
	char key[NO_OF_KEYS][KEY_P_LENGTH];
 
	int S[NO_OF_S][SROWS][SCOLS];
};
 
#endif // !defined(AFX_DES_H__73DFD70F_BB37_4FD4_942C_54906CE719A1__INCLUDED_)
 
 
////////////////////////////////////////////////////////////////////////
//DES.cpp
// DES.cpp: implementation of the CDES class.
//
//////////////////////////////////////////////////////////////////////
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
 
#include "DES.h"
 
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
 
CDES::CDES(char* data, char* key)
{
	strcpy(this->data,data);
	this->data[strlen(this->data)] = '';
	strcpy(this->Compkey,key);
	this->Compkey[strlen(this->Compkey)] = '';
 
	cout << endl << "DATA:";
	print(this->data,DATA_LENGTH);
	cout << endl << "KEY:";
	print(this->Compkey,KEY_TOTAL_LENGTH);
 
	FillAllS();
//	SampleKeys();
}
 
CDES::~CDES()
{
 
}
 
char* CDES::Encrypt()
{
	// Calculate Keys
	GenKeys();
 
	// Begin Encryption
#ifdef SDES
	char *ip = DataIP(); // Initial Permutation on Input bits
#else
	char *ip = DataIP_DES();
#endif
 
	cout << endl << "Initial Permutation";
	print(ip,DATA_LENGTH);
 
	char *loopData = ip;
	char *FKr;
 
	for (int i = 1 ; i <= NO_OF_KEYS ; i++)
	{
		FKr = FKFunction(loopData,i);
 
		cout << endl << "FK" << i << " Result";
		print(FKr,DATA_LENGTH);
 
		if (i != NO_OF_KEYS)
		{
			loopData = Switch(FKr);
 
			cout << endl << "Switch Result";
			print(loopData,DATA_LENGTH);
		}
		else
		{
			loopData = FKr;
		}
	}
 
	char *IPinv = IPInverse(loopData);
 
	cout << endl << "IP Inverse";
	print(IPinv,DATA_LENGTH);
 
	return IPinv;
}
 
char* CDES::keyIPermutation()
{
#ifdef SDES
	char *keyP = new char[KEY_TOTAL_LENGTH];
 
	keyP[0] = Compkey[3-1];
	keyP[1] = Compkey[5-1];
	keyP[2] = Compkey[2-1];
	keyP[3] = Compkey[7-1];
	keyP[4] = Compkey[4-1];
	keyP[5] = Compkey[10-1];
	keyP[6] = Compkey[1-1];
	keyP[7] = Compkey[9-1];
	keyP[8] = Compkey[8-1];
	keyP[9] = Compkey[6-1];
#else
	char *keyP = new char[KEY_USED_BITS];
 
	keyP[0] = Compkey[57-1];
	keyP[1] = Compkey[49-1];
	keyP[2] = Compkey[41-1];
	keyP[3] = Compkey[33-1];
	keyP[4] = Compkey[25-1];
	keyP[5] = Compkey[17-1];
	keyP[6] = Compkey[9-1];
	keyP[7] = Compkey[1-1];
	keyP[8] = Compkey[58-1];
	keyP[9] = Compkey[50-1];
	keyP[10] = Compkey[42-1];
	keyP[11] = Compkey[34-1];
	keyP[12] = Compkey[26-1];
	keyP[13] = Compkey[18-1];
	keyP[14] = Compkey[10-1];
	keyP[15] = Compkey[2-1];
	keyP[16] = Compkey[59-1];
	keyP[17] = Compkey[51-1];
	keyP[18] = Compkey[43-1];
	keyP[19] = Compkey[35-1];
	keyP[20] = Compkey[27-1];
	keyP[21] = Compkey[19-1];
	keyP[22] = Compkey[11-1];
	keyP[23] = Compkey[3-1];
	keyP[24] = Compkey[60-1];
	keyP[25] = Compkey[52-1];
	keyP[26] = Compkey[44-1];
	keyP[27] = Compkey[63-1];
	keyP[28] = Compkey[63-1];
	keyP[29] = Compkey[55-1];
	keyP[30] = Compkey[47-1];
	keyP[31] = Compkey[39-1];
	keyP[32] = Compkey[31-1];
	keyP[33] = Compkey[23-1];
	keyP[34] = Compkey[15-1];
	keyP[35] = Compkey[7-1];
	keyP[36] = Compkey[62-1];
	keyP[37] = Compkey[54-1];
	keyP[38] = Compkey[46-1];
	keyP[39] = Compkey[38-1];
	keyP[40] = Compkey[30-1];
	keyP[41] = Compkey[22-1];
	keyP[42] = Compkey[14-1];
	keyP[43] = Compkey[6-1];
	keyP[44] = Compkey[61-1];
	keyP[45] = Compkey[53-1];
	keyP[46] = Compkey[45-1];
	keyP[47] = Compkey[37-1];
	keyP[48] = Compkey[29-1];
	keyP[49] = Compkey[21-1];
	keyP[50] = Compkey[13-1];
	keyP[51] = Compkey[5-1];
	keyP[52] = Compkey[28-1];
	keyP[53] = Compkey[20-1];
	keyP[54] = Compkey[12-1];
	keyP[55] = Compkey[4-1];
#endif
 
	return keyP;
}
 
char* CDES::LeftShift(char *keyPF, char LorR, int bits)
{
	char *sbits = new char[KEY_USED_BITS/2];
	int i,k;
 
	if (LorR == 'L')		// shift left bits
	{
		for (i = 0,k = 0 ; i < (KEY_USED_BITS/2) ; i++,k++)
		{
			sbits[i] = keyPF[k];
		}
	}
	else if (LorR == 'R')	// shift right bits
	{
		for (i = 0,k = (KEY_USED_BITS/2) ; i < (KEY_USED_BITS/2) ; i++,k++)
		{
			sbits[i] = keyPF[k];
		}
	}
 
	char temb;
 
	// Shift the Bits
	for (i = 1 ; i <= bits ; i++)
	{
		temb = sbits[(KEY_USED_BITS/2)-1];
		for (int k = 0 ; k < (KEY_USED_BITS/2) ; k++)
		{
			if ((KEY_USED_BITS/2)-1 == k)
				sbits[(k+((KEY_USED_BITS/2)-1)) % (KEY_USED_BITS/2)] = temb;
			else
				sbits[(k+((KEY_USED_BITS/2)-1)) % (KEY_USED_BITS/2)] = sbits[k];
		}
	}
 
	return sbits;
}
 
char* CDES::JoinShifted(char *Lbits, char *Rbits)
{
	char *key1 = new char[KEY_USED_BITS];
 
	int i,j;
 
	for (i = 0 ; i < (KEY_USED_BITS/2) ; i++)
	{
		key1[i] = Lbits[i];
	}
 
	for (i = (KEY_USED_BITS/2),j = 0 ; j < (KEY_USED_BITS/2) ; i++,j++)
	{
		key1[i] = Rbits[j];
	}
 
	return key1;
}
 
void CDES::keyPermutationA(char *keyJoined,int k)
{
#ifdef SDES
	key[k-1][0] = keyJoined[6-1];
	key[k-1][1] = keyJoined[3-1];
	key[k-1][2] = keyJoined[7-1];
	key[k-1][3] = keyJoined[4-1];
	key[k-1][4] = keyJoined[8-1];
	key[k-1][5] = keyJoined[5-1];
	key[k-1][6] = keyJoined[10-1];
	key[k-1][7] = keyJoined[9-1];
#else
	key[k-1][0] = keyJoined[14-1];
	key[k-1][1] = keyJoined[17-1];
	key[k-1][2] = keyJoined[11-1];
	key[k-1][3] = keyJoined[24-1];
	key[k-1][4] = keyJoined[1-1];
	key[k-1][5] = keyJoined[5-1];
	key[k-1][6] = keyJoined[3-1];
	key[k-1][7] = keyJoined[28-1];
	key[k-1][8] = keyJoined[15-1];
	key[k-1][9] = keyJoined[6-1];
	key[k-1][10] = keyJoined[21-1];
	key[k-1][11] = keyJoined[10-1];
	key[k-1][12] = keyJoined[23-1];
	key[k-1][13] = keyJoined[19-1];
	key[k-1][14] = keyJoined[12-1];
	key[k-1][15] = keyJoined[4-1];
	key[k-1][16] = keyJoined[26-1];
	key[k-1][17] = keyJoined[8-1];
	key[k-1][18] = keyJoined[16-1];
	key[k-1][19] = keyJoined[7-1];
	key[k-1][20] = keyJoined[27-1];
	key[k-1][21] = keyJoined[20-1];
	key[k-1][22] = keyJoined[13-1];
	key[k-1][23] = keyJoined[2-1];
	key[k-1][24] = keyJoined[41-1];
	key[k-1][25] = keyJoined[52-1];
	key[k-1][26] = keyJoined[31-1];
	key[k-1][27] = keyJoined[37-1];
	key[k-1][28] = keyJoined[47-1];
	key[k-1][29] = keyJoined[55-1];
	key[k-1][30] = keyJoined[30-1];
	key[k-1][31] = keyJoined[40-1];
	key[k-1][32] = keyJoined[51-1];
	key[k-1][33] = keyJoined[45-1];
	key[k-1][34] = keyJoined[33-1];
	key[k-1][35] = keyJoined[48-1];
	key[k-1][36] = keyJoined[44-1];
	key[k-1][37] = keyJoined[49-1];
	key[k-1][38] = keyJoined[39-1];
	key[k-1][39] = keyJoined[56-1];
	key[k-1][40] = keyJoined[34-1];
	key[k-1][41] = keyJoined[53-1];
	key[k-1][42] = keyJoined[46-1];
	key[k-1][43] = keyJoined[42-1];
	key[k-1][44] = keyJoined[50-1];
	key[k-1][45] = keyJoined[36-1];
	key[k-1][46] = keyJoined[29-1];
	key[k-1][47] = keyJoined[32-1];
#endif
}
 
char* CDES::DataIP()
{
	char *dataIP = new char[DATA_LENGTH];
 
	dataIP[0] = data[2-1];
	dataIP[1] = data[6-1];
	dataIP[2] = data[3-1];
	dataIP[3] = data[1-1];
	dataIP[4] = data[4-1];
	dataIP[5] = data[8-1];
	dataIP[6] = data[5-1];
	dataIP[7] = data[7-1];
 
	return dataIP;
}
 
char* CDES::DataIP_DES()
{
	char *dataIP = new char[DATA_LENGTH];
 
	dataIP[0] = data[58-1];
	dataIP[1] = data[50-1