分类:
2010-11-23 22:23:27
转换矩阵常量定义. des_constants.h
#ifndef _DES_CONSTANTS
#define _DES_CONSTANTS
/* 任意Ki和Kj对应的密钥所需要进行的移位之间没有关系,所以修改这里的矩阵*/
const unsigned char rotate[] = {
1, 2, 5, 7, 9, 11, 13, 15,
17, 19, 21, 23, 25, 27, 29, 30
};
const unsigned char trans_c0 [] = {
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
};
const unsigned char trans_d0[] = {
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
};
const unsigned char trans_combine[] = {
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
};
const unsigned char IP[] = {
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
};
const unsigned char Eselect[] = {
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
};
const unsigned char inverseP[] = {
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
};
const unsigned char reverseIP[] = {
40, 8 , 48, 16, 56, 24, 64, 32,
39, 7 , 47, 15, 55, 23, 63, 31,
38, 6 , 46, 14, 54, 22, 62, 30,
37, 5 , 45, 13, 53, 21, 61, 29,
36, 4 , 44, 12, 52, 20, 60, 28,
35, 3 , 43, 11, 51, 19, 59, 27,
34, 2 , 42, 10, 50, 18, 58, 26,
33, 1 , 41, 9 , 49, 17, 57, 25
};
const unsigned char s_box[][64] = {
{
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
}
};
#endif
加密模块 des.c文件,仅需要对外提供一个加密解密的函数接口即可.随意写的...没有严格的参数检查等机制...
#include
#include
#include
#include "des_constants.h"
#include "des_core.h"
void print_binary(unsigned char *b, int bits)
{
int i;
for(i = 0; i < bits; i++) {
printf("%d", b[i]);
if(!((i + 1) % 8))
printf(" ");
}
printf("\n");
}
static int init_cd(unsigned char *c0, unsigned char *d0, unsigned char *key)
{
int i;
for(i = 0; i < 28; i++) {
c0[i] = key[trans_c0[i] - 1];
d0[i] = key[trans_d0[i] - 1];
}
#ifdef __DEBUG__
printf("c0:\t");
print_binary(c0, 28);
printf("d0:\t");
print_binary(d0, 28);
#endif
}
static void gen_subkey(unsigned char *c, unsigned char *d,\
unsigned char *subkey, int no_recursive)
{
int i;
int real_idx;
int cur_rotate_bits = rotate[i];
// for(i = 0; i < no_recursive; i++)
// cur_rotate_bits += rotate[i];
for(i = 0; i < 48; i++) {
real_idx = trans_combine[i];
if(real_idx <= 28) {
real_idx += cur_rotate_bits - 1;
real_idx %= 28;
subkey[i] = c[real_idx];
} else {
real_idx += cur_rotate_bits - 1;
real_idx %= 28;
subkey[i] = d[real_idx];
}
if(subkey[i] > 1) {
printf("\nBUGGY: subkey[%d] = %d\t", i, subkey[i]);
printf("d[%d] = %d\n", real_idx, d[real_idx]);
exit(-1);
}
}
#ifdef __DEBUG__
printf("key%d\t", no_recursive);
print_binary(subkey, 48);
#endif
}
static void init_trans_IP(const unsigned char *plain_text, unsigned char *l, \
unsigned char *r)
{
int i;
for(i = 0; i < 32; i++) {
l[i] = plain_text[IP[i] - 1];
r[i] = plain_text[IP[i+32] - 1];
#ifdef __DEBUG__
if(l[i] > 1 || r[i] > 1) {
printf("BUGGY: %s, %d", __FUNCTION__, __LINE__);
exit(-1);
}
#endif
}
#ifdef __DEBUG__
printf("L0:\t");
print_binary(l, 32);
printf("\nR0:\t");
print_binary(r, 32);
#endif
}
static inline void gen_select_tmp48(unsigned char *r, unsigned char *tmp)
{
int i;
for(i = 0; i < 48; i++)
tmp[i] = r[Eselect[i] - 1];
#ifdef __DEBUG__
printf("select:\t");
print_binary(tmp, 48);
#endif
}
static inline void mod2_add(unsigned char *tmp, unsigned char *subkey, int bits)
{
int i;
for(i = 0; i < bits; i++)
tmp[i] ^= subkey[i];
#ifdef __DEBUG__
printf("add:\t");
print_binary(tmp, bits);
#endif
}
static void replace_funcS(unsigned char *tmp, unsigned char *out)
{
int row, col;
int i, j;
int subout;
for(i = 0; i < 8; i++) {
row = (tmp[i * 6] << 1) + tmp[i * 6 + 5];
col = (tmp[i * 6 + 1] << 3) + (tmp[i * 6 + 2] << 2)
+ (tmp[i * 6 + 3] << 1) + tmp[i * 6 + 4];
subout = s_box[i][row*16 + col];
for(j = 0; j < 4; j++)
out[i * 4 + j] = (subout & (1 << (3 -j))) >> (3 - j);
}
#ifdef __DEBUG__
printf("s_out:\t");
print_binary(out, 32);
#endif
}
static inline void inverse_P(unsigned char *res)
{
unsigned char tmp[32];
int i;
memcpy(tmp, res, 32);
for(i = 0; i < 32; i++)
res[i] = tmp[inverseP[i] -1];
#ifdef __DEBUG__
printf("P:\t");
print_binary(res, 32);
#endif
}
static inline void reverse_IP(const unsigned char *l, const unsigned char *r, \
unsigned char *encrypt)
{
int i;
for(i = 0; i < 64; i++) {
if(reverseIP[i] <= 32)
encrypt[i] = l[(reverseIP[i] - 1) % 32];
else
encrypt[i] = r[(reverseIP[i] - 1) % 32];
if(encrypt[i] > 1) {
printf("BUGGY encrypt[%d] = %d\n",i, encrypt[i] );
printf("r[%d] = %d\n", reverseIP[i] - 1, \
l[reverseIP[i] - 1]);
exit(1);
}
}
}
static void des_core(unsigned char *plain_text, unsigned char *key, \
unsigned char *encrypt, int decode)
{
unsigned char c[28];
unsigned char d[28];
unsigned char subkey[48];
unsigned char tmp[48];
unsigned char s_out[32];
unsigned char *l, *r, *tmpp;
int i;
int recursive, step;
if(!decode) {
recursive = 1;
step = 1;
} else {
recursive = 16;
step = -1;
}
l = (unsigned char *)malloc(sizeof(unsigned char) * 32);
r = (unsigned char *)malloc(sizeof(unsigned char) * 32);
if(!l || !r) {
printf("OOM: malloc failed!\n");
exit(-2);
}
init_cd(c, d, key);
init_trans_IP(plain_text, l, r);
for(i = 0; i < 16; i++) {
gen_subkey(c, d, subkey, recursive);
recursive += step;
gen_select_tmp48(r, tmp);
mod2_add(tmp, subkey, 48);
replace_funcS(tmp, s_out);
inverse_P(s_out);
mod2_add(l, s_out, 32);
if(i != 15) {
tmpp = r;
r = l;
l = tmpp;
}
#ifdef __DEBUG__
printf("L%d:\t", i+1);
print_binary(l, 32);
printf("R%d:\t", i+1);
print_binary(r, 32);
printf("\n");
#endif
}
reverse_IP(l, r, encrypt);
}
void des_encrypt(unsigned char *plain, unsigned char *key, \
unsigned char * encrypt)
{
des_core(plain, key, encrypt, 0);
}
void des_decode(unsigned char *encrypt, unsigned char *key, \
unsigned char *plain)
{
des_core(encrypt, key, plain, 1);
}
加密解密接口函数头文件, des_core.h
#ifndef _DES_CORE_H
#define _DES_CORE_H
void des_encrypt(unsigned char *, unsigned char *, unsigned char *);
void des_decode(unsigned char *, unsigned char *, unsigned char *);
#endif
加密解密程序主函数encrypt.c文件, 提供一些选项... help函数没有实现... 没有实现密钥选择...提供一个选项, 从某文件读取或者直接输入即可... 懒得烦了...嘿嘿...
#include
#include
#include
#include "des_core.h"
#include
#define BUFSIZE 4096
static inline void str2bin64(unsigned char *str, unsigned char *bin64)
{
int i, j;
for(i = 0; i < 8; i++) {
for(j = 0; j < 8; j++) {
bin64[i*8 + j] = str[i] >> (8 - 1 - j);
str[i] &= ~(1 << (8 -1 - j));
}
}
}
static void output_bin64(FILE *out, unsigned char *bin64, int bytes)
{
int i, j;
unsigned char output[8];
bzero(output, sizeof(output));
for(i = 0; i < bytes; i++) {
for(j = 0; j < 8; j++)
output[i] += bin64[i*8 + j] << (8 - 1 - j);
}
write(fileno(out), output, 8);
}
typedef void (*core_fn) (unsigned char *, unsigned char *, unsigned char *);
static void __core_text_en_de(FILE *in, FILE *out, unsigned char *key, int en)
{
unsigned char buf[BUFSIZE];
unsigned char bin64[64];
unsigned char res[64];
unsigned char *ptr;
int i, j;
int left;
core_fn fn;
if(en)
fn = des_encrypt;
else
fn = des_decode;
while((left = read(fileno(in), buf, BUFSIZE)) > 0) {
ptr = buf;
while(left >= 8) {
str2bin64(ptr, bin64);
(*fn)(bin64, key, res);
output_bin64(out, res, 8);
left -= 8;
ptr += 8;
}
if(left) {
int i;
for(i = left; i < 8; i++)
ptr[i] = 0;
str2bin64(ptr, bin64);
des_encrypt(bin64, key, res);
output_bin64(out, res, 8);
left = 0;
}
}
}
void text_encrypt(FILE *in, FILE *out, unsigned char *key)
{
__core_text_en_de(in, out, key, 1);
}
void text_decode(FILE *in, FILE *out, unsigned char *key)
{
__core_text_en_de(in, out, key, 0);
}
static FILE *open_file(const char *filepath, const char *mode)
{
FILE *fp;
fp = fopen(filepath, mode);
if(!fp) {
printf("open file for %s failed!\n", filepath);
exit(-1);
}
return fp;
}
#define open_file_r(filepath) \
open_file(filepath, "r")
#define open_file_w(filepath) \
open_file(filepath, "w")
int main(int argc, char *argv[])
{
int en;
char c;
opterr = 0;
FILE *in = NULL;
FILE *out = NULL;
while((c = getopt(argc, argv, "hedi:o:")) != -1) {
switch(c) {
case 'h': //print help
print_help();
exit(0);
case 'e':
en = 1; // encrypt
break;
case 'd':
en = 0; //decode
break;
case 'i':
in = open_file_r(optarg); // input of plain or encrypted file
break;
case 'o':
out = open_file_w(optarg); // output of plain text or encrypted file
break;
default:
printf("Unrecognized options: %c", c);
exit(-1);
}
}
unsigned char key[64];
unsigned char key_str[] = "abcdefgh";
if(!in)
in = stdin;
if(!out)
out = stdout;
str2bin64(key_str, key);
if(en)
text_encrypt(in, out, key);
else
text_decode(in, out, key);
return 0;
}