10 #include "nettle-types.h"
13 # define BYTE_FORMAT "0x%02x"
14 # define BYTE_COLUMNS 8
16 # define BYTE_FORMAT "%3d"
17 # define BYTE_COLUMNS 0x10
20 #define WORD_FORMAT "0x%08x"
21 #define WORD_COLUMNS 4
26 uint8_t gf2_log[0x100];
27 uint8_t gf2_exp[0x100];
29 uint32_t dtable[4][0x100];
30 uint32_t itable[4][0x100];
46 /* Computes the exponentiatiom and logarithm tables for GF_2, to the
47 * base x+1 (0x03). The unit element is 1 (0x01).*/
54 memset(gf2_log, 0, 0x100);
56 for (i = 0; i < 0x100; i++, x = x ^ xtime(x))
63 /* The loop above sets gf2_log[1] = 0xff, which is correct,
64 * but gf2_log[1] = 0 is nicer. */
69 mult(unsigned a, unsigned b)
71 return (a && b) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0;
77 return x ? gf2_exp[0xff - gf2_log[x]] : 0;
84 (0x63^x^(x>>4)^(x<<4)^(x>>5)^(x<<3)^(x>>6)^(x<<2)^(x>>7)^(x<<1));
91 for (i = 0; i<0x100; i++)
93 sbox[i] = affine(invert(i));
98 /* Generate little endian tables, i.e. the first row of the AES state
99 * arrays occupies the least significant byte of the words.
101 * The sbox values are multiplied with the column of GF2 coefficients
102 * of the polynomial 03 x^3 + x^2 + x + 02. */
107 for (i = 0; i<0x100; i++)
109 unsigned s = sbox[i];
111 uint32_t t =( ( (s ^ xtime(s)) << 24)
112 | (s << 16) | (s << 8)
115 for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
120 /* The inverse sbox values are multiplied with the column of GF2 coefficients
121 * of the polynomial inverse 0b x^3 + 0d x^2 + 09 x + 0e. */
126 for (i = 0; i<0x100; i++)
128 unsigned s = isbox[i];
130 uint32_t t = ( (mult(s, 0xb) << 24)
131 | (mult(s, 0xd) << 16)
132 | (mult(s, 0x9) << 8)
135 for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
141 display_byte_table(const char *name, uint8_t *table)
145 printf("uint8_t %s[0x100] =\n{", name);
147 for (i = 0; i<0x100; i+= BYTE_COLUMNS)
150 for (j = 0; j<BYTE_COLUMNS; j++)
151 printf(BYTE_FORMAT ",", table[i + j]);
158 display_table(const char *name, uint32_t table[][0x100])
162 printf("uint32_t %s[4][0x100] =\n{\n ", name);
164 for (k = 0; k<4; k++)
167 for (i = 0; i<0x100; i+= WORD_COLUMNS)
170 for (j = 0; j<WORD_COLUMNS; j++)
171 printf(WORD_FORMAT ",", table[k][i + j]);
179 display_polynomial(const unsigned *p)
181 printf("(%x x^3 + %x x^2 + %x x + %x)",
182 p[3], p[2], p[1], p[0]);
186 main(int argc, char **argv)
191 display_byte_table("gf2_log", gf2_log);
192 display_byte_table("gf2_exp", gf2_exp);
195 display_byte_table("sbox", sbox);
196 display_byte_table("isbox", isbox);
199 display_table("dtable", dtable);
202 display_table("itable", itable);
209 for (a = 1; a<0x100; a++)
211 unsigned a1 = invert(a);
215 printf("invert(%x) = 0 !\n", a);
219 printf("invert(%x) = %x; product = %x\n",
222 for (b = 1; b<0x100; b++)
224 unsigned b1 = invert(b);
225 unsigned c = mult(a, b);
228 printf("%x x %x = 0\n", a, b);
232 printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
233 a, b, c, a, a1, c, a1, u);
237 printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
238 a, b, c, b, b1, c, b1, u);
247 a = strtoul(argv[1], NULL, 16);
248 b = strtoul(argv[3], NULL, 16);
259 c = mult(a, invert(b));
264 printf("%x %c %x = %x\n", a, op, b, c);
270 /* Compute gcd(a, x^4+1) */
274 for (i = 0; i<4; i++)
275 a[i] = strtoul(argv[1+i], NULL, 16);
284 for (i = 0; i<4; i++)
286 a[i] = strtoul(argv[1+i], NULL, 16);
287 b[i] = strtoul(argv[5+i], NULL, 16);
290 c[0] = mult(a[0],b[0])^mult(a[3],b[1])^mult(a[2],b[2])^mult(a[1],b[3]);
291 c[1] = mult(a[1],b[0])^mult(a[0],b[1])^mult(a[3],b[2])^mult(a[2],b[3]);
292 c[2] = mult(a[2],b[0])^mult(a[1],b[1])^mult(a[0],b[2])^mult(a[3],b[3]);
293 c[3] = mult(a[3],b[0])^mult(a[2],b[1])^mult(a[1],b[2])^mult(a[0],b[3]);
295 display_polynomial(a); printf(" * "); display_polynomial(b);
296 printf(" = "); display_polynomial(c); printf("\n");