c语言如何实现idea算法

编程语言及工具

105人已加入

描述

  摘要: IDEA即国际数据加密算法,也是目前使用广泛的一种算法。本文详细介绍了IDEA算法以及c语言如何实现idea算法,下面一起来看看原文。

  IDEA算法介绍

  IDEA,即国际数据加密算法。是旅居瑞士中国青年学者来学嘉和著名密码专家J.Massey于1990年提出的。它在1990年正式公布并在以后得到增强。这种算法是在DES算法的基础上发展出来的,类似于三重DES,和DES一样IDEA也是属于对称密钥算法。发展IDEA也是因为感到DES具有密钥太短等缺点,已经过时。IDEA的密钥为128位,这么长的密钥在今后若干年内应该是安全的。

  类似于DES,IDEA算法也是一种数据块加密算法,它设计了一系列加密轮次,每轮加密都使用从完整的加密密钥中生成的一个子密钥。与DES的不同处在于,它采用软件实现和采用硬件实现同样快速。

  由于IDEA是在美国之外提出并发展起来的,避开了美国法律上对加密技术的诸多限制,因此,有关IDEA算法和实现技术的书籍都可以自由出版和交流,可极大地促进IDEA的发展和完善。但由于该算法出现的时间不长,针对它的攻击也还不多,还未经过较长时间的考验。因此,尚不能判断出它的优势和缺陷。

  IDEA算法特点

  类似于DES,IDEA算法也是一种数据块加密算法,它设计了一系列加密轮次,每轮加密都使用从完整的加密密钥中生成的一个子密钥。与DES的不同处在于,它采用软件实现和采用硬件实现同样快速。

  由于IDEA是在美国之外提出并发展起来的,避开了美国法律上对加密技术的诸多限制,因此,有关IDEA算法和实现技术的书籍都可以自由出版和交流,可极大地促进IDEA的发展和完善。但由于该算法出现的时间不长,针对它的攻击也还不多,还未经过较长时间的考验。因此,尚不能判断出它的优势和缺陷。

  IDEA算法详解

  1.产生密钥

  算法用了52个子密钥。首先,将128-位源密钥分成8个16-位子密钥。源密钥再次向左环移25位产生另外8个子密钥,如此进行直到产生完52个密匙。具体是:

  IDEA总共进行8轮迭代操作,每轮需要6个子密钥,另外还需要4个额外子密钥,所以总共需要52个子密钥,这个52个子密钥都是从128位密钥中扩展出来的。

  2.加密、解密过程

  输入的64-位数据分组被分成4个16-位子分组:xl,X2,x3和x4。这4个子分组成为算法的第一轮的输入,总共有8轮。在每一轮中,这4个子分组相互相异或,相加,相乘,且与6个16-位子密钥相异或,相加,相乘。在轮与轮间,第二和第三个子分组交换。最后在输出变换中4个子分组与4个子密钥进行运算。

  注意上面的加法运算是对模2的16次方的加法运算,即求两个数的和对65536的余数,

  乘法运算是对模2的16次方加1的乘法运算,即两个数的积对65537的余数。

  在每一轮中,执行的顺序如下:

  (1)X1和第一个子密钥相乘。

  (2)x2和第二个子密钥相加。

  (3)X3和第三个子密钥相加。

  (4)x4和第四个子密钥相乘。

  (5)将第(1)步和第(3)步的结果相异或。 ·

  (6)将第(2)步和第(4)步的结果相异或。

  (7)将第(5)步的结果与第五个子密钥相乘。

  (8)将第(6)步和第(7)步的结果相加。

  (9)将第(8)步的结果与第六个子密钥相乘。

  (10)将第(7)步和第(9)步的结果相加。

  (11)将第(1)步和第(9)步的结果相异或。

  (12)将第(3)步和第(9)步的结果相异或。

  (13)将第(2)步和第(10)步的结果相异或。

  (14)将第(4)步和第(10)步的结果相异或。

  每一轮的输出是第(11)、(12)、(13)和(14) 步的结果形成的4个子分组。将中间两个分组分组交换(最后一轮除外)后,即为下一轮的输入。

  经过8轮运算之后,有一个最终的输出变换:

  (1) X1和第一个子密钥相乘。

  (2) x2和第二个子密钥相加。

  (3) x3和第三个子密钥相加。

  (4) x4和第四个子密钥相乘。

  最后,这4个子分组重新连接到一起产生密文。

      c语言如何实现idea算法程例

  Idea的密匙长度几乎是des的两倍多,因此对idea的穷举攻击几乎是不可能的(它的空间复杂度将达到10的39次方,也许在整个宇宙中有这么多的存储空间),idea也可以有效的抵抗中间相遇攻击和差分分析攻击事实上在idea的八轮算法中在第四轮就已经具有对差分密码分析的免疫了。

  虽然idea是目前公开算法的最好和最安全的加密算法,但是随着时间的流失看似安全的算法往往会被新的密码分析方法破译,目前有几个军事组织已经对idea进行密码分析,他们中的没有一个人愿意公布可能成功破译的结果,但将来的某一天他们可能会成功。

  [c-sharp] view plain copytypedef unsigned char byte;

  typedef char *string;

  typedef unsigned short word16;

  typedef unsigned long word32;

  typedef unsigned short uint16;

  typedef unsigned long ulong;

  #ifndef TRUE

  #define FAUSE 0

  #define TRUE (!FAUSE)

  #endif

  #ifndef min

  #define min(a,b) ((a)《(b)?(a):(b))

  #define max(a,b) ((a)》(b)?(a):(b))

  #endif

  #define keysize 16

  #define blocksize 8

  #define rounds 8

  #define keylen (6*rounds+4)

  typedef struct {

  word16 jia_key[10][7],jie_key[10][7];

  }idea_key;

  #ifdef IDEA32

  #define low16(x) ((x)&0xffff)

  #else

  #define low16(x) (x)

  #endif

  suanfa.cpp

  [c-sharp] view plain copy#define HIGHFIRST

  void key_move(byte a[]) //将源密匙向左移动25位

  {

  int i;

  byte b[17];

  for(i=0;i《=16;i++)

  b[i]=0;

  for(i=1;i《=12;i++){

  b[i]|=a[i+3];

  b[i]《《=1;

  b[i]|=(a[i+4]》》7);

  }

  b[13]|=a[16];

  b[13]《《=1;

  b[13]|=a[1]》》7;

  for(i=14;i《=16;i++){

  b[i]|=a[i-13];

  b[i]《《=1;

  b[i]|=(a[i-12]》》7);

  }

  for(i=0;i《=16;i++)

  a[i]=b[i];

  }

  void get_jia_key(byte userkey[],uint16 jia_key[][7]) //从源密匙得到加密密匙

  {

  int i,j;

  uint16 S[54];

  for(i=0;i《54;i++)

  S[i]=0;

  byte *key=(byte *)(userkey-1);

  for(i=0;i《6;i++){

  for(j=0;j《8;j++){

  S[i*8+j]|=key[2*j+1];

  S[i*8+j]《《=8;

  S[i*8+j]|=key[2*j+2];

  }

  key_move(key);

  }

  for(j=0;j《4;j++){

  S[48+j]|=key[2*j+1];

  S[48+j]《《=8;

  S[48+j]|=key[2*j+2];

  }

  for(i=1;i《=8;i++)

  for(j=1;j《=6;j++)

  jia_key[i][j]=S[(i-1)*6+j-1];

  for(i=48;i《=51;i++)

  jia_key[9][i-47]=S[i];

  }

  uint16 mulinv(uint16 b) //求一个整数对65537的乘法逆元

  {

  int a=65537;

  int x1,x2,x3;

  int y1,y2,y3;

  int t1,t2,t3;

  x1=1;

  x2=0;

  x3=a;

  y1=0;

  y2=1;

  y3=b;

  int k;

  for(t3=x3%y3;t3!=0;t3=x3%y3){

  k=x3/y3;

  t2=x2-k*y2;

  t1=x1-k*y1;

  x1=y1;

  x2=y2;

  x3=y3;

  y1=t1;

  y2=t2;

  y3=t3;

  }

  if(y2《0)

  y2+=a;

  if(y3==1)

  return (uint16)y2;

  else

  return 0;

  }

  void get_jie_key(uint16 jia_key[][7],uint16 jie_key[][7]) //从加密密匙得到解密密匙

  {

  int j;

  for(j=1;j《=rounds+1;j++){

  if(j==9||j==1){

  jie_key[j][2]=-jia_key[10-j][2];

  jie_key[j][3]=-jia_key[10-j][3];

  }

  else {

  jie_key[j][2]=-jia_key[10-j][3];

  jie_key[j][3]=-jia_key[10-j][2];

  }

  jie_key[j][1]=mulinv(jia_key[10-j][1]);

  jie_key[j][4]=mulinv(jia_key[10-j][4]);

  }

  for(j=1;j《=8;j++){

  jie_key[j][5]=jia_key[9-j][5];

  jie_key[j][6]=jia_key[9-j][6];

  }

  }

  uint16 MULi(uint16 x,uint16 y) //求两个数的积对65537的余数

  {

  #ifndef SMALL_CACHE

  uint16 t16;

  word32 t32;

  #endif

  #ifdef SMALL_CACHE

  return mul(low16(x),y);

  #else

  #ifdef AVOID_JUMPS

  x=low16(x-1);

  t16=low16((y)-1);

  t32=(word32)x*t16+x+t16+1;

  x=low16(t32);

  t16=t32》》16;

  x=(x-t16)+(x《t16);

  return x;

  #else

  if(t16=(y)){

  if(x=low16(x)){

  t32=(word32)x*t16;

  x=low16(t32);

  t16=t32》》16;

  x=(x-t16)+(x《t16);

  }

  else

  x=1-t16;

  }

  else

  x=1-x;

  return x;

  #endif

  #endif

  }

  void change(uint16 a[],uint16 *key) //每一轮的变换

  {

  uint16 jie_guo[11];

  jie_guo[1]=MULi(a[1],key[1]);

  jie_guo[2]=a[2]+key[2];

  jie_guo[3]=a[3]+key[3];

  jie_guo[4]=MULi(a[4],key[4]);

  jie_guo[5]=jie_guo[1]^jie_guo[3];

  jie_guo[6]=jie_guo[2]^jie_guo[4];

  jie_guo[7]=MULi(jie_guo[5],key[5]);

  jie_guo[8]=jie_guo[6]+jie_guo[7];

  jie_guo[9]=MULi(jie_guo[8],key[6]);

  jie_guo[10]=jie_guo[7]+jie_guo[9];

  a[1]=jie_guo[1]^jie_guo[9];

  a[2]=jie_guo[3]^jie_guo[9];

  a[3]=jie_guo[2]^jie_guo[10];

  a[4]=jie_guo[4]^jie_guo[10];

  }

  int jia_jie(byte in_buf[],byte out_buf[],uint16 key[][7]) //模拟加密过程

  {

  int i;

  uint16 temp;

  uint16 x[5],s2,s3;

  word16 *in,*out;

  in=(word16 *)in_buf;

  for(i=1;i《=4;i++)

  x[i]=in[i-1];

  #ifndef HIGHFIRST

  for(i=1;i《=4;i++)

  x[i]=(x[i]》》8|x[i]《《8);

  #endif

  for(i=1;i《=rounds;i++)

  change(x,&key[i][0]);

  x[1]=MULi(x[1],key[9][1]);

  x[3]+=key[9][2];

  x[2]+=key[9][3];

  x[4]=MULi(x[4],key[9][4]);

  out=(word16 *)out_buf;

  #ifdef HIGHFIRST

  *out++=x[1];

  *out++=x[3];

  *out++=x[2];

  *out=x[4];

  #else

  *out++=(x[1]》》8)|(x[1]《《8);

  *out++=(x[3]》》8)|(x[3]《《8);

  *out++=(x[2]》》8)|(x[2]《《8);

  *out=(x[4]》》8)|(x[4]《《8);

  #endif

  return 0;

  }

  main.cpp

  [c-sharp] view plain copy#include《stdio.h》

  #include《string.h》

  #include《stdlib.h》

  #include “idea.h”

  #include “suanfa.cpp”

  char prin_ch()

  {

  char ch;

  printf(“shu ru ni de xuan ze/n”);

  printf(“1:jia mi wen jian/n”);

  printf(“2:jie mi wen jian/n”);

  printf(“q:tui chu/n”);

  scanf(“%c”,&ch);

  getchar();

  return ch;

  }

  void get_key(idea_key *key)

  {

  byte sou_key[17];

  printf(“enter your passwor/n”);

  scanf(“%s”,sou_key);

  int b=strlen((char *)sou_key);

  memset(&sou_key[b],1,16-b);

  get_jia_key(sou_key,key-》jia_key);

  get_jie_key(key-》jia_key,key-》jie_key);

  }

  void change(byte *in,byte *out,word16 key[][7],int a)

  {

  for(int i=0;i《a;i++){

  jia_jie(in,out,key);

  in+=8;

  out+=8;

  }

  }

  void lock_file(word16 key[][7])

  {

  char filename[40];

  printf(“enter file name/n”);

  scanf(“%s”,filename);

  getchar();

  FILE *fp,*fp1;

  fp=fopen(filename,“r”);

  fp1=fopen(“locked”,“wb”);

  byte temp_buf[256];

  byte sou_buf[256];

  byte temp[256];

  while(!feof(fp)){

  fgets((char *)temp,8,fp);

  jia_jie(temp,temp_buf,key);

  fwrite(temp_buf,sizeof(byte),8,fp1);

  fputc(‘@’,fp1);

  }

  fclose(fp);

  fclose(fp1);

  }

  void unlock_file(word16 key[][7])

  {

  char filename[40];

  printf(“enter file name/n”);

  scanf(“%s”,filename);

  getchar();

  FILE *fp,*fp1;

  fp=fopen(filename,“rb”);

  fp1=fopen(“unlocked”,“w”);

  byte temp[256];

  byte temp_buf[256];

  while(!feof(fp)){

  int length=0;

  while(1){

  fread(&temp[length++],1,1,fp);

  if(temp[length-1]==‘@’)

  break;

  }

  jia_jie(temp,temp_buf,key);

  fputs((char *)temp_buf,fp1);

  }

  fclose(fp);

  fclose(fp1);

  }

  int main()

  {

  char ch;

  while(1){

  ch=prin_ch();

  if(ch==‘q’)

  break;

  idea_key key;

  get_key(&key);

  switch(ch){

  case ‘1’:

  lock_file(key.jia_key);

  break;

  case ‘2’:

  unlock_file(key.jie_key);

  default:

  break;

  }

  }

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分