⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.h

📁 可实现基于DES的基本的加密解密以及短块、弱密钥分析等实现。
💻 H
字号:
#include<stdio.h>
#include<string.h>
#define NUM1 64
#define NUM2 56
#define NUM3 48
#define NUM4 32
#define NUM5 28
#define NUM6 16
#define MAXLEN 1024
#define MAX 8192

/*以下是关于DES算法中一些数据的定义*/
int key[NUM6][NUM3];   /*用来保存16个子密钥*/
int t[14],f[14];       /*t[],f[]用来保存游程中各数据串的个数*/
static const int IP1[NUM1] = {
                     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,
                     56, 48, 40, 32, 24, 16,  8, 0,
                     58, 50, 42, 34, 26, 18, 10, 2,
                     60, 52, 44, 36, 28, 20, 12, 4,
                     62, 54, 46, 38, 30, 22, 14, 6
}; 

static const int IP2[NUM1] = {
                     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,
                     32, 0, 40,  8, 48, 16, 56, 24
 };

static const int PC1[NUM2] = {
    56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,  
     9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35, 
    62, 54, 46, 38, 30, 22, 14,  6, 61, 53, 45, 37, 29, 21,
    13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11,  3 
};

static const int PC2[NUM3] = {
    13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
    22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
    40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
    43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
};
static const int leftshift[NUM6] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

static const int S[8][64] = {          /*真S盒*/
             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
};

static const int S1[8][64] = {           /*伪S盒*/
             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,
             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,
             11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
              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,

             15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
             13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
              6, 9,13, 4, 7,14, 1, 3,11, 0,12, 2, 5,10,15, 8,
              1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,


             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,
             13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,

              1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
             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,

             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,
              4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
              4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,

              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,
             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,

             13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
              9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
              6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
              1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2
};

/*选择运算E*/
static const int E[NUM3] = {
                          31, 0, 1, 2, 3, 4,
                           3, 4, 5, 6, 7, 8,
                           7, 8, 9,10,11,12,
                          11,12,13,14,15,16,
                          15,16,17,18,19,20,
                          19,20,21,22,23,24,
                          23,24,25,26,27,28,
                          27,28,29,30,31, 1
};
static const int P[NUM4] = {15, 6,19,20,28,11,27,16,
                             0,14,22,25, 4,17,30, 9,
                             1, 7,23,13,31,26, 2, 8,
                            18,12,29, 5,21,10, 3,24
};

int key_setup(int p[]);          /*函数说明*/
void cryption(int p[],int k[],int judge);
void change1(char p[],int q[],int k);
void change2(char p[],int q[]);
void encrypt(int p[],int q[],int pq[],int judge);
void decrypt(int p[],int q[],int pq[]);
void HTB(char n,int *s1);
void traveral(int a[],int tra[],int k);

void DES(char *plaintext,char *ciphertext,char *deciphertext,int k)
{
 int i,j,n,a,b;
 char buf_text[8];
 char ciphertext1[MAXLEN];
 int plain[NUM1],cipher[NUM1],L[NUM4],R[NUM4],short_buf[NUM1];
 int p_temp[NUM1],buf_temp[NUM1]; /*数组中间变量(用作暂存)*/
 int R1[NUM4],L1[NUM4],cipher1[NUM1];
 int yc[MAX],yc1[MAX];      /*保存加密后的0、1串*/
 a=k/8;
 b=k%8;
 for(n=0;n<a;n++)           /*先对前面的8的整数倍的字符串进行加密*/
 {change1(plaintext+8*n,plain,8);
  for(i=0;i<NUM1;i++)
   p_temp[i]=*(plain+IP1[i]);
  for(i=0;i<NUM4;i++)
  {L[i]=p_temp[i];
   R[i]=p_temp[i+NUM4];
   }
  for(i=0;i<NUM4;i++)
  {L1[i]=L[i];
   R1[i]=R[i];
   }
  encrypt(L1,R1,cipher1,0);
  change2(ciphertext1+8*n,cipher1);
  encrypt(L,R,cipher,1);
  change2(ciphertext+8*n,cipher);
  decrypt(R,L,plain);
  change2(deciphertext+8*n,plain);
  }
 if(b!=0)                  /*如果存在短块,则进行相应处理*/
 {for(i=NUM1-(8-b)*8,j=0;i<NUM1;i++,j++)
    buf_temp[j]=cipher[i];
  change1(plaintext+8*a,short_buf,b);
  for(i=0,j=8*(8-b);j<NUM1;i++,j++)
    buf_temp[j]=short_buf[i];
  for(i=0;i<NUM1;i++)
    p_temp[i]=*(buf_temp+IP1[i]);
  for(i=0;i<NUM4;i++)
  {L[i]=p_temp[i];
   R[i]=p_temp[i+NUM4];
   }
  for(i=0;i<NUM4;i++)
  {L1[i]=L[i];
   R1[i]=R[i];
   }
  encrypt(L1,R1,cipher1,0);
  change2(ciphertext1+8*a-(8-b),cipher1);
  encrypt(L,R,cipher,1);
  change2(ciphertext+8*a-(8-b),cipher);
  decrypt(R,L,plain);
  change2(buf_text,plain);
  for(i=8-b,j=k-b;i<8;i++,j++)
    deciphertext[j]=buf_text[i];
  }
 change1(ciphertext,yc,k);
 traveral(yc,t,k*8);
 change1(ciphertext1,yc1,k);
 traveral(yc1,f,k*8);
}

/*用来将十六进制转换位二进制*/
void HTB(char n,int *s1)
{
  int s[4]={0,0,0,0},i,j,k=0,g;
  if(n>=48&&n<=57)  g=(int)(n-48);
  else {
	    if(n>64&&n<71) g=(int)(n-55);
		else g=(int)(n-87);
		}
  i=g%2;
  j=g/2;
  s[3-k]=i;
  while(j)
  {
    k++;
    i=j%2;
    j=j/2;
   s[3-k]=i;
  }
  for(i=0;i<4;i++)
  *(s1+i)=*(s+i);
}

/*用来计算0、1串中各游程的数目*/
void traveral(int a[],int tra[],int k)
{
 int i;
 for(i=0;i<k-2;i++)
 {if(a[i]==0)
  {tra[0]++;
   if(a[i+1]==0)
   {tra[2]++;
    if(a[i+2]==0) tra[6]++;
    else tra[7]++;
    }
   else
   {tra[3]++;
    if(a[i+2]==0) tra[8]++;
    else tra[9]++;
    }
   }
  else
  {tra[1]++;
   if(a[i+1]==0)
   {tra[4]++;
    if(a[i+2]==0) tra[10]++;
    else tra[11]++;
    }
   else
   {tra[5]++;
    if(a[i+2]==0) tra[12]++;
    else tra[13]++;
    }
  }
 }
 if(a[k-2]==0)
 {tra[0]++;
  if(a[MAX-1]==0)
  {tra[0]++;
   tra[2]++;
   }
  else
  {tra[1]++;
   tra[3]++;
   }
  }
  else
  {tra[1]++;
   if(a[k-1]==0)
   {tra[0]++;
    tra[4]++;
    }
   else
   {tra[1]++;
    tra[5]++;
    }
   }
}

/*16轮加密函数(p为指向左边的32位串,q指向右边串,
pq指向密文串),通过变量judge来判断是用真S盒还是伪S盒进行加密*/
void encrypt(int p[],int q[],int pq[],int judge)
{
 int R_temp[NUM4],temp[NUM1];
 int i,j;
 for(i=0;i<NUM6;i++)  /*进行16轮的加密过程*/
 {for(j=0;j<NUM4;j++)
    R_temp[j]=q[j];
  cryption(q,key[i],judge);
  for(j=0;j<NUM4;j++)
  {q[j]=q[j]^p[j];
   p[j]=R_temp[j];
   }
 }
 for(j=0;j<NUM4;j++)
 {temp[j]=q[j];
  temp[j+NUM4]=p[j];
  }
 for(i=0;i<NUM1;i++)
   pq[i]=*(temp+IP2[i]);
}


/*解密函数*/
void decrypt(int p[],int q[],int pq[])
{
 int R_temp[NUM4],temp[NUM1];
 int i,j;
 for(i=NUM6-1;i>=0;i--)    /*进行16轮的解密过程*/
 {for(j=0;j<NUM4;j++)
    R_temp[j]=q[j];
  cryption(q,key[i],1);
  for(j=0;j<NUM4;j++)
  {q[j]=q[j]^p[j];
   p[j]=R_temp[j];
   }
 }
 for(j=0;j<NUM4;j++)
 {temp[j]=q[j];
  temp[j+NUM4]=p[j];
  }
 for(i=0;i<NUM1;i++)
   pq[i]=*(temp+IP2[i]);
}


/*密钥生成函数(并且执行弱密码检验)*/
int key_setup(int p[]) /*p[]为64位密钥的指针*/
{
 int i,j,k,m,n,flag=1,flag1=0;
 int C[NUM5],D[NUM5],C_temp[NUM5],D_temp[NUM5],key_temp[NUM2];
 for(i=0;i<NUM5;i++)
 {C[i]=*(p+PC1[i]);
  D[i]=*(p+PC1[i+NUM5]);
  }
 for(i=0;i<(NUM5-1);i++)
 {if(C[i]!=C[i+1]||D[i]!=D[i+1])
   {flag=0;
    break;
    }
  }
 if(flag==1)
  {
   flag1=1;
   return flag1;
   }
 else
   for(i=0;i<NUM6;i++)      /*进行16轮的子密钥的生成*/
   {k=leftshift[i];
    for(n=0;n<NUM5;n++)
     {C_temp[n]=C[n];
      D_temp[n]=D[n];
      }
    for(j=0;j<NUM5;j++)
    {C[j]=C_temp[(j+k)%NUM5];
     D[j]=D_temp[(j+k)%NUM5];
     key_temp[j]=C[j];
     key_temp[j+NUM5]=D[j];
    }
    for(m=0;m<NUM3;m++)
      key[i][m]=*(key_temp+PC2[m]);
   }
 return flag1;
}

/*加密函数f(A,k),运算结果保存在p[]中,p[]为32位的输入,
 k[]为48位的子密钥,通过judge来判断是用真S盒还是伪s盒来处理*/
void cryption(int p[],int k[],int judge)
{
 int i,j,m,n,flag,a;
 int l=0,b=0;
 int p1[NUM3],q[6],q1[4],temp[32];
 for(i=0;i<NUM3;i++)
  p1[i]=*(p+E[i]);
 for(i=0;i<NUM3;i++)
  p1[i]=p1[i]^k[i];
 for(i=0,flag=0;i<NUM3;flag++)
 {
  for(j=0;j<6;j++,i++)
  q[j]=p1[i];
  m=q[0]*2+q[5];
  n=q[1]*8+q[2]*4+q[3]*2+q[4];
  if(judge==1)  a=S[flag][m*16+n];
  else          a=S1[flag][m*16+n];
  q1[l++]=a/8;
  q1[l++]=(a/4)%2;
  q1[l++]=(a/2)%2;
  q1[l]=a%2;
  l=0;
  for(n=0;n<4;n++,b++)
  {temp[b]=q1[n];}
 }
 for(i=0;i<NUM4;i++)
   p[i]=*(temp+P[i]);
}

/*将字符串转换成对应的1、0串,k为字符串的字符个数*/
void change1(char p[],int q[],int k)
{
 int i,j;
 for(i=0,j=0;i<k;i++)
 {
  q[j++]=(p[i]&0x80)>>7;
  q[j++]=(p[i]&0x40)>>6;
  q[j++]=(p[i]&0x20)>>5;
  q[j++]=(p[i]&0x10)>>4;
  q[j++]=(p[i]&0x08)>>3;
  q[j++]=(p[i]&0x04)>>2;
  q[j++]=(p[i]&0x02)>>1;
  q[j++]=(p[i]&0x01);
 }
}

/*将64bit位的1、0串转换成对应的8个字符串*/
void change2(char p[],int q[])
{
 int i,j;
 for(i=0,j=0;i<8;i++)
 {
  p[i]=(q[j++]&0x01)<<7;
  p[i]+=(q[j++]&0x01)<<6;
  p[i]+=(q[j++]&0x01)<<5;
  p[i]+=(q[j++]&0x01)<<4;
  p[i]+=(q[j++]&0x01)<<3;
  p[i]+=(q[j++]&0x01)<<2;
  p[i]+=(q[j++]&0x01)<<1;
  p[i]+=(q[j++]&0x01);
 }
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -