58,50,42,34,26,18,10,2, 3-2 初始置换IP及逆初始置换
图60,52,44,36,28,20,12,4, 62,54,46,38,30,22,14,6, 64,56,48,40,32,24,16,8, 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 26, 5, 的计算过程如下:
讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。 , E ,13, P 图3-3扩展运算E与置
换P
16,17, 20,21, 24,25, 28,29, 32, 1, 其
中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。 S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是
否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。
图3-4 f函数运算框图
16 每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。
密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。
图3-5子密钥的产生过程
对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。 四、实验组织运行要求
本实验采用集中授课形式,每个同学独立完成上述实验要求。 五、实验条件
每人一台计算机独立完成实验,有如下条件: (1)硬件:微机;
(2)软件:VC++6.0、VC++.Net 2005。 六、实验步骤
(1)将各函数编写完成;
(2)在主函数中调用各函数,实现加密和解密。 七、实验报告
实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。 #include void ip(int ora_bit[],int l[],int r[]);ip置换 void swap(int key[],int c[],int d[]);种密钥置换选择1 17 void move(int a[]);循环左移 void move1(int a[]);循环左移 void swap1(int k[],int c[],int d[] );种密钥置换2 void yihuo32(int l[],int f[]);feistel异或运算 void yihuo48(int a[],int k[]); void s_box(int a[][6],int sbox[][4][16],int result[32]);查询s盒 void p_swap(int result[]);f函数中的置换p void F(int r[],int k[],int result[],int sbox[][4][16]);feistel F函数 void feistel(int l[],int r[],int k[],int sbox[][4][16]);feistel void ip1(int fei_result[64],int ip1[64]);ip逆置换 char ora[8],ora_key[8]; int ora_bit[64],key[64],k[48]; int l[32],r[32],c[28],d[28],fei_result[64],des[8]; int i,j,n; int sbox[8][4][16]={ 1}; s盒 printf(\请输入明文\gets(ora);密码明文 for(i=0;i<8;i++)将明文从字母转换成2进制 { n=ora[i]; for(j=0;j<8;j++) { if(n%2==0) { ora_bit[i*8+j]=0; } else { 18 ora_bit[i*8+j]=1; } n=n2; } } ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题 printf(\请输入8位字母种密钥\gets(ora_key);手动输入种密钥 for(i=0;i<8;i++)将种密钥从字母转换为2进制 { n=ora_key[i]; for(j=0;j<8;j++) { if(n%2==0) { key[i*8+j]=0; } else { key[i*8+j]=1; } n=n2; } } swap(key,c,d);种密钥置换1 for(i=0;i<16;i++) { if(i==0||i==1||i==8||i==15) { 19 move(c);循环左移 move(d);循环左移 } else { move1(c); move1(d); } swap1(k,c,d);置换2--得到k feistel(l,r,k,sbox);feistel运算 } for(i=0;i<32;i++) { fei_result[i]=l[i]; fei_result[32+i]=r[i]; }汇合feistel输出的l-16和r-16 ip1(fei_result,des);进行ip逆置换 for(i=0;i<8;i++) { printf(\} printf(\} void ip(int ora_bit[],int l[],int r[])ip置换 { int i,j,k; int temp[8][8]; for(k=0,i=57;k<4,i<=63;k++,i+=2) { 20