⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aes.cpp

📁 详细的AESRSASHA1实现原理
💻 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()
{
    
}

void CAES::SetKeySize( int iSize )
{
    if ( (iSize <= 0) || (iSize > MAX_KEY_SIZE) ) return;

    m_iKeySize  = iSize;
    m_iCol      = iSize >> 2;
}

void CAES::SetRound( int iRound )
{
    if ( (iRound <= 0) || (iRound > MAX_ROUND) ) return;

    m_iRound = iRound;  
}

void CAES::GenerateRandomKey( )
{
    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::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 += ' ';
        }
    }
}

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 + -