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

📄 diamond.cpp

📁 300种加密解密算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// diamond.cpp - modified by Wei Dai from:

/* diamond2.c - Encryption designed to exceed DES in security.
   This file and the Diamond2 and Diamond2 Lite Block Ciphers
   described herein are hereby dedicated to the Public Domain by the
   author and inventor, Michael Paul Johnson.  Feel free to use these
   for any purpose that is legally and morally right.  The names
   "Diamond2 Block Cipher" and "Diamond2 Lite Block Cipher" should only
   be used to describe the algorithms described in this file, to avoid
   confusion.

   Disclaimers:  the following comes with no warranty, expressed or
   implied.  You, the user, must determine the suitability of this
   information to your own uses.  You must also find out what legal
   requirements exist with respect to this data and programs using
   it, and comply with whatever valid requirements exist.
*/

#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);

⌨️ 快捷键说明

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