typedef unsigned char UC;
UC sboxvalue[8][4 * 16] =
{
0xe, 0x4, 0xd, 0x1, 0x2, 0xf, 0xb, 0x8, 0x3, 0xa, 0x6, 0xc, 0x5, 0x9, 0x0, 0x7,
0x0, 0xf, 0x7, 0x4, 0xe, 0x2, 0xd, 0x1, 0xa, 0x6, 0xc, 0xb, 0x9, 0x5, 0x3, 0x8,
0x4, 0x1, 0xe, 0x8, 0xd, 0x6, 0x2, 0xb, 0xf, 0xc, 0x9, 0x7, 0x3, 0xa, 0x5, 0x0,
0xf, 0xc, 0x8, 0x2, 0x4, 0x9, 0x1, 0x7, 0x5, 0xb, 0x3, 0xe, 0xa, 0x0, 0x6, 0xd,
0xf, 0x1, 0x8, 0xe, 0x6, 0xb, 0x3, 0x4, 0x9, 0x7, 0x2, 0xd, 0xc, 0x0, 0x5, 0xa,
0x3, 0xd, 0x4, 0x7, 0xf, 0x2, 0x8, 0xe, 0xc, 0x0, 0x1, 0xa, 0x6, 0x9, 0xb, 0x5,
0x0, 0xe, 0x7, 0xb, 0xa, 0x4, 0xd, 0x1, 0x5, 0x8, 0xc, 0x6, 0x9, 0x3, 0x2, 0xf,
0xd, 0x8, 0xa, 0x1, 0x3, 0xf, 0x4, 0x2, 0xb, 0x6, 0x7, 0xc, 0x0, 0x5, 0xe, 0x9,
0xa, 0x0, 0x9, 0xe, 0x6, 0x3, 0xf, 0x5, 0x1, 0xd, 0xc, 0x7, 0xb, 0x4, 0x2, 0x8,
0xd, 0x7, 0x0, 0x9, 0x3, 0x4, 0x6, 0xa, 0x2, 0x8, 0x5, 0xe, 0xc, 0xb, 0xf, 0x1,
0xd, 0x6, 0x4, 0x9, 0x8, 0xf, 0x3, 0x0, 0xb, 0x1, 0x2, 0xc, 0x5, 0xa, 0xe, 0x7,
0x1, 0xa, 0xd, 0x0, 0x6, 0x9, 0x8, 0x7, 0x4, 0xf, 0xe, 0x3, 0xb, 0x5, 0x2, 0xc,
0x7, 0xd, 0xe, 0x3, 0x0, 0x6, 0x9, 0xa, 0x1, 0x2, 0x8, 0x5, 0xb, 0xc, 0x4, 0xf,
0xd, 0x8, 0xb, 0x5, 0x6, 0xf, 0x0, 0x3, 0x4, 0x7, 0x2, 0xc, 0x1, 0xa, 0xe, 0x9,
0xa, 0x6, 0x9, 0x0, 0xc, 0xb, 0x7, 0xd, 0xf, 0x1, 0x3, 0xe, 0x5, 0x2, 0x8, 0x4,
0x3, 0xf, 0x0, 0x6, 0xa, 0x1, 0xd, 0x8, 0x9, 0x4, 0x5, 0xb, 0xc, 0x7, 0x2, 0xe,
0x2, 0xc, 0x4, 0x1, 0x7, 0xa, 0xb, 0x6, 0x8, 0x5, 0x3, 0xf, 0xd, 0x0, 0xe, 0x9,
0xe, 0xb, 0x2, 0xc, 0x4, 0x7, 0xd, 0x1, 0x5, 0x0, 0xf, 0xa, 0x3, 0x9, 0x8, 0x6,
0x4, 0x2, 0x1, 0xb, 0xa, 0xd, 0x7, 0x8, 0xf, 0x9, 0xc, 0x5, 0x6, 0x3, 0x0, 0xe,
0xb, 0x8, 0xc, 0x7, 0x1, 0xe, 0x2, 0xd, 0x6, 0xf, 0x0, 0x9, 0xa, 0x4, 0x5, 0x3,
0xc, 0x1, 0xa, 0xf, 0x9, 0x2, 0x6, 0x8, 0x0, 0xd, 0x3, 0x4, 0xe, 0x7, 0x5, 0xb,
0xa, 0xf, 0x4, 0x2, 0x7, 0xc, 0x9, 0x5, 0x6, 0x1, 0xd, 0xe, 0x0, 0xb, 0x3, 0x8,
0x9, 0xe, 0xf, 0x5, 0x2, 0x8, 0xc, 0x3, 0x7, 0x0, 0x4, 0xa, 0x1, 0xd, 0xb, 0x6,
0x4, 0x3, 0x2, 0xc, 0x9, 0x5, 0xf, 0xa, 0xb, 0xe, 0x1, 0x7, 0x6, 0x0, 0x8, 0xd,
0x4, 0xb, 0x2, 0xe, 0xf, 0x0, 0x8, 0xd, 0x3, 0xc, 0x9, 0x7, 0x5, 0xa, 0x6, 0x1,
0xd, 0x0, 0xb, 0x7, 0x4, 0x9, 0x1, 0xa, 0xe, 0x3, 0x5, 0xc, 0x2, 0xf, 0x8, 0x6,
0x1, 0x4, 0xb, 0xd, 0xc, 0x3, 0x7, 0xe, 0xa, 0xf, 0x6, 0x8, 0x0, 0x5, 0x9, 0x2,
0x6, 0xb, 0xd, 0x8, 0x1, 0x4, 0xa, 0x7, 0x9, 0x5, 0x0, 0xf, 0xe, 0x2, 0x3, 0xc,
0xd, 0x2, 0x8, 0x4, 0x6, 0xf, 0xb, 0x1, 0xa, 0x9, 0x3, 0xe, 0x5, 0x0, 0xc, 0x7,
0x1, 0xf, 0xd, 0x8, 0xa, 0x3, 0x7, 0x4, 0xc, 0x5, 0x6, 0xb, 0x0, 0xe, 0x9, 0x2,
0x7, 0xb, 0x4, 0x1, 0x9, 0xc, 0xe, 0x2, 0x0, 0x6, 0xa, 0xd, 0xf, 0x3, 0x5, 0x8,
0x2, 0x1, 0xe, 0x7, 0x4, 0xa, 0x8, 0xd, 0xf, 0xc, 0x9, 0x0, 0x3, 0x5, 0x6, 0xb,
};
void BitsToByte(UC *bitstr, UC *bytechar)
//将长度为8个字节的比特位(最低一个位有效)串压缩成一个字节,比特位的存放是由高到低
{
register i;
UC tmpchar, tmpstr[8];
tmpchar = 0;
memcpy(tmpstr, bitstr, 8);
for (i = 0; i < 8; i++)
{
tmpstr[i] = tmpstr[i] & 0x01; //clear high 7 bit
}
for (i = 0; i < 7;i++)
{
tmpchar = tmpchar | tmpstr[i];
tmpchar = tmpchar << 1;
}
tmpchar = tmpchar | tmpstr[7];
*bytechar = tmpchar;
}
void ByteToBits(UC bytechar, UC *bitstr)
//将一个字节扩展为8个字节的比特位(最低一个位有效)串
{
register i;
UC tmpchar;
tmpchar = bytechar;
for (i = 7; i >= 0 ;i--)
{
bitstr[i] = tmpchar & 0x01;
tmpchar = tmpchar >> 1;
}
}
void Permute_IP(UC *text, UC *text_ip)
//对明文做初始置换
//text-明文,长度为8字节;test_ip-置换后的明文,长度为8字节
{
UC byte_text[64], byte_ip_text[64];
register i, j;
memset(byte_text, 0, 64);
memset(byte_ip_text, 0, 64);
for (i = 0; i < 8; i++)
{
ByteToBits(text[i], byte_text + i * 8);
}
for (i = 0; i < 4; i++)
{
for (j = 0; j < 8; j++)
{
byte_ip_text[i * 8 + j] = byte_text[(7 - j) * 8 + i * 2 + 1];
}
}
for (i = 4; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
byte_ip_text[i * 8 + j] = byte_text[(7 - j) * 8 + (i - 4) * 2];
}
}
for (i = 0; i < 8; i++)
{
BitsToByte(byte_ip_text + i * 8, &text_ip[i]);
}
}
void Reverse_IP(UC *ip_text, UC *text)
//逆初始置换
//ip_text-源码,长度为8字节;test-逆置换后的码,长度为8字节
{
UC byte_ip_text[64], byte_text[64];
register i, j;
memset(byte_text, 0, 64);
memset(byte_ip_text, 0, 64);
for (i = 0; i < 8; i++)
{
ByteToBits(ip_text[i], byte_ip_text + i * 8);
}
for (i = 0; i < 8; i++)
{
for (j = 0; j < 4; j++)
{
byte_text[i * 8 + j * 2] = byte_ip_text[(j + 4) * 8 + (7 - i)];
}
}
for (i = 0; i < 8; i++)
{
for (j = 0; j < 4; j++)
{
byte_text[i * 8 + j * 2 + 1] = byte_ip_text[j * 8 + (7 - i)];
}
}
for (i = 0; i < 8; i++)
{
BitsToByte(byte_text + i * 8, &text[i]);
}
}
void MoveLeft(UC *buff)
//将长度为28个字节的串循环左移
{
register i;
UC tmpchar;
tmpchar = buff[0];
for (i = 0; i < 27; i++)
{
buff[i] = buff[i + 1];
}
buff[27] = tmpchar;
}
void GetCircleKey(UC *inkey, UC *outkey)
//用原始密码(64位)产生一组48位的子密钥Ki,1<=i<=16
//inkey-原始密码,长度为8个字节,outkey-16个48位子密钥,要求长度为96个字节
{
register i, j;
UC keybuff[64];
UC c0[28], d0[28];
UC ki_buff[48];
for (i = 0; i < 8; i++)
{
ByteToBits(inkey[i], keybuff + i * 8);
}
//得到C0
for (i = 0; i < 3; i++)
{
for (j = 0; j < 8; j++)
{
c0[i * 8 + j] = keybuff[(7 - j) * 8 + i];
}
}
c0[24] = keybuff[59];
c0[25] = keybuff[51];
c0[26] = keybuff[43];
c0[27] = keybuff[35];
//得到D0
for (i = 0; i < 3; i++)
{
for (j = 0; j < 8; j++)
{
d0[i * 8 + j] = keybuff[(7 - j) * 8 + (6 - i)];
}
}
d0[24] = keybuff[27];
d0[25] = keybuff[19];
d0[26] = keybuff[11];
d0[27] = keybuff[3];
//得到16个48位的子密钥
for (i = 0; i < 16; i++)
{
switch (i)
{
case 0:
case 1:
case 8:
case 15:
MoveLeft(c0);
MoveLeft(d0);
break;
default:
MoveLeft(c0);
MoveLeft(c0);
MoveLeft(d0);
MoveLeft(d0);
break;
}
ki_buff[0] = c0[13];
ki_buff[1] = c0[16];
ki_buff[2] = c0[10];
ki_buff[3] = c0[23];
ki_buff[4] = c0[0];
ki_buff[5] = c0[4];
ki_buff[6] = c0[2];
ki_buff[7] = c0[27];
ki_buff[8] = c0[14];
ki_buff[9] = c0[5];
ki_buff[10] = c0[20];
ki_buff[11] = c0[9];
ki_buff[12] = c0[22];
ki_buff[13] = c0[18];
ki_buff[14] = c0[11];
ki_buff[15] = c0[3];
ki_buff[16] = c0[25];
ki_buff[17] = c0[7];
ki_buff[18] = c0[15];
ki_buff[19] = c0[6];
ki_buff[20] = c0[26];
ki_buff[21] = c0[19];
ki_buff[22] = c0[12];
ki_buff[23] = c0[1];
ki_buff[24] = d0[12];
ki_buff[25] = d0[23];
ki_buff[26] = d0[2];
ki_buff[27] = d0[8];
ki_buff[28] = d0[18];
ki_buff[29] = d0[26];
ki_buff[30] = d0[1];
ki_buff[31] = d0[11];
ki_buff[32] = d0[22];
ki_buff[33] = d0[16];
ki_buff[34] = d0[4];
ki_buff[35] = d0[19];
ki_buff[36] = d0[15];
ki_buff[37] = d0[20];
ki_buff[38] = d0[10];
ki_buff[39] = d0[27];
ki_buff[40] = d0[5];
ki_buff[41] = d0[24];
ki_buff[42] = d0[17];
ki_buff[43] = d0[13];
ki_buff[44] = d0[21];
ki_buff[45] = d0[7];
ki_buff[46] = d0[0];
ki_buff[47] = d0[3];
for (j = 0; j < 6; j++)
{
BitsToByte(ki_buff + 8 * j, &outkey[i * 6 + j]);
}
}
}
void Select_E(UC *str32, UC *str48)
//选择运算E,对32位变量进行操作,产生48位输出
//str32-32位输入,长度为4个字节;str48-48位输出,长度为6个字节
{
UC in_buff[33], out_buff[48];
register i, j;
for (i = 0; i < 4; i++)
{
ByteToBits(str32[i], in_buff + i * 8);
}
for (i = 0; i < 8; i++)
{
for (j = 0; j < 2; j++)
{
if (i != 0)
{
out_buff[i * 6 + j] = in_buff[i * 4 + j - 1];
}
}
for (j = 2; j < 6; j++)
{
out_buff[i * 6 + j] = in_buff[i * 4 + j - 1];
}
}
out_buff[0] = in_buff[31];
out_buff[1] = in_buff[0];
out_buff[47] = in_buff[0];
for (i = 0; i < 6; i++)
{
BitsToByte(out_buff + i * 8, &str48[i]);
}
}
void Select_Si(UC *str48, UC *str32)
//通过选择函数Si把48位结果变成32位输出
//str48-长度为6个字节;str32-长度为4个字节
{
register i;
UC buff48[48], buff[8], tmpchar;
int x, y;
for (i = 0; i < 6;i++)
{
ByteToBits(str48[i], buff48 + i * 8);
}
for (i = 0; i < 8; i++)
{
x = buff48[i * 6] * 2 + buff48[i * 6 + 5];
y = buff48[i * 6 + 1] * 8 + buff48[i * 6 + 2] * 4 + buff48[i * 6 + 3] * 2 +
buff48[i * 6 + 4];
tmpchar = sboxvalue[i][x * 16 + y];
buff[i] = tmpchar;
}
for (i = 0; i < 4; i++)
{
tmpchar = ((buff[i * 2] << 4) & 0xf0) + (buff[ i * 2 + 1] & 0x0f);
str32[i] = tmpchar;
}
}
void Permute_P(UC *text, UC *text_p)
//对32位数据做P置换
//text-长度为4字节;test_p-置换后的32位,长度为4字节
{
UC byte_text[32], byte_p_text[32];
register i;
memset(byte_text, 0, 32);
memset(byte_p_text, 0, 32);
for (i = 0; i < 4; i++)
{
ByteToBits(text[i], byte_text + i * 8);
}
byte_p_text[0] = byte_text[15];
byte_p_text[1] = byte_text[6];
byte_p_text[2] = byte_text[19];
byte_p_text[3] = byte_text[20];
byte_p_text[4] = byte_text[28];
byte_p_text[5] = byte_text[11];
byte_p_text[6] = byte_text[27];
byte_p_text[7] = byte_text[16];
byte_p_text[8] = byte_text[0];
byte_p_text[9] = byte_text[14];
byte_p_text[10] = byte_text[22];
byte_p_text[11] = byte_text[25];
byte_p_text[12] = byte_text[4];
byte_p_text[13] = byte_text[17];
byte_p_text[14] = byte_text[30];
byte_p_text[15] = byte_text[9];
byte_p_text[16] = byte_text[1];
byte_p_text[17] = byte_text[7];
byte_p_text[18] = byte_text[23];
byte_p_text[19] = byte_text[13];
byte_p_text[20] = byte_text[31];
byte_p_text[21] = byte_text[26];
byte_p_text[22] = byte_text[2];
byte_p_text[23] = byte_text[8];
byte_p_text[24] = byte_text[18];
byte_p_text[25] = byte_text[12];
byte_p_text[26] = byte_text[29];
byte_p_text[27] = byte_text[5];
byte_p_text[28] = byte_text[21];
byte_p_text[29] = byte_text[10];
byte_p_text[30] = byte_text[3];
byte_p_text[31] = byte_text[24];
for (i = 0; i < 4; i++)
{
BitsToByte(byte_p_text + i * 8, &text_p[i]);
}
}
void DES_encrypt(UC *plain_text, UC *key_text, UC *encrypt_text)
//DES加密运算
//plain_text-明文,8个字节;key_text-密钥,8个字节;encrypt_text-密文,8个字节
{
register i,j;
UC key16[16 * 6]; //存放16个48位子密钥
UC plain_ip[8], tmpbuff[4], buff48[6], tmp32[4];
//初始置换
Permute_IP(plain_text,plain_ip);
//得到16个子密钥
GetCircleKey(key_text,key16);
//16次迭代
for (i = 0; i < 16;i++)
{
memcpy(tmpbuff, plain_ip + 4, 4); //L(i)=R(i-1)
Select_E(plain_ip + 4, buff48); //R(i-1)从32位变为48位
for (j = 0; j < 6; j++)
{
buff48[j] = buff48[j] ^ key16[i * 6 + j]; //48位模2加
}
Select_Si(buff48, tmp32); //通过选择函数从48位变为32位
Permute_P(tmp32, buff48); //P置换
memcpy(tmp32, buff48, 4);
for (j = 0; j < 4; j++)
{
buff48[j] = tmp32[j] ^ plain_ip[j]; //32位模2加
}
memcpy(plain_ip, tmpbuff, 4); //L(i)
memcpy(plain_ip + 4, buff48, 4); //R(i)
}
//码组交换
memcpy(tmpbuff, plain_ip + 4, 4);
memcpy(plain_ip + 4, plain_ip, 4);
memcpy(plain_ip, tmpbuff, 4);
Reverse_IP(plain_ip, encrypt_text);
}
void DES_decrypt(UC *encrypt_text, UC *key_text, UC *plain_text)
//DES解密运算
//encrypt_text-密文,8个字节;key_text-密钥,8个字节;plain_text-明文,8个字节
{
register i,j;
UC key16[16 * 6]; //存放16个48位子密钥
UC plain_ip[8], tmpbuff[4], buff48[6], tmp32[4];
//初始置换
Permute_IP(encrypt_text, plain_ip);
//得到16个子密钥
GetCircleKey(key_text, key16);
//16次迭代
for (i = 15; i >= 0; i--)
{
memcpy(tmpbuff, plain_ip + 4, 4); //R(i-1)=L(i)
Select_E(plain_ip + 4, buff48); //L(i)从32位变为48位
for (j = 0; j < 6; j++)
{
buff48[j] = buff48[j] ^ key16[i * 6 + j]; //48位模2加
}
Select_Si(buff48, tmp32); //通过选择函数从48位变为32位
Permute_P(tmp32, buff48); //P置换
memcpy(tmp32, buff48, 4);
for (j = 0; j < 4; j++)
{
buff48[j] = tmp32[j] ^ plain_ip[j]; //32位模2加
}
memcpy(plain_ip, tmpbuff, 4); //L(i)
memcpy(plain_ip + 4, buff48, 4); //R(i)
}
memcpy(tmpbuff, plain_ip + 4, 4);
memcpy(plain_ip + 4, plain_ip, 4);
memcpy(plain_ip, tmpbuff, 4);
Reverse_IP(plain_ip, plain_text);
}