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

📄 aes.cpp

📁 cRijndael - Advanced Encryption Standard (AES)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	else
		return STATE_OK;
}

// Go back one layer
int CAES::Back ()
{
		// Make sure the key is initialized first
	if (!m_bKeyInit)
		return STATE_IDLE;

	if (STATE_ENCRYPT == m_eState)
	{
		if (0 < m_iRound)
		{
			// Operate depending on last rounds layer
			switch (m_eLayer)
			{
			case ARK:	// Do ARK Inverse
				m_iRound--; //Need to decriment the round first before doing
							//ARK, since the ARK done before was from the 
							//previous round!
				AddRoundKey(m_eState);
				if(0 == m_iRound)
					m_eLayer = NC;
				else
					m_eLayer = MC;
				break;
			case BS:	// Do BS Inverse
				InvByteSub();
				m_eLayer = ARK;
				break;
			case SR:	// Do SR Inverse
				InvShiftRow();
				m_eLayer = BS;
				break;
			case MC:	// Do MC Inverse
				InvMixColumn();
				m_eLayer = SR;
				break;
			default:
				return STATE_ERR;
			}
		}
	}
	else 
	if (STATE_DECRYPT == m_eState)
	{
		if (0 < m_iRound)
		{
			// Operate depending on last rounds layer
			switch (m_eLayer)
			{
			case ARK:	// Do ARK
				m_iRound--;
				AddRoundKey(m_eState);
				if(m_iRound == 0)
					m_eLayer = NC;
				else
					m_eLayer = IMC;
				break;
			case IBS:	// Do BS
				ByteSub();
				m_eLayer = ARK;
				break;
			case ISR:	// Do SR
				ShiftRow();
				m_eLayer = IBS;
				break;
			case IMC:	// Do MC
				MixColumn();
				m_eLayer = ISR;
				break;
			default:
				return STATE_ERR;
			}
		}
	}
	else
		return STATE_IDLE;

	if (0 == m_iRound) // We are done
		return STATE_DONE;
	else
		return STATE_OK;
}

// Complete the current cipher process
int CAES::Complete ()
{
	int ret;

	while(STATE_OK == (ret = Step()));
	
	return ret;
}

// Reset the current cipher process
int CAES::Reset ()
{
	int ret;

	while(STATE_OK == (ret = Back()));
	
	return ret;
}

// Perform the AddRoundKey Transformation
//  mode - either STATE_ENCRYPT or STATE_DECRYPT
void CAES::AddRoundKey(int mode)
{
	MBYTE key[BC][4];	// General Round Key
	int *pk;			// Pointer to round Key

	// Get the correct key and round
	if (STATE_ENCRYPT == mode)
		pk = m_iKe[m_iRound];
	else
		pk = m_iKd[m_iRound];
	
	// Convert key into usable chunks
	for (int i=0; i < BC; i++)
	{
		key[i][0] = (MBYTE)((pk[i] >> 24) & 0xff);
		key[i][1] = (MBYTE)((pk[i] >> 16) & 0xff);
		key[i][2] = (MBYTE)((pk[i] >> 8) & 0xff);
		key[i][3] = (MBYTE)(pk[i] & 0xff);
	}

	// Add Round Key
	for (i=0; i < BLOCK_SIZE; i++)
		m_byData[i/BC][i%BC] ^= key[i/BC][i%BC];
}

// Perform the ByteSyb Transformation
void CAES::ByteSub()
{
	for (int i=0; i < BLOCK_SIZE; i++)
		m_byData[i/BC][i%4] = sm_S[(m_byData[i/BC][i%4])];
}

// Perform the ShiftRow Transformation
void CAES::ShiftRow()
{
	MBYTE tmp[4][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; 

	tmp[0][0] = m_byData[0][0];
	tmp[1][0] = m_byData[1][0];
	tmp[2][0] = m_byData[2][0];
	tmp[3][0] = m_byData[3][0];
	tmp[0][1] = m_byData[1][1];
	tmp[1][1] = m_byData[2][1];
	tmp[2][1] = m_byData[3][1];
	tmp[3][1] = m_byData[0][1];
	tmp[0][2] = m_byData[2][2];
	tmp[1][2] = m_byData[3][2];
	tmp[2][2] = m_byData[0][2];
	tmp[3][2] = m_byData[1][2];
	tmp[0][3] = m_byData[3][3];
	tmp[1][3] = m_byData[0][3];
	tmp[2][3] = m_byData[1][3];
	tmp[3][3] = m_byData[2][3];

/*	for (int i = 0; i < BLOCK_SIZE; i++)
		tmp[i%BC][i/4] = m_byData[((sm_shifts[0][i/BC][0]+(i/BC))%BC)][i/4];
*/	for (int i = 0; i < BLOCK_SIZE; i++)
		m_byData[i/BC][i%4] = tmp[i/BC][i%4];
}

// Perform the MixColumn Transformation
void CAES::MixColumn()
{
	MBYTE mat[4][4] = {{0x02, 0x03, 0x01, 0x01},
					  {0x01, 0x02, 0x03, 0x01},
					  {0x01, 0x01, 0x02, 0x03},
					  {0x03, 0x01, 0x01, 0x02}};

	MBYTE tmp[4][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; 

	for (int i = 0; i < BC; i++)
	{
		GFMatMul(m_byData[i], mat, tmp[i]);
	}
	
	for (int j = 0; j < BLOCK_SIZE; j++)
		m_byData[j/BC][j%4] = tmp[j/BC][j%4];
}

// Perform the InvByteSub Transformation
void CAES::InvByteSub()
{
	for (int i=0; i < BLOCK_SIZE; i++)
		m_byData[i/BC][i%4] = sm_Si[(m_byData[i/BC][i%4])];
}

// Perform the InvShiftRow Transformation
void CAES::InvShiftRow()
{
	MBYTE tmp[4][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};

	tmp[0][0] = m_byData[0][0];
	tmp[1][0] = m_byData[1][0];
	tmp[2][0] = m_byData[2][0];
	tmp[3][0] = m_byData[3][0];
	tmp[0][1] = m_byData[3][1];
	tmp[1][1] = m_byData[0][1];
	tmp[2][1] = m_byData[1][1];
	tmp[3][1] = m_byData[2][1];
	tmp[0][2] = m_byData[2][2];
	tmp[1][2] = m_byData[3][2];
	tmp[2][2] = m_byData[0][2];
	tmp[3][2] = m_byData[1][2];
	tmp[0][3] = m_byData[1][3];
	tmp[1][3] = m_byData[2][3];
	tmp[2][3] = m_byData[3][3];
	tmp[3][3] = m_byData[0][3];

/*	for (int i = 0; i < BLOCK_SIZE; i++)
		tmp[i%BC][i/4] = m_byData[((sm_shifts[0][i/BC][0]+(i/BC))%BC)][i/4];*/
	for (int i = 0; i < BLOCK_SIZE; i++)
		m_byData[i/BC][i%4] = tmp[i/BC][i%4];
}

// Perform the InvMixColumn Transformation
void CAES::InvMixColumn()
{
	MBYTE mat[4][4] = {{0x0e, 0x0b, 0x0d, 0x09},
					  {0x09, 0x0e, 0x0b, 0x0d},
					  {0x0d, 0x09, 0x0e, 0x0b},
					  {0x0b, 0x0d, 0x09, 0x0e}};

	MBYTE tmp[4][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; 

	for (int i = 0; i < BC; i++)
	{
		GFMatMul(m_byData[i], mat, tmp[i]);
	}
	
	for (int j = 0; j < BLOCK_SIZE; j++)
		m_byData[j/BC][j%4] = tmp[j/BC][j%4];
}

// Reduces the a value by modulo m(x) in GF(2^8) and is used
// GF(2^8) multiplication
//  x - value to be reduced
MBYTE CAES::xTime(MBYTE x)
{
	if (1==((x>>7)&0x01))
	{
		MBYTE xt = x^0x8d;
		return ((((xt<<1)^0x1b)-1)&0xff);
	}
	else
	{
		return (((x<<1)^0x1b));
	}
}

// Performes a binary polynomial multiplication in GF(2^8),
//  operation => a * b;  NOTE: order does matter
//	a - multiplier
//  b - multiplicand
MBYTE CAES::GFMul(MBYTE a, MBYTE b)
{
	MBYTE res = 0;
	MBYTE xt[8];
	int i;

	// Create the xtime table
	xt[0] = b;
	for (i = 1; i < 7; i++)
		xt[i] = xTime(xt[i-1]);
	
	// Multiply
	for (i = 0; i < 7; i++)
	{
		if (((a>>i)&1) == 1)
			res ^= xt[i];
	}

	return res;
}

// Preforms a binary polynomial matrix multiplication in GF(2^8)
//  operation => |Res0|    |B00 B01 B02 B03||A0|
//               |Res1| _\ |B10 B11 B12 B13||A1|
//               |Res2|  / |B20 B21 B22 B23||A2|
//               |Res3|    |B30 B31 B32 B33||A3|
//
//  A   - Input 1x4 Matrix Multiplicand
//  B   - Input 4x4 Matrix Multiplier
//  Res - Resulting 1x4 Matrix
void CAES::GFMatMul (MBYTE *A, const MBYTE B[4][4], MBYTE *Res)
{
	for (int i = 0; i < 4; i++)
	{
		Res[i] = 0;
		for (int j = 0; j < 4; j++)
		{
			Res[i] ^= GFMul(B[i][j], A[j]);
		}
	}
}

// Makes a 32-bit Word out of 4 8-bit Bytes
//  x1-x4 - The 4 bytes
MWORD CAES::MakeWord (MBYTE x1, MBYTE x2, MBYTE x3, MBYTE x4)
{
	MWORD ret = 0;

	ret |= (MWORD)(x1 << 24);
	ret |= (MWORD)(x2 << 16);
	ret |= (MWORD)(x3 << 8);
	ret |= (MWORD)(x4);

	return ret;
}

// Rotates a word on byte to the left
//  x - The word to be rotated
//MMWORD RotWord (MMWORD x)
//{
//	return ((x<<8) | ((x>>24)&0xff));
//}

// Performes the S-Box substitution on the word
//  x - word input
MWORD CAES::SubWord(MWORD x)
{
	MBYTE tmp[4] = {0,0,0,0};
	
	tmp[0] = sm_S[((x>>24)&0xff)];
	tmp[1] = sm_S[((x>>16)&0xff)];
	tmp[2] = sm_S[((x>>8)&0xff)];
	tmp[3] = sm_S[((x)&0xff)];

	return ((tmp[0]<<24)|(tmp[1]<<16)|(tmp[2]<<8)|tmp[3]);
}

// Applies the InvMixColumn on a word.  This is used
// for the decryption keys
//  x - input word
MWORD CAES::InvMixColumnWord(MWORD x)
{
	MBYTE tmp[4];
	MBYTE tmp2[4];

	tmp[0] = ((x>>24)&0xff);
	tmp[1] = ((x>>16)&0xff);
	tmp[2] = ((x>>8)&0xff);
	tmp[3] = (x&0xff);

	MBYTE mat[4][4] = {{0x0e, 0x0b, 0x0d, 0x09},
					  {0x09, 0x0e, 0x0b, 0x0d},
					  {0x0d, 0x09, 0x0e, 0x0b},
					  {0x0b, 0x0d, 0x09, 0x0e}};
	GFMatMul(tmp, mat, tmp2);
	return (MakeWord(tmp2[0], tmp2[1],tmp2[2], tmp2[3]));
}

⌨️ 快捷键说明

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