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

📄 blowfish.cpp

📁 一个16为的blowfish的加密算法的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	memcpy(m_auiS, scm_auiInitS, sizeof m_auiS);
	//Load P boxes with key bytes
	const unsigned char* p = aucLocalKey;
	unsigned int x=0;
	//Repeatedly cycle through the key bits until the entire P array has been XORed with key bits
	int iCount = 0;
	for(i=0; i<18; i++)
	{
		x=0;
		for(int n=4; n--; )
		{
			int iVal = (int)(*p);
			x <<= 8;
			x |= *(p++);
			iCount++;
			if(iCount == keysize)
			{
				//All bytes used, so recycle bytes 
				iCount = 0;
				p = aucLocalKey;
			}
		}
		m_auiP[i] ^= x;
	}
	//Reflect P and S boxes through the evolving Blowfish
	SBlock block(0UL,0UL); //all-zero block
	for(i=0; i<18; )
		Encrypt(block), m_auiP[i++] = block.m_uil, m_auiP[i++] = block.m_uir;
	for(j=0; j<4; j++)
		for(int k=0; k<256; )
			Encrypt(block), m_auiS[j][k++] = block.m_uil, m_auiS[j][k++] = block.m_uir;
}

//Sixteen Round Encipher of Block
void CBlowFish::Encrypt(SBlock& block)
{
	unsigned int uiLeft = block.m_uil;
	unsigned int uiRight = block.m_uir;
	uiLeft ^= m_auiP[0];
	uiRight ^= F(uiLeft)^m_auiP[1]; uiLeft ^= F(uiRight)^m_auiP[2];
	uiRight ^= F(uiLeft)^m_auiP[3]; uiLeft ^= F(uiRight)^m_auiP[4];
	uiRight ^= F(uiLeft)^m_auiP[5]; uiLeft ^= F(uiRight)^m_auiP[6];
	uiRight ^= F(uiLeft)^m_auiP[7]; uiLeft ^= F(uiRight)^m_auiP[8];
	uiRight ^= F(uiLeft)^m_auiP[9]; uiLeft ^= F(uiRight)^m_auiP[10];
	uiRight ^= F(uiLeft)^m_auiP[11]; uiLeft ^= F(uiRight)^m_auiP[12];
	uiRight ^= F(uiLeft)^m_auiP[13]; uiLeft ^= F(uiRight)^m_auiP[14];
	uiRight ^= F(uiLeft)^m_auiP[15]; uiLeft ^= F(uiRight)^m_auiP[16];
	uiRight ^= m_auiP[17];
	block.m_uil = uiRight;
	block.m_uir = uiLeft;
}

//Sixteen Round Decipher of SBlock
void CBlowFish::Decrypt(SBlock& block)
{
	unsigned int uiLeft = block.m_uil;
	unsigned int uiRight = block.m_uir;
	uiLeft ^= m_auiP[17];
	uiRight ^= F(uiLeft)^m_auiP[16]; uiLeft ^= F(uiRight)^m_auiP[15];
	uiRight ^= F(uiLeft)^m_auiP[14]; uiLeft ^= F(uiRight)^m_auiP[13];
	uiRight ^= F(uiLeft)^m_auiP[12]; uiLeft ^= F(uiRight)^m_auiP[11];
	uiRight ^= F(uiLeft)^m_auiP[10]; uiLeft ^= F(uiRight)^m_auiP[9];
	uiRight ^= F(uiLeft)^m_auiP[8]; uiLeft ^= F(uiRight)^m_auiP[7];
	uiRight ^= F(uiLeft)^m_auiP[6]; uiLeft ^= F(uiRight)^m_auiP[5];
	uiRight ^= F(uiLeft)^m_auiP[4]; uiLeft ^= F(uiRight)^m_auiP[3];
	uiRight ^= F(uiLeft)^m_auiP[2]; uiLeft ^= F(uiRight)^m_auiP[1];
	uiRight ^= m_auiP[0];
	block.m_uil = uiRight;
	block.m_uir = uiLeft;
}

//Semi-Portable Byte Shuffling
inline void BytesToBlock(unsigned char const* p, SBlock& b)
{
	unsigned int y;
	//Left
	b.m_uil = 0;
	y = *p++;
	y <<= 24;
	b.m_uil |= y;
	y = *p++;
	y <<= 16;
	b.m_uil |= y;
	y = *p++;
	y <<= 8;
	b.m_uil |= y;
	y = *p++;
	b.m_uil |= y;
	//Right
	b.m_uir = 0;
	y = *p++;
	y <<= 24;
	b.m_uir |= y;
	y = *p++;
	y <<= 16;
	b.m_uir |= y;
	y = *p++;
	y <<= 8;
	b.m_uir |= y;
	y = *p++;
	b.m_uir |= y;
}

inline void BlockToBytes(SBlock const& b, unsigned char* p)
{
	unsigned int y;
	//Right
	y = b.m_uir;
	*--p = Byte(y);
	y = b.m_uir >> 8;
	*--p = Byte(y);
	y = b.m_uir >> 16;
	*--p = Byte(y);
	y = b.m_uir >> 24;
	*--p = Byte(y);
	//Left
	y = b.m_uil;
	*--p = Byte(y);
	y = b.m_uil >> 8;
	*--p = Byte(y);
	y = b.m_uil >> 16;
	*--p = Byte(y);
	y = b.m_uil >> 24;
	*--p = Byte(y);
}

//Encrypt Buffer in Place
//Returns false if n is multiple of 8
void CBlowFish::Encrypt(unsigned char* buf, size_t n, int iMode)
{
	//Check the buffer's length - should be > 0 and multiple of 8
	if((n==0)||(n%8!=0))
		throw exception("Incorrect buffer length");
	SBlock work;
	if(iMode == CBC) //CBC mode, using the Chain
	{
		SBlock chain(m_oChain);
		for(; n >= 8; n -= 8)
		{
			BytesToBlock(buf, work);
			work ^= chain;
			Encrypt(work);
			chain = work;
			BlockToBytes(work, buf+=8);
		}
	}
	else if(iMode == CFB) //CFB mode, using the Chain
	{
		SBlock chain(m_oChain);
		for(; n >= 8; n -= 8)
		{
			Encrypt(chain);
			BytesToBlock(buf, work);
			work ^= chain;
			chain = work;
			BlockToBytes(work, buf+=8);
		}
	}
	else //ECB mode, not using the Chain
	{
		for(; n >= 8; n -= 8)
		{
			BytesToBlock(buf, work);
			Encrypt(work);
			BlockToBytes(work, buf+=8);
		}
	}
}

//Decrypt Buffer in Place
//Returns false if n is multiple of 8
void CBlowFish::Decrypt(unsigned char* buf, size_t n, int iMode)
{
	//Check the buffer's length - should be > 0 and multiple of 8
	if((n==0)||(n%8!=0))
		throw exception("Incorrect buffer length");
	SBlock work;
	if(iMode == CBC) //CBC mode, using the Chain
	{
		SBlock crypt, chain(m_oChain);
		for(; n >= 8; n -= 8)
		{
			BytesToBlock(buf, work);
			crypt = work;
			Decrypt(work);
			work ^= chain;
			chain = crypt;
			BlockToBytes(work, buf+=8);
		}
	}
	else if(iMode == CFB) //CFB mode, using the Chain, not using Decrypt()
	{
		SBlock crypt, chain(m_oChain);
		for(; n >= 8; n -= 8)
		{
			BytesToBlock(buf, work);
			Encrypt(chain);
			crypt = work;
			work ^= chain;
			chain = crypt;
			BlockToBytes(work, buf+=8);
		}
	}
	else //ECB mode, not using the Chain
	{
		for(; n >= 8; n -= 8)
		{
			BytesToBlock(buf, work);
			Decrypt(work);
			BlockToBytes(work, buf+=8);
		}
	}
}

//Encrypt from Input Buffer to Output Buffer
//Returns false if n is multiple of 8
void CBlowFish::Encrypt(const unsigned char* in, unsigned char* out, size_t n, int iMode)
{
	//Check the buffer's length - should be > 0 and multiple of 8
	if((n==0)||(n%8!=0))
		throw exception("Incorrect buffer length");
	SBlock work;
	if(iMode == CBC) //CBC mode, using the Chain
	{
		SBlock chain(m_oChain);
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(in, work);
			work ^= chain;
			Encrypt(work);
			chain = work;
			BlockToBytes(work, out+=8);
		}
	}
	else if(iMode == CFB) //CFB mode, using the Chain
	{
		SBlock chain(m_oChain);
		for(; n >= 8; n -= 8, in += 8)
		{
			Encrypt(chain);
			BytesToBlock(in, work);
			work ^= chain;
			chain = work;
			BlockToBytes(work, out+=8);
		}
	}
	else //ECB mode, not using the Chain
	{
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(in, work);
			Encrypt(work);
			BlockToBytes(work, out+=8);
		}
	}
}

//Decrypt from Input Buffer to Output Buffer
//Returns false if n is multiple of 8
void CBlowFish::Decrypt(const unsigned char* in, unsigned char* out, size_t n, int iMode)
{
	//Check the buffer's length - should be > 0 and multiple of 8
	if((n==0)||(n%8!=0))
		throw exception("Incorrect buffer length");
	SBlock work;
	if(iMode == CBC) //CBC mode, using the Chain
	{
		SBlock crypt, chain(m_oChain);
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(in, work);
			crypt = work;
			Decrypt(work);
			work ^= chain;
			chain = crypt;
			BlockToBytes(work, out+=8);
		}
	}
	else if(iMode == CFB) //CFB mode, using the Chain, not using Decrypt()
	{
		SBlock crypt, chain(m_oChain);
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(in, work);
			Encrypt(chain);
			crypt = work;
			work ^= chain;
			chain = crypt;
			BlockToBytes(work, out+=8);
		}
	}
	else //ECB mode, not using the Chain
	{
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(in, work);
			Decrypt(work);
			BlockToBytes(work, out+=8);
		}
	}
}

⌨️ 快捷键说明

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