[ 簡単な説明 ]
IBM開発のDESアルゴリズムを用いたファイル暗号化/復号化プログラムです。 C++版のプログラム・ソースは、実行ファイルと共に、NIFTY-Serve に公開しました。 使用法の詳細は、後述のマニュアルと、使用例を参照して下さい。 |
/* des.c Data Encryption Standard */ #include <stdio.h> #include <ctype.h> #include <memory.h> /*#define DEBUG /* print out for debug */ #define SC 1 /* = sizeof(char) */ typedef unsigned int UINT; FILE *fp1, *fp2; char buf[256], bufo[1024]; char *bufolast = bufo + 1016, *bufo_blen = bufo + 8; UINT *key32[16], *key16[16]; UINT *message_IP[64]; UINT *key_L_s[16], *key_R_s[16], *temp_PC2M[48], *temp_PC2K[48]; UINT *mes_IP1[64], *mes_P1[32], *mes_P2[32], *mes_EK1[16], *mes_EK2[16]; UINT cipher[64], code[64], temp[64], mes[64]; UINT key_L[56], key_R[56]; UINT *des_in, *temp_28, *mes_32; UINT *ini_len, *ini_len1, *xb1, *xb2; static int mode = 1, count; static int blen = 8, blen8 = 64, blen8a = 0, llen = 64, llen1 = 0; static int blen8_M = 64 * sizeof(UINT), blen8a_M = 0; static int llen_M = 64 * sizeof(UINT), llen1_M = 0; static UINT initial[64], key[64]; static UINT x[64] = {1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1 }; static UINT IP[64] = { 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 UINT IP1[64] = { 7,39,15,47,23,55,31,63, 6,38,14,46,22,54,30,62, 5,37,13,45,21,53,29,61, 4,36,12,44,20,52,28,60, 3,35,11,43,19,51,27,59, 2,34,10,42,18,50,26,58, 1,33, 9,41,17,49,25,57, 0,32, 8,40,16,48,24,56 }; static UINT S[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 } }, { {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 UINT EK1[16] = { 63,36,35,40,39,44,43,48, 47,52,51,56,55,60,59,32 }; static UINT EK2[16] = { 31, 4, 3, 8, 7,12,11,16, 15,20,19,24,23,28,27, 0 }; static UINT PINV[32] = { 8,16,22,30, 12,27, 1,17, 23,15,29, 5, 25,19, 9, 0, 7,13,24, 2, 3,28,10,18, 31,11,21, 6, 4,26,14,20 }; static UINT PC1[56] = { 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 UINT PC2M[32] = { 16,10,23, 0, 27,14, 5,20, 18,11, 3,25, 6,26,19,12, 51,30,36,46, 39,50,44,32, 48,38,55,33, 41,49,35,28 }; static UINT PC2K[16] = { 13, 4, 2, 9, 22, 7,15, 1, 40,54,29,47, 43,52,45,31 }; static UINT shift[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28}; #ifdef DEBUG char kki[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; #endif /* prototype declaration */ void init_des(), makekey(), des(), usage(), openerr(); void hex_to_code(), byte_to_code(), code_to_byte(); void address(), xor(), ini_shift(), substitute(); void ecb(), cbc_e(), cbc_d(), ofb(), cfb_e(), cfb_d(); #ifdef DEBUG void bprint(), cprint(), code_to_hex(); void bprint(mes1, m, n) UINT *mes1; int m, n; { UINT *p; p = mes1; do { printf("%d", *p++); if(--n == 0) { printf(" "); n = 8; } } while(--m); } void cprint(code1) UINT *code1; { UINT *p; int i; p = code1; i = 16; do { putchar(kki[(((*p++ * 2) + *p++) * 2 + *p++) * 2 + *p++]); } while(--i); } void code_to_hex(code1, hex) UINT *code1; char *hex; { UINT *q; char *p; int i; p = hex; q = code1; i = 16; do { *p++ = kki[(((*q++ * 2) + *q++) * 2 + *q++) * 2 + *q++]); } while(--i); *p = '\0'; } #endif void hex_to_code(hex, code1) char *hex; UINT *code1; { UINT *q = code1; char *p = hex; int ch, i = 16; while(ch = tolower(*p++)) { if(ch >= '0' && ch <= '9') ch -= '0'; else if(ch >= 'a' && ch <= 'f') ch = ch - 'a' + 10; else break; *q++ = (ch >> 3) & 1; *q++ = (ch >> 2) & 1; *q++ = (ch >> 1) & 1; *q++ = ch & 1; if(i-- == 1) return; } memset(q, 0, i * 4 * sizeof(UINT)); } void byte_to_code(byte, code1, cc) char *byte; UINT *code1; int cc; { UINT *q = code1; char *p = byte; int ch, n; n = (8 - cc) * 8 * sizeof(UINT); do { *q++ = ((ch = *p++) >> 7) & 1; *q++ = (ch >> 6) & 1; *q++ = (ch >> 5) & 1; *q++ = (ch >> 4) & 1; *q++ = (ch >> 3) & 1; *q++ = (ch >> 2) & 1; *q++ = (ch >> 1) & 1; *q++ = ch & 1; } while(--cc); memset(q, 0, n); } void code_to_byte(byte, code1) char *byte; UINT *code1; { UINT *q = code1; char *p = byte; int n = blen; do { *p++ = (((((((*q++*2)+*q++)*2+*q++)*2+*q++)*2+*q++)*2+*q++)*2+*q++)*2+*q++; } while(--n); } void address(add, base, index, n) UINT **add, *base, *index; int n; { UINT **pp = add; UINT *p = index; do { *pp++ = base + *p++; } while(--n); } void xor(bufout) char *bufout; { char *p = buf, *q = bufout; int n = count; do { *q++ ^= *p++; } while(--n); } void ini_shift() { UINT *p = ini_len - 1, *q = initial + 63; int n = llen; while(n--) *q-- = *p--; memset(initial, 0, llen1); } void substitute(code1, sub, n) UINT *code1, **sub; int n; { UINT **pp = sub; UINT *p = code1; do { *p++ = *(*pp++); } while(--n); } void init_des() { UINT **pp, **pp1, **qq; UINT *p, *q; int i; pp = key32; qq = key16; i = 16; do { *pp++ = (UINT *)malloc(32 * sizeof(UINT)); *qq++ = (UINT *)malloc(16 * sizeof(UINT)); } while(--i); des_in = (mode <= 2)? code: initial; temp_28 = temp + 28; mes_32 = mes + 32; address(key_L_s, key_L, shift, 16); address(key_R_s, key_R, shift, 16); address(temp_PC2M, temp, PC2M, 32); address(temp_PC2K, temp, PC2K, 16); address(mes_P1, mes, PINV, 32); address(mes_P2, mes_32, PINV, 32); address(mes_EK1, mes, EK1, 16); address(mes_EK2, mes, EK2, 16); address(mes_IP1, mes, IP1, 64); address(message_IP, des_in, IP, 64); } void makekey(edflag) int edflag; /* 1 : encryption, 0 : decryption */ { UINT **ps1 = key_L_s, **ps2 = key_R_s; UINT *p1, *p2, *q1, *q2; int i = 28, j, m = 28 * sizeof(UINT); p2 = (p1 = PC1) + 28; q1 = key_L; q2 = key_R; do { *q1++ = key[*p1++]; *q2++ = key[*p2++]; } while(--i); memcpy(key_L + 28, key_L, m); memcpy(key_R + 28, key_R, m); i = 15; do { memcpy(temp, *ps1++, m); memcpy(temp_28, *ps2++, m); j = (edflag)? 15 - i: i; substitute(key32[j], temp_PC2M, 32); substitute(key16[j], temp_PC2K, 16); } while(--i >= 0); } void des(crypt, crypt_b) UINT *crypt; char *crypt_b; { UINT **pp1, **pp2, **qq1 = key32, **qq2 = key16; UINT *p1, *p2, *q1; int i = 8, j, m; substitute(mes, message_IP, 64); do { pp1 = mes_P1; pp2 = mes_EK1; q1 = mes_32; p1 = *qq1++; p2 = *qq2++; j = 0; do { m = S[j] [(*(*pp2++)^ *p2++)*2 + *(*pp2++) ^ *p2++] [(((*q1++ ^ *p1++)*2 + *q1++ ^ *p1++)*2 + *q1++ ^ *p1++)*2 + *q1++ ^ *p1++]; *(*pp1) ^= ((m >> 3) & 1); pp1++; *(*pp1) ^= ((m >> 2) & 1); pp1++; *(*pp1) ^= ((m >> 1) & 1); pp1++; *(*pp1) ^= (m & 1); pp1++; } while(++j < 8); pp1 = mes_P2; pp2 = mes_EK2; q1 = mes; p1 = *qq1++; p2 = *qq2++; j = 0; do { m = S[j] [(*(*pp2++) ^ *p2++)* 2 + *(*pp2++) ^ *p2++] [(((*q1++ ^ *p1++)* 2 + *q1++ ^ *p1++)* 2 + *q1++ ^ *p1++)* 2 + *q1++ ^ *p1++]; *(*pp1) ^= ((m >> 3) & 1); pp1++; *(*pp1) ^= ((m >> 2) & 1); pp1++; *(*pp1) ^= ((m >> 1) & 1); pp1++; *(*pp1) ^= (m & 1); pp1++; } while(++j < 8); } while(--i); substitute(crypt, mes_IP1, 64); code_to_byte(crypt_b, crypt); } void ecb() { while(count = fread(buf, SC, blen, fp1)) { byte_to_code(buf, code, count); des(cipher, bufo); fwrite(bufo, SC, blen, fp2); } } void cbc_e() { code_to_byte(bufo, initial); while(count = fread(buf, SC, blen, fp1)) { xor(bufo); byte_to_code(bufo, code, blen); des(cipher, bufo); fwrite(bufo, SC, blen, fp2); } } void cbc_d() { char *p = bufo, *q = bufo_blen; code_to_byte(bufo, initial); while(count = fread(q, SC, blen, fp1)) { byte_to_code(q, code, count); des(cipher, buf); xor(p); fwrite(p, SC, blen, fp2); if(count != blen) return; if((p = q) < bufolast) q += blen; else { memcpy(bufo, p, 8); p = bufo; q = bufo_blen; } } } void ofb() { des(code, bufo); while(count = fread(buf, SC, blen, fp1)) { xor(bufo); fwrite(bufo, SC, blen, fp2); if(count != blen) return; memcpy(initial, ini_len, llen1_M); memcpy(ini_len1, code, llen_M); des(code, bufo); } } void cfb_e() { ini_shift(); des(code, bufo); while(count = fread(buf, SC, blen, fp1)) { xor(bufo); fwrite(bufo, SC, blen, fp2); if(count != blen) return; byte_to_code(bufo, cipher, blen); memcpy(x, xb1, blen8a_M); memcpy(xb2, cipher, blen8_M); memcpy(initial, ini_len, llen1_M); memcpy(ini_len1, x, llen_M); des(code, bufo); } } void cfb_d() { ini_shift(); des(code, bufo); while(count = fread(buf, SC, blen, fp1)) { byte_to_code(buf, cipher, count); memcpy(x, xb1, blen8a_M); memcpy(xb2, cipher, blen8_M); xor(bufo); fwrite(bufo, SC, blen, fp2); if(count != blen) return; memcpy(initial, ini_len, llen1_M); memcpy(ini_len1, x, llen_M); des(code, bufo); } } void usage(prog) char *prog; { fprintf(stderr, "Usage : %s [-Xn] [-Kkey] [-Finit] [-Jn] [-Ln] <-E|-D> file1 file2\n", prog); fprintf(stderr, " -X : Modes of Operations\n"); fprintf(stderr, " n : Mode Number (default = 1)\n"); fprintf(stderr, " 1 = ECB(Electric CodeBook)\n"); fprintf(stderr, " 2 = CBC(Cipher Block Chaining)\n"); fprintf(stderr, " 3 = OFB(Output FeedBack)\n"); fprintf(stderr, " 4 = CFB(Cipher FeedBack)\n"); fprintf(stderr, " -K : key file definition\n"); fprintf(stderr, " key : key file name\n"); fprintf(stderr, " -F : Initial Value of CBC,OFB,CFB mode(default = all'0')\n"); fprintf(stderr, " init : initial value file name\n"); fprintf(stderr, " -J : Block length direction\n"); fprintf(stderr, " n : Bleck length(1 - 8 Bytes, default = 8)\n"); fprintf(stderr, " -L : Key Feedback bit length direction\n"); fprintf(stderr, " n : Feedback length(1 - 64, default = 64)\n"); fprintf(stderr, " -E : Encryption mode\n"); fprintf(stderr, " -D : Decryption mode\n"); fprintf(stderr, " file1 : source file\n"); fprintf(stderr, " file2 : destination file\n\n"); fprintf(stderr, " (note 1 : file is 8byte Hexa-decimal code = 16 characters.)\n"); exit(0); } void openerr(kind, file) char *kind, *file; { fprintf(stderr, "Error : %s file(%s) can't open.\n", kind, file); exit(-1); } int main(argc, argv) int argc; char *argv[]; { char *prog = argv[0]; long tm0, tm1; int edflag = -1, ki = 0, kk = 0, tflag = 0; int k, k1; #ifdef DEBUG static char desmode[4][4] = {"ECB", "CBC", "OFB", "CFB"}; setvbuf(stderr, (char *)NULL, _IONBF, 0); setvbuf(stdout, (char *)NULL, _IONBF, 0); #endif if(argc < 2 || *argv[1] != '-') usage(prog); k = 1; do { switch(tolower(*(argv[k] + 1))) { case 'x': mode = atoi(argv[k] + 2); if(mode < 1 || mode > 4) usage(prog); break; case 'k': kk = k; break; case 'f': ki = k; break; case 'j': blen = atoi(argv[k] + 2); if(blen < 1 || blen > 8) usage(prog); blen8 = blen * 8; blen8_M = blen8 * sizeof(UINT); blen8a = 64 - blen8; blen8a_M = blen8a * sizeof(UINT); break; case 'l': llen = atoi(argv[k] + 2); if(llen < 1 || llen > 64) usage(prog); llen_M = llen * sizeof(UINT); llen1 = 64 - llen; llen1_M = llen1 * sizeof(UINT); break; case 'd': if(edflag == 1) usage(prog); edflag = 0; break; case 'e': if(edflag == 0) usage(prog); edflag = 1; break; case 't': tflag = 1; break; case 'm': fp1 = fopen("des.man", "r"); if(fp1 == NULL) usage(prog); while(fgets(buf, 256, fp1) != NULL) fprintf(stderr, "%s", buf); exit(0); default: usage(prog); } } while(*argv[++k] == '-'); if((mode == 4 && blen8 > llen) || edflag == -1 || k >= argc) usage(prog); k1 = k++; if(k >= argc) usage(prog); init_des(); if(kk != 0) { fp1 = fopen(argv[kk] + 2, "r"); if(fp1 == NULL) openerr("key", argv[kk] + 2); fgets(buf, 256, fp1); fclose(fp1); hex_to_code(buf, key); } if(mode >= 2) { if(ki) { fp1 = fopen(argv[ki] + 2, "r"); if(fp1 == NULL) openerr("initial", argv[ki] + 2); fgets(buf, 256, fp1); fclose(fp1); hex_to_code(buf, initial); } if(mode == 2) bufo_blen = bufo + blen; if(mode >= 3) { ini_len = initial + llen; ini_len1 = initial + llen1; } if(mode == 4) { xb1 = x + blen8; xb2 = x + blen8a; } } fp1 = fopen(argv[k1], "r"); if(fp1 == NULL) openerr("source", argv[k1]); fp2 = fopen(argv[k], "r"); if(fp2 != NULL) { fprintf(stderr, "Error : destination file(%s) already exist.\n", argv[k]); exit(-1); } fp2 = fopen(argv[k], "w"); #ifdef DEBUG if(edflag) printf("<<< Encryption ("); else printf("<<< Decryprion ("); printf("%s) >>>\n", desmode[mode - 1]); printf(" file1 : %s\n", argv[k1]); printf(" file2 : %s\n", argv[k2]); printf(" key : "); cprint(key); putchar('\n'); if(mode > 1) { printf("initial : "); cprint(initial); putchar('\n'); } if(mode == 3) printf("Block length = %d [Bytes]\n", blen); #endif tm0 = clock(); switch(mode) { case 1: makekey(edflag); ecb(); break; case 2: makekey(edflag); if(edflag) cbc_e(); else cbc_d(); break; case 3: makekey(1); ofb(); break; case 4: makekey(1); if(edflag) cfb_e(); else cfb_d(); break; } tm1 = clock(); fclose(fp1); fclose(fp2); if(tflag) fprintf(stderr, "lap time : %7.3f [s]\n", (double)(tm1 - tm0) * 1.e-6); return 0; } |
// // des.cpp Data Encryption Standard // const char *COPYRIGHT = "by Tomy(NIFTY:SGV01401) all rights reserved."; const char *VER = "2.1"; const char *DATE = "1994/11/10"; #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <mem.h> #include <io.h> #include <fcntl.h> #include <sys\stat.h> //#define NODISP typedef unsigned int UINT; typedef unsigned long ULONG; union { ULONG a; char b[4]; } m; char *mb0 = m.b, *mb1 = m.b + 1, *mb2 = m.b + 2, *mb3 = m.b + 3; const long BUFFER_SIZE = 51200; const int U28 = 28 * sizeof(UINT); FILE *fp; int handle1, handle2; ULONG bufsize, bufsize1, count, mem; UINT mem1; char buffer[BUFFER_SIZE], bufo[8], inibuf[16], keybuf[16]; char *blast, *bp; UINT key32[128], key16[128], tmp[56], key_L[56], key_R[56]; #ifndef NODISP static ULONG filesize, outsize = 0, outcount = 0; #endif static int blen = 8, edflag = -1, llen = 64, mode = 1, k1 = 0, k2 = 0; int blena, lshift, rshift; #ifndef NODISP int blen50; #endif static UINT key[64] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; static char initial[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static char x[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; char *xb1, *xb2; char *initial4 = initial + 4; static int kk[16][4] = { {0,0,0,0}, {0,0,0,1}, {0,0,1,0}, {0,0,1,1}, {0,1,0,0}, {0,1,0,1}, {0,1,1,0}, {0,1,1,1}, {1,0,0,0}, {1,0,0,1}, {1,0,1,0}, {1,0,1,1}, {1,1,0,0}, {1,1,0,1}, {1,1,1,0}, {1,1,1,1}}; static int *S0[4][16] = { {kk[14], kk[ 4], kk[13], kk[ 1], kk[ 2], kk[15], kk[11], kk[ 8], kk[ 3], kk[10], kk[ 6], kk[12], kk[ 5], kk[ 9], kk[ 0], kk[ 7] }, {kk[ 0], kk[15], kk[ 7], kk[ 4], kk[ 14], kk[ 2], kk[13], kk[ 1], kk[10], kk[ 6], kk[12], kk[11], kk[ 9], kk[ 5], kk[ 3], kk[ 8] }, {kk[ 4], kk[ 1], kk[14], kk[ 8], kk[ 13], kk[ 6], kk[ 2], kk[11], kk[15], kk[12], kk[ 9], kk[ 7], kk[ 3], kk[10], kk[ 5], kk[ 0] }, {kk[15], kk[12], kk[ 8], kk[ 2], kk[ 4], kk[ 9], kk[ 1], kk[ 7], kk[ 5], kk[11], kk[ 3], kk[14], kk[ 10], kk[ 0], kk[ 6], kk[13] } }; static int *S1[4][16] = { {kk[15], kk[ 1], kk[ 8], kk[14], kk[ 6], kk[11], kk[ 3], kk[ 4], kk[ 9], kk[ 7], kk[ 2], kk[13], kk[ 12], kk[ 0], kk[ 5], kk[10] }, {kk[ 3], kk[13], kk[ 4], kk[ 7], kk[ 15], kk[ 2], kk[ 8], kk[14], kk[12], kk[ 0], kk[ 1], kk[10], kk[ 6], kk[ 9], kk[11], kk[ 5] }, {kk[ 0], kk[14], kk[ 7], kk[11], kk[ 10], kk[ 4], kk[13], kk[ 1], kk[ 5], kk[ 8], kk[12], kk[ 6], kk[ 9], kk[ 3], kk[ 2], kk[15] }, {kk[13], kk[ 8], kk[10], kk[ 1], kk[ 3], kk[15], kk[ 4], kk[ 2], kk[11], kk[ 6], kk[ 7], kk[12], kk[ 0], kk[ 5], kk[14], kk[ 9] } }; static int *S2[4][16] = { {kk[10], kk[ 0], kk[ 9], kk[14], kk[ 6], kk[ 3], kk[15], kk[ 5], kk[ 1], kk[13], kk[12], kk[ 7], kk[ 11], kk[ 4], kk[ 2], kk[ 8] }, {kk[13], kk[ 7], kk[ 0], kk[ 9], kk[ 3], kk[ 4], kk[ 6], kk[10], kk[ 2], kk[ 8], kk[ 5], kk[14], kk[ 12], kk[11], kk[15], kk[ 1] }, {kk[13], kk[ 6], kk[ 4], kk[ 9], kk[ 8], kk[15], kk[ 3], kk[ 0], kk[11], kk[ 1], kk[ 2], kk[12], kk[ 5], kk[10], kk[14], kk[ 7] }, {kk[ 1], kk[10], kk[13], kk[ 0], kk[ 6], kk[ 9], kk[ 8], kk[ 7], kk[ 4], kk[15], kk[14], kk[ 3], kk[ 11], kk[ 5], kk[ 2], kk[12] } }; static int *S3[4][16] = { {kk[ 7], kk[13], kk[14], kk[ 3], kk[ 0], kk[ 6], kk[ 9], kk[10], kk[ 1], kk[ 2], kk[ 8], kk[ 5], kk[ 11], kk[12], kk[ 4], kk[15] }, {kk[13], kk[ 8], kk[11], kk[ 5], kk[ 6], kk[15], kk[ 0], kk[ 3], kk[ 4], kk[ 7], kk[ 2], kk[12], kk[ 1], kk[10], kk[14], kk[ 9] }, {kk[10], kk[ 6], kk[ 9], kk[ 0], kk[ 12], kk[11], kk[ 7], kk[13], kk[15], kk[ 1], kk[ 3], kk[14], kk[ 5], kk[ 2], kk[ 8], kk[ 4] }, {kk[ 3], kk[15], kk[ 0], kk[ 6], kk[ 10], kk[ 1], kk[13], kk[ 8], kk[ 9], kk[ 4], kk[ 5], kk[11], kk[ 12], kk[ 7], kk[ 2], kk[14] } }; static int *S4[4][16] = { {kk[ 2], kk[12], kk[ 4], kk[ 1], kk[ 7], kk[10], kk[11], kk[ 6], kk[ 8], kk[ 5], kk[ 3], kk[15], kk[ 13], kk[ 0], kk[14], kk[ 9] }, {kk[14], kk[11], kk[ 2], kk[12], kk[ 4], kk[ 7], kk[13], kk[ 1], kk[ 5], kk[ 0], kk[15], kk[10], kk[ 3], kk[ 9], kk[ 8], kk[ 6] }, {kk[ 4], kk[ 2], kk[ 1], kk[11], kk[ 10], kk[13], kk[ 7], kk[ 8], kk[15], kk[ 9], kk[12], kk[ 5], kk[ 6], kk[ 3], kk[ 0], kk[14] }, {kk[11], kk[ 8], kk[12], kk[ 7], kk[ 1], kk[14], kk[ 2], kk[13], kk[ 6], kk[15], kk[ 0], kk[ 9], kk[ 10], kk[ 4], kk[ 5], kk[ 3] } }; static int *S5[4][16] = { {kk[12], kk[ 1], kk[10], kk[15], kk[ 9], kk[ 2], kk[ 6], kk[ 8], kk[ 0], kk[13], kk[ 3], kk[ 4], kk[ 14], kk[ 7], kk[ 5], kk[11] }, {kk[10], kk[15], kk[ 4], kk[ 2], kk[ 7], kk[12], kk[ 9], kk[ 5], kk[ 6], kk[ 1], kk[13], kk[14], kk[ 0], kk[11], kk[ 3], kk[ 8] }, {kk[ 9], kk[14], kk[15], kk[ 5], kk[ 2], kk[ 8], kk[12], kk[ 3], kk[ 7], kk[ 0], kk[ 4], kk[10], kk[ 1], kk[13], kk[11], kk[ 6] }, {kk[ 4], kk[ 3], kk[ 2], kk[12], kk[ 9], kk[ 5], kk[15], kk[10], kk[11], kk[14], kk[ 1], kk[ 7], kk[ 6], kk[ 0], kk[ 8], kk[13] } }; static int *S6[4][16] = { {kk[ 4], kk[11], kk[ 2], kk[14], kk[ 15], kk[ 0], kk[ 8], kk[13], kk[ 3], kk[12], kk[ 9], kk[ 7], kk[ 5], kk[10], kk[ 6], kk[ 1] }, {kk[13], kk[ 0], kk[11], kk[ 7], kk[ 4], kk[ 9], kk[ 1], kk[10], kk[14], kk[ 3], kk[ 5], kk[12], kk[ 2], kk[15], kk[ 8], kk[ 6] }, {kk[ 1], kk[ 4], kk[11], kk[13], kk[ 12], kk[ 3], kk[ 7], kk[14], kk[10], kk[15], kk[ 6], kk[ 8], kk[ 0], kk[ 5], kk[ 9], kk[ 2] }, {kk[ 6], kk[11], kk[13], kk[ 8], kk[ 1], kk[ 4], kk[10], kk[ 7], kk[ 9], kk[ 5], kk[ 0], kk[15], kk[ 14], kk[ 2], kk[ 3], kk[12] } }; static int *S7[4][16] = { {kk[13], kk[ 2], kk[ 8], kk[ 4], kk[ 6], kk[15], kk[11], kk[ 1], kk[10], kk[ 9], kk[ 3], kk[14], kk[ 5], kk[ 0], kk[12], kk[ 7] }, {kk[ 1], kk[15], kk[13], kk[ 8], kk[ 10], kk[ 3], kk[ 7], kk[ 4], kk[12], kk[ 5], kk[ 6], kk[11], kk[ 0], kk[14], kk[ 9], kk[ 2] }, {kk[ 7], kk[11], kk[ 4], kk[ 1], kk[ 9], kk[12], kk[14], kk[ 2], kk[ 0], kk[ 6], kk[10], kk[13], kk[ 15], kk[ 3], kk[ 5], kk[ 8] }, {kk[ 2], kk[ 1], kk[14], kk[ 7], kk[ 4], kk[10], kk[ 8], kk[13], kk[15], kk[12], kk[ 9], kk[ 0], kk[ 3], kk[ 5], kk[ 6], kk[11] } }; static UINT *key_Lp1[16] = { &key_L[ 1], &key_L[ 2], &key_L[ 4], &key_L[ 6], &key_L[ 8], &key_L[10], &key_L[12], &key_L[14], &key_L[15], &key_L[17], &key_L[19], &key_L[21], &key_L[23], &key_L[25], &key_L[27], &key_L[28] }; static UINT *key_Rp1[16] = { &key_R[ 1], &key_R[ 2], &key_R[ 4], &key_R[ 6], &key_R[ 8], &key_R[10], &key_R[12], &key_R[14], &key_R[15], &key_R[17], &key_R[19], &key_R[21], &key_R[23], &key_R[25], &key_R[27], &key_R[28] }; static UINT *key_Lp2[16] = { &key_L[28], &key_L[27], &key_L[25], &key_L[23], &key_L[21], &key_L[19], &key_L[17], &key_L[15], &key_L[14], &key_L[12], &key_L[10], &key_L[ 8], &key_L[ 6], &key_L[ 4], &key_L[ 2], &key_L[ 1] }; static UINT *key_Rp2[16] = { &key_R[28], &key_R[27], &key_R[25], &key_R[23], &key_R[21], &key_R[19], &key_R[17], &key_R[15], &key_R[14], &key_R[12], &key_R[10], &key_R[ 8], &key_R[ 6], &key_R[ 4], &key_R[ 2], &key_R[ 1] }; UINT *key_L28 = key_L + 28, *key_R28 = key_R + 28; UINT *tmp0 = tmp, *tmp1 = tmp + 1, *tmp2 = tmp + 2, *tmp3 = tmp + 3; UINT *tmp4 = tmp + 4, *tmp5 = tmp + 5, *tmp6 = tmp + 6, *tmp7 = tmp + 7; UINT *tmp9 = tmp + 9, *tmp10 = tmp + 10, *tmp11 = tmp + 11, *tmp12 = tmp + 12; UINT *tmp13 = tmp + 13, *tmp14 = tmp + 14, *tmp15 = tmp + 15, *tmp16 = tmp + 16; UINT *tmp18 = tmp + 18, *tmp19 = tmp + 19, *tmp20 = tmp + 20, *tmp22 = tmp + 22; UINT *tmp23 = tmp + 23, *tmp25 = tmp + 25, *tmp26 = tmp + 26, *tmp27 = tmp + 27; UINT *tmp28 = tmp + 28, *tmp29 = tmp + 29, *tmp30 = tmp + 30, *tmp31 = tmp + 31; UINT *tmp32 = tmp + 32, *tmp33 = tmp + 33, *tmp35 = tmp + 35, *tmp36 = tmp + 36; UINT *tmp38 = tmp + 38, *tmp39 = tmp + 39, *tmp40 = tmp + 40, *tmp41 = tmp + 41; UINT *tmp43 = tmp + 43, *tmp44 = tmp + 44, *tmp45 = tmp + 45, *tmp46 = tmp + 46; UINT *tmp47 = tmp + 47, *tmp48 = tmp + 48, *tmp49 = tmp + 49, *tmp50 = tmp + 50; UINT *tmp51 = tmp + 51, *tmp52 = tmp + 52, *tmp54 = tmp + 54, *tmp55 = tmp + 55; // prototype declaration void (*ini_s)(); void (*rot_i)(char *set); void (*xor)(char *code1, char *code2); int hexcode(char a); void iniset(void); void keyset(void); void xor1(char *code1, char *code2); void xor2(char *code1, char *code2); void xor3(char *code1, char *code2); void xor4(char *code1, char *code2); void xor5(char *code1, char *code2); void xor6(char *code1, char *code2); void xor7(char *code1, char *code2); void xor8(char *code1, char *code2); ULONG char_to_long(char *a); void long_to_char(ULONG m1, ULONG m2); void rot_initial1(char *set); void rot_initial2(char *set); void rot_initial3(char *set); void rot_initial4(char *set); void ini_shift1(void); void ini_shift2(void); void ini_shift3(void); void ini_shift4(void); void makekey(int flag); void des(char *in, char *out); void ecb(void); void cbc(void); void ofb(void); void cfb(void); void openerr(char *kind, char *file); void usage(char *prog); int hexcode(char a) { if(a >= '0' && a <= '9') return a - '0'; else if(a >= 'A' && a <= 'F') return a - 'A' + 10; else if(a >= 'a' && a <= 'f') return a - 'a' + 10; else return a & 0x0f; } void iniset(void) { char *p = inibuf, *q = initial; register int ch, i = 16; while(*p != '\0') { *p = hexcode(*p); p++; if(--i == 0) break; } while(i--) *p++ = 0; p = inibuf; i = 8; do { *q++ = *p * 16 + *(p + 1); p += 2; } while(--i); } void keyset(void) { char *p = keybuf; UINT *q = key; register int i = 16; while(*p != '\0') { register int ch = hexcode(*p++); *q++ = (ch >> 3) & 1; *q++ = (ch >> 2) & 1; *q++ = (ch >> 1) & 1; *q++ = ch & 1; if(--i == 0) return; } } void xor1(char *code1, char *code2) { code2[0] ^= code1[0]; } void xor2(char *code1, char *code2) { code2[0] ^= code1[0]; code2[1] ^= code1[1]; } void xor3(char *code1, char *code2) { code2[0] ^= code1[0]; code2[1] ^= code1[1]; code2[2] ^= code1[2]; } void xor4(char *code1, char *code2) { code2[0] ^= code1[0]; code2[1] ^= code1[1]; code2[2] ^= code1[2]; code2[3] ^= code1[3]; } void xor5(char *code1, char *code2) { code2[0] ^= code1[0]; code2[1] ^= code1[1]; code2[2] ^= code1[2]; code2[3] ^= code1[3]; code2[4] ^= code1[4]; } void xor6(char *code1, char *code2) { code2[0] ^= code1[0]; code2[1] ^= code1[1]; code2[2] ^= code1[2]; code2[3] ^= code1[3]; code2[4] ^= code1[4]; code2[5] ^= code1[5]; } void xor7(char *code1, char *code2) { code2[0] ^= code1[0]; code2[1] ^= code1[1]; code2[2] ^= code1[2]; code2[3] ^= code1[3]; code2[4] ^= code1[4]; code2[5] ^= code1[5]; code2[6] ^= code1[6]; } void xor8(char *code1, char *code2) { code2[0] ^= code1[0]; code2[1] ^= code1[1]; code2[2] ^= code1[2]; code2[3] ^= code1[3]; code2[4] ^= code1[4]; code2[5] ^= code1[5]; code2[6] ^= code1[6]; code2[7] ^= code1[7]; } ULONG char_to_long(char *a) { *mb3 = a[0]; *mb2 = a[1]; *mb1 = a[2]; *mb0 = a[3]; return m.a; } void long_to_char(ULONG m1, ULONG m2) { m.a = m1; initial[0] = *mb3; initial[1] = *mb2; initial[2] = *mb1; initial[3] = *mb0; m.a = m2; initial[4] = *mb3; initial[5] = *mb2; initial[6] = *mb1; initial[7] = *mb0; } void rot_initial1(char *set) { memcpy(initial, initial4, 4); memcpy(initial4, set, 4); } void rot_initial2(char *set) { memcpy(initial, set, 8); } void rot_initial3(char *set) { ULONG m2 = char_to_long(initial4); long_to_char((char_to_long(initial) << lshift) | (m2 >> rshift), (m2 << lshift) | (char_to_long(set) >> rshift)); } void rot_initial4(char *set) { ULONG s1 = char_to_long(set); long_to_char((char_to_long(initial4) << lshift) | (s1 >> rshift), (s1 << lshift) | (char_to_long(set + 4) >> rshift)); } void ini_shift1(void) { memcpy(initial4, initial, 4); setmem(initial, 4, 0); } void ini_shift2(void) { setmem(initial, 8, 0); } void ini_shift3(void) { setmem(initial, 4, 0); m.a = char_to_long(initial) >> rshift; initial[4] = *mb3; initial[5] = *mb2; initial[6] = *mb1; initial[7] = *mb0; } void ini_shift4(void) { ULONG m1 = char_to_long(initial); long_to_char((m1 >> rshift), ((m1 << lshift) | (char_to_long(initial4) >> rshift))); } void makekey(int flag) { key_L[ 0] = key[56]; key_L[14] = key[ 9]; key_L[ 1] = key[48]; key_L[15] = key[ 1]; key_L[ 2] = key[40]; key_L[16] = key[58]; key_L[ 3] = key[32]; key_L[17] = key[50]; key_L[ 4] = key[24]; key_L[18] = key[42]; key_L[ 5] = key[16]; key_L[19] = key[34]; key_L[ 6] = key[ 8]; key_L[20] = key[26]; key_L[ 7] = key[ 0]; key_L[21] = key[18]; key_L[ 8] = key[57]; key_L[22] = key[10]; key_L[ 9] = key[49]; key_L[23] = key[ 2]; key_L[10] = key[41]; key_L[24] = key[59]; key_L[11] = key[33]; key_L[25] = key[51]; key_L[12] = key[25]; key_L[26] = key[43]; key_L[13] = key[17]; key_L[27] = key[35]; key_R[ 0] = key[62]; key_R[14] = key[13]; key_R[ 1] = key[54]; key_R[15] = key[ 5]; key_R[ 2] = key[46]; key_R[16] = key[60]; key_R[ 3] = key[38]; key_R[17] = key[52]; key_R[ 4] = key[30]; key_R[18] = key[44]; key_R[ 5] = key[22]; key_R[19] = key[36]; key_R[ 6] = key[14]; key_R[20] = key[28]; key_R[ 7] = key[ 6]; key_R[21] = key[20]; key_R[ 8] = key[61]; key_R[22] = key[12]; key_R[ 9] = key[53]; key_R[23] = key[ 4]; key_R[10] = key[45]; key_R[24] = key[27]; key_R[11] = key[37]; key_R[25] = key[19]; key_R[12] = key[29]; key_R[26] = key[11]; key_R[13] = key[21]; key_R[27] = key[ 3]; memcpy(key_L28, key_L, U28); memcpy(key_R28, key_R, U28); UINT **ps1 = (flag)? key_Lp1: key_Lp2; UINT **ps2 = (flag)? key_Rp1: key_Rp2; UINT *p1 = key32; UINT *p2 = key16; register int i = 8; do { register int k = 2; do { memcpy(tmp0, *ps1++, U28); memcpy(tmp28, *ps2++, U28); *p1++ = ((*tmp16 * 2 + *tmp10) * 2 + *tmp23) * 2 + *tmp0; *p1++ = ((*tmp27 * 2 + *tmp14) * 2 + *tmp5) * 2 + *tmp20; *p1++ = ((*tmp18 * 2 + *tmp11) * 2 + *tmp3) * 2 + *tmp25; *p1++ = ((*tmp6 * 2 + *tmp26) * 2 + *tmp19) * 2 + *tmp12; *p1++ = ((*tmp51 * 2 + *tmp30) * 2 + *tmp36) * 2 + *tmp46; *p1++ = ((*tmp39 * 2 + *tmp50) * 2 + *tmp44) * 2 + *tmp32; *p1++ = ((*tmp48 * 2 + *tmp38) * 2 + *tmp55) * 2 + *tmp33; *p1++ = ((*tmp41 * 2 + *tmp49) * 2 + *tmp35) * 2 + *tmp28; *p2++ = *tmp13 * 2 + *tmp4; *p2++ = *tmp2 * 2 + *tmp9; *p2++ = *tmp22 * 2 + *tmp7; *p2++ = *tmp15 * 2 + *tmp1; *p2++ = *tmp40 * 2 + *tmp54; *p2++ = *tmp29 * 2 + *tmp47; *p2++ = *tmp43 * 2 + *tmp52; *p2++ = *tmp45 * 2 + *tmp31; } while(--k); } while(--i); } void des(char *in, char *out) { register int m = in[0]; int m39 = (m >> 7) & 1; int m7 = (m >> 6) & 1; int m47 = (m >> 5) & 1; int m15 = (m >> 4) & 1; int m55 = (m >> 3) & 1; int m23 = (m >> 2) & 1; int m63 = (m >> 1) & 1; int m31 = m & 1; int m30 = (m = in[1]) & 1; int m38 = (m >> 7) & 1; int m6 = (m >> 6) & 1; int m46 = (m >> 5) & 1; int m14 = (m >> 4) & 1; int m54 = (m >> 3) & 1; int m22 = (m >> 2) & 1; int m62 = (m >> 1) & 1; int m29 = (m = in[2]) & 1; int m37 = (m >> 7) & 1; int m5 = (m >> 6) & 1; int m45 = (m >> 5) & 1; int m13 = (m >> 4) & 1; int m53 = (m >> 3) & 1; int m21 = (m >> 2) & 1; int m61 = (m >> 1) & 1; int m28 = (m = in[3]) & 1; int m36 = (m >> 7) & 1; int m4 = (m >> 6) & 1; int m44 = (m >> 5) & 1; int m12 = (m >> 4) & 1; int m52 = (m >> 3) & 1; int m20 = (m >> 2) & 1; int m60 = (m >> 1) & 1; int m27 = (m = in[4]) & 1; int m35 = (m >> 7) & 1; int m3 = (m >> 6) & 1; int m43 = (m >> 5) & 1; int m11 = (m >> 4) & 1; int m51 = (m >> 3) & 1; int m19 = (m >> 2) & 1; int m59 = (m >> 1) & 1; int m26 = (m = in[5]) & 1; int m34 = (m >> 7) & 1; int m2 = (m >> 6) & 1; int m42 = (m >> 5) & 1; int m10 = (m >> 4) & 1; int m50 = (m >> 3) & 1; int m18 = (m >> 2) & 1; int m58 = (m >> 1) & 1; int m25 = (m = in[6]) & 1; int m33 = (m >> 7) & 1; int m1 = (m >> 6) & 1; int m41 = (m >> 5) & 1; int m9 = (m >> 4) & 1; int m49 = (m >> 3) & 1; int m17 = (m >> 2) & 1; int m57 = (m >> 1) & 1; int m24 = (m = in[7]) & 1; int m32 = (m >> 7) & 1; int m0 = (m >> 6) & 1; int m40 = (m >> 5) & 1; int m8 = (m >> 4) & 1; int m48 = (m >> 3) & 1; int m16 = (m >> 2) & 1; int m56 = (m >> 1) & 1; UINT *p1 = key32, *p2 = key16; register int i = 8; do { int *q = S0[(m63*2+m36)^*p2++][(((m32*2+m33)*2+m34)*2+m35)^*p1++]; m8 ^= *q; m16 ^= *(q + 1); m22 ^= *(q + 2); m30 ^= *(q + 3); q = S1[(m35*2+m40)^*p2++][(((m36*2+m37)*2+m38)*2+m39)^*p1++]; m12 ^= *q; m27 ^= *(q + 1); m1 ^= *(q + 2); m17 ^= *(q + 3); q = S2[(m39*2+m44)^*p2++][(((m40*2+m41)*2+m42)*2+m43)^*p1++]; m23 ^= *q; m15 ^= *(q + 1); m29 ^= *(q + 2); m5 ^= *(q + 3); q = S3[(m43*2+m48)^*p2++][(((m44*2+m45)*2+m46)*2+m47)^*p1++]; m25 ^= *q; m19 ^= *(q + 1); m9 ^= *(q + 2); m0 ^= *(q + 3); q = S4[(m47*2+m52)^*p2++][(((m48*2+m49)*2+m50)*2+m51)^*p1++]; m7 ^= *q; m13 ^= *(q + 1); m24 ^= *(q + 2); m2 ^= *(q + 3); q = S5[(m51*2+m56)^*p2++][(((m52*2+m53)*2+m54)*2+m55)^*p1++]; m3 ^= *q; m28 ^= *(q + 1); m10 ^= *(q + 2); m18 ^= *(q + 3); q = S6[(m55*2+m60)^*p2++][(((m56*2+m57)*2+m58)*2+m59)^*p1++]; m31 ^= *q; m11 ^= *(q + 1); m21 ^= *(q + 2); m6 ^= *(q + 3); q = S7[(m59*2+m32)^*p2++][(((m60*2+m61)*2+m62)*2+m63)^*p1++]; m4 ^= *q; m26 ^= *(q + 1); m14 ^= *(q + 2); m20 ^= *(q + 3); q = S0[(m31*2+m4)^*p2++][(((m0*2+m1)*2+m2)*2+m3)^*p1++]; m40 ^= *q; m48 ^= *(q + 1); m54 ^= *(q + 2); m62 ^= *(q + 3); q = S1[(m3*2+m8)^*p2++][(((m4*2+m5)*2+m6)*2+m7)^*p1++]; m44 ^= *q; m59 ^= *(q + 1); m33 ^= *(q + 2); m49 ^= *(q + 3); q = S2[(m7*2+m12)^*p2++][(((m8*2+m9)*2+m10)*2+m11)^*p1++]; m55 ^= *q; m47 ^= *(q + 1); m61 ^= *(q + 2); m37 ^= *(q + 3); q = S3[(m11*2+m16)^*p2++][(((m12*2+m13)*2+m14)*2+m15)^*p1++]; m57 ^= *q; m51 ^= *(q + 1); m41 ^= *(q + 2); m32 ^= *(q + 3); q = S4[(m15*2+m20)^*p2++][(((m16*2+m17)*2+m18)*2+m19)^*p1++]; m39 ^= *q; m45 ^= *(q + 1); m56 ^= *(q + 2); m34 ^= *(q + 3); q = S5[(m19*2+m24)^*p2++][(((m20*2+m21)*2+m22)*2+m23)^*p1++]; m35 ^= *q; m60 ^= *(q + 1); m42 ^= *(q + 2); m50 ^= *(q + 3); q = S6[(m23*2+m28)^*p2++][(((m24*2+m25)*2+m26)*2+m27)^*p1++]; m63 ^= *q; m43 ^= *(q + 1); m53 ^= *(q + 2); m38 ^= *(q + 3); q = S7[(m27*2+m0)^*p2++][(((m28*2+m29)*2+m30)*2+m31)^*p1++]; m36 ^= *q; m58 ^= *(q + 1); m46 ^= *(q + 2); m52 ^= *(q + 3); } while(--i); out[0] = ((((((m7*2+m39)*2+m15)*2+m47)*2+m23)*2+m55)*2+m31)*2+m63; out[1] = ((((((m6*2+m38)*2+m14)*2+m46)*2+m22)*2+m54)*2+m30)*2+m62; out[2] = ((((((m5*2+m37)*2+m13)*2+m45)*2+m21)*2+m53)*2+m29)*2+m61; out[3] = ((((((m4*2+m36)*2+m12)*2+m44)*2+m20)*2+m52)*2+m28)*2+m60; out[4] = ((((((m3*2+m35)*2+m11)*2+m43)*2+m19)*2+m51)*2+m27)*2+m59; out[5] = ((((((m2*2+m34)*2+m10)*2+m42)*2+m18)*2+m50)*2+m26)*2+m58; out[6] = ((((((m1*2+m33)*2+m9 )*2+m41)*2+m17)*2+m49)*2+m25)*2+m57; out[7] = ((((((m0*2+m32)*2+m8 )*2+m40)*2+m16)*2+m48)*2+m24)*2+m56; } void ecb(void) { while((count = read(handle1, buffer, bufsize)) != 0) { mem1 = bufsize1; if(count != bufsize) { mem1 = (count + 7) / 8; mem = mem1 * 8; setmem(buffer + count, mem - count, 0); } char *p = buffer; do { des(p, p); p += 8; #ifndef NODISP if((outsize += blen50) >= outcount) { fputc('.', stderr); outcount += filesize; } #endif } while(--mem1); write(handle2, buffer, mem); } } void cbc(void) { while((count = read(handle1, buffer, bufsize)) != 0) { mem1 = bufsize1; if(count != bufsize) { mem1 = (count + 7) / 8; mem = mem1 * 8; setmem(buffer + count, mem - count, 0); } char *p = buffer; if(edflag) { do { xor8(initial, p); des(p, initial); memcpy(p, initial, 8); p += 8; #ifndef NODISP if((outsize += blen50) >= outcount) { fputc('.', stderr); outcount += filesize; } #endif } while(--mem1); } else { do { des(p, bufo); xor8(initial, bufo); memcpy(initial, p, 8); memcpy(p, bufo, 8); p += 8; #ifndef NODISP if((outsize += blen50) >= outcount) { fputc('.', stderr); outcount += filesize; } #endif } while(--mem1); } write(handle2, buffer, mem); } } void ofb(void) { while((count = read(handle1, buffer, bufsize)) != 0) { mem1 = bufsize1; if(count != bufsize) { mem1 = (count + blen - 1) / blen; mem = mem1 * blen; setmem(buffer + count, mem - count, 0); } char *p = buffer; do { des(initial, bufo); xor(bufo, p); rot_i(bufo); p += blen; #ifndef NODISP if((outsize += blen50) >= outcount) { fputc('.', stderr); outcount += filesize; } #endif } while(--mem1); write(handle2, buffer, mem); } } void cfb(void) { ini_s(); while((count = read(handle1, buffer, bufsize)) != 0) { mem1 = bufsize1; if(count != bufsize) { mem1 = (count + blen - 1) / blen; mem = mem1 * blen; setmem(buffer + count, mem - count, 0); } char *p = buffer; if(edflag) { do { des(initial, bufo); xor(bufo, p); memcpy(x, xb1, blena); memcpy(xb2, p, blen); rot_i(x); p += blen; #ifndef NODISP if((outsize += blen50) >= outcount) { fputc('.', stderr); outcount += filesize; } #endif } while(--mem1); } else { do { des(initial, bufo); memcpy(x, xb1, blena); memcpy(xb2, p, blen); rot_i(x); xor(bufo, p); p += blen; #ifndef NODISP if((outsize += blen50) >= outcount) { fputc('.', stderr); outcount += filesize; } #endif } while(--mem1); } write(handle2, buffer, mem); } } void openerr(char *kind, char *file) { fprintf(stderr, "Error : %s file(%s) can't open.\n", kind, file); exit(-1); } void usage(char *prog) { fprintf(stderr, "Usage : %s [-Xn] [-Kkey] [-Finit] [-Bn] [-Ln] <-E|-D> file1 file2\n", prog); fprintf(stderr, " -X : Modes of Operations\n"); fprintf(stderr, " n : Mode Number (default = 1)\n"); fprintf(stderr, " 1 = ECB(Electric CodeBook)\n"); fprintf(stderr, " 2 = CBC(Cipher Block Chaining)\n"); fprintf(stderr, " 3 = OFB(Output FeedBack)\n"); fprintf(stderr, " 4 = CFB(Cipher FeedBack)\n"); fprintf(stderr, " -K : key file definition\n"); fprintf(stderr, " key : key file name\n"); fprintf(stderr, " -F : Initial Value of CBC,OFB,CFB mode(default = all'0'\n"); fprintf(stderr, " init : initial value file name\n"); fprintf(stderr, " -B : Block length direction\n"); fprintf(stderr, " n : Bleck length(1 - 8 Bytes, default = 8)\n"); fprintf(stderr, " -L : Key Feedback bit length direction\n"); fprintf(stderr, " n : Feedback length(1 - 64, default = 64)\n"); fprintf(stderr, " -E : Encryption mode\n"); fprintf(stderr, " -D : Decryption mode\n"); fprintf(stderr, " file1 : source file\n"); fprintf(stderr, " file2 : destination file\n\n"); fprintf(stderr, " (note 1 : file is 8byte Hexa-decimal code = 16 characters.)\n"); exit(0); } int main(int argc, char *argv[]) { int fi = 0, fk = 0; if(argc < 2 || *argv[1] != '-') usage(argv[0]); register int k = 1; do { switch(tolower(*(argv[k] + 1))) { case 'x': mode = atoi(argv[k] + 2); if(mode < 1 || mode > 4) usage(argv[0]); break; case 'k': fk = k; break; case 'f': fi = k; break; case 'b': blen = atoi(argv[k] + 2); if(blen < 1 || blen > 8) usage(argv[0]); break; case 'l': llen = atoi(argv[k] + 2); if(llen < 1 || llen > 64) usage(argv[0]); break; case 'd': if(edflag == 1) usage(argv[0]); edflag = 0; break; case 'e': if(edflag == 0) usage(argv[0]); edflag = 1; break; case 'm': fp = fopen("des.man", "rt"); if(fp == NULL) openerr("Document", "des.man"); while(fgets(buffer, 256, fp) != NULL) fprintf(stderr, "%s", buffer); fclose(fp); exit(0); case '?': usage(argv[0]); default: fprintf(stderr, "Error : illegal option.\n"); usage(argv[0]); } } while(*argv[++k] == '-'); if(mode <= 2) blen = 8; blena = 8 - blen; #ifndef NODISP blen50 = blen * 50; #endif if((mode == 4 && blen * 8 > llen) || edflag == -1) usage(argv[0]); if(k < argc) { k1 = k++; if(k < argc) k2 = k; } if(k1 == 0 || k2 == 0) usage(argv[0]); if(fk != 0) { handle1 = open(argv[fk] + 2, O_RDONLY | O_BINARY); if(handle1 == -1) openerr("key", argv[fk] + 2); read(handle1, keybuf, 16); keyset(); close(handle1); } if(mode >= 2 && fi != 0) { handle1 = open(argv[fi] + 2, O_RDONLY | O_BINARY); if(handle1 == -1) openerr("initial", argv[fi] + 2); read(handle1, inibuf, 16); iniset(); close(handle1); } handle1 = open(argv[k1], O_RDONLY | O_BINARY); if(handle1 == -1) openerr("source", argv[k1]); fp = fopen(argv[k2], "rb"); if(fp != NULL) { fprintf(stderr, "Error : destination file(%s) already exist.\n", argv[k2]); exit(-1); } handle2 = open(argv[k2], O_WRONLY | O_CREAT | O_BINARY, S_IREAD | S_IWRITE); #ifndef NODISP outcount = filesize = filelength(handle1); fprintf(stderr, "\nDES%s (Ver.%s) ( %s --> %s )\n", (edflag)? "暗号化": "復号化", VER, argv[k1], argv[k2]); fprintf(stderr, " Copyright(C) %s %s\n ----+----!----+----!----+----!----+----!----+----!\n処理進行 ", DATE, COPYRIGHT); #endif bp = buffer; bufsize1 = BUFFER_SIZE / blen; mem = bufsize = bufsize1 * blen; if(mode >= 3) { switch(blen) { case 1: xor = xor1; break; case 2: xor = xor2; break; case 3: xor = xor3; break; case 4: xor = xor4; break; case 5: xor = xor5; break; case 6: xor = xor6; break; case 7: xor = xor7; break; case 8: xor = xor8; break; } if(mode == 4) { xb1 = x + blen; xb2 = x + blena; } if(llen == 32) { ini_s = ini_shift1; rot_i = rot_initial1; } else if(llen == 64) { ini_s = ini_shift2; rot_i = rot_initial2; } else if(llen < 32) { ini_s = ini_shift3; rot_i = rot_initial3; lshift = llen; rshift = 32 - lshift; } else { ini_s = ini_shift4; rot_i = rot_initial4; lshift = llen - 32; rshift = 32 - lshift; } } makekey((mode <= 2)? edflag: 1); switch(mode) { case 1: ecb(); break; case 2: cbc(); break; case 3: ofb(); break; case 4: cfb(); break; } #ifndef NODISP fputc('\n', stderr); #endif close(handle1); close(handle2); return 0; } |
下記、コマンド群を処理した例を示します。 des コマンドの様々なオプション使用方法を紹介しています。 ( bmatch コマンドは、2つのファイルのバイナリレベルの一致を検査する機能があります。) また、あらかじめ、初期値および暗号鍵を記述したファイル initial、key を準備しています。 des -e -kkey des.man dummy1 des -d -kkey dummy1 dummy1m bmatch dummy1m des.man des -x2 -finitial -e -kkey des.man dummy2 des -x2 -finitial -d -kkey dummy2 dummy2m bmatch dummy2m des.man des -x3 -finitial -b6 -e -kkey des.man dummy3 des -x3 -finitial -b6 -d -kkey dummy3 dummy3m bmatch dummy3m des.man des -x4 -finitial -b6 -l50 -e -kkey des.man dummy4 des -x4 -finitial -b6 -l50 -d -kkey dummy4 dummy4m bmatch dummy4m des.man |
DES暗号化 (Ver.2.0) ( des.man --> dummy1 ) Copyright(C) 1994/11/05 by Tomy(NIFTY:SGV01401) all rights reserved. ----+----!----+----!----+----!----+----!----+----! 処理進行 .................................................. DES復号化 (Ver.2.0) ( dummy1 --> dummy1m ) Copyright(C) 1994/11/05 by Tomy(NIFTY:SGV01401) all rights reserved. ----+----!----+----!----+----!----+----!----+----! 処理進行 .................................................. file1(dummy1m) & file2(des.man) matched in 5052 byte. DES暗号化 (Ver.2.0) ( des.man --> dummy2 ) Copyright(C) 1994/11/05 by Tomy(NIFTY:SGV01401) all rights reserved. ----+----!----+----!----+----!----+----!----+----! 処理進行 .................................................. DES復号化 (Ver.2.0) ( dummy2 --> dummy2m ) Copyright(C) 1994/11/05 by Tomy(NIFTY:SGV01401) all rights reserved. ----+----!----+----!----+----!----+----!----+----! 処理進行 .................................................. file1(dummy2m) & file2(des.man) matched in 5052 byte. DES暗号化 (Ver.2.0) ( des.man --> dummy3 ) Copyright(C) 1994/11/05 by Tomy(NIFTY:SGV01401) all rights reserved. ----+----!----+----!----+----!----+----!----+----! 処理進行 .................................................. DES復号化 (Ver.2.0) ( dummy3 --> dummy3m ) Copyright(C) 1994/11/05 by Tomy(NIFTY:SGV01401) all rights reserved. ----+----!----+----!----+----!----+----!----+----! 処理進行 .................................................. file1(dummy3m) & file2(des.man) matched in 5052 byte. DES暗号化 (Ver.2.0) ( des.man --> dummy4 ) Copyright(C) 1994/11/05 by Tomy(NIFTY:SGV01401) all rights reserved. ----+----!----+----!----+----!----+----!----+----! 処理進行 .................................................. DES復号化 (Ver.2.0) ( dummy4 --> dummy4m ) Copyright(C) 1994/11/05 by Tomy(NIFTY:SGV01401) all rights reserved. ----+----!----+----!----+----!----+----!----+----! 処理進行 .................................................. file1(dummy4m) & file2(des.man) matched in 5052 byte. |
高速DES処理プログラム
|