📄 blowfish.cpp
字号:
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 + -