7 # define BYTE_FORMAT "0x%02x"
8 # define BYTE_COLUMNS 8
10 # define BYTE_FORMAT "%3d"
11 # define BYTE_COLUMNS 0x10
14 #define WORD_FORMAT "0x%08lx"
15 #define WORD_COLUMNS 4
17 unsigned char sbox
[0x100];
18 unsigned char isbox
[0x100];
20 unsigned char gf2_log
[0x100];
21 unsigned char gf2_exp
[0x100];
23 unsigned long dtable
[4][0x100];
24 unsigned long itable
[4][0x100];
25 unsigned long mtable
[4][0x100];
41 /* Computes the exponentiatiom and logarithm tables for GF_2, to the
42 * base x+1 (0x03). The unit element is 1 (0x01).*/
49 memset(gf2_log
, 0, 0x100);
51 for (i
= 0; i
< 0x100; i
++, x
= x
^ xtime(x
))
58 /* The loop above sets gf2_log[1] = 0xff, which is correct,
59 * but gf2_log[1] = 0 is nicer. */
64 mult(unsigned a
, unsigned b
)
66 return (a
&& b
) ? gf2_exp
[ (gf2_log
[a
] + gf2_log
[b
]) % 255] : 0;
72 return x
? gf2_exp
[0xff - gf2_log
[x
]] : 0;
79 (0x63^x
^(x
>>4)^(x
<<4)^(x
>>5)^(x
<<3)^(x
>>6)^(x
<<2)^(x
>>7)^(x
<<1));
86 for (i
= 0; i
<0x100; i
++)
88 sbox
[i
] = affine(invert(i
));
93 /* Generate little endian tables, i.e. the first row of the AES state
94 * arrays occupies the least significant byte of the words.
96 * The sbox values are multiplied with the column of GF2 coefficients
97 * of the polynomial 03 x^3 + x^2 + x + 02. */
102 for (i
= 0; i
<0x100; i
++)
104 unsigned s
= sbox
[i
];
106 unsigned long t
=( ( (s
^ xtime(s
)) << 24)
107 | (s
<< 16) | (s
<< 8)
110 for (j
= 0; j
<4; j
++, t
= (t
<< 8) | (t
>> 24))
115 /* The inverse sbox values are multiplied with the column of GF2 coefficients
116 * of the polynomial inverse 0b x^3 + 0d x^2 + 09 x + 0e. */
121 for (i
= 0; i
<0x100; i
++)
123 unsigned s
= isbox
[i
];
125 unsigned long t
= ( (mult(s
, 0xb) << 24)
126 | (mult(s
, 0xd) << 16)
127 | (mult(s
, 0x9) << 8)
130 for (j
= 0; j
<4; j
++, t
= (t
<< 8) | (t
>> 24))
135 /* Used for key inversion, inverse mix column. No sbox. */
140 for (i
= 0; i
<0x100; i
++)
143 unsigned long t
= ( (mult(i
, 0xb) << 24)
144 | (mult(i
, 0xd) << 16)
145 | (mult(i
, 0x9) << 8)
148 for (j
= 0; j
<4; j
++, t
= (t
<< 8) | (t
>> 24))
154 display_byte_table(const char *name
, unsigned char *table
)
158 printf("uint8_t %s[0x100] =\n{", name
);
160 for (i
= 0; i
<0x100; i
+= BYTE_COLUMNS
)
163 for (j
= 0; j
<BYTE_COLUMNS
; j
++)
164 printf(BYTE_FORMAT
",", table
[i
+ j
]);
171 display_table(const char *name
, unsigned long table
[][0x100])
175 printf("uint32_t %s[4][0x100] =\n{\n ", name
);
177 for (k
= 0; k
<4; k
++)
180 for (i
= 0; i
<0x100; i
+= WORD_COLUMNS
)
183 for (j
= 0; j
<WORD_COLUMNS
; j
++)
184 printf(WORD_FORMAT
",", table
[k
][i
+ j
]);
192 display_polynomial(const unsigned *p
)
194 printf("(%x x^3 + %x x^2 + %x x + %x)",
195 p
[3], p
[2], p
[1], p
[0]);
199 main(int argc
, char **argv
)
204 display_byte_table("gf2_log", gf2_log
);
205 display_byte_table("gf2_exp", gf2_exp
);
208 display_byte_table("sbox", sbox
);
209 display_byte_table("isbox", isbox
);
212 display_table("dtable", dtable
);
215 display_table("itable", itable
);
218 display_table("mtable", mtable
);
225 for (a
= 1; a
<0x100; a
++)
227 unsigned a1
= invert(a
);
231 printf("invert(%x) = 0 !\n", a
);
235 printf("invert(%x) = %x; product = %x\n",
238 for (b
= 1; b
<0x100; b
++)
240 unsigned b1
= invert(b
);
241 unsigned c
= mult(a
, b
);
244 printf("%x x %x = 0\n", a
, b
);
248 printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
249 a
, b
, c
, a
, a1
, c
, a1
, u
);
253 printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
254 a
, b
, c
, b
, b1
, c
, b1
, u
);
263 a
= strtoul(argv
[1], NULL
, 16);
264 b
= strtoul(argv
[3], NULL
, 16);
275 c
= mult(a
, invert(b
));
280 printf("%x %c %x = %x\n", a
, op
, b
, c
);
286 /* Compute gcd(a, x^4+1) */
290 for (i
= 0; i
<4; i
++)
291 a
[i
] = strtoul(argv
[1+i
], NULL
, 16);
300 for (i
= 0; i
<4; i
++)
302 a
[i
] = strtoul(argv
[1+i
], NULL
, 16);
303 b
[i
] = strtoul(argv
[5+i
], NULL
, 16);
306 c
[0] = mult(a
[0],b
[0])^mult(a
[3],b
[1])^mult(a
[2],b
[2])^mult(a
[1],b
[3]);
307 c
[1] = mult(a
[1],b
[0])^mult(a
[0],b
[1])^mult(a
[3],b
[2])^mult(a
[2],b
[3]);
308 c
[2] = mult(a
[2],b
[0])^mult(a
[1],b
[1])^mult(a
[0],b
[2])^mult(a
[3],b
[3]);
309 c
[3] = mult(a
[3],b
[0])^mult(a
[2],b
[1])^mult(a
[1],b
[2])^mult(a
[0],b
[3]);
311 display_polynomial(a
); printf(" * "); display_polynomial(b
);
312 printf(" = "); display_polynomial(c
); printf("\n");