aes_lib.c

来自「AES算法」· C语言 代码 · 共 607 行 · 第 1/3 页

C
607
字号
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, 
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d}; 

/*_____ D E C L A R A T I O N ________________________________________________*/

static void ShiftRows(AES_U8 *state);
static void InvShiftRows(AES_U8 *state);
static void MixSubColumns(AES_U8 *state);
static void InvMixSubColumns(AES_U8 *state);
static void AddRoundKey(AES_U8 *state, AES_U8 *key);


/*F*****************************************************************************
* PARAMS:   state       4*4的状态表首指针
*
* RETURN:   None
*-------------------------------------------------------------------------------
* PURPOSE:  S-box变换和行变换
*-------------------------------------------------------------------------------
* EXAMPLE:
*-------------------------------------------------------------------------------
* NOTE:     row0 - 位置不变,        row1 - 向左循环移动1位
*           row2 - 向左循环移动2位  row3 - 向左循环移动3位
*******************************************************************************/
static void ShiftRows(AES_U8 *state)
{
AES_U8 tmp;

    // just substitute row 0
    state[0]  = Sbox[state[0]];
    state[4]  = Sbox[state[4]];
    state[8]  = Sbox[state[8]];
    state[12] = Sbox[state[12]];

    // rotate row 1
    tmp       = Sbox[state[1]];
    state[1]  = Sbox[state[5]];
    state[5]  = Sbox[state[9]];
    state[9]  = Sbox[state[13]];
    state[13] = tmp;

    // rotate row 2
    tmp       = Sbox[state[2]];
    state[2]  = Sbox[state[10]];
    state[10] = tmp;
    tmp       = Sbox[state[6]];
    state[6]  = Sbox[state[14]];
    state[14] = tmp;

    // rotate row 3
    tmp       = Sbox[state[15]];
    state[15] = Sbox[state[11]];
    state[11] = Sbox[state[7]];
    state[7]  = Sbox[state[3]];
    state[3]  = tmp;
}


/*F*****************************************************************************
* PARAMS:   state       4*4的状态表首指针
*
* RETURN:   None
*-------------------------------------------------------------------------------
* PURPOSE:  反S-box变换和反行变换
*-------------------------------------------------------------------------------
* EXAMPLE:
*-------------------------------------------------------------------------------
* NOTE:     row0 - 位置不变,        row1 - 向右循环移动1位
*           row2 - 向右循环移动2位  row3 - 向右循环移动3位
*******************************************************************************/
static void InvShiftRows(AES_U8 *state)
{
AES_U8 tmp;

    // restore row 0
    state[0]  = InvSbox[state[0]];
    state[4]  = InvSbox[state[4]];
    state[8]  = InvSbox[state[8]];
    state[12] = InvSbox[state[12]];

    // restore row 1
    tmp       = InvSbox[state[13]];
    state[13] = InvSbox[state[9]];
    state[9]  = InvSbox[state[5]];
    state[5]  = InvSbox[state[1]];
    state[1]  = tmp;

    // restore row 2
    tmp       = InvSbox[state[2]];
    state[2]  = InvSbox[state[10]];
    state[10] = tmp;
    tmp       = InvSbox[state[6]];
    state[6]  = InvSbox[state[14]];
    state[14] = tmp;

    // restore row 3
    tmp       = InvSbox[state[3]];
    state[3]  = InvSbox[state[7]];
    state[7]  = InvSbox[state[11]];
    state[11] = InvSbox[state[15]];
    state[15] = tmp;
}


/*F*****************************************************************************
* PARAMS:   state       4*4的状态表首指针
*
* RETURN:   None
*-------------------------------------------------------------------------------
* PURPOSE:  列混合操作。事实上是一种替代操作,用 State 字节列的值进行数学域加
*           和域乘的结果代替每个字节。
*           包括S-box变换,行变换,列变换
*-------------------------------------------------------------------------------
* EXAMPLE:
*-------------------------------------------------------------------------------
* NOTE:     MixColumns 使用特殊的加法和乘法,是基于近代数学的域论的有限域GF(28).
*           GF(28)由一组从 0x00 到 0xff 的256个值组成,加上加法和乘法。 GF代表
*           伽罗瓦域,以发明这一理论的数学家的名字命名。GF(28) 的一个特性是一个
*           加法或乘法的操作的结果必须是在{0x00 ... 0xff}这组数中。虽然域论是相
*           当深奥的,但GF(28)加法的最终结果却很简单。GF(28) 加法就是异或(XOR)
*           操作。
*
*         GF(28)的乘法有点繁难。AES的加密和解密例程需要知道怎样只用七个常量
*           0x01、0x02、0x03、0x09、0x0b、0x0d 和 0x0e 来相乘。只是针对这七种特殊
*           情况进行说明。
*
*         在GF(28)中用0x01的乘法是特殊的;它相当于普通算术中用1做乘法并且结果
*           也同样—任何值乘0x01等于其自身。
*
*         用0x02做乘法。和加法的情况相同,理论是深奥的,但最终结果十分简单。只要
*           被乘的值小于0x80,这时乘法的结果就是该值左移1比特位。如果被乘的值大于
*           或等于0x80,这时乘法的结果就是左移1比特位再用值0x1b异或。它防止了“域溢
*           出”并保持乘法的乘积在范围以内。
*
*           清楚在GF(28)中用0x02建立了加法和乘法,就可以用任何常量去定义乘法。用
*           0x03做乘法时,你可以将0x03分解为2的幂之和。为了用0x03乘以任意字节b, 
*           因为 0x03 = 0x02 + 0x01,因此: 
*               b * 0x03 = b * (0x02 + 0x01) = (b * 0x02) + (b * 0x01)
*******************************************************************************/
static void MixSubColumns(AES_U8 *state)
{
AES_U8 newstate[4 * Nc];    //用于缓存新的"state"数组

    // mixing column 0
    newstate[0]  = Xtime2Sbox[state[0]] ^ Xtime3Sbox[state[5]] ^ Sbox[state[10]] ^ Sbox[state[15]];
    newstate[1]  = Sbox[state[0]] ^ Xtime2Sbox[state[5]] ^ Xtime3Sbox[state[10]] ^ Sbox[state[15]];
    newstate[2]  = Sbox[state[0]] ^ Sbox[state[5]] ^ Xtime2Sbox[state[10]] ^ Xtime3Sbox[state[15]];
    newstate[3]  = Xtime3Sbox[state[0]] ^ Sbox[state[5]] ^ Sbox[state[10]] ^ Xtime2Sbox[state[15]];

    // mixing column 1
    newstate[4]  = Xtime2Sbox[state[4]] ^ Xtime3Sbox[state[9]] ^ Sbox[state[14]] ^ Sbox[state[3]];
    newstate[5]  = Sbox[state[4]] ^ Xtime2Sbox[state[9]] ^ Xtime3Sbox[state[14]] ^ Sbox[state[3]];
    newstate[6]  = Sbox[state[4]] ^ Sbox[state[9]] ^ Xtime2Sbox[state[14]] ^ Xtime3Sbox[state[3]];
    newstate[7]  = Xtime3Sbox[state[4]] ^ Sbox[state[9]] ^ Sbox[state[14]] ^ Xtime2Sbox[state[3]];

    // mixing column 2
    newstate[8]  = Xtime2Sbox[state[8]] ^ Xtime3Sbox[state[13]] ^ Sbox[state[2]] ^ Sbox[state[7]];
    newstate[9]  = Sbox[state[8]] ^ Xtime2Sbox[state[13]] ^ Xtime3Sbox[state[2]] ^ Sbox[state[7]];
    newstate[10] = Sbox[state[8]] ^ Sbox[state[13]] ^ Xtime2Sbox[state[2]] ^ Xtime3Sbox[state[7]];
    newstate[11] = Xtime3Sbox[state[8]] ^ Sbox[state[13]] ^ Sbox[state[2]] ^ Xtime2Sbox[state[7]];

    // mixing column 3
    newstate[12] = Xtime2Sbox[state[12]] ^ Xtime3Sbox[state[1]] ^ Sbox[state[6]] ^ Sbox[state[11]];
    newstate[13] = Sbox[state[12]] ^ Xtime2Sbox[state[1]] ^ Xtime3Sbox[state[6]] ^ Sbox[state[11]];
    newstate[14] = Sbox[state[12]] ^ Sbox[state[1]] ^ Xtime2Sbox[state[6]] ^ Xtime3Sbox[state[11]];
    newstate[15] = Xtime3Sbox[state[12]] ^ Sbox[state[1]] ^ Sbox[state[6]] ^ Xtime2Sbox[state[11]];

    memcpy (state, newstate, sizeof(newstate));
}


/*F*****************************************************************************
* PARAMS:   state       4*4的状态表首指针
*
* RETURN:   None
*-------------------------------------------------------------------------------
* PURPOSE:  反列混合运算
*           包括
*-------------------------------------------------------------------------------
* EXAMPLE:
*-------------------------------------------------------------------------------
* NOTE:     
*******************************************************************************/
static void InvMixSubColumns(AES_U8 *state)
{
AES_U8  newstate[4 * Nc];   //用于缓存新的"state"数组
AES_U16 i;                  

    // restore column 0
    newstate[0]  = XtimeE[state[0]] ^ XtimeB[state[1]] ^ XtimeD[state[2]] ^ Xtime9[state[3]];
    newstate[5]  = Xtime9[state[0]] ^ XtimeE[state[1]] ^ XtimeB[state[2]] ^ XtimeD[state[3]];
    newstate[10] = XtimeD[state[0]] ^ Xtime9[state[1]] ^ XtimeE[state[2]] ^ XtimeB[state[3]];
    newstate[15] = XtimeB[state[0]] ^ XtimeD[state[1]] ^ Xtime9[state[2]] ^ XtimeE[state[3]];

    // restore column 1
    newstate[4]  = XtimeE[state[4]] ^ XtimeB[state[5]] ^ XtimeD[state[6]] ^ Xtime9[state[7]];
    newstate[9]  = Xtime9[state[4]] ^ XtimeE[state[5]] ^ XtimeB[state[6]] ^ XtimeD[state[7]];
    newstate[14] = XtimeD[state[4]] ^ Xtime9[state[5]] ^ XtimeE[state[6]] ^ XtimeB[state[7]];
    newstate[3]  = XtimeB[state[4]] ^ XtimeD[state[5]] ^ Xtime9[state[6]] ^ XtimeE[state[7]];

    // restore column 2
    newstate[8]  = XtimeE[state[8]] ^ XtimeB[state[9]] ^ XtimeD[state[10]] ^ Xtime9[state[11]];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?