📄 aes.cpp
字号:
// AES.cpp: implementation of the CAES class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Cryptology.h"
#include "AES.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
char AES_HexMap[] = "0123456789abcdef";
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CAES::CAES()
{
GenerateSboxAndInvSBox();
ValuedMixColMatrixAndInvMixColMatrix();
m_iKeySize = 24;
m_iCol = 6;
m_iRound = 10;
}
CAES::~CAES()
{
}
//////////////////////////////////////////////////////////////////////
// get / set
//////////////////////////////////////////////////////////////////////
void CAES::GetRoundKey( int iRound, CString& strKey )
{
strKey.Empty( );
for( int i=0; i<4; i++ )
{
for( int j=0; j<m_iCol; j++ )
{
strKey += AES_HexMap[m_pRoundKey[iRound][i][j]>>4];
strKey += AES_HexMap[m_pRoundKey[iRound][i][j]&0xf];
strKey += ' ';
}
}
}
int CAES::GetKeySize( )
{
return m_iKeySize;
}
int CAES::GetRound( )
{
return m_iRound;
}
//////////////////////////////////////////////////////////////////////
// initial
//////////////////////////////////////////////////////////////////////
void CAES::GenerateRandomKey( int iKeySize, int iRound )
{
if ( (iKeySize > 0) && (iKeySize <= MAX_KEY_SIZE) )
{
m_iKeySize = iKeySize;
m_iCol = iKeySize >> 2;
}
if ( (iRound > 0) && (iRound <= MAX_ROUND) )
{
m_iRound = iRound;
}
for( int i=0; i<4; i++ )
{
for( int j=0; j<m_iCol; j++ )
m_pRoundKey[0][i][j] = rand()%0x100;
}
KeyExpansion( );
}
void CAES::GenerateSboxAndInvSBox()
{
BYTE i, j, t1, t2;
for( i=0; i<16; i++ )
{
for( j=0; j<16; j++ )
{
t1 = (i<<4)+j;
t2 = GF256_Affine( GF256_Eculid_Inverse(t1) );
m_pSBox[i][j] = t2;
m_pInvSBox[t2>>4][t2&0xf] = t1;
}
}
}
void CAES::ValuedMixColMatrixAndInvMixColMatrix()
{
{
m_pMixColMatrix[0][0] = 0x02;
m_pMixColMatrix[0][1] = 0x03;
m_pMixColMatrix[0][2] = 0x01;
m_pMixColMatrix[0][3] = 0x01;
m_pMixColMatrix[1][0] = 0x01;
m_pMixColMatrix[1][1] = 0x02;
m_pMixColMatrix[1][2] = 0x03;
m_pMixColMatrix[1][3] = 0x01;
m_pMixColMatrix[2][0] = 0x01;
m_pMixColMatrix[2][1] = 0x01;
m_pMixColMatrix[2][2] = 0x02;
m_pMixColMatrix[2][3] = 0x03;
m_pMixColMatrix[3][0] = 0x03;
m_pMixColMatrix[3][1] = 0x01;
m_pMixColMatrix[3][2] = 0x01;
m_pMixColMatrix[3][3] = 0x02;
}
{
m_pInvMixColMatrix[0][0] = 0x0e;
m_pInvMixColMatrix[0][1] = 0x0b;
m_pInvMixColMatrix[0][2] = 0x0d;
m_pInvMixColMatrix[0][3] = 0x09;
m_pInvMixColMatrix[1][0] = 0x09;
m_pInvMixColMatrix[1][1] = 0x0e;
m_pInvMixColMatrix[1][2] = 0x0b;
m_pInvMixColMatrix[1][3] = 0x0d;
m_pInvMixColMatrix[2][0] = 0x0d;
m_pInvMixColMatrix[2][1] = 0x09;
m_pInvMixColMatrix[2][2] = 0x0e;
m_pInvMixColMatrix[2][3] = 0x0b;
m_pInvMixColMatrix[3][0] = 0x0b;
m_pInvMixColMatrix[3][1] = 0x0d;
m_pInvMixColMatrix[3][2] = 0x09;
m_pInvMixColMatrix[3][3] = 0x0e;
}
}
void CAES::TransKeyRow3(BYTE round, BYTE result[MAX_COL])
{
BYTE i;
for( i=0; i<m_iCol-1; i++ )
result[i] = m_pRoundKey[round][3][i+1];
result[m_iCol-1] = m_pRoundKey[round][3][0];
for( i=0; i<m_iCol; i++ )
result[i] = m_pSBox[result[i]>>4][result[i]&0xf];
result[0] ^= (1<<round);
}
void CAES::KeyExpansion()
{
BYTE round, i, j, tmp[MAX_COL];
for( round=1; round<=1; round++ )
{
TransKeyRow3( round-1,tmp );
for( j=0; j<m_iCol; j++ )
m_pRoundKey[round][0][j] = m_pRoundKey[round-1][0][j]^tmp[j];
for( i=1; i<4; i++ )
{
for( j=0; j<m_iCol; j++ )
m_pRoundKey[round][i][j] = \
m_pRoundKey[round-1][i][j]^m_pRoundKey[round][i-1][j];
}
}
}
//////////////////////////////////////////////////////////////////////
// encrypt
//////////////////////////////////////////////////////////////////////
void CAES::TransMsgToBlocks( CString strMsg )
{
int i, l, t;
l = strMsg.GetLength( );
m_iBlocks = l/m_iKeySize+1;
for( i=0; i<l; i++ )
*((BYTE*)m_pBlocks+i) = strMsg[i];
t = m_iBlocks*m_iKeySize;
for( i=l; i<t; i++ )
*((BYTE*)m_pBlocks+i) = 0x0;
}
void CAES::TransBlocksToCryptInHex( CString& strCrypt )
{
int i, t;
strCrypt.Empty( );
t = m_iBlocks*m_iKeySize;
for( i=0; i<t; i++ )
{
strCrypt += AES_HexMap[(*((BYTE*)m_pBlocks+i))>>4];
strCrypt += AES_HexMap[(*((BYTE*)m_pBlocks+i))&0xf];
strCrypt += ' ';
}
}
void CAES::Encrypt( CString strMsg, CString& strCrypt )
{
TransMsgToBlocks( strMsg );
for ( int i=0; i<m_iBlocks; i++ )
EncryptBlock( m_pBlocks[i] );
TransBlocksToCryptInHex( strCrypt );
}
void CAES::EncryptBlock( AES_BLOCK b )
{
BYTE round=0;
AddRoundKey( b, 0 );
for( round = 1; round<m_iRound; round++ )
{
SubBytes( b );
ShiftRows( b );
MixColumns( b );
AddRoundKey( b, round );
}
SubBytes( b );
ShiftRows( b );
AddRoundKey( b, m_iRound );
}
void CAES::SubBytes( AES_BLOCK b )
{
BYTE i, j;
for( i=0; i<4; i++ )
{
for( j=0; j<m_iCol; j++ )
b[i][j] = m_pSBox[b[i][j]>>4][b[i][j]&0xf];
}
}
void CAES::ShiftRows( AES_BLOCK b )
{
BYTE i, j, tmp[MAX_COL];
for( i=0; i<4; i++ )
{
for( j=0; j<m_iCol; j++ )
tmp[j] = b[i][j];
for( j=0; j<m_iCol; j++ )
b[i][j] = tmp[(j+i)%m_iCol];
}
}
void CAES::MixColumns( AES_BLOCK b )
{
BYTE i, j, k;
AES_BLOCK res;
for( i=0; i<4; i++ )
{
for( j=0; j<m_iCol; j++ )
{
res[i][j] = 0;
for( k=0; k<4; k++ )
res[i][j] = GF256_Add( res[i][j], GF256_Mul(m_pMixColMatrix[i][k], b[k][j]) );
}
}
for( i=0; i<4; i++ )
for( j=0; j<m_iCol; j++ )
b[i][j] = res[i][j];
}
void CAES::AddRoundKey( AES_BLOCK b, BYTE round )
{
BYTE i, j;
for( i=0; i<4; i++ )
for( j=0; j<m_iCol; j++ )
b[i][j] ^= m_pRoundKey[round][i][j];
}
//////////////////////////////////////////////////////////////////////
// decrypt
//////////////////////////////////////////////////////////////////////
void CAES::TransBlocksToDecrypt( CString& strDecrypt )
{
int i, t;
strDecrypt.Empty( );
t = m_iBlocks*m_iKeySize;
for( i=0; i<t; i++ )
strDecrypt += *((BYTE*)m_pBlocks+i);
}
void CAES::Decrypt( CString strCrypt, CString& strDecrypt )
{
for( int i=0; i<m_iBlocks; i++ )
DecryptBlock( m_pBlocks[i] );
TransBlocksToDecrypt( strDecrypt );
}
void CAES::DecryptBlock( AES_BLOCK b )
{
BYTE round=0;
InvAddRoundKey( b, m_iRound );
InvShiftRows( b );
InvSubBytes( b );
for( round = m_iRound-1; round>0; round-- )
{
InvAddRoundKey( b, round );
InvMixColumns( b );
InvShiftRows( b );
InvSubBytes( b );
}
InvAddRoundKey( b, 0 );
}
void CAES::InvSubBytes( AES_BLOCK b )
{
BYTE i, j;
for( i=0; i<4; i++ )
{
for( j=0; j<m_iCol; j++ )
b[i][j] = m_pInvSBox[b[i][j]>>4][b[i][j]&0xf];
}
}
void CAES::InvShiftRows( AES_BLOCK b )
{
BYTE i, j, tmp[MAX_COL];
for( i=0; i<4; i++ )
{
for( j=0; j<m_iCol; j++ )
tmp[j] = b[i][j];
for( j=0; j<m_iCol; j++ )
b[i][j] = tmp[(j-i+m_iCol)%m_iCol];
}
}
void CAES::InvMixColumns( AES_BLOCK b )
{
BYTE i, j, k;
AES_BLOCK res;
for( i=0; i<4; i++ )
{
for( j=0; j<m_iCol; j++ )
{
res[i][j] = 0;
for( k=0; k<4; k++ )
res[i][j] = GF256_Add( res[i][j], GF256_Mul(m_pInvMixColMatrix[i][k], b[k][j]) );
}
}
for( i=0; i<4; i++ )
for( j=0; j<m_iCol; j++ )
b[i][j] = res[i][j];
}
void CAES::InvAddRoundKey( AES_BLOCK b, BYTE round )
{
BYTE i, j;
for( i=0; i<4; i++ )
for( j=0; j<m_iCol; j++ )
b[i][j] ^= m_pRoundKey[round][i][j];
}
//////////////////////////////////////////////////////////////////////
// GF(2^8)
//////////////////////////////////////////////////////////////////////
BYTE CAES::GF256_GetHighBitPos( BYTE n )
{
BYTE high=8;
while( !(n&(1<<high)) )
high--;
return high;
}
BYTE CAES::GF256_IsBitTrue( BYTE n, BYTE pos )
{
if( n&(1<<pos) )
return 1;
else
return 0;
}
BYTE CAES::GF256_Add( BYTE a, BYTE b )
{
return a^b;
}
BYTE CAES::GF256_Sub( BYTE a, BYTE b )
{
return a^b;
}
BYTE CAES::GF256_Xtime( BYTE n )
{
if( n&0x80 )
return (n<<1)^0x1b;
else
return n<<1;
}
BYTE CAES::GF256_Mul( BYTE a, BYTE b )
{
BYTE res = 0x0;
while( b )
{
if( b&1 )
res ^= a;
a = GF256_Xtime(a);
b >>= 1;
}
return res;
}
BYTE CAES::GF256_Div( BYTE a, BYTE b )
{
BYTE quot=0, t1, t2;
while( b<a )
{
t1 = GF256_GetHighBitPos( a );
t2 = GF256_GetHighBitPos( b );
quot += 1<<(t1-t2);
a = GF256_Sub( a, b<<(t1-t2) );
}
return quot;
}
BYTE CAES::GF256_Eculid_Inverse( BYTE b )
{
if( b==0 || b==1 )
return b;
BYTE a1,a2,a3, b1,b2,b3, t1,t2,t3, t0, qt;
t0 = 8-GF256_GetHighBitPos(b);
qt = (1<<t0) + GF256_Div( 0x11b-b<<t0,b );
a1 = 0;
a2 = 1;
a3 = b;
b1 = 1;
b2 = qt;
b3 = GF256_Mul(qt,b);
while( b3!=0 && b3!=1 )
{
qt = GF256_Div( a3, b3 );
t1 = GF256_Sub( a1, GF256_Mul(qt,b1) );
t2 = GF256_Sub( a2, GF256_Mul(qt,b2) );
t3 = GF256_Sub( a3, GF256_Mul(qt,b3) );
a1 = b1;
a2 = b2;
a3 = b3;
b1 = t1;
b2 = t2;
b3 = t3;
}
if( b3==1 )
return b2;
else
return 0;
}
BYTE CAES::GF256_Affine( BYTE n )
{
BYTE i, j, t, sum=0;
for( i=0; i<8; i++ )
{
t = GF256_IsBitTrue(n, i);
for( j=0; j<4; j++ )
t ^= GF256_IsBitTrue(n, (i+j+4)&0x7);
if( t )
sum += (1<<i);
}
return sum^0x63;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -