www.pudn.com > cryptology.rar > DES.h


//程序:DES加密解密雪崩效应分析,差分分析 
#include 
#include 
using namespace std; 
typedef bool eletype; 
#define ZERO false 
#define ONE true; 
 
class Des{ 
public: 
    Des(void); 
    Des(eletype* p , unsigned long p_len); 
    Des(Des& a); 
	~Des(); 
 
	void  operator =  (Des a); 
	void  operator >> (int n);//右移 
	void  operator << (int n);//左移 
	void  operator += (Des a); 
	void  operator ^= (Des a); 
    Des   operator ^  (Des a); 
	Des   operator +  (Des a); 
//	void  operator=(Des a ,int i); 
	 
	Des Encrpty(Des key);	//加密函数 
	Des Decrpty(Des key);   //解密函数 
 
	void  ByteToDes(char* In,int bits);     
	char* DesToByte();						 
 
	void IntToDes(int n,int len); 
 
	void  xuebeng(Des key, Des second,unsigned long* count); //统计雪崩效应 
	void  print(); 
	eletype* getptr(); 
	void Difference(Des plain1,Des plain2,int n,int* ND);    //差分分析 
	void RandonS();											 //随机产生S盒 
 
 
private: 
	eletype* IntToBit(unsigned int i); 
	unsigned int BitToInt(int n); 
 
 
	Des DesF(Des Keyi); 
	Des Enc(Des Keyi); 
	Des Key(int i); 
 
	Des Substitution(int n)	; 
	Des Permutation(int* ip,int n); 
 
	void LS(int round); 
	void RS(int n);//循环右移 
	 
 
private: 
	eletype* desptr; 
	unsigned long deslen; 
 
	static int IP[]; 
	static int IP_1[]; 
	static int pc_1[]; 
	static int pc_2[]; 
	static int E[]; 
	static int P[]; 
	static int S[10][4][16]; 
 
}; 
 
 
Des::Des(void) 
{ 
	desptr = NULL; 
	deslen = 0; 
} 
 
Des::Des(Des& a) 
{ 
	deslen = a.deslen; 
	desptr = new eletype[deslen]; 
 
	for(int i = 0 ; i < deslen ; i++) 
		desptr[i] = a.desptr[i]; 
	 
} 
 
Des::Des(eletype* p,unsigned long p_len) 
{ 
	deslen = p_len; 
	desptr = new eletype[deslen]; 
	for(int i = 0 ; i < deslen ; i++) 
		desptr[i] = p[i]; 
} 
 
Des::~Des() 
{ 
	deslen = 0; 
	delete [] desptr; 
} 
 
void Des::print() 
{ 
	cout<<"It's lenth is "<> (int n) 
{ 
	Des r; 
	int i,j; 
 
	r = *this; 
	j = 0; 
	if( deslen < n)  n = deslen; 
 
	for(i = 0 ; i < n ; i++) 
	{ 
		r.desptr[i] = ZERO; 
	} 
	for(i = n ; i < deslen ; i++,j++) 
	{ 
		r.desptr[i] = desptr[j]; 
	} 
	*this = r; 
} 
 
eletype* Des::getptr() 
{ 
	return desptr; 
} 
/**********加密函数。64位明文输入,64位密文输出。key为64位加密密钥**********/ 
Des Des::Encrpty(Des key ) 
{ 
 
	int i; 
	Des ki; 
	Des cipher(*this); 
 
	cipher = cipher.Permutation(IP,64); 
	key = key.Permutation(pc_1,56); 
	for(i = 0 ; i < 16; i++) 
	{ 
		ki = key.Key(i); 
		cipher = cipher.Enc(ki); 
	} 
 
	cipher.RS(32); 
 
	cipher = cipher.Permutation(IP_1,64); 
	return cipher; 
} 
 
/**********解密函数。64位密文输入,64位明文输出。key为64位加密密钥**********/ 
Des Des::Decrpty(Des key) 
{ 
	int i; 
	Des k[16]; 
	Des plain(*this); 
 
	plain = plain.Permutation(IP,64); 
 
	key = key.Permutation(pc_1,56); 
 
	for(i = 15 ; i >=0 ; i--) 
	{ 
		k[i] = key.Key(15-i); 
	} 
	for(i = 0 ; i < 16 ; i++) 
	{ 
		plain = plain.Enc(k[i]);//change 
	} 
	 
	plain.RS(32); 
 
	plain = plain.Permutation(IP_1,64); 
	 
	return plain; 
} 
void Des::ByteToDes(char* In,int bits) 
{//in要转化的字符数组。bit转化后的位数。 
	int i,j; 
	deslen = bits; 
	desptr = new eletype[deslen]; 
	for(j = 0 ; j < bits/8 ; j++) 
	{ 
		for(i = 8*j+0 ; i < 8*j+8 ; i++) 
			desptr[8*j-(i%8)+7] = (In[i>>3]>>(i&7))&1; 
	} 
} 
 
char* Des::DesToByte() 
{ 
	int i,j,res; 
	char* out; 
	out = new char[deslen/8]; 
 
	for(j = 0 ; j < deslen/8 ; j++) 
	{ 
		res=0; 
		for(i = 8*j+0 ; i < 8*j+8 ; i++) 
			res=res*2+desptr[i]; 
		out[j]=res; 
	} 
	return out; 
} 
	 
//------------------------------------------------------------------------ 
//pravite: 
/**********置换函数,ip为置换盒,可以取IP,IP_1,E,P。n为输出位数,分别为64,64,48,32*********/ 
Des Des::Permutation(int* ip,int n) 
{ 
	eletype* p0 = new eletype[n]; 
	int i,j; 
 
	for( i = 0 ; i < n ; i++) 
	{ 
		j = ip[i]; 
		p0[i] = this->desptr[j]; 
	} 
 
	Des a(p0,n); 
	 
	return a; 
} 
 
/**********S代换。输入6比特,输出4比特。n为盒号(0-7)。**********/ 
Des Des::Substitution(int n) 
{//question 
	unsigned int i,j,m; 
	eletype* t; 
  
    i = desptr[0] * 2 + desptr[5]; 
 
    *this<<1; 
	j = this->BitToInt(4); 
	*this<<5; 
    m = S[n][i][j]; 
	t = this->IntToBit(m); 
	Des tmp(t,4); 
 
	return tmp; 
} 
 
/**********左移调度函数。28位输入输出。round为轮数(0-15)**********/ 
void Des::LS(int round) 
{ 
	int i; 
	const int n = 28; 
	Des tmp(*this); 
	if(round >= 0 && round < 16) 
	{ 
		switch(round) 
		{ 
			case 0:    case 1:		case 8:		case 15: 
				for(i = 0 ; i < n-1 ; i++) 
				{ 
					desptr[i] = tmp.desptr[i+1]; 
				} 
				desptr[i] = tmp.desptr[0]; 
			break; 
 
			default: 
				for(i = 0 ; i < n-2 ; i++) 
				{ 
					desptr[i] = tmp.desptr[i+2]; 
				} 
				desptr[26] = tmp.desptr[0]; 
				desptr[27] = tmp.desptr[1]; 
			break; 
		} 
	} 
} 
void Des::RS(int n) 
{//循环右移n位 
	Des a(*this); 
	int i; 
	for(i = 0 ; i < n ; i++ ) 
	{ 
		desptr[i] = a.desptr[deslen-n+i]; 
	} 
	for(i = n ; i < deslen ; i++) 
	{ 
		desptr[i] = a.desptr[i-n]; 
	} 
} 
	 
//------------------------------------------------------------------------------ 
eletype* Des::IntToBit(unsigned int i) 
{ 
	eletype* b; 
	b = new eletype[4]; 
 
	for(int k = 0 ; k < 4 ; k++) 
	    b[k] = ZERO; 
AGAIN: 
	if(i < 4) 
	{ 
		switch(i) 
		{ 
			case 0:										break; 
			case 1:		b[3] = 1;						break; 
			case 2:		b[2] = 1;						break; 
			case 3:		b[2] = 1;		b[3] = 1;		break; 
		} 
		return b; 
	} 
	else if( i<8 ) 
	{ 
		b[1] = 1; 
		i = i-4; 
		goto AGAIN; 
	} 
	else if(i<16 ) 
	{ 
		b[0] = 1; 
		i = i-8; 
		goto AGAIN; 
	} 
	else  
		return NULL; 
} 
void Des::IntToDes(int n,int len) 
{//将一个数字n转成len比特 
	int a = n; 
	int k; 
	int i = len-1; 
	deslen = len; 
	desptr = new eletype [len] ; 
	for( k = 0 ; k < len ; k++) 
	{ 
		desptr[k] = false; 
	} 
	while( a != 0 ) 
	{ 
		desptr[i--] = a % 2;  
		a = a / 2; 
	} 
} 
unsigned int Des::BitToInt(int n) 
{ 
	unsigned int a = 0; 
	int i; 
	for(i = 0 ; i < n ; i++) 
	{ 
		a = a*2; 
		if(desptr[i]) 
			a++; 
	} 
 
	return a; 
} 
 
/***********F函数,32位输入输出。仅被Enc函数调用。Keyi为48位**************/ 
Des Des::DesF(Des Keyi) 
{ 
    int k; 
	Des c1; 
	Des r; 
 
	c1 = (*this).Permutation(E,48); 
	c1 ^= Keyi; 
	for(k = 0 ; k < 8 ; k++) 
	{ 
		r += c1.Substitution(k); 
	//	c1<<6; 
	} 
 
	c1 = r.Permutation(P,32); 
 
	return c1; 
} 
 
/**********单轮加密解密函数,64位输出输出。仅被Encrpty和Decrpty调用。Keyi为48位**********/ 
Des Des::Enc(Des Keyi) 
{ 
	Des r(this->desptr+32*sizeof(eletype),32); 
	Des l(this->desptr,32); 
 //   r<<32; 
	Des res(r.desptr,32); 
 //	r=res; 
  
	r=r.DesF(Keyi); 
	r^=l; 
	res+=r; 
	return res; 
} 
 
/***********顺序产生每一轮的子密钥,56位输入输出。i为轮数,从零开始。*************/ 
Des Des::Key(int i) 
{//产生每一轮子密钥56位输入输出 
	Des r(this->desptr+28*sizeof(eletype),28); 
	Des l(this->desptr,28); 
//	Des k; 
 
	r.LS(i); 
	l.LS(i); 
 
    *this = l+r; 
   	 
	return   this->Permutation(pc_2,48); 
 
}	 
 
unsigned long  countDiff (bool* first , bool* second , int n ) 
{//统计两个字符串中不同的个数 
	int i ; 
	unsigned long count = 0 ;  
	 
	for( i = 0 ; i < n ; i ++) 
	{ 
		if(first[i] != second[i] ) 
			count ++; 
	} 
	return count; 
} 
void Des::xuebeng(Des key, Des second,unsigned long* count) 
{//count[]数组共18个元素 第一个用来记录IP置换后不同个数,最后一个用来进行IP_1置换后不同的个数。 
	int i; 
 
	Des ki; 
	Des cipher1(*this); 
	Des cipher2 =  second; 
 
	cipher1 = cipher1.Permutation(IP,64); 
	cipher2 = cipher2.Permutation(IP,64); 
	key = key.Permutation(pc_1,56); 
	count[0] = count[0]+countDiff(cipher1.desptr, cipher2.desptr, deslen); 
	 
	for(i = 0 ; i < 16; i++) 
	{ 
		ki = key.Key(i); 
		cipher1 = cipher1.Enc(ki); 
		cipher2 = cipher2.Enc(ki);  
		int j=	countDiff(cipher1.desptr , cipher2.desptr , deslen); 
				count[i+1] = count[i+1]+j; 
	} 
 
	//cipher.RS(32); 
 
	cipher1 = cipher1.Permutation(IP_1,64); 
	cipher2 = cipher2.Permutation(IP_1,64); 
 
	count[17] = count[17] + countDiff(cipher1.desptr, cipher2.desptr, deslen); 
 
} 
void Des::Difference(Des plain1,Des plain2,int n,int* ND) 
{// i为第几个S盒 plain1,plain2 均为6位 
	int i,j; 
	Des y1,y2; 
	 
	y1 = plain1;//x 
	y2 = plain2;//x* 
 
	y1 = y1.Substitution(n);//y 
 
 
	y2 = y2.Substitution(n);//y* 
 
	y1 ^= y2;//y' 
 
	y2 = plain1^plain2;//x' 
 
	i = y2.BitToInt(6);//i 
	j = y1.BitToInt(4);//j 
	ND[i*16+j] ++; 
	 
} 
 
void Des::RandonS() 
{ 
	srand(time(NULL)); 
	int i,j; 
	for(i = 0; i < 4 ; i ++) 
	{ 
		for(j = 0 ; j < 16 ; j++ ) 
		{ 
			S[8][i][j] = rand() % 16; 
			cout<