📄 aesengine1.cpp
字号:
// while not enough round key material calculated
// calculate new values
//
while ( t < ( ROUNDS + 1 ) * 4 )
{
for ( i = 0; i < 4; i++ )
tk[i][0] ^= S[tk[(i+1)%4][KC-1] & 0xff];
tk[0][0] ^= rcon[rconpointer++];
if ( KC <= 6 )
{
for ( j = 1; j < KC; j++ )
{
for ( i = 0; i < 4; i++ )
tk[i][j] ^= tk[i][j-1];
}
}
else
{
for ( j = 1; j < 4; j++ )
{
for ( i = 0; i < 4; i++ )
tk[i][j] ^= tk[i][j-1];
}
for ( i = 0; i < 4; i++ )
tk[i][4] ^= S[tk[i][3] & 0xff];
for ( j = 5; j < KC; j++ )
{
for ( i = 0; i < 4; i++ )
tk[i][j] ^= tk[i][j-1];
}
}
//
// copy values into round key array
//
for ( j = 0; ( j < KC ) && ( t < ( ROUNDS+1 ) * ( 32 / 8 ) ); j++, t++ )
{
for ( i = 0; i < 4; i++ )
workingKey_[t / (32/8)][i] |= (int)(tk[i][j] & 0xff) << ((t * 8) % (32));
}
}
}
int AESEngine1::processBlock( byte in[], int inOff, byte out[], int outOff)
{
if ( forEncryption_ )
{
unpackBlock( in, inOff );
encryptBlock( workingKey_ );
packBlock( out, outOff );
}
else
{
unpackBlock( in, inOff );
decryptBlock( workingKey_ );
packBlock( out, outOff );
}
return BLOCK_SIZE;
}
void AESEngine1::unpackBlock( byte bytes[], int index )
{
A0 = ( bytes[index++] & 0xff );
A1 = ( bytes[index++] & 0xff );
A2 = ( bytes[index++] & 0xff );
A3 = ( bytes[index++] & 0xff );
for ( int j = 8; j != 32; j += 8 )
{
A0 |= ( bytes[index++] & 0xff ) << j;
A1 |= ( bytes[index++] & 0xff ) << j;
A2 |= ( bytes[index++] & 0xff ) << j;
A3 |= ( bytes[index++] & 0xff ) << j;
}
}
void AESEngine1::packBlock( byte bytes[], int index )
{
for ( int j = 0; j != 32; j += 8 )
{
bytes[index++] = (byte)( A0 >> j );
bytes[index++] = (byte)( A1 >> j );
bytes[index++] = (byte)( A2 >> j );
bytes[index++] = (byte)( A3 >> j );
}
}
void AESEngine1::encryptBlock( int rk[][4] )
{
int r;
//
// begin with a key addition
//
KeyAddition( rk[0] );
//
// ROUNDS-1 ordinary rounds
//
for ( r = 1; r < ROUNDS; r++ )
{
Substitution( S );
ShiftRow();
MixColumn();
KeyAddition( rk[r] );
}
//
// Last round is special: there is no MixColumn
//
Substitution( S );
ShiftRow();
KeyAddition( rk[ROUNDS] );
}
void AESEngine1::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 AESEngine1::mul0x2( int b )
{
if (b != 0)
return Alogtable[25 + (Logtable[b] & 0xff)];
else
return 0;
}
byte AESEngine1::mul0x3( int b )
{
if (b != 0)
return Alogtable[1 + (Logtable[b] & 0xff)];
else
return 0;
}
byte AESEngine1::mul0x9( int b )
{
if (b >= 0)
return Alogtable[199 + b];
else
return 0;
}
byte AESEngine1::mul0xb( int b )
{
if (b >= 0)
return Alogtable[104 + b];
else
return 0;
}
byte AESEngine1::mul0xd( int b )
{
if (b >= 0)
return Alogtable[238 + b];
else
return 0;
}
byte AESEngine1::mul0xe( int b )
{
if (b >= 0)
return Alogtable[223 + b];
else
return 0;
}
//////////////////////////////////////////////////////////////////////////
// XOR corresponding text input and round key input bytes
//////////////////////////////////////////////////////////////////////////
void AESEngine1::KeyAddition( int rk[] )
{
A0 ^= (int)rk[0];
A1 ^= (int)rk[1];
A2 ^= (int)rk[2];
A3 ^= (int)rk[3];
}
int AESEngine1::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 AESEngine1::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 AESEngine1::InvShiftRow()
{
A1 = shift(A1, 24);
A2 = shift(A2, 16);
A3 = shift(A3, 8);
}
int AESEngine1::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 AESEngine1::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 AESEngine1::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 AESEngine1::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 + -