RC5 分组密钥算法 C语言实现

来源:互联网 发布:虹吸效应 知乎 编辑:程序博客网 时间:2024/05/03 23:03
/*RC5  C代码实现 w/r/b=32/12/16 基本的RC5 3种算法组成,即密钥扩展算法、加密算法和解密算法。故RC5的C语言实现也由以下几个部分构成。 1、    参数的定义 */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h>     int w=32;//字长 32bit 4字节 int r=12;//12;//加密轮数12 int b=16;//主密钥(字节为单位8bit)个数  这里有16个int t=26;//2*r+2=12*2+2=26 int c=4; //主密钥个数*8/w = 16*8/32  typedef unsigned long int FOURBYTEINT;//四字节 typedef unsigned short int TWOBYTEINT;//2字节 typedef unsigned char BYTE; void InitialKey(unsigned char* KeyK,int b); void generateChildKey(unsigned char* KeyK,FOURBYTEINT* ChildKeyS); void Encipher(FOURBYTEINT* In,FOURBYTEINT* Out,FOURBYTEINT* S); void Decipher(FOURBYTEINT* In,FOURBYTEINT* Out,FOURBYTEINT* S); #define NoOfData  4  /**2、循环移位函数 由于在生成子密钥,加密,解密过程中都要进行循环移位,故要首先定义循环以为函数。 * 循环左移和右移函数 * x : 被循环的数 * y : 将要循环的位数 */ #define ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1))))) #define ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1)))))   /**3、    初始密钥产生函数 生成一个初始的长度为b字节的密钥。   产生初始密钥的函数 */ void InitialKey(unsigned char* KeyK,int b) {      int i,j;int intiSeed=3;     for( i=0;i<b;i++)//初始化     {         KeyK[i]=0;     }     KeyK[0]=intiSeed;printf("初始主密钥(16字节共128位):%.2lx ",KeyK[0]);     for(j=1;j<b;j++)//生成      {          KeyK[j] = (BYTE)( (int)pow(3,j)%(255-j) );  //pow(x,y)  x^y: 2^3=8printf("%.2X ",KeyK[j]);         //KeyK[j] = (BYTE) ( ((int)(pow(double(3),j))%(255-j)));      } printf("\n");}   /**4、    密钥扩展函数 由于需加密r轮,每轮需要两个子密钥,所以需要密钥扩展函数根据初始密钥来扩展出2r+2个子密钥。   产生子密钥的函数 */ void generateChildKey(unsigned char* KeyK,FOURBYTEINT* ChildKeyS) {      //const double e = 2.718281828459;      //const double Phia = 1.618033988749;       int PW = 0xB7E15163;//0xb7e1;      int QW = 0x9E3779B9;//0x9e37;//genggai      int i; int u =w/8;// b/8; FOURBYTEINT A,B,X,Y;      FOURBYTEINT L[4]; //c=16*8/32A=B=X=Y=0;      //初始化数组S      ChildKeyS[0]=PW; printf("\n初始子密钥(没有主密钥的参与):\n%.8X ", ChildKeyS[0]);     for (i=1;i<t;i++)   //t=26     { if(i%13==0)printf("\n");        ChildKeyS[i]=(ChildKeyS[i-1]+ QW);  printf("%.8X ", ChildKeyS[i]);     } printf("\n");     //将K数组转换为L数组      for(i=0;i<c;i++)//初始化L数组c=8      {         L[i]=0;      }         for (i=b-1;i!=-1; i--)//b=16  转换主密钥数组(16个 单位为8bit)为L数组(8个单位为16bit),数组L每一元素长为16bit,数组K每一元素长为8bit      {          L[i/u] = (L[i/u]<<8)+KeyK[i];      } printf("\n把主密钥变换为4字节单位:\n");      for (i=0;i<c;i++)//16进制输出gaidong      {          printf("%.8X ",L[i]);      }      printf("\n\n");      //产生子密钥,存储在ChildKeyS中      for(i=0;i<3*t;i++)      {         X = ChildKeyS[A] = ROTL(ChildKeyS[A]+X+Y,3);          A = (A+1) % t;         Y = L[B] = ROTL(L[B]+X+Y,(X+Y));          B = (B+1) % c;      } printf("生成的子密钥(初始主密钥参与和初始子密钥也参与):");      for (i=0;i<t;i++)//16进制输出      { if(i%13==0)printf("\n");         printf("%.8X ",ChildKeyS[i]);       }      printf("\n\n"); } /**5、    加密函数   加密函数 */ void Encipher(FOURBYTEINT * In,FOURBYTEINT * Out,FOURBYTEINT* S) {      FOURBYTEINT X,Y; //定义两个16位存储器      int i,j;      for(j=0;j<NoOfData;j+=2)      {          X = In[j]+S[0]; //In[j]+S[0];         Y = In[j+1]+S[1]; //In[j+1]+S[1];         for( i=1;i<=r;i++)          { X=ROTL((X^Y),Y) + S[2*i]; // X=ROTL((X^Y),Y) + S[2*i];   异或,循环移位,相加 //ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1))))) Y=ROTL((Y^X),X) + S[2*i+1]; //Y=ROTL((Y^X),X) + S[2*i+1];          }          Out[j]=X;          Out[j+1]=Y; //密文      } } /**6、    解密函数   解密函数 */ void Decipher(FOURBYTEINT* In,FOURBYTEINT* Out,FOURBYTEINT* S) {      int i=0,j;      FOURBYTEINT X,Y;      for(j=0;j<NoOfData;j+=2)      {          X = In[j];          Y = In[j+1];          for(i=r;i>0;i--)          {              Y = ROTR(Y-S[2*i+1],X)^X; //Y = ROTR(Y-S[2*i+1],X)^X;相减,循环移位,异或  //ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1)))))              X = ROTR(X-S[2*i],Y)^Y;  // X = ROTR(X-S[2*i],Y)^Y;           }          Out[j]=X - S[0]; //Out[j]=X - S[0];          Out[j+1]=Y - S[1]; //明文 Out[j+1]=Y - S[1];      } }     /**7、    主函数测试     主函数 */ int main(void) { int k;      FOURBYTEINT ChildKeyS[2*12+2]; //  r=12  子密钥个数为26     FOURBYTEINT ChildKey1[26];     //       BYTE KeyK[16];   //8bit=byte    16=b  主密钥共16字节     FOURBYTEINT Source[]={0xfffff2fe,0x56211681,0xee111560,0x44575555};    //测试明文 FOURBYTEINT Dest[NoOfData];               //用来存储密文 FOURBYTEINT Data[NoOfData]={0};           //用来存储解密后的密文 InitialKey(KeyK,b);//生成初始密钥      generateChildKey(KeyK,ChildKeyS); //根据初始密钥生成子密钥      printf("加密以前的明文:");      for (k=0;k<NoOfData;k++)      { if (k%2==0){printf("  ");}         printf("%.8X ",Source[k]); //16进制输出      }      printf("\n");      for(k=0;k<26;k++)      { //************************************有问题         ChildKey1[k]=ChildKeyS[k];//如果此处自定义简单的数值为加密密钥,则可以解密出密文                         }      Encipher(Source,Dest,ChildKey1); //加密      printf("\n");      printf("加密以后的密文:");      for (k=0;k<NoOfData;k++)       { if (k%2==0){printf("  ");}         printf("%.8X ",Dest[k]);      }      printf("\n");      Decipher(Dest,Data,ChildKey1); //解密      printf("解密以后的明文:");      for (k=0;k<NoOfData;k++)       { if (k%2==0){printf("  ");}         printf("%.8X ",Data[k]);      }      printf("\n");      //printf("sizeof unsigned short int: %d",sizeof(unsigned short int)); // system("pause\n"); }  ///////////////////////////////////////////////////////////////////////////////////////////////////////*RC5  C代码实现 w/r/b=16/12/16  基本的RC5 3种算法组成,即密钥扩展算法、加密算法和解密算法。故RC5的C语言实现也由以下几个部分构成。 1、    参数的定义   */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h>     int w=16;//字长 int r=10;//12;//轮数12 int b=16;//密钥字节个数  int t=26;//2*r+2=12*2+2=26 int c=8; //b*8/w = 16*8/16  //typedef unsigned long int FOURBYTEINT;//四字节 typedef unsigned short int TWOBYTEINT;//2字节 typedef unsigned char BYTE; void InitialKey(unsigned char* KeyK,int b); void generateChildKey(unsigned char* KeyK,TWOBYTEINT* ChildKeyS); void Encipher(TWOBYTEINT* In,TWOBYTEINT* Out,TWOBYTEINT* S); void Decipher(TWOBYTEINT* In,TWOBYTEINT* Out,TWOBYTEINT* S); #define NoOfData  4  /**2、循环移位函数 由于在生成子密钥,加密,解密过程中都要进行循环移位,故要首先定义循环以为函数。 * 循环左移和右移函数 * x : 被循环的数 * y : 将要循环的位数 */ #define ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1))))) #define ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1)))))   /**3、    初始密钥产生函数 生成一个初始的长度为b字节的密钥。   产生初始密钥的函数 */ void InitialKey(unsigned char* KeyK,int b) {      int i,j;int intiSeed=3;     for( i=0;i<b;i++)//初始化     {         KeyK[i]=0;     }     KeyK[0]=intiSeed;printf("初始主密钥(16字节共128位):%.2lx ",KeyK[0]);     for(j=1;j<b;j++)//生成      {          KeyK[j] = (BYTE)( (int)pow(3,j)%(255-j) );  //pow(x,y)  x^y: 2^3=8printf("%.2X ",KeyK[j]);         //KeyK[j] = (BYTE) ( ((int)(pow(double(3),j))%(255-j)));      } printf("\n");}   /**4、    密钥扩展函数 由于需加密r轮,每轮需要两个子密钥,所以需要密钥扩展函数根据初始密钥来扩展出2r+2个子密钥。   产生子密钥的函数 */ void generateChildKey(unsigned char* KeyK,TWOBYTEINT* ChildKeyS) {      //const double e = 2.718281828459;      //const double Phia = 1.618033988749;       int PW = 0xb7e1;      int QW = 0x9e37;//genggai      int i; int u = w/8; TWOBYTEINT A,B,X,Y;      TWOBYTEINT L[8]; //c=b*8/w=8A=B=X=Y=0;      //初始化数组S      ChildKeyS[0]=PW; printf("\n初始子密钥(没有主密钥的参与):\n%.4lx ", ChildKeyS[0]);     for (i=1;i<t;i++)   //t=26     { if(i%13==0)printf("\n");        ChildKeyS[i]=(ChildKeyS[i-1]+ QW);  printf("%.4X ", ChildKeyS[i]);     } printf("\n");     //将K数组转换为L数组      for(i=0;i<c;i++)//初始化L数组c=8      {         L[i]=0;      }         for (i=b-1;i!=-1; i--)//b=16  转换主密钥数组(16个 单位为8bit)为L数组(8个单位为16bit),数组L每一元素长为16bit,数组K每一元素长为8bit      {          L[i/u] = (L[i/u]<<8)+KeyK[i];      } printf("\n把主密钥变换为2字节单位:\n");      for (i=0;i<c;i++)//16进制输出gaidong      {          printf("%.4X ",L[i]);      }      printf("\n\n");      //产生子密钥,存储在ChildKeyS中      for(i=0;i<3*t;i++)      {         X = ChildKeyS[A] = ROTL(ChildKeyS[A]+X+Y,3);          A = (A+1) % t;         Y = L[B] = ROTL(L[B]+X+Y,(X+Y));          B = (B+1) % c;      } printf("生成的子密钥(初始主密钥参与和初始子密钥也参与):");      for (i=0;i<t;i++)//16进制输出      { if(i%13==0)printf("\n");         printf("%.4X ",ChildKeyS[i]);       }      printf("\n\n"); } /**5、    加密函数   加密函数 */ void Encipher(TWOBYTEINT * In,TWOBYTEINT * Out,TWOBYTEINT* S) {      TWOBYTEINT X,Y; //定义两个16位存储器      int i,j;      for(j=0;j<NoOfData;j+=2)      {          X = In[j]+S[0]; //In[j]+S[0];         Y = In[j+1]+S[1]; //In[j+1]+S[1];         for( i=1;i<=r;i++)          {  X=ROTL((X^Y),Y) + S[2*i]; // X=ROTL((X^Y),Y) + S[2*i];   异或,循环移位,相加 //ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1))))) Y=ROTL((Y^X),X) + S[2*i+1]; //Y=ROTL((Y^X),X) + S[2*i+1];          }          Out[j]=X;          Out[j+1]=Y; //密文      } } /**6、    解密函数   解密函数 */ void Decipher(TWOBYTEINT* In,TWOBYTEINT* Out,TWOBYTEINT* S) {      int i=0,j;      TWOBYTEINT X,Y;      for(j=0;j<NoOfData;j+=2)      {          X = In[j];          Y = In[j+1];          for(i=r;i>0;i--)          {    //***********重要*****************一定要强制转换为unsigned short int 否则循环右移出错                Y = ROTR((unsigned short int)(Y-S[2*i+1]),X)^X; //Y = ROTR(Y-S[2*i+1],X)^X;相减,循环移位,异或  //ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1)))))  X = ROTR((unsigned short int)(X-S[2*i]),Y)^Y;  // X = ROTR(X-S[2*i],Y)^Y;           }          Out[j]=X - S[0]; //Out[j]=X - S[0];          Out[j+1]=Y - S[1]; //明文 Out[j+1]=Y - S[1];      } }     /**7、    主函数测试     主函数 */ int main(void) { unsigned   int aa=0xffffFFF1;unsigned   int bb=0xffffFFF2;unsigned   int cc;int k;      TWOBYTEINT ChildKeyS[2*12+2]; //  r=12  子密钥个数为26     TWOBYTEINT ChildKey1[26];     //       BYTE KeyK[16];   //8bit=byte    16=b  主密钥共16字节     TWOBYTEINT Source[]={25142,1681,11561,5555};    //测试明文 TWOBYTEINT Dest[NoOfData];               //用来存储密文 TWOBYTEINT Data[NoOfData]={0};           //用来存储解密后的密文 InitialKey(KeyK,b);//生成初始密钥      generateChildKey(KeyK,ChildKeyS); //根据初始密钥生成子密钥      printf("加密以前的明文:");      for (k=0;k<NoOfData;k++)      {          printf("%.4lX ",Source[k]); //16进制输出      }      printf("\n");      for(k=0;k<26;k++)      { //************************************有问题         ChildKey1[k]=ChildKeyS[k];//如果此处自定义简单的数值为加密密钥,则可以解密出密文                         //  printf("%.4lX ",ChildKey1[k]);      }      Encipher(Source,Dest,ChildKey1); //加密      printf("\n");      printf("加密以后的密文:");      for (k=0;k<NoOfData;k++)       {          printf("%.4lX ",Dest[k]);      }      printf("\n");      Decipher(Dest,Data,ChildKey1); //解密      printf("解密以后的明文:");      for (k=0;k<NoOfData;k++)       {          printf("%.4lX ",Data[k]);      }      printf("\n");  cc=aa+bb; // printf("\n%16X\n",cc); // printf("%8X\n",(cc-aa));      //printf("sizeof unsigned short int: %d",sizeof(unsigned short int)); // system("pause\n"); } 


                                             
0 0