📄 aesengine.cpp
字号:
{
Substitution( S );
ShiftRow();
MixColumn();
KeyAddition( rk[r] );
}
//
// Last round is special: there is no MixColumn
//
Substitution( S );
ShiftRow();
KeyAddition( rk[ROUNDS] );
}
void AESEngine::decryptBlock( int rk[][4] )
{
int r;
// To decrypt: apply the inverse operations of the encrypt routine,
// in opposite order
//
// (KeyAddition is an involution: it 's equal to its inverse)
// (the inverse of Substitution with table S is Substitution with the inverse table of S)
// (the inverse of Shiftrow is Shiftrow over a suitable distance)
//
// First the special round:
// without InvMixColumn
// with extra KeyAddition
//
KeyAddition( rk[ROUNDS] );
Substitution( Si );
InvShiftRow();
//
// ROUNDS-1 ordinary rounds
//
for ( r = ROUNDS-1; r > 0; r-- )
{
KeyAddition(rk[r]);
InvMixColumn();
Substitution(Si);
InvShiftRow();
}
//
// End with the extra key addition
//
KeyAddition( rk[0] );
}
//--------------------------------------------------------------------------
// cipher utilities
//--------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// multiply two elements of GF(2^m)
// needed for MixColumn and InvMixColumn
//////////////////////////////////////////////////////////////////////////
byte AESEngine::mul0x2( int b )
{
if (b != 0)
return Alogtable[25 + (Logtable[b] & 0xff)];
else
return 0;
}
byte AESEngine::mul0x3( int b )
{
if (b != 0)
return Alogtable[1 + (Logtable[b] & 0xff)];
else
return 0;
}
byte AESEngine::mul0x9( int b )
{
if (b >= 0)
return Alogtable[199 + b];
else
return 0;
}
byte AESEngine::mul0xb( int b )
{
if (b >= 0)
return Alogtable[104 + b];
else
return 0;
}
byte AESEngine::mul0xd( int b )
{
if (b >= 0)
return Alogtable[238 + b];
else
return 0;
}
byte AESEngine::mul0xe( int b )
{
if (b >= 0)
return Alogtable[223 + b];
else
return 0;
}
//////////////////////////////////////////////////////////////////////////
// XOR corresponding text input and round key input bytes
//////////////////////////////////////////////////////////////////////////
void AESEngine::KeyAddition( int rk[] )
{
A0 ^= (int)rk[0];
A1 ^= (int)rk[1];
A2 ^= (int)rk[2];
A3 ^= (int)rk[3];
}
int AESEngine::shift( int r, int shift )
{
int temp = r;
//////////////////////////////////////////////////////////////////////////
//
// This Block Implements the >>> Shift Operator
// Since this operator is not provided in C++ Platform , we had to implement
// the same as in JAVA
//
//////////////////////////////////////////////////////////////////////////
for ( int j = 0; j < shift / 8 ; ++j )
{
temp = temp >> 8;
temp = temp & 0x00FFFFFF;
}
return ( ( temp | ( r << ( 32 - shift ) ) ) );
}
//////////////////////////////////////////////////////////////////////////
// Row 0 remains unchanged
// The other three rows are shifted a variable amount
//////////////////////////////////////////////////////////////////////////
void AESEngine::ShiftRow()
{
A1 = shift(A1, 8);
A2 = shift(A2, 16);
A3 = shift(A3, 24);
}
//////////////////////////////////////////////////////////////////////////
// Row 0 remains unchanged
// The other three rows are shifted a variable amount
//////////////////////////////////////////////////////////////////////////
void AESEngine::InvShiftRow()
{
A1 = shift(A1, 24);
A2 = shift(A2, 16);
A3 = shift(A3, 8);
}
int AESEngine::applyS( int r, const byte* box )
{
return ( box[(r & 0xff)] & 0xff )
| ( ( box[ ( ( r >> 8 ) & 0xff ) ] & 0xff) << 8 )
| ( ( box[ ( ( r >> 16 ) & 0xff ) ] & 0xff) << 16 )
| ( ( box[ ( ( r >> 24 ) & 0xff ) ] & 0xff) << 24 );
}
//////////////////////////////////////////////////////////////////////////
// Replace every byte of the input by the byte at that place
// in the nonlinear S-box
//////////////////////////////////////////////////////////////////////////
void AESEngine::Substitution( const byte* box )
{
A0 = applyS(A0, box);
A1 = applyS(A1, box);
A2 = applyS(A2, box);
A3 = applyS(A3, box);
}
//////////////////////////////////////////////////////////////////////////
// Mix the bytes of every column in a linear way
//////////////////////////////////////////////////////////////////////////
void AESEngine::MixColumn()
{
int r0, r1, r2, r3;
r0 = r1 = r2 = r3 = 0;
for ( int j = 0; j < 32; j += 8 )
{
int a0 = ( ( A0 >> j ) & 0xff );
int a1 = ( ( A1 >> j ) & 0xff );
int a2 = ( ( A2 >> j ) & 0xff );
int a3 = ( ( A3 >> j ) & 0xff );
r0 |= ( ( mul0x2(a0) ^ mul0x3(a1) ^ a2 ^ a3 ) & 0xff ) << j;
r1 |= ( ( mul0x2(a1) ^ mul0x3(a2) ^ a3 ^ a0 ) & 0xff ) << j;
r2 |= ( ( mul0x2(a2) ^ mul0x3(a3) ^ a0 ^ a1 ) & 0xff ) << j;
r3 |= ( ( mul0x2(a3) ^ mul0x3(a0) ^ a1 ^ a2 ) & 0xff ) << j;
}
A0 = r0;
A1 = r1;
A2 = r2;
A3 = r3;
}
//////////////////////////////////////////////////////////////////////////
// Mix the bytes of every column in a linear way
// This is the opposite operation of Mix column
//////////////////////////////////////////////////////////////////////////
void AESEngine::InvMixColumn()
{
int r0, r1, r2, r3;
r0 = r1 = r2 = r3 = 0;
for ( int j = 0; j < 32; j += 8 )
{
int a0 = ( ( A0 >> j ) & 0xff );
int a1 = ( ( A1 >> j ) & 0xff );
int a2 = ( ( A2 >> j ) & 0xff );
int a3 = ( ( A3 >> j ) & 0xff );
//
// pre-lookup the log table
//
a0 = ( a0 != 0 ) ? ( Logtable[ a0 & 0xff ] & 0xff ) : -1;
a1 = ( a1 != 0 ) ? ( Logtable[ a1 & 0xff ] & 0xff ) : -1;
a2 = ( a2 != 0 ) ? ( Logtable[ a2 & 0xff ] & 0xff ) : -1;
a3 = ( a3 != 0 ) ? ( Logtable[ a3 & 0xff ] & 0xff ) : -1;
r0 |= ( ( mul0xe( a0 ) ^ mul0xb( a1 ) ^ mul0xd( a2 ) ^ mul0x9( a3 ) ) & 0xff ) << j;
r1 |= ( ( mul0xe( a1 ) ^ mul0xb( a2 ) ^ mul0xd( a3 ) ^ mul0x9( a0 ) ) & 0xff) << j;
r2 |= ( ( mul0xe( a2 ) ^ mul0xb( a3 ) ^ mul0xd( a0 ) ^ mul0x9( a1 ) ) & 0xff) << j;
r3 |= ( ( mul0xe( a3 ) ^ mul0xb( a0 ) ^ mul0xd( a1 ) ^ mul0x9( a2 ) ) & 0xff) << j;
}
A0 = r0;
A1 = r1;
A2 = r2;
A3 = r3;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -