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