c语言实现RC5分组密钥算法的应用

c语言实现RC5分组密钥算法的应用,第1张

  RC5分组密码算法是1994由麻萨诸塞技术研究所的Ronald L. Rivest教授发明的,并由RSA实验室分析。它是参数可变的分组密码算法,三个可变的参数是:分组大小、密钥大小和加密轮数。在此算法中使用了三种运算:异或、加和循环。

  简介

  RC5是种比较新的算法,Rivest设计了RC5的一种特殊的实现方式,因此RC5算法有一个面向字的结构:RC5-w/r/b,这里w是字长其值可以是16、32或64对于不同的字长明文和密文块的分组长度为2w位,r是加密轮数,b是密钥字节长度。由于RC5一个分组长度可变的密码算法,为了便于说明在本文中主要是针对64位的分组w=32进行处理的,下面详细说明了RC5加密解密的处理过程:

  加密解密

  1、创建密钥组

  RC5算法加密时使用了2r+2个密钥相关的的32位字: ,这里r表示加密的轮数。创建这个密钥组的过程是非常复杂的但也是直接的,首先将密钥字节拷贝到32位字的数组L中(此时要注意处理器是little-endian顺序还是big-endian顺序),如果需要,最后一个字可以用零填充。然后利用线性同余发生器模2初始化数组S:

  对于i=1到2(r+1)-1: (本应模 ,本文中令w=32)

  其中对于16位字32位分组的RC5,P=0xb7e1 Q=0x9e37

  对于32位字和64位分组的RC5,P=0xb7e15163 Q=0x9e3779b9

  对于64位字和128位分组,P=0xb7151628aed2a6b Q=0x9e3779b97f4a7c15

  最后将L与S混合,混合过程如下:

  c语言实现RC5分组密钥算法的应用,c语言实现RC5分组密钥算法的应用,第2张

  i=j=0

  A=B=0

  处理3n次(这里n是2(r+1)和c中的最大值,其中c表示输入的密钥字的个数)

  2、加密处理

  在创建完密钥组后开始进行对明文的加密,加密时,首先将明文分组划分为两个32位字:A和B(在假设处理器字节顺序是little-endian、w=32的情况下,第一个明文字节进入A的最低字节,第四个明文字节进入A的最高字节,第五个明文字节进入B的最低字节,以此类推),其中操作符《《《表示循环左移,加运算是模 (本应模 ,本文中令w=32)的。

  输出的密文是在寄存器A和B中的内容

  3、解密处理

  解密也是很容易的,把密文分组划分为两个字:A和B(存储方式和加密一样),这里符合》》》是循环右移,减运算也是模 (本应模 ,本文中令w=32)的。

  RSA试验室花费了相当的时间来分析64位分组的RC5算法,在5轮后统计特性看起来非常好。在8轮后,每一个明文位至少影响一个循环。对于5轮的RC5,差分攻击需要 个选择明文;对10轮需要 个;对于12轮需要 个;对15轮需要 个。而对于64位的分组只有 个可能的明文,所以对于15轮或以上的RC5的差分攻击是失败的。在6轮后线性分析就是安全的了,Rivest推荐至少12轮,甚至可能是16轮。这个轮数可以进行选择。

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

  [cpp] view plain copy/*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=8

  printf(“%.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/32

  A=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=8

  printf(“%.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=8

  A=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”);

  }

欢迎分享,转载请注明来源:内存溢出

原文地址:https://outofmemory.cn/dianzi/2717799.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-08-17
下一篇2022-08-17

随机推荐

  • 射覆是什么意思

     射覆,是中国民间近于占卜术的一种猜物游戏。古时数术家为了提高自己的占卜能力,会经常玩“射覆”的游戏,在唐朝时期这还是考核天文郎的主要内容之一。“射”是猜的意思,“覆”是覆盖的意思。“于覆器之下置诸物

    2022-12-06
    000
  • 古代四大美女是谁

    古代四大美女分别是西施、王昭君、貂蝉、杨玉环。四大美女享有“沉鱼落雁之容,闭月羞花之貌”的美誉。“沉鱼”,讲的是西施浣纱的故事。“落雁&am

  • 皇太极第一个孩子是谁

    皇太极的第一个儿子是爱新觉罗·豪格。生母为继妃乌拉那拉氏。豪格是清初的著名将领,为大清帝国的建立,和清军入关后稳定关内局势,剪除明朝旧势力做出了显著贡献。豪格和他的父亲一样,经历了战争的

    2022-12-06
    000
  • 冀是哪个省的简称

    冀是河北省的简称;河北省是中华人民共和国省级行政区,省会石家庄。古称冀州,舜分置十二州,河北为幽州,春秋时期,河北省北部属于燕国。河北是长城途经距离最长、保存最完好、建筑风格最具代表性的省份。河北的承

    2022-12-06
    000
  • 什么风什么逃成语是什么

    1、什么风什么逃成语是:闻风而逃。2、闻风而逃,拼音是wén fēngér táo,意思是听到风声,立即逃跑。3、出处:清·李宝嘉《官场现形记》第12回:“只要望见土匪的影子,早已闻风而逃。”4、近义

    2022-12-06
    000
  • 冰粉是白凉粉吗

    冰粉不是白凉粉,两者的原料、外观、作用是不同的。原料:白凉粉只要是用植物当中所提取的凉粉胶来作为原料,冰粉是用冰粉籽作为原料。作用:相对而言,冰粉的营养价值比白凉粉更高。外观:白凉粉看起来是白色固态的

    2022-12-06
    000
  • 中南林业科技大学在哪里

    1、地址:湖南省长沙市天心区韶山南路498号。2、入选国家“中西部高校基础能力建设工程”、卓越农林人才教育培养计划、国家“特色重点学科项目”、国家建设高水平大学公派研究生项目、湖南省2011计划,是湖

    2022-12-06
    000
  • 只用数字8组成五个数等于1000

    只用数字8组成五个数等于1000的答案就是888+88+8+8+8=1000。既然是5个数,切相加等于1000,就意味着这5个数中,最大只能是888。然后再依次往里面带8。解析:1、10008=12

    2022-12-06
    000
  • 狸猫换太子什么意思

    1、比喻以假冒真。2、拼音:lí māo huàn tài zǐ。3、这句话源自清朝的名著《三侠五义》,讲的是宋真宗时期,刘妃为了让自己的儿子当上太子,就和太监郭槐密谋以剥皮狸猫调换李宸妃所生孩子,后

    2022-12-06
    000

发表评论

登录后才能评论

评论列表(0条)

    保存