📄 sdesimpl.cpp
字号:
// SDESImpl.cpp: implementation of the SDESImpl class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SDES.h"
#include "SDESImpl.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
SDESImpl::SDESImpl()
{
}
SDESImpl::~SDESImpl()
{
}
// initial permutation IP
const static char IP_Table[8] = {
2, 6, 3, 1, 4, 8, 5,7
};
// final permutation IP^-1
const static char IPR_Table[8] = {
4, 1, 3, 5, 7, 2, 8, 6
};
// expansion operation matrix //扩张和置换后得到2*4的矩阵
static const char E_Table[8] = {
4, 1, 2, 3,
2, 3, 4, 1
};
// 4-bit permutation function P used on the output of the S-boxes
const static char P_Table[4] = {
2, 4, 3, 1
};
// permuted choice table (key)
const static char PC1_Table[10] = {
3, 5, 2, 7, 4, 10, 1, 9, 8, 6
};
// permuted choice key (table)
const static char PC2_Table[8] = {
6, 3, 7, 4, 8, 5, 10,9
};
// number left rotations of pc1
const static char LOOP_Table[2] = {
1,2
};
// The (in)famous S-boxes
const static char S_Box[2][4][4] = {
// S1
1, 0, 3, 2,
3, 2, 1, 0,
0, 2, 1, 3,
3, 1, 3, 2,
// S2
0, 1, 2, 3,
2, 0, 1, 3,
3, 0, 1, 0,
2, 1, 0, 3
};
//////////////////////////////////////////////////////////////////////////
typedef bool (*PSubKey)[2][8];//PSubKey为指向subKey[16][48]的指针//
//static bool SubKey[2][16][48];// 16圈子密钥
//////////////////////////////////////////////////////////////////////////
static void SDES(char Out[1], char In[1], const PSubKey pSubKey, bool Type);//标准DES加/解密
static void SetKey(const char* Key, int len);// 设置密钥
static void SetSubKey(PSubKey pSubKey, const char Key[2]);// 设置子密钥
static void F_func(bool In[4], const bool Ki[8]);// f 函数
static void S_func(bool Out[4], const bool In[8]);// S 盒代替
static void Transform(bool *Out, bool *In, const char *Table, int len);// 变换
static void Xor(bool *InA, const bool *InB, int len);// 异或
static void RotateL(bool *In, int len, int loop);// 循环左移
static void ByteToBit(bool *Out, const char *In, int bits);// 字节组转换成位组
static void BitToByte(char *Out, const bool *In, int bits);// 位组转换成字节组
//////////////////////////////////////////////////////////////////////////
static bool SubKey[2][2][8];// 16圈子密钥
static bool Is3DES;// 3次DES标志
static char Tmp[256], deskey[4];
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Code starts from Line 130
//////////////////////////////////////////////////////////////////////////
void SetKey(const char* Key, int len)
{
memset(deskey, 0, 4);
memcpy(deskey, Key, len>4?4:len);
SetSubKey(&SubKey[0], &deskey[0]);
Is3DES = len>2 ? (SetSubKey(&SubKey[1], &deskey[2]), true) : false;
//如果密钥长度大于8个字节,就后面的16组48位的子密钥生成存放在SubKey[1],前面生成的已经放在SubKey[0]
}
void SDES(char Out[1], char In[1], const PSubKey pSubKey, bool Type)
{
static bool M[8], tmp[4], *Li=&M[0], *Ri=&M[4];
ByteToBit(M, In, 8);
Transform(M, M, IP_Table, 8);
if( Type == ENCRYPT ){
for(int i=0; i<2; ++i) {
memcpy(tmp, Ri, 4);
F_func(Ri, (*pSubKey)[i]);
Xor(Ri, Li, 4);
memcpy(Li, tmp, 4);
}
}else{
for(int i=1; i>=0; --i) {
memcpy(tmp, Li, 4);
F_func(Li, (*pSubKey)[i]);
Xor(Li, Ri, 4);
memcpy(Ri, tmp, 4);
}
}
Transform(M, M, IPR_Table, 8);
BitToByte(Out, M, 8);
}
void SetSubKey(PSubKey pSubKey, const char Key[2])//用密钥Key(2*8=16位,但取前5*2=10位)生成2组子密钥,放在(*pSubKey)[i],每组48位
{
static bool K[16], *KL=&K[0], *KR=&K[5];
ByteToBit(K, Key, 16);
Transform(K, K, PC1_Table, 10);
for(int i=0; i<2; ++i) {
RotateL(KL, 5, LOOP_Table[i]);
RotateL(KR, 5, LOOP_Table[i]);
Transform((*pSubKey)[i], K, PC2_Table, 8);
}
}
void F_func(bool In[4], const bool Ki[8])
{
static bool MR[8];
Transform(MR, In, E_Table, 8);//由4位扩大为8位
Xor(MR, Ki, 8);
S_func(In, MR);
Transform(In, In, P_Table, 4);
}
void S_func(bool Out[4], const bool In[8])
{
for(char i=0,j,k; i<2; ++i,In+=4,Out+=2) {
j = (In[0]<<1) + In[3];//化为十进制
k = (In[1]<<1) + In[2];//化为十进制
ByteToBit(Out, &S_Box[i][j][k], 2);//2 bits * 2 = 4 bits
}
}
void Transform(bool *Out, bool *In, const char *Table, int len)
{
for(int i=0; i<len; ++i)
Tmp[i] = In[ Table[i]-1 ];
memcpy(Out, Tmp, len);
}
void Xor(bool *InA, const bool *InB, int len)
{
for(int i=0; i<len; ++i)
InA[i] ^= InB[i];
}
void RotateL(bool *In, int len, int loop)
{
memcpy(Tmp, In, loop);
memcpy(In, In+loop, len-loop);
memcpy(In+len-loop, Tmp, loop);
}
void ByteToBit(bool *Out, const char *In, int bits)
{
for(int i=0; i<bits; ++i)
Out[i] = (In[i>>3]>>(i&7)) & 1;
}
void BitToByte(char *Out, const bool *In, int bits)
{
memset(Out, 0, bits>>3);
for(int i=0; i<bits; ++i)
Out[i>>3] |= In[i]<<(i&7);
}
bool SDESImpl::SDESer(char * Out,char * In,long datalen,const char*Key,int keylen,bool Type)
{
if( !( Out && In && Key && (datalen=(datalen+7)&0xfffffff8) ) )
return false;
SetKey(Key, keylen);
if( !Is3DES ) { // 1次DES
for(long i=0,j=datalen; i<j; ++i,Out+=1,In+=1)
SDES(Out, In, &SubKey[0], Type);//每次加密8位,总共要datalen次
} else{ // 3次DES 加密:加(key0)-解(key1)-加(key0) 解密::解(key0)-加(key1)-解(key0)
for(long i=0,j=datalen; i<j; ++i,Out+=1,In+=1) {
SDES(Out, In, &SubKey[0], Type);
SDES(Out, Out, &SubKey[1], !Type);
SDES(Out, Out, &SubKey[0], Type);
}
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -