DES加密算法的源码实现

来源:互联网 发布:百度推广账户优化公司 编辑:程序博客网 时间:2024/06/05 08:37

 #include "stdafx.h"
#include "FDatatype.h"
//====================================
//
//将一个字节的第j位复制到另一个字节的第k位
//@参数src :源字节
//@参数from:源位数
//@参数des :目的字节
//@参数to:目的位数
//====================================
PRIVATE void bitCopy(unsigned char* src,int from,unsigned char* des,int to)
{
 unsigned char mask=0x01;
 unsigned char temp;
 temp=(mask<<from)&*src;
   if(from < to) temp = temp<<(to-from);
   else temp=temp>>(from-to);//)&(mask<<to);
   *des |=temp;
}
//=====================================================
//@param orgKey: input key
//@param newIp: the buffer for permutated key
//@param map:mapping  src to des buffer
//@param mapSize: the length of the buffer map in bytes
//=====================================================
PRIVATE void initPermutation(unsigned char* orgKey, int orgKeyLen,unsigned char* newIPKey, int newIPKeyLen,unsigned char* map,size_t mapSize)
{
 int from;
 int to;
 int srcByteID;
 int desByteID;
 orgKeyLen -=1;
 newIPKeyLen -=1;
 for(size_t i=0;i<mapSize;i++){
  srcByteID = orgKeyLen-((map[i]-1)>>3);//among which byte;
  from=(map[i]-1)%8;//at which bit;
  
  desByteID = newIPKeyLen-(i>>3);
  to=i%8;
  bitCopy(orgKey+srcByteID,from,newIPKey+desByteID,to);
 }

}
//将输入64位对象分成左右两个部分。
PRIVATE void split2LR(INPUTPAR lInput,INPUTPAR rInput,KEY theKey)
{
 /*for(size_t i=0;i<63;i++){
  if(i<32) lInput[3-((i>>3)%4)] = theKey[7-(i>>3)];
  else rInput[3-((i>>3)%4)] = theKey[7-(i>>3)];
 }*/
 memcpy(lInput,theKey,4);
 memcpy(rInput,theKey+4,4);

}


//====================================
//
//
//Cipher function:f(R,K)
//====================================
PRIVATE void f(

    INPUTPAR rPrev,
    KEYN keyn,
    unsigned char* eFunction,
    SelectionArray selectFunc,
    SelectPermutation theP
    )
{
 int from;
 int to;
 int srcByteID;
 int desByteID;
 KEYN elizedR;
 INPUTPAR tempR;
 //input R is processed by E function,
 //buffer elizedR stores the aftermath.
 memset(elizedR,0,6);
 for(size_t i=0;i<ELength;i++){
  srcByteID = 3-((eFunction[i]-1)>>3);//among which byte;
  from=(eFunction[i]-1)%8;//at which bit;
  
  desByteID = 5-(i>>3);
  to=i%8;
  bitCopy(
   rPrev+srcByteID,//from byte
   from,//bit number
   elizedR+desByteID,//to byte
   to//to bit number
   );
 }
 // elized buffer XORs keyFunc
 for(i=0;i<KeyNLength;i++) elizedR[i] ^= keyn[i];

 //B blocks are converted by a set of selection functions Ss.
 //doSelection(elizedR,selectFunc,rPrev);
 for(i=0;i<8;i++)
  doSFun(elizedR,rPrev,selectFunc[i],i);
 //selected result has to be permuted in accordance with P
 memset(tempR,0,4);
 for(i=0;i<PLength;i++){
  srcByteID = 3-((theP[i]-1)>>3);//among which byte;
  from=(theP[i]-1)%8;//at which bit;
  
  desByteID = 3-(i>>3);
  to=i%8;
  bitCopy(
   rPrev+srcByteID,//from byte
   from,//bit number
   tempR+desByteID,//to byte
   to//to bit number
   );
 }
 memcpy(rPrev,tempR,4);
}

 


//selection functions are to interpret input blocks inputBs
PRIVATE void doSFun(KEYN inputBs,INPUTPAR rPrev,Selection sFuncs,BlockNo blockNo)
{
 int start = 6*(8-blockNo);
 int byteNo;//in which byte the specified bit is located
 int shift;// in which bit the specified bit populated
 unsigned char sOutput=(unsigned char)0x00;
 unsigned char row=0;
 unsigned char col=0;
 for(int i=0;i<6;i++){
  start -= 1;
  byteNo = 5- (start>>3);
  shift = start%8;
  bitCopy(inputBs+byteNo,shift,&sOutput,5-i);
 }
 row = ((sOutput&0x20)>>4)|((sOutput&0x01));
 col = ((sOutput&0x1e)>>1);
 if((blockNo%2)==0){
  blockNo >>=1;
  rPrev[blockNo] &= 0x0f;
  rPrev[blockNo] |=(sFuncs[row][col]<<4);
 }else{
  blockNo >>=1;
  rPrev[blockNo] &= 0xf0;
  rPrev[blockNo] |=sFuncs[row][col];
 }
 
}
// cihper and decipher function,integerating relevant components
PUBLIC void enCiphering(DATA input,DATA output,INITP initP,
     INITP inInitP,CHOICEP1 pChoice1,
     CHOICEP2 pChoice2,EFUNC E,SelectionArray sFuncs,
     KEY key,CIPHERP cipherP,LSHCTRL lshftCtrl,KEYNSET keyNSet)
{
 INPUTPAR lPart;
 INPUTPAR rPart;
 INPUTPAR templPart;
 //INPUTPAR temprPart;

 Buffer aBuffer;

 /*KEY backOrigKey;
 //backup tempKey
 memcpy(backOrigKey,key,8);*/
 Zero(aBuffer);
 //ciphering
 initPermutation(input,8,aBuffer,8,initP,64);
 memcpy(input,aBuffer,8);
 
 split2LR(lPart,rPart,input);
 
 
 

 for(int i=0;i<16;i++){
  
  memcpy(templPart,rPart,4);
  f(rPart,keyNSet[i],E,sFuncs,cipherP);
  for(int j=0;j<4;j++) rPart[j] ^= lPart[j];
  memcpy(lPart,templPart,4);
 }
 //making preoutput
 memcpy(output,rPart,4);
 memcpy(output+4,lPart,4);
    Zero(aBuffer);
 initPermutation(output,8,aBuffer,8,inInitP,64);
 memcpy(output,aBuffer,8);
}
PUBLIC void deCiphering(DATA input,DATA output,INITP initP,
     INITP inInitP,CHOICEP1 pChoice1,
     CHOICEP2 pChoice2,EFUNC E,SelectionArray sFuncs,
     KEY key,CIPHERP cipherP,LSHCTRL lshftCtrl,KEYNSET keyNSet)
{
 INPUTPAR lPart;
 INPUTPAR rPart;
 INPUTPAR templPart;
 Buffer aBuffer;
 /*KEY backOrigKey;
 //backup tempKey
 memcpy(backOrigKey,key,8);*/
 Zero(aBuffer);
 //ciphering
 initPermutation(input,8,aBuffer,8,initP,64);
 memcpy(input,aBuffer,8);
 split2LR(lPart,rPart,input);
 //============================
 for(int i=0;i<16;i++){
  
  memcpy(templPart,rPart,4);
  f(rPart,keyNSet[15-i],E,sFuncs,cipherP);
  for(int j=0;j<4;j++) rPart[j] ^= lPart[j];
  memcpy(lPart,templPart,4);
 }
 //making preoutput
 memcpy(output,rPart,4);
 memcpy(output+4,lPart,4);
    Zero(aBuffer);
 initPermutation(output,8,aBuffer,8,inInitP,64);
 memcpy(output,aBuffer,8);
}


PRIVATE void leftShift(unsigned char* object, int size,int bits)
{
 int lastIndex = size-1;
 unsigned char mask = 0x80;
 unsigned char clean_mask=0xff;
 mask >>=7-((bits-1) % 8);
 clean_mask >>=7-((bits-1) % 8);
 unsigned char CR = (object[0] & mask)>>((bits-1)% 8);
 unsigned char CL;
 mask =0x80;
 for(int i=0;i<lastIndex;i++){
  CL = (object[lastIndex-i] &mask) >>7;
  object[lastIndex-i] <<=1;
  object[lastIndex-i] |=CR;
  CR= CL;
 }
 object[0] <<=1;
 object[0] |=CR;
 object[0] &= clean_mask;
}
PRIVATE void splitKey(KEY oldKey,INPUTPAR lKey, INPUTPAR rKey,unsigned char* pChoice1,int choiceSize)
{
 memset(lKey,0,4);
 memset(rKey,0,4);
 initPermutation(oldKey,8,lKey,4,pChoice1,28);
 initPermutation(oldKey,8,rKey,4,pChoice1+28,28);
}
PRIVATE void combineKeys(INPUTPAR C,INPUTPAR D,CMBKEY output)
{
 unsigned char mask = 0xf0;
 unsigned char CR;
 memcpy(output,C,sizeof(INPUTPAR));
 for(int i=0;i<3;i++){
 output[i] <<= 4;
 CR = (output[i+1]&mask)>>4;
 output[i] |= CR;
 }
 output[i] <<=4;//对第3个字节左移4位,这样该字节的最后4位为0
 memcpy(output+4,D+1,3);//将D后三个字节拷贝到output[4.5.6]
 output[i] |=D[0];//D的第一个字节第四位有数据并入到output[3]低4位。

}
PUBLIC ENCDLL_API void keyShedule(KEY theInpuKey,KEYNSET keyNSet)
{
 INPUTPAR lkN;
 INPUTPAR rkN;
 CMBKEY tempKey;//input to pChoice2
 memset(keyNSet,0,sizeof(KEYNSET));
 splitKey(theInpuKey,lkN,rkN,pChoice1,56);
 for(int i=0;i<16;i++){
  for(int k=0;k<lshftCtrl[i];k++){
   leftShift(lkN,4,28);
   leftShift(rkN,4,28); 
  }
  combineKeys(lkN,rkN,tempKey);
  //memset(keyNSet[i],0,sizeof(KEYN));
  initPermutation(tempKey,7,keyNSet[i],6,pChoice2,48);
 }
}
typedef unsigned char Selection[4][16];
typedef Selection SelectionArray[8];
#define PLength 32
//字符数组第一个字节是63-56 ……
unsigned char  initP[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
 };
unsigned char inInitP[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
 };
unsigned char pChoice1[56]={
  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
 };
unsigned char E[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
 };
SelectionArray sFuncs={
  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,
  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,
  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,
  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
 };
unsigned char cipherP[PLength]={
  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
};
unsigned char pChoice2[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
};
unsigned char lshftCtrl[16]={
 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
unsigned char PI_SUBST[256] = {
  41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
  19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
  76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
  138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
  245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
  148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
  39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
  181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
  150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
  112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
  96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
  85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
  234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
  129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
  8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
  203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
  166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
  31, 26, 219, 153, 141, 51, 159, 17, 131, 20
};
测试程序: