Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15530669
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类:

2010-02-09 21:40:19

#include
#include

void gmix_column(unsigned char *r) {
    unsigned char a[4];
    unsigned char b[4];
    unsigned char c;
    unsigned char h;
    /* The array 'a' is simply a copy of the input array 'r'
         * The array 'b' is each element of the array 'a' multiplied by 2
         * in Rijndael's Galois field
         * a[n] ^ b[n] is element n multiplied by 3 in Rijndael's Galois field */
    for(c=0;c<4;c++) {
        a[c] = r[c];
        h = r[c] & 0x80; /* hi bit */
        b[c] = r[c] << 1;
        if(h == 0x80)
            b[c] ^= 0x1b; /* Rijndael's Galois field */
    }
    r[0] = b[0] ^ a[3] ^ a[2] ^ b[1] ^ a[1]; /* 2 * a0 + a3 + a2 + 3 * a1 */
    r[1] = b[1] ^ a[0] ^ a[3] ^ b[2] ^ a[2]; /* 2 * a1 + a0 + a3 + 3 * a2 */
    r[2] = b[2] ^ a[1] ^ a[0] ^ b[3] ^ a[3]; /* 2 * a2 + a1 + a0 + 3 * a3 */
    r[3] = b[3] ^ a[2] ^ a[1] ^ b[0] ^ a[0]; /* 2 * a3 + a2 + a1 + 3 * a0 */
}

int main(int argc, char *argv[])
{
    unsigned char r[4];
    r[0] = strtol(argv[1],NULL,0);
    r[1] = strtol(argv[2],NULL,0);
    r[2] = strtol(argv[3],NULL,0);
    r[3] = strtol(argv[4],NULL,0);

    printf("[%02x %02x %02x %02x] ==> ", r[0], r[1], r[2], r[3]);
    gmix_column(r);
    printf("[%02x %02x %02x %02x]\n", r[0], r[1], r[2], r[3]);
}

以上代码可以验证后面红色字体部分数据

luther@gliethttp:/vobs/tmp$ ./a.out 0xdb 0x13 0x53 0x45
[db 13 53 45] ==> [8e 4d a1 bc]

下面一组测试数据来自FIPS-197.pdf第37页
luther@gliethttp:/vobs/tmp$ ./a.out 0xd4 0xbf 0x5d 0x30
[d4 bf 5d 30] ==> [04 66 81 e5]
luther@gliethttp:/vobs/tmp$ ./a.out 0xe0 0xb4 0x52 0xae
[e0 b4 52 ae] ==> [e0 cb 19 9a]
luther@gliethttp:/vobs/tmp$ ./a.out 0xb8 0x41 0x11 0xf1
[b8 41 11 f1] ==> [48 f8 d3 7a]
luther@gliethttp:/vobs/tmp$ ./a.out 0x1e 0x27 0x98 0xe5
[1e 27 98 e5] ==> [28 06 26 4c]

========================================

The MixColumns operation performed by the cipher, along with the shift-rows step, is the primary source of in Rijndael. Each column is treated as a polynomial over GF(28) and is then multiplied modulo x4 + 1 with a fixed polynomial c(x) = 3x3 + x2 + x + 2; the inverse of this polynomial is c − 1(x) = 11x3 + 13x2 + 9x + 14.

Contents

[]
//

[] MixColumns

The MixColumns step can be performed by multiplying a of four numbers in by the following circulant :

\begin{bmatrix}r_0\\r_1\\r_2\\r_3\end{bmatrix}
 =
\begin{bmatrix}
2&3&1&1 \\
1&2&3&1 \\
1&1&2&3 \\
3&1&1&2 \end{bmatrix} 
\begin{bmatrix}a_0\\a_1\\a_2\\a_3\end{bmatrix}

This can also be seen as the following:

r0 = 2a0 + 3a1 + a2 + a3r1 = 2a1 + 3a2 + a3 + a0r2 = 2a2 + 3a3 + a0 + a1r3 = 2a3 + 3a0 + a1 + a2

Since this math is done in , the addition above is actually an operation, and multiplication is a .

[] Implementation example

This can be simplified somewhat in actual implementation by replacing the multiply by 2 with a single shift and conditional exclusive or, and replacing a multiply by 3 with a multiply by 2 combined with an exclusive or. A example of such an implementation follows:

void gmix_column(unsigned char *r) {
unsigned char a[4];
unsigned char b[4];
unsigned char c;
unsigned char h;
/* The array 'a' is simply a copy of the input array 'r'
* The array 'b' is each element of the array 'a' multiplied by 2
* in Rijndael's Galois field
* a[n] ^ b[n] is element n multiplied by 3 in Rijndael's Galois field */
for(c=0;c<4;c++) {
a[c] = r[c];
h = r[c] & 0x80; /* hi bit */
b[c] = r[c] << 1;
if(h == 0x80)
b[c] ^= 0x1b; /* Rijndael's Galois field */
}
r[0] = b[0] ^ a[3] ^ a[2] ^ b[1] ^ a[1]; /* 2 * a0 + a3 + a2 + 3 * a1 */
r[1] = b[1] ^ a[0] ^ a[3] ^ b[2] ^ a[2]; /* 2 * a1 + a0 + a3 + 3 * a2 */
r[2] = b[2] ^ a[1] ^ a[0] ^ b[3] ^ a[3]; /* 2 * a2 + a1 + a0 + 3 * a3 */
r[3] = b[3] ^ a[2] ^ a[1] ^ b[0] ^ a[0]; /* 2 * a3 + a2 + a1 + 3 * a0 */
}

Note that this implementation is vulnerable to a .

[] InverseMixColumns

The MixColumns operation has the following inverse (numbers are decimal):

\begin{bmatrix}
14&11&13&9 \\
9&14&11&13 \\
13&9&14&11 \\
11&13&9&14 \end{bmatrix} 
\begin{bmatrix}a_0\\a_1\\a_2\\a_3\end{bmatrix}

Or:

r0 = 14a0 + 9a3 + 13a2 + 11a1r1 = 14a1 + 9a0 + 13a3 + 11a2r2 = 14a2 + 9a1 + 13a0 + 11a3r3 = 14a3 + 9a2 + 13a1 + 11a0

[] Test vectors

Hexadecimal Decimal
Before After Before After
db 13 53 45 8e 4d a1 bc 219 19 83 69 142 77 161 188
f2 0a 22 5c 9f dc 58 9d 242 10 34 92 159 220 88 157
01 01 01 01 01 01 01 01 1 1 1 1 1 1 1 1
c6 c6 c6 c6 c6 c6 c6 c6 198 198 198 198 198 198 198 198
d4 d4 d4 d5 d5 d5 d7 d6 212 212 212 213 213 213 215 214
2d 26 31 4c 4d 7e bd f8 45 38 49 76 77 126 189 248

[] References

  • ( compressed PDF file).
  • (PDF file)

[] See also

Retrieved from ""
阅读(1950) | 评论(0) | 转发(0) |
0

上一篇:AES' Galois field

下一篇:转置矩阵

给主人留下些什么吧!~~