📄 dodes.cpp
字号:
//File name: doDes.cpp
// use DES algrithom to encryption or decryption a segment
//of memory
// interface:
// setKey(char *k)-----Set the Key for DES
// encryption(char *memory,DWORD length)
// decryption(char *memory,DWORD length)
//==================================================================
//Public data for encryption and decryption
// two table for first selection and last selection
#include "doDes.h"
//#include "string.h" // for strlen....
char ip[64]={ /* initial permutation P */
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
};
char fp[64]={ /* final permutation F */
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
};
// encryption a memory block
BOOL CDES::encryption (void *memory,DWORD pLength)
{
DWORD i,j;
__int64 *pDat,iDat,leftPart,rightPart,temp;
if(pLength%8){
errorNumber=ERR_LENGTH;
return FALSE;
}
if(pTable==NULL){
errorNumber=ERR_ALLOCATEMEMORY;
return FALSE;
}
for(i=0,pDat=(__int64 *)memory
;i<pLength;i+=8,pDat++){
// first shuffle
iDat=shuffle(*pDat,ip);
//divide to 2 partion
leftPart =0xffffffff & iDat; // low 32bits
rightPart=0xffffffff & (iDat>>32); // high 32 bits
//do encryption function 16 times
for(j=0;j<16;j++){
temp=rightPart;
rightPart=expand(rightPart); //convert 32 to 48
rightPart^=subKey[j]; //XOR
rightPart=deflate(rightPart); //convert 48 to 32 bits
rightPart=shuffle32(rightPart);// shuffle 32 bits
rightPart^=leftPart;
leftPart=temp;
}
//combination
iDat=(leftPart<<32) | rightPart;
//last shuffle
*pDat=shuffle(iDat,fp);
}
return TRUE; // finished successfully
}
BOOL CDES::decryption(void *memory,DWORD pLength)
{ DWORD i,j;
__int64 *pDat,iDat,leftPart,rightPart,temp;
if(pLength%8){
errorNumber=ERR_LENGTH;
return FALSE;
}
if(pTable==NULL){
errorNumber=ERR_ALLOCATEMEMORY;
return FALSE;
}
for(i=0,pDat=(__int64 *)memory
;i<pLength;i+=8,pDat++){
// first shuffle
iDat=shuffle(*pDat,ip);
//divide to 2 partion
leftPart =0xffffffff & iDat; // low 32bits
rightPart=0xffffffff & (iDat>>32); // high 32 bits
//do encryption function 16 times
for(j=0;j<16;j++){
temp=rightPart;
rightPart=expand(rightPart); //convert 32 to 48
rightPart^=subKey[15-j]; //XOR
rightPart=deflate(rightPart); //convert 48 to 32 bits
rightPart=shuffle32(rightPart);// shuffle 32 bits
rightPart^=leftPart;
leftPart=temp;
}
//combination
iDat=(leftPart<<32) | rightPart;
//last shuffle
*pDat=shuffle(iDat,fp);
}
return TRUE; // finished successfully
}
__int64 CDES::expand(__int64 x)
{
char exp[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
};
__int64 r;
int i;
for(i=0,r=0;i<48;i++){
if(x & bitTable[exp[i]-1])
r|=bitTable[i];
}
//r= x & bitTable[31] ? 1:0; //32 =>0
/*
r|=(x<< 1)& (__int64)0x3e; //1,2,3,4,5
r|=(x<<( 7- 4))& (__int64)0xfc0; //4,5,6,..9
r|=(x<<(13- 8))& (__int64)0x3f000; //8,9...13
r|=(x<<(19-12))& (__int64)0xfc0000; //12,13,..17
r|=(x<<(25-16))& (__int64)0x3f000000; //,16,17,.21
r|=(x<<(31-20))& (__int64)0xfc0000000; //20,21,..25
r|=(x<<(37-24))& (__int64)0x3f000000000;//24,25..29
r|=(x<<(42-28))& (__int64)0xfc0000000000;//28,29...32
if(x&0x1)
r|=bitTable[47]; // bit 1=> 48
*/
//r|=(x<< 1)& (__int64)0x3e; //1,2,3,4,5
//r|=x & (__int64)3; //4,5
//r|=
return r;
}
//convert 48bits to 32bits
//
__int64 CDES::deflate(__int64 x)
{
__int64 r; //return value
char s12,s34,s56,s78;
/*s12=*(pTable +(int)(x&0xfff)); //S1 and S2
s34=*(pTable+ 4*1024+(int)((x>>12)&0xfff)); // S3,S4
s56=*(pTable+ 8*1024+(int)((x>>24)&0xfff)); // S5,S6
s78=*(pTable+12*1024+(int)((x>>36)&0xfff)); // S7,S8
*/
s12=*(pTable +(int)(((x&0xff)<<4)|((x&0xf000)>>12))); //S1 and S2
s34=*(pTable+ 4*1024+
(int)((x&0xf00)| (x>>16)&0xff)); // S3,S4
s56=*(pTable+ 8*1024+
(int)( ((x>>36)&0xf) | ((x>>20)&0xff0 ) )); // S5,S6
s78=*(pTable+12*1024+
(int)( ((x>>24)&0xf00)| ((x>>40)&0xff ) )); // S7,S8
r=0;
r|=((__int64)s12&0xff)|(((__int64)s34&0xff)<<8)|
(((__int64)s56&0xff)<<16)|(((__int64)s78&0xff)<<24);
return r;
}
__int64 CDES::shuffle(__int64 d,char *p)
{
__int64 r=0;
for(int i=0;i<64;i++){
if(d & bitTable[p[i]-1])
r|=bitTable[i];
}
return r;
}
__int64 CDES::shuffle32(__int64 x)
{
char sfTab[32]={ //shuffle table
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
};
__int64 r;
r=0;
for(int i=0;i<32;i++){
if(x & bitTable[sfTab[i]-1])
r|=bitTable[i];
}
return r;
}
CDES::CDES(char *cKey) //=NULL)
{
int i;
__int64 bitIs1;
// set bitTable
/*for(i=0,bitIs1=1 //0x8000000000000000 // the highest bit 1
;i<64;i++,bitIs1<<=1)//bitIs1>>=1)
bitTable[i]=bitIs1;*/
int j;
for(i=0;i<8;i++)
for(bitIs1=0x80,j=0;j<8;j++,bitIs1>>=1)
bitTable[i*8+j]=((__int64)bitIs1)<<i*8;
if(cKey==NULL) // set default keys
setKey("-SINMIN-");
else{ //set key;
setKey(cKey);
}
//allocate memory
//pTable=new char[ 4*(4*1024) ]; // I don't know why use this line to cause link error
pTable=(char *)malloc(4*4*1024); //allocate memory
if(pTable==NULL)
errorNumber=ERR_ALLOCATEMEMORY;
initializeDES();
}
int CDES::setKey(char *s)
{
for(int i=0;i<8;i++)
key[i]=0;
for(i=0;i<(int)strlen(s);i++){
key[i]=(*(s+i))<<1; //push out Odd/even check bit
if(i>=MAXKEYLENGTH) break;
}
calculateSubKey();
return (int)strlen(s);
}
void CDES::calculateSubKey(void)
{
char rotate[16]={ //rotate TIMES for every key
1,1,2,2,2,2,2,2,
1,2,2,2,2,2,2,1
};
char select1[56]={ // first selection for Keys
//convert 64bit keys to 56bits(clear odd CheckCode)
57,49,41,33,25,17, 9, //for PartC
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, //for partD
7,62,54,46,38,30,22,
14, 6,61,53,45,37,29,
21,13, 5,28,20,12, 4
};
char select2[48]={ // permuted choice key (table)
// create a 48bit subkey
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
};
__int64 tempKey,key64;
int i,j;
char partC[56],*partD;
partD=partC+28;
//convert key to a 64 bits value
for(i=0,key64=0;i<8;i++)
key64|=((__int64)key[i])<<i*8; //force convert
//convert a bit to a byte to make algrithom eary
// and then set initialize values for C and D
for(i=0;i<56;i++)
partC[i]= (key64 & bitTable[select1[i]-1]) ? 1:0;
//calculate 16 subkeys, one by one
for(i=0;i<16;i++){
//rotate paryD and partC
runCircle(partC,rotate[i]);
runCircle(partD,rotate[i]);
//create a subKey, from 56bit select 48bit
for(j=0,tempKey=0;j<48;j++){
if(partC[select2[j]-1])
tempKey|=bitTable[j];
}
subKey[i]=tempKey;
}
}
// circle left shift dat by iTms times
void CDES::runCircle(char *dat, int iTms)
{
int i,j;
char cMemory;
for(i=0;i<iTms;i++){
cMemory=dat[0];
for(j=0;j<27;j++)
dat[j]=dat[j+1];
dat[j]=cMemory; //dat[28]
}
}
BOOL CDES::initializeDES()
{
int i,j;
char cLow,cHigh;
if(pTable==NULL)return FALSE; //memory not allocated, error,
//return false
//calculate table for convert 48 bits to 32 bits
for(i=0;i<4;i++){
for(j=0;j<4*1024;j++){
cLow=cv6to4(i*2+1,j&0x3f); // LOW 6 BITS
cHigh=cv6to4(i*2,(j>>6)&0x3f); //HIGH 6 BITS
*(pTable+i*4*1024+j)=cLow|(cHigh<<4);
}
}
return TRUE;
}
char CDES::cv6to4(int tabN, char val)
{
char sTab[8][64]={
{ /* S[1] */
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
},{ /* S[2] */
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
},{ /* S[3] */
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
},{ /* S[4] */
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
},{ /* S[5] */
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
},{ /* S[6] */
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
},{ /* S[7] */
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
},{ /* S[8] */
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
}
};
int iRow,iPos;
char r;
iRow=((0x20 & val) ? 2:0) // bit 6( start from 1,not 0)
+((0x1 & val) ? 1:0); // bit 1(see upper)
iPos=16*iRow+((val>>1)&0xf);
r=sTab[tabN][iPos]; //16*iRow+(val>>1) & 0xf];
return r;
}
CDES::~CDES()
{
if(pTable!=NULL) // free memory
free(pTable); //delete pTable will cause link error
}
char *CDES::getErrorDescription(int errNum)
{
char errDesc[][1024]={
"内存分配出错", //[0]
"加密/解密长度不为 8 的整数倍", //[1]
"未知错误" //[2]
};
//char
switch(errNum){
case ERR_ALLOCATEMEMORY:
return errDesc[0];
case ERR_LENGTH:
return errDesc[1];
case ERR_UNKNOW:
return errDesc[2];
default:
return errDesc[2];
}
}
int CDES::getErrorNumber(void)
{
return errorNumber;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -