|
[ 簡単な説明 ]
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処理プログラム
|