void AES::Cipher( BYTE *input, BYTE *output )
{
if (this->State[0] == NULL)
{
for(int i=0;i<4;i++)
{
this->State[i] = new BYTE[this->Nb];
}
}
for (int i = 0; i < (4 * Nb); ++i)
{
this->State[i%4][i/4] = input[i];
}
AddRoundKey(0);
for (int round = 1; round <= (Nr - 1); ++round) // main round loop
{
SubBytes();
ShiftRows();
MixColumns();
AddRoundKey(round);
} // main round loop
SubBytes();
ShiftRows();
AddRoundKey(Nr);
// output = state
for (int i = 0; i < (4 * Nb); ++i)
{
output[i] = this->State[i % 4][ i / 4];
}
}
void AES::InvCipher( BYTE *input, BYTE *output )
{
if (this->State[0] == NULL)
{
for(int i=0;i<4;i++)
{
this->State[i] = new BYTE[this->Nb];
}
}
for (int i = 0; i < (4 * Nb); ++i)
{
this->State[i % 4][ i / 4] = input[i];
}
AddRoundKey(Nr);
for (int round = Nr-1; round >= 1; --round) // main round loop
{
InvShiftRows();
InvSubBytes();
AddRoundKey(round);
InvMixColumns();
} // end main round loop for InvCipher
InvShiftRows();
InvSubBytes();
AddRoundKey(0);
// output = state
for (int i = 0; i < (4 * Nb); ++i)
{
output[i] = this->State[i % 4][ i / 4];
}
}
void AES::AddRoundKey( int round )
{
for (int r = 0; r < 4; ++r)
{
for (int c = 0; c < 4; ++c)
{
this->State[r][c] = (BYTE) ( (int)this->State[r][c] ^ (int)w[(round*4)+c].w[r] );
}
}
}
void AES::SubBytes()
{
for (int r = 0; r < 4; ++r)
{
for (int c = 0; c < 4; ++c)
{
this->State[r][c] = Sbox[ (this->State[r][c] >> 4)][ (this->State[r][c] & 0x0f) ];
}
}
}
void AES::InvSubBytes()
{
for (int r = 0; r < 4; ++r)
{
for (int c = 0; c < 4; ++c)
{
this->State[r][c] = iSbox[ (this->State[r][c] >> 4)][ (this->State[r][c] & 0x0f) ];
}
}
}
void AES::ShiftRows()
{
BYTE4 temp[4];
// byte[,] temp = new byte[4,4];
for (int r = 0; r < 4; ++r) // copy State into temp[]
{
for (int c = 0; c < 4; ++c)
{
temp[r].w[c] = this->State[r][c];
// temp[r,c] = this.State[r,c];
}
}
for (int r = 1; r < 4; ++r) // shift temp into State
{
for (int c = 0; c < 4; ++c)
{
this->State[r][c] = temp[ r].w[ (c + r) % Nb ];
}
}
} // ShiftRows()
void AES::InvShiftRows()
{
BYTE4 temp[4];
for (int r = 0; r < 4; ++r) // copy State into temp[]
{
for (int c = 0; c < 4; ++c)
{
temp[r].w[c] = this->State[r][c];
}
}
for (int r = 1; r < 4; ++r) // shift temp into State
{
for (int c = 0; c < 4; ++c)
{
this->State[r][ (c + r) % Nb ] = temp[r].w[c];
}
}
} // InvShiftRows()
void AES::MixColumns()
{
BYTE4 temp[4];
for (int r = 0; r < 4; ++r) // copy State into temp[]
{
for (int c = 0; c < 4; ++c)
{
temp[r].w[c] = this->State[r][c];
}
}
for (int c = 0; c < 4; ++c)
{
this->State[0][c] = (BYTE) ( (int)gfmultby02(temp[0].w[c]) ^ (int)gfmultby03(temp[1].w[c]) ^
(int)gfmultby01(temp[2].w[c]) ^ (int)gfmultby01(temp[3].w[c]) );
this->State[1][c] = (BYTE) ( (int)gfmultby01(temp[0].w[c]) ^ (int)gfmultby02(temp[1].w[c]) ^
(int)gfmultby03(temp[2].w[c]) ^ (int)gfmultby01(temp[3].w[c]) );
this->State[2][c] = (BYTE) ( (int)gfmultby01(temp[0].w[c]) ^ (int)gfmultby01(temp[1].w[c]) ^
(int)gfmultby02(temp[2].w[c]) ^ (int)gfmultby03(temp[3].w[c]) );
this->State[3][c] = (BYTE) ( (int)gfmultby03(temp[0].w[c]) ^ (int)gfmultby01(temp[1].w[c]) ^
(int)gfmultby01(temp[2].w[c]) ^ (int)gfmultby02(temp[3].w[c]) );
}
} // MixColumns
void AES::InvMixColumns()
{
BYTE4 temp[4];
for (int r = 0; r < 4; ++r) // copy State into temp[]
{
for (int c = 0; c < 4; ++c)
{
temp[r].w[c] = this->State[r][c];
}
}