#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <conio.h>windows
DWORDLONG dwlKey_PC_1[64] =
{ 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, 0 };spa
DWORDLONG dwlKey_PC_2[64] =
{ 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, 0 };get
DWORDLONG dwlData_IP[65] =
{ 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, 0 };string
DWORDLONG dwlData_Expansion[64] =
{ 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, 0 };it
DWORDLONG dwlData_P[33] =
{ 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, 0 };io
DWORDLONG dwlData_FP[65] =
{ 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, 0 };class
DWORDLONG OS[512] =
{ 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,stream
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,nio
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,di
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,
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,
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,
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,
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 };
class CShift
{
public:
DWORDLONG mask[16];
int step[16];
CShift()
{
for (int i = 0; i < 16; i++)
{
step[i] = 2;
mask[i] = 0xc000000;
}
step[0] = step[1] = step[8] = step[15] = 1;
mask[0] = mask[1] = mask[8] = mask[15] = 0x8000000;
}
};
class CDES
{
public:
CDES()
{
m_dwlKey = 0;
m_dwlData = 0;
ConvertTableToMask(dwlKey_PC_1, 64);
//PrintTable(dwlKey_PC_1,7,8);
ConvertTableToMask(dwlKey_PC_2, 56);
ConvertTableToMask(dwlData_IP, 64);
ConvertTableToMask(dwlData_Expansion, 32);
ConvertTableToMask(dwlData_FP, 64);
ConvertTableToMask(dwlData_P, 32);
Generate_S();
}
void PrintBit(DWORDLONG);
void EncryptKey(char *);
unsigned char* EncryptData(unsigned char *);
unsigned char* DescryptData(unsigned char*);
private:
void ConvertTableToMask(DWORDLONG *, int);
void Generate_S(void);
void PrintTable(DWORDLONG*, int, int);
DWORDLONG ProcessByte(unsigned char*, BOOL);
DWORDLONG PermuteTable(DWORDLONG, DWORDLONG*, int);
void Generate_K(void);
void EncryptKernel(void);
DWORDLONG Generate_B(DWORDLONG, DWORDLONG*);
/*For verify schedule permutation only*/
DWORDLONG UnPermuteTable(DWORDLONG, DWORDLONG*, int);
/**************************************/
DWORDLONG dwlData_S[9][4][16];
CShift m_shift;
DWORDLONG m_dwlKey;
DWORDLONG m_dwlData;
DWORDLONG m_dwl_K[17];
};
void CDES::EncryptKey(char *key)
{
printf("Original Key: %s\n", key);
m_dwlKey = ProcessByte((unsigned char*) key, TRUE);
// PrintBit(m_dwlKey);
m_dwlKey = PermuteTable(m_dwlKey, dwlKey_PC_1, 56);
// PrintBit(m_dwlKey);
Generate_K();
// printf("\n******************************************\n");
}
void CDES::Generate_K(void)
{
DWORDLONG C[17], D[17], tmp;
C[0] = m_dwlKey >> 28;
D[0] = m_dwlKey & 0xfffffff;
for (int i = 1; i <= 16; i++)
{
tmp = (C[i - 1] & m_shift.mask[i - 1]) >> (28 - m_shift.step[i - 1]);
C[i] = ((C[i - 1] << m_shift.step[i - 1]) | tmp) & 0x0fffffff;
tmp = (D[i - 1] & m_shift.mask[i - 1]) >> (28 - m_shift.step[i - 1]);
D[i] = ((D[i - 1] << m_shift.step[i - 1]) | tmp) & 0x0fffffff;
m_dwl_K[i] = (C[i] << 28) | D[i];
m_dwl_K[i] = PermuteTable(m_dwl_K[i], dwlKey_PC_2, 48);
}
}
DWORDLONG CDES::ProcessByte(unsigned char *key, BOOL shift)
{
unsigned char tmp;
DWORDLONG byte = 0;
int i = 0;
while (i < 8)
{
while (*key)
{
if (byte != 0)
byte <<= 8;
tmp = *key;
if (shift)
tmp <<= 1;
byte |= tmp;
i++;
key++;
}
if (i < 8)
byte <<= 8;
i++;
}
return byte;
}
DWORDLONG CDES::PermuteTable(DWORDLONG dwlPara, DWORDLONG* dwlTable,
int nDestLen)
{
int i = 0;
DWORDLONG tmp = 0, moveBit;
while (i < nDestLen)
{
moveBit = 1;
if (dwlTable[i] & dwlPara)
{
moveBit <<= nDestLen - i - 1;
tmp |= moveBit;
}
i++;
}
return tmp;
}
DWORDLONG CDES::UnPermuteTable(DWORDLONG dwlPara, DWORDLONG* dwlTable,
int nDestLen)
{
DWORDLONG tmp = 0;
int i = nDestLen - 1;
while (dwlPara != 0)
{
if (dwlPara & 0x01)
tmp |= dwlTable[i];
dwlPara >>= 1;
i--;
}
return tmp;
}
void CDES::PrintTable(DWORDLONG *dwlPara, int col, int row)
{
int i, j;
for (i = 0; i < row; i++)
{
printf("\n");
getch();
for (j = 0; j < col; j++)
PrintBit(dwlPara[i * col + j]);
}
}
void CDES::PrintBit(DWORDLONG bitstream)
{
char out[76];
int i = 0, j = 0, space = 0;
while (bitstream != 0)
{
if (bitstream & 0x01)
out[i++] = '1';
else
out[i++] = '0';
j++;
if (j % 8 == 0)
{
out[i++] = ' ';
space++;
}
bitstream = bitstream >> 1;
}
out[i] = '\0';
strcpy(out, strrev(out));
printf("%s **:%d\n", out, i - space);
}
void CDES::ConvertTableToMask(DWORDLONG *mask, int max)
{
int i = 0;
DWORDLONG nBit = 1;
while (mask[i] != 0)
{
nBit = 1;
nBit <<= max - mask[i];
mask[i++] = nBit;
}
}
void CDES::Generate_S(void)
{
int i;
int j, m, n;
m = n = 0;
j = 1;
for (i = 0; i < 512; i++)
{
dwlData_S[j][m][n] = OS[i];
n = (n + 1) % 16;
if (!n)
{
m = (m + 1) % 4;
if (!m)
j++;
}
}
}
unsigned char * CDES::EncryptData(unsigned char *block)
{
unsigned char *EncrytedData = new unsigned char(15);
printf("Original Data: %s\n", block);
m_dwlData = ProcessByte(block, 0);
// PrintBit(m_dwlData);
m_dwlData = PermuteTable(m_dwlData, dwlData_IP, 64);
EncryptKernel();
// PrintBit(m_dwlData);
DWORDLONG bit6 = m_dwlData;
for (int i = 0; i < 11; i++)
{
EncrytedData[7 - i] = (unsigned char) (bit6 & 0x3f) + 46;
bit6 >>= 6;
}
EncrytedData[11] = '\0';
printf("\nAfter Encrypted: %s", EncrytedData);
for (int i = 0; i < 8; i++)
{
EncrytedData[7 - i] = (unsigned char) (m_dwlData & 0xff);
m_dwlData >>= 8;
}
EncrytedData[8] = '\0';
return EncrytedData;
}
void CDES::EncryptKernel(void)
{
int i = 1;
DWORDLONG L[17], R[17], B[9], EK, PSB;
L[0] = m_dwlData >> 32;
R[0] = m_dwlData & 0xffffffff;
for (i = 1; i <= 16; i++)
{
L[i] = R[i - 1];
R[i - 1] = PermuteTable(R[i - 1], dwlData_Expansion, 48); //Expansion R
EK = R[i - 1] ^ m_dwl_K[i]; //E Permutation
PSB = Generate_B(EK, B); //P Permutation
R[i] = L[i - 1] ^ PSB;
}
R[16] <<= 32;
m_dwlData = R[16] | L[16];
m_dwlData = PermuteTable(m_dwlData, dwlData_FP, 64);
}
unsigned char* CDES::DescryptData(unsigned char *desData)
{
int i = 1;
unsigned char *DescryptedData = new unsigned char(15);
DWORDLONG L[17], R[17], B[9], EK, PSB;
DWORDLONG dataPara;
dataPara = ProcessByte(desData, 0);
dataPara = PermuteTable(dataPara, dwlData_IP, 64);
R[16] = dataPara >> 32;
L[16] = dataPara & 0xffffffff;
for (i = 16; i >= 1; i--)
{
R[i - 1] = L[i];
L[i] = PermuteTable(L[i], dwlData_Expansion, 48); //Expansion L
EK = L[i] ^ m_dwl_K[i]; //E Permutation
PSB = Generate_B(EK, B); //P Permutation
L[i - 1] = R[i] ^ PSB;
}
L[0] <<= 32;
dataPara = L[0] | R[0];
dataPara = PermuteTable(dataPara, dwlData_FP, 64);
// PrintBit(dataPara);
for (i = 0; i < 8; i++)
{
DescryptedData[7 - i] = (unsigned char) (dataPara & 0xff);
dataPara >>= 8;
}
DescryptedData[8] = '\0';
printf("After Decrypted: %s", DescryptedData);
printf("\n");
return DescryptedData;
}
DWORDLONG CDES::Generate_B(DWORDLONG EKPara, DWORDLONG *block)
{
int i, m, n;
DWORDLONG tmp = 0;
for (i = 8; i > 0; i--)
{
block[i] = EKPara & 0x3f;
m = (int) (block[i] & 0x20) >> 4;
m |= block[i] & 0x01;
n = (int) (block[i] << 1) >> 2;
block[i] = dwlData_S[i][m][n];
EKPara >>= 6;
}
for (i = 1; i <= 8; i++)
{
tmp |= block[i];
tmp <<= 4;
}
tmp >>= 4;
tmp = PermuteTable(tmp, dwlData_P, 32);
return tmp;
}
void main(void)
{
CDES des; des.EncryptKey("12345678"); unsigned char *result = des.EncryptData((unsigned char*) "DemoData"); des.DescryptData(result); }