📄 des1.cpp
字号:
// DES1.cpp: implementation of the CDES class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DES.h"
#include "DES1.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#undef TEXT
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDES::CDES()
{
LastCipher.Attach(lastcipher,8,8);
resetCBC();
}
CDES::~CDES()
{
}
void CDES::Permute(CTableArray<ULONG> &src, CTableArray<UINT> &reftbl,CTableArray<ULONG>&result)
{
memset(&result[0],0,(result.col*result.row==32)?4:8);
int prmtblsize=reftbl.col*reftbl.row; //置换表size
int srcsize=src.col*src.row ;//源表SIZE
int srcline=ceil((double)(src.col*src.row)/(double)(sizeof(ULONG)*8));//源表中实际所含LONG数个数
for(int i=prmtblsize;i>=1;i--)
{
ULONG mskbit=1; //置换:最复杂的一步,基本原理是根据置换表提供的BIT位置,将源表src中的该位掩出,然后根据我们将要移到的位位置
int l=(reftbl[prmtblsize-i]-1)/(srcsize/srcline);//将该位移动到目标表result的该位置上,期间还要考虑到目标表长度的变化,有些是由2个LONG组成,有些是由一个LONG组成
int c=(reftbl[prmtblsize-i])%(srcsize/srcline);//要根据表类型CTableArray的行列属性判断移位的多少.
if(c==0) c=(srcsize/srcline);//以上三步是根据置换表中的BIT位置,计算将要移动BIT所在SRC表中的行,和它到左边最高位的距离位数,这里需要考虑到SRC表实际有多少个LONG构成
mskbit=_lrotr(mskbit,c); //将掩位循环右移相应的上一步得到的位数
mskbit&=src[l];//将掩位与要处理的BIT 位AND操作,得到我们将要处理的BIT,
mskbit=_lrotl(mskbit,c);//将掩位循环左移到原来的位置
mskbit=_lrotr(mskbit,(prmtblsize-i)%(prmtblsize/(prmtblsize>32?2:1))+1); //计算我们将要添加到result的LONG数据中哪个位上,并循环右移到那个位子上,因为根据输出的表的不同,可能有32,28,等不同未数一组的
result[(prmtblsize-i)/(prmtblsize/(prmtblsize>32?2:1))]|=mskbit;//计算我们将要添加到那个LONG数据中,将掩码并位或上这个LONG数据上
}
}
CString * CDES::showBit(CTableArray<ULONG>* in)
{
CString *str=new CString;
CString s;
for(int sc=0;sc<in->col;sc++)
{
s.Format("%d ",sc);
*str+=s;
}
*str+="\r\n";
ULONG seg=(*in)[0];
for(int i=0;i<in->row ;i++){
for(int j=0;j<in->col;j++){
if(i*in->col+j==in->col*in->row/(in->col*in->row>32?2:1) )
seg=(*in)[1];
s.Format("%d ",(((seg&0x80000000)>>31)==0)?0:1);
seg<<=1;
*str+=s;
}
*str+="\r\n";
}
return str;
}
void CDES::Crypto(CTableArray<ULONG> &Text,CTableArray<ULONG>& K,BOOL DIRECTION,CTableArray<ULONG>&result)
{
static CTableArray<ULONG> out(8,8);
static CTableArray<UINT> IP((UINT*)ip,8,8);
static CTableArray<UINT> IP_1((UINT*)ip_1,8,8);
Permute(Text,IP,out); //IP置换
ULONG L0;
static CTableArray<ULONG> KI(8,6);
for(UINT i=1;i<=16;i++)//16次迭代开始
{
KeyGen(K,abs(17*!DIRECTION-i),KI); //假如DIRECTION是TRUE则子密钥从K1->K16; FALSE则从K16->K1,
L0=out[0];
out[0]=out[1]; //L1=R0
out[1]=L0^f(out[1],KI); //R1=L0 xor F(R0,Ki)
}
L0=out[0]; //L16R16 --> R16L16
out[0]=out[1];
out[1]=L0;
Permute(out,IP_1,result);//IP-1 置换
}
unsigned char * CDES::Crypto(UCHAR text[], UCHAR key[], BOOL DIRECTION)
{
static CTableArray<ULONG> TEXT(8,8);
static CTableArray<ULONG> KEY(8,8);
static CTableArray<ULONG> result(8,8);
memcpy(&TEXT[0],text,8);
memcpy(&KEY[0],key,8);
Crypto(TEXT,KEY,DIRECTION,result);
UCHAR *out=new UCHAR[8];
memcpy(out,&result[0],8);
return out;
}
ULONG CDES::f(ULONG &R, CTableArray<ULONG>& K) //where K is 48bit and R is the higher
{ //segment of plain text ,
//return 32bit LONG
static CTableArray<UINT> E((UINT*)e,8,6);
static CTableArray<UINT> P((UINT*)p,8,4);
static CTableArray<ULONG> SRC(8,4);
static CTableArray<ULONG> afterE(8,6);
static CTableArray<ULONG> afterSBOX(8,4);
static CTableArray<ULONG> afterP(8,4);
SRC[0]=R;
Permute(SRC,E,afterE); //E置换expand from 32bit to 48bit
afterE[0]^=K[0];//将KEY和E置换后的数据进行XOR
afterE[1]^=K[1];
SBOX(afterE,afterSBOX);//放到S盒中
Permute(afterSBOX,P,afterP);//进行P置换
return afterP[0];
}
void CDES::SBOX(CTableArray<ULONG>&aftxor,CTableArray<ULONG>&result) //48bit in 32bit out
{
ULONG mskbit=0xFC000000;
memset(&result[0],0,4);
for(int i=0;i<8;i++){
ULONG part=aftxor[i/4]<<((i%4)*6); //每次将下次要处理的6位移到最高位
ULONG t=part&mskbit; //去最高6位
t>>=26; //使取得的最高6位右对齐
int line=(t&1)+ 2*(1&(t>>5));//取行数:取最低和最高比特得到SBOX的行数,先将最低位与1,再将6位右移5位,使最高位移到最低位再与1乘2,与前面得低位值相加
ULONG col=t>>1; //取列数:取中间4位,也就是将6位右移1位,然后和0xf位与去低4位,得到列数
col&=0xf;
ULONG tmp=s[i][line][col]; //查S盒
tmp<<=(32-(i+1)*4); //将得到的数字,移到将来会出现的位置上,这与当前处理的次数有关系
result[0]|=tmp;
}
}
void CDES::KeyGen(CTableArray<ULONG>&KEY,int times,CTableArray<ULONG>&result) //INTPUT 64bit,
//OUTPUT 48BIT
{
static CTableArray<UINT> PC1((UINT*)pc1,8,7);
static CTableArray<UINT> PC2((UINT*)pc2,8,6);
CTableArray<ULONG> afterPC1(PC1.row,PC1.col);
Permute(KEY,PC1,afterPC1); //afterPC1 is 56bit 8x7
ULONG a;
for(int i=1;i<=times;i++)
{
int shift=2;
if(i==1 ||i==2 ||i==9 ||i==16) //根据次数判别
shift=1;
a=(afterPC1[0]&0XC0000000)>>(28-shift); //循环左移shift位
afterPC1[0]<<=shift;
afterPC1[0]|=a;
a=(afterPC1[1]&0XC0000000)>>(28-shift);
afterPC1[1]<<=shift;
afterPC1[1]|=a;
}
Permute(afterPC1,PC2,result);
}
void CDES::TripleDES(CTableArray<ULONG> &Text, CTableArray<ULONG> &KEY1, CTableArray<ULONG> &KEY2,BOOL DIRECTION,CTableArray<ULONG> &result)
{
static CTableArray<ULONG> result2(8,8);
Crypto(Text,KEY1,DIRECTION,result);
Crypto(result,KEY2,!DIRECTION,result2);
Crypto(result2,KEY1,DIRECTION,result);
}
unsigned char * CDES::TripleDES(UCHAR text[], UCHAR key1[],UCHAR key2[], BOOL DIRECTION)
{
static CTableArray<ULONG> TEXT(8,8);
static CTableArray<ULONG> KEY1(8,8);
static CTableArray<ULONG> KEY2(8,8);
static CTableArray<ULONG> result(8,8);
memcpy(&TEXT[0],text,8);
memcpy(&KEY1[0],key1,8);
memcpy(&KEY2[0],key2,8);
TripleDES(TEXT,KEY1,KEY2,DIRECTION,result);
UCHAR *out=new UCHAR[8];
memcpy(out,&result[0],8);
return out;
}
void CDES::CBCDES(CTableArray<ULONG> &Text, CTableArray<ULONG> &KEY, BOOL DIRECTION,CTableArray<ULONG>&result)
{
if(DIRECTION==ENCRYPT)
{
Text[0]^=LastCipher[0];
Text[1]^=LastCipher[1];
Crypto(Text,KEY,DIRECTION,result);
LastCipher[0]=result[0];
LastCipher[1]=result[1];
}
else
{
ULONG L,R;
Crypto(Text,KEY,DIRECTION,result);
L=result[0];
R=result[1];
result[0]^=LastCipher[0];
result[1]^=LastCipher[1];
LastCipher[0]=L;
LastCipher[1]=R;
}
}
unsigned char * CDES::CBCDES(UCHAR text[], UCHAR key[], BOOL DIRECTION)
{
static CTableArray<ULONG> TEXT(8,8);
static CTableArray<ULONG> KEY(8,8);
static CTableArray<ULONG> result(8,8);
memcpy(&TEXT[0],text,8);
memcpy(&KEY[0],key,8);
CBCDES(TEXT,KEY,DIRECTION,result);
UCHAR *out=new UCHAR[8];
memcpy(out,&result[0],8);
return out;
}
CDES::resetCBC()
{
LastCipher[0]=LastCipher[1]=0;
}
void CDES::CBC3DES(CTableArray<ULONG> &Text, CTableArray<ULONG> &KEY1, CTableArray<ULONG> &KEY2, BOOL DIRECTION,CTableArray<ULONG> &result)
{
if(DIRECTION==ENCRYPT)
{
Text[0]^=LastCipher[0];
Text[1]^=LastCipher[1];
TripleDES(Text,KEY1,KEY2,DIRECTION,result);
LastCipher[0]=result[0];
LastCipher[1]=result[1];
}
else
{
ULONG L,R;
TripleDES(Text,KEY1,KEY2,DIRECTION,result);
L=result[0];
R=result[1];
result[0]^=LastCipher[0];
result[1]^=LastCipher[1];
LastCipher[0]=L;
LastCipher[1]=R;
}
}
unsigned char * CDES::CBC3DES(UCHAR text[], UCHAR key1[],UCHAR key2[], BOOL DIRECTION)
{
static CTableArray<ULONG> TEXT(8,8);
static CTableArray<ULONG> KEY1(8,8);
static CTableArray<ULONG> KEY2(8,8);
static CTableArray<ULONG> result(8,8);
memcpy(&TEXT[0],text,8);
memcpy(&KEY1[0],key1,8);
memcpy(&KEY2[0],key2,8);
CBC3DES(TEXT,KEY1,KEY2,DIRECTION,result);
UCHAR *out=new UCHAR[8];
memcpy(out,&result[0],8);
return out;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -