1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<time.h>
5 typedef enum { true=1, false=0 }bool;
6 int She[8][4][16]={{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},\
7 {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},\
8 {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},\
9 {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},\
10 {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},\
11 {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},\
12 {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 {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}};
14 int ss[49]={0,32,1,2,3,4,5,4,5,6,7,8,9,8,9,10,11,12,13,12,13,14,15,16,17,16,17,18,19,20,21,20,21,22,23,24,25,24,25,26,27,28,29,28,29,30,31,32,1};//E函数的置换
15 int p[33]={0,16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25};
16 void outputAll(bool*input,int total){
17 int i;
18 for(i=1;i<=total;i++){
19 printf("%d",input[i]);
20 if(i%8==0)printf("\n");
21 }
22 printf("\n");
23 }
24 void*forward(bool*input,int bit){//确保0的位置不使用,向后轮转
25 int i;
26 for(i=1;i<=bit;i++){
27 input[i]=input[i-1];
28 }
29 }
30 int fact(int n)
31 { if(n<2) //将 2 换成其它数如 8 就可输出 8 进制的结果
32 return n;
33 else
34 { return fact(n/2)*10+n%2; //将二进制结果整个输出
35 }
36 }
37 bool* hextoBin(char*input){//只能使用16个16进制字符串输入,输出二进制数字数组
38 bool *output=(bool*)malloc(65*sizeof(bool));
39 int i;
40 int a;
41 for(i =1;i<=16;i++){
42
43 if(input[i]<58)a=fact(input[i]-48);
44 else a=fact(input[i]-55);
45 output[4*i-3]=a/1000;
46 output[4*i-2]=a/100%10;
47 output[4*i-1]=a/10%10;
48 output[4*i]=a%10;
49 }
50 return output;
51 }
52 bool*IP(bool*input,int mode){//模式1是IP,模式2是IP-1
53 int ip[65]={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,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};
54 int i;
55 bool*output=(bool*)malloc(65*sizeof(bool));
56 if(mode==1){
57 for( i=1;i<=64;i++){
58 output[i]=input[ip[i]];
59 }
60 }else{
61 for( i=1;i<=64;i++){
62 output[ip[i]]=input[i];
63 }
64 }
65 return output;
66 }
67 bool*PC1(bool*input){
68 int ss[65]={0,57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4};
69 bool*output=(bool*)malloc(57*sizeof(bool));int i;
70 for(i=1;i<=56;i++){
71 output[i]=input[ss[i]];
72 }
73 return output;
74 }
75 bool*PC2(bool*input1,bool*input2){
76 int ss[49]={0,14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32};
77 bool*output=(bool*)malloc(49*sizeof(bool));int i;
78 for(i=1;i<=48;i++){
79 if(ss[i]>28){
80 output[i]=input2[ss[i]-28];
81 }else{
82 output[i]=input1[ss[i]];
83 }
84 }
85 return output;
86 }
87 bool*P(bool*input){
88
89 bool*output=(bool*)malloc(33*sizeof(bool));int i;
90 for(i=1;i<=32;i++){
91 output[i]=input[p[i]];
92 }return output;
93 }
94 bool*makeKey(bool*key,int num){//num=1--16
95 key=PC1(key);
96 bool*outputKey=(bool*)malloc(49*sizeof(bool));
97 bool*temp;
98 int LS[17]={0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
99 bool*C0=(bool*)malloc(29*sizeof(bool));
100 bool*D0=(bool*)malloc(29*sizeof(bool));
101 int i,j;
102 for(i=1;i<=56;i++){
103 if(i>28){
104 D0[i-28]=key[i];
105 }else{
106 C0[i]=key[i];
107 }
108
109 }
110
111 for(i=1;i<=num;i++){
112 temp=(bool*)malloc(29*sizeof(bool));
113 for(j=1;j<=28;j++){
114 if(j+LS[i]>28)temp[j]=C0[j+LS[i]-28];
115 else temp[j]=C0[j+LS[i]];
116 }
117 for(j=1;j<=28;j++)C0[j]=temp[j];
118 for(j=1;j<=28;j++){
119 if(j+LS[i]>28)temp[j]=D0[j+LS[i]-28];
120 else temp[j]=D0[j+LS[i]];
121 }
122 for(j=1;j<=28;j++)D0[j]=temp[j];
123 free(temp);
124 }
125 outputKey=PC2(C0,D0);
126 return outputKey;
127 }
128 bool*E(bool*input){//针对32位 到48的拓展
129 int ss[49]={0,32,1,2,3,4,5,4,5,6,7,8,9,8,9,10,11,12,13,12,13,14,15,16,17,16,17,18,19,20,21,20,21,22,23,24,25,24,25,26,27,28,29,28,29,30,31,32,1};
130 bool*output=(bool*)malloc(sizeof(bool)*49);int i;
131 for(i =1;i<=48;i++){
132 output[i]=input[ss[i]];
133 }
134 return output;
135 }
136 bool* S(bool*input){
137 bool*output=(bool*)malloc(sizeof(bool)*49);
138 int i,j, hex;
139 for(i=1,j=1;i<=48;i+=6,j++){
140 hex=fact(She[j-1][input[i]*2+input[i+5]][input[i+1]*8+input[i+2]*4+input[i+3]*2+input[i+4]*1]);
141 output[4*j-3]=hex/1000;
142 output[4*j-2]=hex/100%10;
143 output[4*j-1]=hex/10%10;
144 output[4*j]=hex%10;
145 }
146 return output;
147 }
148
149 bool*XOR(bool*input1,bool*input2,int total){//不同位数的异或操作
150 int i;
151 bool*output=(bool*)malloc(sizeof(bool)*(total+1));
152 for(i=1;i<=total;i++){
153 if((input1[i]+input2[i])==1)output[i]=1;
154 else output[i]=0;
155 }
156 return output;
157 }
158 bool*DESf(bool*R,bool*key){//R是64位的,将前32位进行加密,后32位放到前面
159
160 bool*ER=E(&R[32]);int i;
161 bool*un=(bool*)malloc(sizeof(bool)*65);
162 ER=XOR(ER,key,48);
163 ER=S(ER);
164 ER=P(ER);
165 ER=XOR(ER,R,32);
166 for(i=1;i<=64;i++){
167 if(i<33){
168 un[i]=R[i+32];
169 }else{
170 un[i]=ER[i-32];
171 }
172 }
173 return un;
174 }
175 char*bintoHex(bool*input){
176 char*result=(char*)malloc(sizeof(char)*18);
177 int i,j;int m;
178 for(i=1,j=1;i<=64;i+=4,j++){
179 m=input[i]*8+input[i+1]*4+input[i+2]*2+input[i+3];
180 if(m>9)result[j]=m+55;
181 else result[j]=m+48;
182 }
183 result[17]='\0';
184 return result;
185 }
186 bool* reverse(bool*input){
187 bool*output=(bool*)malloc(sizeof(bool)*65);
188 int i;
189 for(i=1;i<=64;i++){
190 if(i>32){
191 output[i]=input[i-32];
192 }else{
193 output[i]=input[i+32];
194 }
195 }
196 return output;
197 }
198 bool* DES(bool*BIN64,bool*key){
199 BIN64=IP(BIN64,1);int i;
200 for(i=1;i<=16;i++){
201 BIN64= DESf(BIN64,makeKey(key,i));
202 }
203 BIN64=reverse(BIN64);
204 BIN64=IP(BIN64,2);
205
206 return BIN64;
207 }
208 char*scanfFile(char*fileName){//不需要考虑换行问题
209 FILE *f=fopen(fileName,"r");
210 char*output=(char*)malloc(sizeof(char)*66);
211 if(!f){
212 printf("打开文件%s失败",fileName);
213 }else{
214 fscanf(f,"%s",output);
215 }
216 int i;
217
218 for(i=strlen(output);i>=0;i--){//保证从1开始
219 output[i+1]=output[i];
220 }output[strlen(output)+2]='\0';
221 return output;
222 }
223 void*writeFile(char*fileName,char*s,char*mode){//s是要写入的字符串
224 FILE*f=fopen(fileName,mode);printf("%s",fileName);
225 if(!f){
226 printf("打开文件%s失败",fileName);
227 }else{
228 fprintf(f,"%s",s);
229 }
230 fclose(f);
231 }
232 void ECB(char*plainfile,char*keyfile,char*cipherfile){//测试成功
233 char *a;int i,j;char *ckey;char mode[3]="w+";
234 a=scanfFile(plainfile);bool*BIN64;
235 ckey=scanfFile(keyfile);
236 bool*key=hextoBin(ckey);
237 for(j=1;j<strlen(a);j=j+16){
238 BIN64=hextoBin(&a[j-1]);//高位在高索引,确认一检查 ,16进制如何摆放问题????
239 /*BIN64=IP(BIN64,1);
240 for(i=1;i<=16;i++){
241 BIN64= DESf(BIN64,makeKey(key,i));
242 }
243 BIN64=reverse(BIN64);
244 BIN64=IP(BIN64,2);*/
245 bool*cipherB=DES(BIN64,key);
246 char*cipher=bintoHex(cipherB);
247 writeFile(cipherfile,&cipher[1],mode);
248 if(j==1){
249 mode[0]='a';mode[1]='\0';
250 }
251 }
252 }
253 void CBC(char*plainfile,char*keyfile,char*cipherfile,char*vifile){
254 //printf("CBC");
255 char *a;int j;char *ckey;char mode[3]="w+";
256 a=scanfFile(plainfile);bool*BIN64;
257 ckey=scanfFile(keyfile);
258 bool*key=hextoBin(ckey);
259 char*siv=scanfFile(vifile);
260 bool*iv=hextoBin(siv); char*cipher;
261 for(j=1;j<strlen(a);j=j+16){
262 BIN64=hextoBin(&a[j-1]);//高位在高索引,确认一检查 ,16进制如何摆放问题????
263 BIN64=XOR(BIN64,iv,64);
264 iv=DES(BIN64,key);
265 cipher=bintoHex(iv);
266 writeFile(cipherfile,&cipher[1],mode);
267 if(j==1){
268 mode[0]='a';mode[1]='\0';
269 }
270 }
271 }
272 void CFB(char*plainfile,char*keyfile,char*cipherfile,char*vifile){
273 char *a;int i,j,k,counter=0;char *ckey;char mode[3]="w+";
274 a=scanfFile(plainfile);
275 bool*BIN64,*c;
276 bool*cipherB=(bool*)malloc(sizeof(bool)*65);
277 ckey=scanfFile(keyfile);
278 bool*key=hextoBin(ckey);
279 char*siv=scanfFile(vifile);
280 bool*iv=hextoBin(siv);
281 char*cipher;
282 for(j=1;j<strlen(a);j=j+16){
283 BIN64=hextoBin(&a[j-1]);
284 //BIN64=XOR(BIN64,iv,64);
285 for(i=1;i<=8;i++){
286 c=XOR(DES(iv,key),&BIN64[8*i-8],8);
287 for(k=1;k<=64;k++){//iv左移8位
288 if(k<=56)iv[k]=iv[k+8];
289 else iv[k]=c[k-56];
290 }
291 for(k=1;k<=8;k++){
292 cipherB[counter+k]=c[k];
293 }counter+=8;
294 }
295
296 cipher=bintoHex(cipherB);
297 writeFile(cipherfile,&cipher[1],mode);
298 if(j==1){
299 mode[0]='a';mode[1]='\0';
300 }
301 counter=0;
302 }
303 }
304 void OFB(char*plainfile,char*keyfile,char*cipherfile,char*vifile){
305 char *a;int i,j,k,counter=0;char *ckey;char mode[3]="w+";
306 a=scanfFile(plainfile);bool*BIN64;
307 ckey=scanfFile(keyfile);
308 bool*key=hextoBin(ckey);
309 char*siv=scanfFile(vifile);
310 bool*iv=hextoBin(siv); bool*cipherB=(bool*)malloc(sizeof(bool)*65);bool*temp;
311 bool*c;char*cipher;
312
313 for(j=1;j<strlen(a);j=j+16){
314 BIN64=hextoBin(&a[j-1]);
315 temp=(bool*)malloc(sizeof(bool)*65);
316 for(i=1;i<=8;i++){printf("i=%d",i);
317 for(k=1;k<=64;k++)temp[k]=iv[k];
318 iv=DES(iv,key);
319 c=XOR(iv,&BIN64[8*i-8],8);
320 for(k=64;k>=1;k--){//iv左移8位
321 if(k<=56)iv[k]=temp[k+8];
322 else iv[k]=iv[k-56];
323 }
324 for(k=1;k<=8;k++){
325 cipherB[counter+k]=c[k];
326 }counter+=8;
327 }
328 cipher=bintoHex(cipherB);
329 writeFile(plainfile,&cipher[1],mode);
330 if(j==1){
331 mode[0]='a';mode[1]='\0';
332 }
333 counter=0;
334 }
335 }
336 bool*DDESF(bool*cipher,bool*key){//key是64位的,cipher是64位的
337
338 int i;
339 for(i=16;i>=1;i--){
340 cipher=reverse(cipher);
341 cipher=DESf(cipher,makeKey(key,i));cipher=reverse(cipher);
342 }
343
344 return cipher;
345
346 }
347 bool* DDES(bool*cipher,bool*key){//均为从1开始的64位
348 int i;bool*output=(bool*)malloc(sizeof(bool)*65) ;
349 cipher=IP(cipher,1);
350 cipher=reverse(cipher);
351 output=DDESF(cipher,key);//区别于f函数,解密F论函数
352 output=IP(output,2);
353 return output;
354
355 }
356 void DECB(char*plainfile,char*keyfile,char*cipherfile){
357 char *a;int i,j;char *ckey;char mode[3]="w+";
358 a=scanfFile(cipherfile);bool*BIN64,*cipherB;
359 ckey=scanfFile(keyfile);char*cipher;
360 bool*key=hextoBin(ckey);
361 for(j=1;j<strlen(a);j=j+16){
362 BIN64=hextoBin(&a[j-1]);
363
364 cipherB=DDES(BIN64,key);
365 cipher=bintoHex(cipherB);
366 writeFile(plainfile,&cipher[1],mode);
367 if(j==1){
368 mode[0]='a';mode[1]='\0';
369 }
370 }
371 }
372 void DCBC(char*plainfile,char*keyfile,char*cipherfile,char*vifile){
373 char *a;int i,j;char *ckey;char mode[3]="w+";
374 a=scanfFile(cipherfile);bool*BIN64;bool*output=(bool*)malloc(sizeof(bool)*65);
375 ckey=scanfFile(keyfile);
376 bool*key=hextoBin(ckey);
377 char*siv=scanfFile(vifile);
378 bool*iv=hextoBin(siv); char*cipher;
379 for(j=1;j<strlen(a);j=j+16){
380 BIN64=hextoBin(&a[j-1]);
381 for(i=1;i<=64;i++)output[i]=BIN64[i];
382 BIN64=DDES(BIN64,key);
383 BIN64=XOR(BIN64,iv,64);
384 cipher=bintoHex(BIN64);
385 for(i=1;i<=64;i++)iv[i]=output[i];
386 writeFile(plainfile,&cipher[1],mode);
387 if(j==1){
388 mode[0]='a';mode[1]='\0';
389 }
390 }
391 }
392 void DCFB(char*plainfile,char*keyfile,char*cipherfile,char*vifile){//由于未在CFB上修改很多 ,命名有误请谅解
393 char *a;int i,j,k,counter=0;char *ckey;char mode[3]="w+";
394 a=scanfFile(cipherfile);
395 bool*BIN64,*c;
396 bool*cipherB=(bool*)malloc(sizeof(bool)*65);
397 ckey=scanfFile(keyfile);
398 bool*key=hextoBin(ckey);
399 char*siv=scanfFile(vifile);
400 bool*iv=hextoBin(siv);
401 char*cipher;
402 for(j=1;j<strlen(a);j=j+16){
403 BIN64=hextoBin(&a[j-1]);
404 //BIN64=XOR(BIN64,iv,64);
405 for(i=1;i<=8;i++){
406 c=XOR(DES(iv,key),&BIN64[8*i-8],8);
407 for(k=1;k<=64;k++){//iv左移8位
408 if(k<=56)iv[k]=iv[k+8];
409 else iv[k]=BIN64[8*i-8+k-56];
410 }
411 for(k=1;k<=8;k++){
412 cipherB[counter+k]=c[k];
413 }counter+=8;
414 }
415
416 cipher=bintoHex(cipherB);
417 writeFile(plainfile,&cipher[1],mode);
418 if(j==1){
419 mode[0]='a';mode[1]='\0';
420 }
421 counter=0;
422 }
423 }
424 void DOFB(char*plainfile,char*keyfile,char*cipherfile,char*vifile){
425 char *a;int i,j,k,counter=0;char *ckey;char mode[3]="w+";
426 a=scanfFile(cipherfile);bool*BIN64;
427 ckey=scanfFile(keyfile);
428 bool*key=hextoBin(ckey);
429 char*siv=scanfFile(vifile);
430 bool*iv=hextoBin(siv); bool*cipherB=(bool*)malloc(sizeof(bool)*65);bool*temp;
431 bool*c;char*cipher;
432
433 for(j=1;j<strlen(a);j=j+16){
434 BIN64=hextoBin(&a[j-1]);
435 temp=(bool*)malloc(sizeof(bool)*65);
436 for(i=1;i<=8;i++){
437 for(k=1;k<=64;k++)temp[k]=iv[k];
438 iv=DES(iv,key);
439 c=XOR(iv,&BIN64[8*i-8],8);
440 for(k=64;k>=1;k--){//iv左移8位
441 if(k<=56)iv[k]=temp[k+8];
442 else iv[k]=iv[k-56];
443 }
444 for(k=1;k<=8;k++){
445 cipherB[counter+k]=c[k];
446 }counter+=8;
447 }
448 cipher=bintoHex(cipherB);
449 writeFile(plainfile,&cipher[1],mode);
450 if(j==1){
451 mode[0]='a';mode[1]='\0';
452 }
453 counter=0;
454 }
455 }
456 void test(){
457
458 char plainfile[20]="des_plain.txt";
459 char cipherfile[20]="des_Cipher.txt";
460 char keyfile[20]="des_key.txt";
461 char vifile[20]="des_iv.txt";
462 long int sum=10*1024*1024;
463 printf("%d",sum);
464 FILE*f=fopen("des_plain.txt","w");
465 int i,temp;srand((unsigned)time( NULL ) );
466 for(i=0;i<sum;i++){
467 //printf("%d\n", rand()%16);
468 temp=rand()%16;
469 if(temp>9)temp+=55;
470 else temp+=48;
471 fprintf(f,"%c",temp);
472 }
473 fclose(f);clock_t start,end;
474 start =clock();
475 for(i=0;i<20;i++)
476 {
477 //ECB(plainfile,keyfile,cipherfile)
478 //CBC(plainfile,keyfile,cipherfile,param.vifile);
479 //CFB(plainfile,keyfile,cipherfile,param.vifile);
480 OFB(plainfile,keyfile,cipherfile,vifile);
481 DOFB(plainfile,keyfile,cipherfile,vifile);
482
483 }
484 end=clock();
485 printf("OFB模式花的时间:%d ms",(int)(end-start));
486 }
487 int main(int argc,char *argv[]){
488 //e1des -p plainfile -k keyfile [-v vifile] -m mode -c cipherfile
489 /*char plainfile[20]="des_plain.txt";
490 char cipherfile[20]="des_Cipher.txt";
491 char keyfile[20]="des_key.txt";
492 char vifile[20]="des_iv.txt";
493 char mode[4]="OFB";//上面均为默认参数
494 int i=1;
495 while(i<argc)
496 {
497 if(!strcmp(argv[i],"-p"))
498 //plainfile=&argv[i+1];
499 strcpy(plainfile,argv[i+1]);
500 else if(!strcmp(argv[i],"-k"))
501 strcpy(keyfile,argv[i+1]);
502 else if(!strcmp(argv[i],"-m"))
503 strcpy(mode,argv[i+1]);
504 else if(!strcmp(argv[i],"-c"))
505 strcpy(cipherfile,argv[i+1]);
506 else if(!strcmp(argv[i],"-v"))
507 strcpy(vifile,argv[i+1]);
508 i+=2;
509 }
510 printf("plain=%s\n",plainfile);
511 printf("keyfile=%s",keyfile);
512 printf("%s",mode);
513 if(!strcmp(mode,"ECB"))
514 DECB(plainfile,keyfile,cipherfile);
515 else if(!strcmp(mode,"CBC"))
516 DCBC(plainfile,keyfile,cipherfile,vifile);
517 else if(!strcmp(mode,"CFB"))
518 DCFB(plainfile,keyfile,cipherfile,vifile);
519 else if(!strcmp(mode,"OFB"))
520 DOFB(plainfile,keyfile,cipherfile,vifile);
521 else
522 printf("Wrong mode!Please try again!");*/
523 test();
524 }