⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diamond.cpp

📁 各种加密算法的集合
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "pch.h" 
#include "diamond.h" 
 
NAMESPACE_BEGIN(CryptoPP) 
 
class Diamond2SboxMaker 
{ 
public: 
	Diamond2SboxMaker(const byte *external_key, unsigned int key_size, 
					 unsigned int rounds, bool lite); 
 
	void MakeSbox(byte *sbox, CipherDir direction); 
 
private: 
	unsigned int keyrand(unsigned int max_value, const byte *prevSbox); 
	void makeonebox(byte *s, unsigned int i, unsigned int j); 
 
	CRC32 crc; 
	const byte *const key; 
	const unsigned keysize; 
	unsigned keyindex; 
	const unsigned numrounds; 
	const unsigned roundsize; // Number of bytes in one round of substitution boxes 
	const unsigned blocksize; 
}; 
 
Diamond2SboxMaker::Diamond2SboxMaker(const byte *external_key, unsigned int key_size, unsigned int rounds, 
								   bool lite) 
	: key(external_key), 
	  keysize(key_size), 
	  keyindex(0), 
	  numrounds(rounds), 
	  roundsize(lite ? 2048 : 4096), 
	  blocksize(lite ? 8 : 16) 
{ 
	assert((rounds * blocksize) <= 255); 
} 
 
// Returns uniformly distributed pseudorandom value based on key[], sized keysize 
inline unsigned int Diamond2SboxMaker::keyrand(unsigned int max_value, const byte *prevSbox) 
{ 
	if (!max_value) return 0; 
 
	unsigned int mask, prandvalue, i; 
 
	// Create a mask to get the minimum number of  
	// bits to cover the range 0 to max_value. 
	for (i=max_value, mask=0; i > 0; i = i >> 1) 
		mask = (mask << 1) | 1; 
 
	assert(i==0); 
	do 
	{ 
		if (prevSbox) 
			crc.UpdateByte(prevSbox[key[keyindex++]]); 
		else 
			crc.UpdateByte(key[keyindex++]); 
 
		if (keyindex >= keysize) 
		{ 
			keyindex = 0;   /* Recycle thru the key */ 
			crc.UpdateByte(byte(keysize)); 
			crc.UpdateByte(byte(keysize >> 8)); 
		} 
		prandvalue = (unsigned int)~crc.GetCrc() & mask; 
		if ((++i>97) && (prandvalue > max_value))   /* Don't loop forever. */ 
			prandvalue -= max_value;                /* Introduce negligible bias. */ 
	} 
	while (prandvalue > max_value); /* Discard out of range values. */ 
	return prandvalue; 
} 
 
void Diamond2SboxMaker::makeonebox(byte *s, unsigned int i, unsigned int j) 
{ 
	bool filled[256]; 
	byte *sbox = s + (roundsize*i) + (256*j); 
	byte *prevSbox = (i||j) ? sbox-256 : 0; 
 
	unsigned m; 
	for (m = 0; m < 256; m++)   /* The filled array is used to make sure that */ 
		filled[m] = false;      /* each byte of the array is filled only once. */ 
	for (int n = 255; n >= 0 ; n--) /* n counts the number of bytes left to fill */ 
	{ 
		// pos is the position among the UNFILLED 
		// components of the s array that the number n should be placed. 
		unsigned pos = keyrand(n, prevSbox);    
		unsigned p=0; 
		while (filled[p]) p++; 
		for (m=0; m<pos; m++) 
		{ 
			p++; 
			while (filled[p]) p++; 
		} 
		assert(p<256); 
		sbox[p] = n; 
		filled[p] = true; 
	} 
} 
 
void Diamond2SboxMaker::MakeSbox(byte *s, CipherDir direction) 
{ 
	unsigned int i, j, k; 
 
	for (i = 0; i < numrounds; i++) 
		for (j = 0; j < blocksize; j++) 
			makeonebox(s, i, j); 
 
	if (direction==DECRYPTION) 
	{ 
		SecByteBlock si(numrounds * roundsize); 
		for (i = 0; i < numrounds; i++) 
			for (j = 0; j < blocksize; j++) 
				for (k = 0; k < 256; k++) 
					*(si + (roundsize * i) + (256 * j) + *(s + (roundsize * i) + (256 * j) + k)) = k; 
		memcpy(s, si, numrounds * roundsize); 
	} 
} 
 
Diamond2Base::Diamond2Base(const byte *key, unsigned int key_size, 
				 unsigned int rounds, CipherDir direction) 
	: numrounds(rounds), 
	  s(numrounds * ROUNDSIZE) 
{ 
	Diamond2SboxMaker m(key, key_size, rounds, false); 
	m.MakeSbox(s, direction); 
} 
 
inline void Diamond2Base::substitute(int round, byte *y) const 
{ 
	const byte *sbox = s + (ROUNDSIZE*round); 
	y[0] = sbox[0*256+y[0]]; 
	y[1] = sbox[1*256+y[1]]; 
	y[2] = sbox[2*256+y[2]]; 
	y[3] = sbox[3*256+y[3]]; 
	y[4] = sbox[4*256+y[4]]; 
	y[5] = sbox[5*256+y[5]]; 
	y[6] = sbox[6*256+y[6]]; 
	y[7] = sbox[7*256+y[7]]; 
	y[8] = sbox[8*256+y[8]]; 
	y[9] = sbox[9*256+y[9]]; 
	y[10] = sbox[10*256+y[10]]; 
	y[11] = sbox[11*256+y[11]]; 
	y[12] = sbox[12*256+y[12]]; 
	y[13] = sbox[13*256+y[13]]; 
	y[14] = sbox[14*256+y[14]]; 
	y[15] = sbox[15*256+y[15]]; 
} 
 
#ifdef DIAMOND_USE_PERMTABLE 
 
inline void Diamond2Base::permute(byte *a) 
{ 
#ifdef IS_LITTLE_ENDIAN 
	word32 temp0     = (a[0] | (word32(a[10])<<24)) & 0x80000001; 
#else 
	word32 temp0     = ((word32(a[0])<<24) | a[10]) & 0x01000080; 
#endif 
		   temp0    |=                      permtable[0][a[1]] | 
					   permtable[1][a[2]] | permtable[2][a[3]] | 
					   permtable[3][a[4]] | permtable[4][a[5]] | 
					   permtable[5][a[6]] | permtable[6][a[7]] | 
					   permtable[7][a[8]] | permtable[8][a[9]]; 
 
#ifdef IS_LITTLE_ENDIAN 
	word32 temp1     = (a[4] | (word32(a[14])<<24)) & 0x80000001; 
#else 
	word32 temp1     = ((word32(a[4])<<24) | a[14]) & 0x01000080; 
#endif 
		   temp1    |=                      permtable[0][a[5]] | 
					   permtable[1][a[6]] | permtable[2][a[7]] | 
					   permtable[3][a[8]] | permtable[4][a[9]] | 
					   permtable[5][a[10]] | permtable[6][a[11]] | 
					   permtable[7][a[12]] | permtable[8][a[13]]; 
 
#ifdef IS_LITTLE_ENDIAN 
	word32 temp2     = (a[8] | (word32(a[2])<<24)) & 0x80000001; 
#else 
	word32 temp2     = ((word32(a[8])<<24) | a[2]) & 0x01000080; 
#endif 
		   temp2    |=                       permtable[0][a[9]] | 
					   permtable[1][a[10]] | permtable[2][a[11]] | 
					   permtable[3][a[12]] | permtable[4][a[13]] | 
					   permtable[5][a[14]] | permtable[6][a[15]] | 
					   permtable[7][a[0]] | permtable[8][a[1]]; 
 
#ifdef IS_LITTLE_ENDIAN 
	word32 temp3     = (a[12] | (word32(a[6])<<24)) & 0x80000001; 
#else 
	word32 temp3     = ((word32(a[12])<<24) | a[6]) & 0x01000080; 
#endif 
	((word32 *)a)[3] = temp3 |               permtable[0][a[13]] | 
					   permtable[1][a[14]] | permtable[2][a[15]] | 
					   permtable[3][a[0]] | permtable[4][a[1]] | 
					   permtable[5][a[2]] | permtable[6][a[3]] | 
					   permtable[7][a[4]] | permtable[8][a[5]]; 
 
	((word32 *)a)[0] = temp0; 
	((word32 *)a)[1] = temp1; 
	((word32 *)a)[2] = temp2; 
} 
 
inline void Diamond2Base::ipermute(byte *a) 
{ 
#ifdef IS_LITTLE_ENDIAN 
	word32 temp0     = (a[9] | (word32(a[3])<<24)) & 0x01000080; 
#else 
	word32 temp0     = ((word32(a[9])<<24) | a[3]) & 0x80000001; 
#endif 
		   temp0    |=                      ipermtable[0][a[2]] | 
					   ipermtable[1][a[1]] | ipermtable[2][a[0]] | 
					   ipermtable[3][a[15]] | ipermtable[4][a[14]] | 
					   ipermtable[5][a[13]] | ipermtable[6][a[12]] | 
					   ipermtable[7][a[11]] | ipermtable[8][a[10]]; 
 
#ifdef IS_LITTLE_ENDIAN 
	word32 temp1     = (a[13] | (word32(a[7])<<24)) & 0x01000080; 
#else 
	word32 temp1     = ((word32(a[13])<<24) | a[7]) & 0x80000001; 
#endif 
		   temp1    |=                      ipermtable[0][a[6]] | 
					   ipermtable[1][a[5]] | ipermtable[2][a[4]] | 
					   ipermtable[3][a[3]] | ipermtable[4][a[2]] | 
					   ipermtable[5][a[1]] | ipermtable[6][a[0]] | 
					   ipermtable[7][a[15]] | ipermtable[8][a[14]]; 
 
#ifdef IS_LITTLE_ENDIAN 
	word32 temp2     = (a[1] | (word32(a[11])<<24)) & 0x01000080; 
#else 
	word32 temp2     = ((word32(a[1])<<24) | a[11]) & 0x80000001; 
#endif 
		   temp2    |=                      ipermtable[0][a[10]] | 
					   ipermtable[1][a[9]] | ipermtable[2][a[8]] | 
					   ipermtable[3][a[7]] | ipermtable[4][a[6]] | 
					   ipermtable[5][a[5]] | ipermtable[6][a[4]] | 
					   ipermtable[7][a[3]] | ipermtable[8][a[2]]; 
 
#ifdef IS_LITTLE_ENDIAN 
	word32 temp3     = (a[5] | (word32(a[15])<<24)) & 0x01000080; 
#else 
	word32 temp3     = ((word32(a[5])<<24) | a[15]) & 0x80000001; 
#endif 
	((word32 *)a)[3] = temp3 |               ipermtable[0][a[14]] | 
					   ipermtable[1][a[13]] | ipermtable[2][a[12]] | 
					   ipermtable[3][a[11]] | ipermtable[4][a[10]] | 
					   ipermtable[5][a[9]] | ipermtable[6][a[8]] | 
					   ipermtable[7][a[7]] | ipermtable[8][a[6]]; 
 
	((word32 *)a)[0] = temp0; 
	((word32 *)a)[1] = temp1; 
	((word32 *)a)[2] = temp2; 
} 
 
#else // DIAMOND_USE_PERMTABLE 
 
inline void Diamond2Base::permute(byte *x) 
{ 
	byte y[16]; 
 
	y[0] = (x[0] & 1) | (x[1] & 2) | (x[2] & 4) | 
			(x[3] & 8) | (x[4] & 16) | (x[5] & 32) | 
			(x[6] & 64) | (x[7] & 128); 
	y[1] = (x[1] & 1) | (x[2] & 2) | (x[3] & 4) | 
			(x[4] & 8) | (x[5] & 16) | (x[6] & 32) | 
			(x[7] & 64) | (x[8] & 128); 
	y[2] = (x[2] & 1) | (x[3] & 2) | (x[4] & 4) | 
			(x[5] & 8) | (x[6] & 16) | (x[7] & 32) | 
			(x[8] & 64) | (x[9] & 128); 
	y[3] = (x[3] & 1) | (x[4] & 2) | (x[5] & 4) | 
			(x[6] & 8) | (x[7] & 16) | (x[8] & 32) | 
			(x[9] & 64) | (x[10] & 128); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -