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

📄 calculate_ji_calculate_key.cpp

📁 实现《密码学导引》一书中DES算法差分攻击。输出J1-J8及密钥Key。默认是3轮DES
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	

                                               //计算L0'
	for(i=0;i<4;i++)
	{	
		p1=*(plaintext1+i);
		p2=*(plaintext2+i);
		for(j=7;j>=0;j--)
		{
			L0[8*i+j]=p1%2;	
		     p1=p1/2;
		    l0[8*i+j]=p2%2;	
		     p2=p2/2;
		    L [8*i+j]=L0[8*i+j]^l0[8*i+j];
		}
	}
	
	                                       //计算L3和L3*
	for(i=0;i<4;i++)
	{	
		p1=*(ciphertext1+i);
		p2=*(ciphertext2+i);
		for(j=7;j>=0;j--)
		{
			L3[8*i+j]=p1%2;	
		     p1=p1/2;
		    l3[8*i+j]=p2%2;	
		     p2=p2/2;		    
		}
	}

	
                                               //计算R3'
	for(i=4;i<8;i++)
	{	
		p1=*(ciphertext1+i);
		p2=*(ciphertext2+i);
		for(j=7;j>=0;j--)
		{
			R3[8*(i-4)+j]=p1%2;	
		     p1=p1/2;
		    r3[8*(i-4)+j]=p2%2;	
		     p2=p2/2;
		    R [8*(i-4)+j]=R3[8*(i-4)+j]^r3[8*(i-4)+j];
		}
		
	}
	

                                             //计算C'=P-1(R3'^L0')   课本中(1)
	for(i=0;i<32;i++)
		c[P[i]]=R[i]^L[i];	

	                                         
                                            //计算E(L3)和E(L3*)     课本中(2)
	for(i=0;i<48;i++)
	{
		EL[i]=L3[E[i]];
		el[i]=l3[E[i]];	
	}                	
	                                       //计算testj(Ej,Ej*,Cj')

	test(EL,el,c,J);


}


                                                                            //计算Ji外16-bit,其中des()为简化des加密算法,key()为求16-bit子函数

void des(unsigned char *source,unsigned char * dest1,unsigned char * inkey, int flg)                                                                                          
                                                                                                                                                                                
{   

    unsigned char bufout[64],kwork[56], worka[48], kn[48], buffer[64],
		          nbrofshift, temp1, temp2;
    int valindex;
    register i, j, k, iter;                                                          

                                                                                        /* MAIN PROCESS */
                                                                                 
                                                                                       /* Convert from 64-bit data into 64-byte data */  /* buffer是明文 */
   for (i = 0; i < 8; i++) 
   {
      j = *(source + i);
	  for(k=7;k>=0;k--)
	  {	  
		  buffer[8*i+k] = j% 2;
		  j=j/2;
      
	  }
   }

                                       
                                      //此处为简化des,无IP置换,不过为了形式统一起见,仍然赋值
	for(i=0;i<64;i++)
	   bufout[i]=buffer[i];
	
	                                   /* Convert from 64-bit key into 64-byte key */ 
/*   for (i = 0; i < 8; i++) 
   {
	  kwork[8*i] = ((j = *(inkey + i)) / 128) % 2;
      key[8*i+1] = (j / 64) % 2;
      key[8*i+2] = (j / 32) % 2;
      key[8*i+3] = (j / 16) % 2;
      key[8*i+4] = (j / 8) % 2;
      key[8*i+5] = (j / 4) % 2;
      key[8*i+6] = (j / 2) % 2;
      key[8*i+7] = j % 2;
   } */

                                                                                        /* Initial Permutation of Key */      /*  初始密钥生成置换PC-1  */
    for(i=0;i<56;i++)  
	   kwork[i] = inkey[i];
     

                                                                                        /* 16 Iterations */
for (iter = 1; iter < Round+1; iter++) 
{
    for (i = 0; i < 32; i++)
         buffer[i] = bufout[32+i];                                                         /*  取右边(低位)32位 r 计算f  */

     for(i=0;i<48;i++)                                                                                   /* Calculation of F(R, K) */
         worka[i] = buffer[E[i]];                                                                               /* Permute - E */          /* E置换,把r由32位扩充为48位 */
     
                                                                                        /* KS Function Begin */ /* 轮密钥移位算法,用于生成进入PC-2的中间密钥 */
  if (flg)
  {
      nbrofshift = shift[iter-1];
      for (i = 0; i < (int) nbrofshift; i++) 
      {
        temp1 = kwork[0];
        temp2 = kwork[28];
        for (j = 0; j < 27; j++) 
        {
         kwork[j] = kwork[j+1];
         kwork[j+28] = kwork[j+29];
        }
        kwork[27] = temp1;
        kwork[55] = temp2;
      }
  }   
  else if (iter > 1) 
  {
      nbrofshift = shift[17-iter];
      for (i = 0; i < (int) nbrofshift; i++) 
	  {
        temp1 = kwork[27];
        temp2 = kwork[55];
        for (j = 27; j > 0; j--) 
		{
          kwork[j] = kwork[j-1];
          kwork[j+28] = kwork[j+27];
		}
        kwork[0] = temp1;
        kwork[28] = temp2;
	  }
  }
  
       
    for(i=0;i<48;i++)          
		kn[i] = kwork[PC2[i]];                                                                  /* Permute kwork - PC2 */ /* 经过PC-2 生成轮密钥 k[i] */

                                                                                        /* KS Function End */

                                                                                        /* worka XOR kn */ /* 异或运算生成Bi,准备通过s盒变换 */
    for (i = 0; i < 48; i++)   
		worka[i] = worka[i] ^ kn[i];

                                                                                        /* 8 s-functions */ /* 8个s盒函数运算 */

	for(i=0;i<32;i++)
	{
	  if(i>=0&&i<=3)
		valindex = s1[2*worka[ 0]+worka[ 5]][2*(2*(2*worka[ 1]+worka[ 2])+worka[ 3])+worka[ 4]];
	  if(i>=4&&i<=7)
		valindex = s2[2*worka[ 6]+worka[11]][2*(2*(2*worka[ 7]+worka[ 8])+worka[ 9])+worka[10]];
	  if(i>=8&&i<=11)
		valindex = s3[2*worka[12]+worka[17]][2*(2*(2*worka[13]+worka[14])+worka[15])+worka[16]];
	  if(i>=12&&i<=15)
		valindex = s4[2*worka[18]+worka[23]][2*(2*(2*worka[19]+worka[20])+worka[21])+worka[22]];
	  if(i>=16&&i<=19)
		valindex = s5[2*worka[24]+worka[29]][2*(2*(2*worka[25]+worka[26])+worka[27])+worka[28]];
	  if(i>=20&&i<=23)
		valindex = s6[2*worka[30]+worka[35]][2*(2*(2*worka[31]+worka[32])+worka[33])+worka[34]];
	  if(i>=24&&i<=27)
		valindex = s7[2*worka[36]+worka[41]][2*(2*(2*worka[37]+worka[38])+worka[39])+worka[40]];
	  if(i>=28&&i<=31)
		valindex = s8[2*worka[42]+worka[47]][2*(2*(2*worka[43]+worka[44])+worka[45])+worka[46]];

	  valindex = valindex * 4;
	  kn[i]=binary[(i%4)+valindex];   	  
	  
	}                           /* binary[i]将si[][]中元素转化为2进制*/ 

                                                                                        /* Permute - P */ /* f函数中的P置换 */
        for(i=0;i<32;i++)
            worka[i] = kn[P[i]];
                                                                    /* worka中储存f函数的值 */

                                                                                        /* bufout XOR worka */
  for (i = 0; i < 32; i++) 
  { 
   bufout[i+32] = bufout[i] ^ worka[i];
    bufout[i] = buffer[i];
  }
 
}                                         /* End of Iter n轮迭代结束 */

                                                                   /* Prepare Output */

                                          /*此处为简化des,bufout左右未交换,且未对bufout进行IP逆置换,只是为了与下个程序段中参数buffer对应,
                                              才将bufout赋值给buffer*/

  for(i=0;i<64;i++) 
	   buffer[i]=bufout[i];
                                          

  j = 0;
  for (i = 0; i < 8; i++) 
  {  
	  dest1 [i] = 0x00;  
	  for (k = 0; k < 7; k++)    
		  dest1 [i] = (dest1 [i] + buffer[j+k]) * 2;  
  
	  dest1 [i] = dest1 [i] + buffer[j+7];  
	  j += 8;

  } 

}

                                                          //新加入从k3推key算法
void key(unsigned char *source,unsigned char * dest,unsigned char * inkey, int flg,unsigned char *kr)
{
	                                                    
	unsigned char k3[48],k[56],direct[8],dest1[N],kround[56],key[64];
	register i,j,p,iter,temp1,temp2;
	
                                                      //initialize k3
	for(i=0;i<8;i++)                     
	{
		p=*(kr+i);
		for(j=5;j>=0;j--)
		{
			k3[6*i+j]=p%2;
		    p=p/2;
		}
	
	}
		
	                                                    //对k3进行PC-2逆
	for(i=0;i<48;i++)             
           k[PC2[i]]=k3[i];
	                                                    
                                                        //search for the direction of the unknown 8-bit
	 p=0;
	 for(i=0;i<56;i++)
	 {
		for(j=0;j<48;j++)
		{ 
			if(PC2[j]==i) 
				break;
		}
		if(j==48)
		{
			direct[p]=i;
		    p++;
		}
	 }
	                                                     //对k[]未赋值的字节进行256次的穷尽搜索
	for(i=0;i<256;i++)	 
	{
		 j=i;
		 for(p=0;p<8;p++)
		 {
			 k[direct[p]]=j%2;
			 j=j/2;
			 
		 }
		 for(j=0;j<56;j++)		 			 
			 kround[j]=k[j];
		 	                                                   /* 3 round Iterations 求key*/
    
		 for (iter = 0; iter < Round; iter++) 
		 {
	 				 
			 for (p = 0; p < (int) shift[iter]; p++) 
			 {				     
				 temp1 = kround[27];					 
				 temp2 = kround[55];					 
				 for (j = 27; j > 0; j--)					 
				 {						 
					 kround[j] = kround[j-1];						 
					 kround[j+28] = kround[j+27];					 
				 }					 
				 kround[0]  = temp1;					 
				 kround[28] = temp2;				 
			 }			 
	
		 }
		 
                                                   //compute dest1[8] ,and will be compared with *dest
		 des(source,dest1,kround,flg);
		 
		                                           // 对dest(密文)的正确性进行判断
		 p=0;
		 for(j=0;j<N;j++)
		 {
			 if(dest1[j]==dest[j])			 
				 p++;	
			 else
				 break;
		 }
			 
		 if(p==N)		 
			 break;

	}
	
                                              //calculate PC1逆 get 56bit value of key[64];
	for(i=0;i<56;i++)			
			key[PC1[i]]=kround[i];    
	
		                                      //calculate the other 8bit value of key[64](the checkout bit);
	for(i=0;i<8;i++)
	{
			key[8*i+7]=1;
		    for(j=0;j<7;j++)
			   key[8*i+7]=key[8*i+7]^key[8*i+j];
	}

	printf("\nThe Key is:\n");	
	for(i=0;i<64;i++)
	{
		printf("%d ",key[i]);
		if((i+1)%8==0)
			printf("    ");
	}
                                              
	                                         //calculate inkey;
	for(i=0;i<8;i++)
	{
		inkey[i]=key[8*i];
		for(j=1;j<8;j++)
		{
			inkey[i]*=2;
			inkey[i]=inkey[i]+key[8*i+j];
		}
			   
	}

}

 
void main()
{
    unsigned char plaintext1[N]={0x74,0x85,0x02,0xcd,0x38,0x45,0x10,0x97};
	unsigned char plaintext2[N]={0x38,0x74,0x75,0x64,0x38,0x45,0x10,0x97};
	unsigned char ciphertext1[N]={0x03,0xc7,0x03,0x06,0xd8,0xa0,0x9f,0x10};
	unsigned char ciphertext2[N]={0x78,0x56,0x0a,0x09,0x60,0xe6,0xd4,0xcb};

	unsigned char plaintext1b[N]={0x48,0x69,0x11,0x02,0x6a,0xcd,0xff,0x31};
	unsigned char plaintext2b[N]={0x37,0x5b,0xd3,0x1f,0x6a,0xcd,0xff,0x31};
	unsigned char ciphertext1b[N]={0x45,0xfa,0x28,0x5b,0xe5,0xad,0xc7,0x30};
	unsigned char ciphertext2b[N]={0x13,0x4f,0x79,0x15,0xac,0x25,0x34,0x57};

    unsigned char plaintext1c[N]={0x35,0x74,0x18,0xda,0x01,0x3f,0xec,0x86};
	unsigned char plaintext2c[N]={0x12,0x54,0x98,0x47,0x01,0x3f,0xec,0x86};
	unsigned char ciphertext1c[N]={0xd8,0xa3,0x1b,0x2f,0x28,0xbb,0xc5,0xcf};
	unsigned char ciphertext2c[N]={0x0f,0x31,0x7a,0xc2,0xb2,0x3c,0xb9,0x44};

	unsigned char J[8][64],kr[8],inkey[8];
	int i,j,flg=1;
	                                        
                                           //为J[8][64]赋初值0	
	for(i=0;i<8;i++)
		for(j=0;j<64;j++)
		  J[i][j]=0;
	                                                         //通过三组明密文对求得Ji
	differentialattack(plaintext1,ciphertext1,plaintext2,ciphertext2,&J[0][0]);

	differentialattack(plaintext1b,ciphertext1b,plaintext2b,ciphertext2b,&J[0][0]);

	differentialattack(plaintext1c,ciphertext1c,plaintext2c,ciphertext2c,&J[0][0]);

	for(i=0;i<8;i++)
	{
		printf("J[%d]:\n",i+1);
		for(j=0;j<64;j++)
		{
		   printf("%d ",J[i][j]);
		   if((j+1)%16==0)
			 printf("\n");
		}
	}
	printf("J[i] hex denote:\n");
	                                   //用key[8]记录Ji的值
	for(i=0;i<8;i++)
	{
		printf("J[%d]=",i+1);
		for(j=0;j<64;j++)
			if(J[i][j]==3)
			{
				kr[i]=j;
				printf("%x ",j);
			}
	
	}
	cout<<endl;

	                                   //计算inkey的子函数
	key(plaintext1,ciphertext1,inkey,flg,kr);
	printf("\The Key's Hex Denotation is:\n");
	for(i=0;i<8;i++)
		printf("%x  ",inkey[i]);
	printf("\n");

}



⌨️ 快捷键说明

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