[Title] Add packaging/nettle.spec to build nettle on OBS system
[external/nettle.git] / aesdata.c
1 #if HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #include <assert.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9
10 #include "nettle-types.h"
11
12 #if 1
13 # define BYTE_FORMAT "0x%02x"
14 # define BYTE_COLUMNS 8
15 #else
16 # define BYTE_FORMAT "%3d"
17 # define BYTE_COLUMNS 0x10
18 #endif
19
20 #define WORD_FORMAT "0x%08x"
21 #define WORD_COLUMNS 4
22
23 uint8_t sbox[0x100];
24 uint8_t isbox[0x100];
25
26 uint8_t gf2_log[0x100];
27 uint8_t gf2_exp[0x100];
28
29 uint32_t dtable[4][0x100];
30 uint32_t itable[4][0x100];
31
32 static unsigned
33 xtime(unsigned x)
34 {
35   assert (x < 0x100);
36
37   x <<= 1;
38   if (x & 0x100)
39     x ^= 0x11b;
40
41   assert (x < 0x100);
42
43   return x;
44 }
45
46 /* Computes the exponentiatiom and logarithm tables for GF_2, to the
47  * base x+1 (0x03). The unit element is 1 (0x01).*/
48 static void
49 compute_log(void)
50 {
51   unsigned i = 0;
52   unsigned x = 1;
53
54   memset(gf2_log, 0, 0x100);
55   
56   for (i = 0; i < 0x100; i++, x = x ^ xtime(x))
57     {
58       gf2_exp[i] = x;
59       gf2_log[x] = i;
60     }
61   /* Invalid. */
62   gf2_log[0] = 0;
63   /* The loop above sets gf2_log[1] = 0xff, which is correct,
64    * but gf2_log[1] = 0 is nicer. */
65   gf2_log[1] = 0;
66 }
67
68 static unsigned
69 mult(unsigned a, unsigned b)
70 {
71   return (a && b) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0;
72 }
73
74 static unsigned
75 invert(unsigned x)
76 {
77   return x ? gf2_exp[0xff - gf2_log[x]] : 0;
78 }
79
80 static unsigned
81 affine(unsigned x)
82 {
83   return 0xff &
84     (0x63^x^(x>>4)^(x<<4)^(x>>5)^(x<<3)^(x>>6)^(x<<2)^(x>>7)^(x<<1));
85 }
86      
87 static void
88 compute_sbox(void)
89 {
90   unsigned i;
91   for (i = 0; i<0x100; i++)
92     {
93       sbox[i] = affine(invert(i));
94       isbox[sbox[i]] = i;
95     }
96 }
97
98 /* Generate little endian tables, i.e. the first row of the AES state
99  * arrays occupies the least significant byte of the words.
100  *
101  * The sbox values are multiplied with the column of GF2 coefficients
102  * of the polynomial 03 x^3 + x^2 + x + 02. */
103 static void
104 compute_dtable(void)
105 {
106   unsigned i;
107   for (i = 0; i<0x100; i++)
108     {
109       unsigned s = sbox[i];
110       unsigned j;
111       uint32_t t  =( ( (s ^ xtime(s)) << 24)
112                      | (s << 16) | (s << 8)
113                      | xtime(s) );
114
115       for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
116         dtable[j][i] = t;
117     }
118 }
119
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. */
122 static void
123 compute_itable(void)
124 {
125   unsigned i;
126   for (i = 0; i<0x100; i++)
127     {
128       unsigned s = isbox[i];
129       unsigned j;
130       uint32_t t = ( (mult(s, 0xb) << 24)
131                    | (mult(s, 0xd) << 16)
132                    | (mult(s, 0x9) << 8)
133                    | (mult(s, 0xe) ));
134       
135       for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
136         itable[j][i] = t;
137     }
138 }
139
140 static void
141 display_byte_table(const char *name, uint8_t *table)
142 {
143   unsigned i, j;
144
145   printf("uint8_t %s[0x100] =\n{", name);
146
147   for (i = 0; i<0x100; i+= BYTE_COLUMNS)
148     {
149       printf("\n  ");
150       for (j = 0; j<BYTE_COLUMNS; j++)
151         printf(BYTE_FORMAT ",", table[i + j]);
152     }
153
154   printf("\n};\n\n");
155 }
156
157 static void
158 display_table(const char *name, uint32_t table[][0x100])
159 {
160   unsigned i, j, k;
161   
162   printf("uint32_t %s[4][0x100] =\n{\n  ", name);
163
164   for (k = 0; k<4; k++)
165     {
166       printf("{ ");
167       for (i = 0; i<0x100; i+= WORD_COLUMNS)
168         {
169           printf("\n    ");
170           for (j = 0; j<WORD_COLUMNS; j++)
171             printf(WORD_FORMAT ",", table[k][i + j]);
172         }
173       printf("\n  },");
174     }
175   printf("\n};\n\n");
176 }
177
178 static void
179 display_polynomial(const unsigned *p)
180 {
181   printf("(%x x^3 + %x x^2 + %x x + %x)",
182          p[3], p[2], p[1], p[0]);
183 }
184
185 int
186 main(int argc, char **argv)
187 {
188   compute_log();
189   if (argc == 1)
190     {
191       display_byte_table("gf2_log", gf2_log);
192       display_byte_table("gf2_exp", gf2_exp);
193
194       compute_sbox();
195       display_byte_table("sbox", sbox);
196       display_byte_table("isbox", isbox);
197
198       compute_dtable();
199       display_table("dtable", dtable);
200
201       compute_itable();
202       display_table("itable", itable);
203   
204       return 0;
205     }
206   else if (argc == 2)
207     {
208       unsigned a;
209       for (a = 1; a<0x100; a++)
210         {
211           unsigned a1 = invert(a);
212           unsigned b;
213           unsigned u;
214           if (a1 == 0)
215             printf("invert(%x) = 0 !\n", a);
216
217           u = mult(a, a1);
218           if (u != 1)
219             printf("invert(%x) = %x; product = %x\n",
220                    a, a1, u);
221           
222           for (b = 1; b<0x100; b++)
223             {
224               unsigned b1 = invert(b);
225               unsigned c = mult(a, b);
226
227               if (c == 0)
228                 printf("%x x %x = 0\n", a, b);
229
230               u = mult(c, a1);
231               if (u != b)
232                 printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
233                        a, b, c, a, a1, c, a1, u);
234               
235               u = mult(c, b1);
236               if (u != a)
237                 printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
238                        a, b, c, b, b1, c, b1, u);
239             }
240         }
241       return 0;
242     }
243   else if (argc == 4)
244     {
245       unsigned a, b, c;
246       int op = argv[2][0];
247       a = strtoul(argv[1], NULL, 16);
248       b = strtoul(argv[3], NULL, 16);
249       switch (op)
250         {
251         case '+':
252           c = a ^ b;
253           break;
254         case '*':
255         case 'x':
256           c = mult(a,b);
257           break;
258         case '/':
259           c = mult(a, invert(b));
260           break;
261         default:
262           return 1;
263         }
264       printf("%x %c %x = %x\n", a, op, b, c);
265       return 0;
266     }
267 #if 0
268   else if (argc == 5)
269     {
270       /* Compute gcd(a, x^4+1) */
271       unsigned d[4];
272       unsigned u[4];
273       
274       for (i = 0; i<4; i++)
275         a[i] = strtoul(argv[1+i], NULL, 16);
276     }
277 #endif
278   else if (argc == 9)
279     {
280       unsigned a[4];
281       unsigned b[4];
282       unsigned c[4];
283       unsigned i;
284       for (i = 0; i<4; i++)
285         {
286           a[i] = strtoul(argv[1+i], NULL, 16);
287           b[i] = strtoul(argv[5+i], NULL, 16);
288         }
289
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]);
294
295       display_polynomial(a); printf(" * "); display_polynomial(b);
296       printf(" = "); display_polynomial(c); printf("\n");
297     }
298   return 1;
299 }