Add crypto hash SM3.
[libgcrypt.git] / cipher / gost-s-box.c
1 /* gost-s-box.c - GOST 28147-89 S-Box expander
2  * Copyright (C) 2013 Dmitry Eremin-Solenikov
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
24
25 struct gost_sbox
26 {
27   const char *name;
28   const char *oid;
29   unsigned char sbox[16*8];
30 } gost_sboxes[] = {
31   { "test_3411", "1.2.643.2.2.30.0", {
32       0x4, 0xE, 0x5, 0x7, 0x6, 0x4, 0xD, 0x1,
33       0xA, 0xB, 0x8, 0xD, 0xC, 0xB, 0xB, 0xF,
34       0x9, 0x4, 0x1, 0xA, 0x7, 0xA, 0x4, 0xD,
35       0x2, 0xC, 0xD, 0x1, 0x1, 0x0, 0x1, 0x0,
36
37       0xD, 0x6, 0xA, 0x0, 0x5, 0x7, 0x3, 0x5,
38       0x8, 0xD, 0x3, 0x8, 0xF, 0x2, 0xF, 0x7,
39       0x0, 0xF, 0x4, 0x9, 0xD, 0x1, 0x5, 0xA,
40       0xE, 0xA, 0x2, 0xF, 0x8, 0xD, 0x9, 0x4,
41
42       0x6, 0x2, 0xE, 0xE, 0x4, 0x3, 0x0, 0x9,
43       0xB, 0x3, 0xF, 0x4, 0xA, 0x6, 0xA, 0x2,
44       0x1, 0x8, 0xC, 0x6, 0x9, 0x8, 0xE, 0x3,
45       0xC, 0x1, 0x7, 0xC, 0xE, 0x5, 0x7, 0xE,
46
47       0x7, 0x0, 0x6, 0xB, 0x0, 0x9, 0x6, 0x6,
48       0xF, 0x7, 0x0, 0x2, 0x3, 0xC, 0x8, 0xB,
49       0x5, 0x5, 0x9, 0x5, 0xB, 0xF, 0x2, 0x8,
50       0x3, 0x9, 0xB, 0x3, 0x2, 0xE, 0xC, 0xC,
51     }
52   },
53   { "CryptoPro_3411", "1.2.643.2.2.30.1", {
54       0xA, 0x5, 0x7, 0x4, 0x7, 0x7, 0xD, 0x1,
55       0x4, 0xF, 0xF, 0xA, 0x6, 0x6, 0xE, 0x3,
56       0x5, 0x4, 0xC, 0x7, 0x4, 0x2, 0x4, 0xA,
57       0x6, 0x0, 0xE, 0xC, 0xB, 0x4, 0x1, 0x9,
58
59       0x8, 0x2, 0x9, 0x0, 0x9, 0xD, 0x7, 0x5,
60       0x1, 0xD, 0x4, 0xF, 0xC, 0x9, 0x0, 0xB,
61       0x3, 0xB, 0x1, 0x2, 0x2, 0xF, 0x5, 0x4,
62       0x7, 0x9, 0x0, 0x8, 0xA, 0x0, 0xA, 0xF,
63
64       0xD, 0x1, 0x3, 0xE, 0x1, 0xA, 0x3, 0x8,
65       0xC, 0x7, 0xB, 0x1, 0x8, 0x1, 0xC, 0x6,
66       0xE, 0x6, 0x5, 0x6, 0x0, 0x5, 0x8, 0x7,
67       0x0, 0x3, 0x2, 0x5, 0xE, 0xB, 0xF, 0xE,
68
69       0x9, 0xC, 0x6, 0xD, 0xF, 0x8, 0x6, 0xD,
70       0x2, 0xE, 0xA, 0xB, 0xD, 0xE, 0x2, 0x0,
71       0xB, 0xA, 0x8, 0x9, 0x3, 0xC, 0x9, 0x2,
72       0xF, 0x8, 0xD, 0x3, 0x5, 0x3, 0xB, 0xC,
73     }
74   },
75   { "Test_89", "1.2.643.2.2.31.0", {
76       0x4, 0xC, 0xD, 0xE, 0x3, 0x8, 0x9, 0xC,
77       0x2, 0x9, 0x8, 0x9, 0xE, 0xF, 0xB, 0x6,
78       0xF, 0xF, 0xE, 0xB, 0x5, 0x6, 0xC, 0x5,
79       0x5, 0xE, 0xC, 0x2, 0x9, 0xB, 0x0, 0x2,
80
81       0x9, 0x8, 0x7, 0x5, 0x6, 0x1, 0x3, 0xB,
82       0x1, 0x1, 0x3, 0xF, 0x8, 0x9, 0x6, 0x0,
83       0x0, 0x3, 0x9, 0x7, 0x0, 0xC, 0x7, 0x9,
84       0x8, 0xA, 0xA, 0x1, 0xD, 0x5, 0x5, 0xD,
85
86       0xE, 0x2, 0x1, 0x0, 0xA, 0xD, 0x4, 0x3,
87       0x3, 0x7, 0x5, 0xD, 0xB, 0x3, 0x8, 0xE,
88       0xB, 0x4, 0x2, 0xC, 0x7, 0x7, 0xE, 0x7,
89       0xC, 0xD, 0x4, 0x6, 0xC, 0xA, 0xF, 0xA,
90
91       0xD, 0x6, 0x6, 0xA, 0x2, 0x0, 0x1, 0xF,
92       0x7, 0x0, 0xF, 0x4, 0x1, 0xE, 0xA, 0x4,
93       0xA, 0xB, 0x0, 0x3, 0xF, 0x2, 0x2, 0x1,
94       0x6, 0x5, 0xB, 0x8, 0x4, 0x4, 0xD, 0x8,
95     }
96   },
97   { "CryptoPro_A", "1.2.643.2.2.31.1", {
98       0x9, 0x3, 0xE, 0xE, 0xB, 0x3, 0x1, 0xB,
99       0x6, 0x7, 0x4, 0x7, 0x5, 0xA, 0xD, 0xA,
100       0x3, 0xE, 0x6, 0xA, 0x1, 0xD, 0x2, 0xF,
101       0x2, 0x9, 0x2, 0xC, 0x9, 0xC, 0x9, 0x5,
102
103       0x8, 0x8, 0xB, 0xD, 0x8, 0x1, 0x7, 0x0,
104       0xB, 0xA, 0x3, 0x1, 0xD, 0x2, 0xA, 0xC,
105       0x1, 0xF, 0xD, 0x3, 0xF, 0x0, 0x6, 0xE,
106       0x7, 0x0, 0x8, 0x9, 0x0, 0xB, 0x0, 0x8,
107
108       0xA, 0x5, 0xC, 0x0, 0xE, 0x7, 0x8, 0x6,
109       0x4, 0x2, 0xF, 0x2, 0x4, 0x5, 0xC, 0x2,
110       0xE, 0x6, 0x5, 0xB, 0x2, 0x9, 0x4, 0x3,
111       0xF, 0xC, 0xA, 0x4, 0x3, 0x4, 0x5, 0x9,
112
113       0xC, 0xB, 0x0, 0xF, 0xC, 0x8, 0xF, 0x1,
114       0x0, 0x4, 0x7, 0x8, 0x7, 0xF, 0x3, 0x7,
115       0xD, 0xD, 0x1, 0x5, 0xA, 0xE, 0xB, 0xD,
116       0x5, 0x1, 0x9, 0x6, 0x6, 0x6, 0xE, 0x4,
117     }
118   },
119   { "CryptoPro_B", "1.2.643.2.2.31.2", {
120       0x8, 0x0, 0xE, 0x7, 0x2, 0x8, 0x5, 0x0,
121       0x4, 0x1, 0xC, 0x5, 0x7, 0x3, 0x2, 0x4,
122       0xB, 0x2, 0x0, 0x0, 0xC, 0x2, 0xA, 0xB,
123       0x1, 0xA, 0xA, 0xD, 0xF, 0x6, 0xB, 0xE,
124
125       0x3, 0x4, 0x9, 0xB, 0x9, 0x4, 0x9, 0x8,
126       0x5, 0xD, 0x2, 0x6, 0x5, 0xD, 0x1, 0x3,
127       0x0, 0x5, 0xD, 0x1, 0xA, 0xE, 0xC, 0x7,
128       0x9, 0xC, 0xB, 0x2, 0xB, 0xB, 0x3, 0x1,
129
130       0x2, 0x9, 0x7, 0x3, 0x1, 0xC, 0x7, 0xA,
131       0xE, 0x7, 0x5, 0xA, 0x4, 0x1, 0x4, 0x2,
132       0xA, 0x3, 0x8, 0xC, 0x0, 0x7, 0xD, 0x9,
133       0xC, 0xF, 0xF, 0xF, 0xD, 0xF, 0x0, 0x6,
134
135       0xD, 0xB, 0x3, 0x4, 0x6, 0xA, 0x6, 0xF,
136       0x6, 0x8, 0x6, 0xE, 0x8, 0x0, 0xF, 0xD,
137       0x7, 0x6, 0x1, 0x9, 0xE, 0x9, 0x8, 0x5,
138       0xF, 0xE, 0x4, 0x8, 0x3, 0x5, 0xE, 0xC,
139     }
140   },
141   { "CryptoPro_C", "1.2.643.2.2.31.3", {
142       0x1, 0x0, 0x8, 0x3, 0x8, 0xC, 0xA, 0x7,
143       0xB, 0x1, 0x2, 0x6, 0xD, 0x9, 0x9, 0x4,
144       0xC, 0x7, 0x5, 0x0, 0xB, 0xB, 0x6, 0x0,
145       0x2, 0xD, 0x0, 0x1, 0x0, 0x1, 0x8, 0x5,
146
147       0x9, 0xB, 0x4, 0x5, 0x4, 0x8, 0xD, 0xA,
148       0xD, 0x4, 0x9, 0xD, 0x5, 0xE, 0xE, 0x2,
149       0x0, 0x5, 0xF, 0xA, 0x1, 0x2, 0x2, 0xF,
150       0xF, 0x2, 0xA, 0x8, 0x2, 0x4, 0x0, 0xE,
151
152       0x4, 0x8, 0x3, 0xB, 0x9, 0x7, 0xF, 0xC,
153       0x5, 0xE, 0x7, 0x2, 0x3, 0x3, 0x3, 0x6,
154       0x8, 0xF, 0xC, 0x9, 0xC, 0x6, 0x5, 0x1,
155       0xE, 0xC, 0xD, 0x7, 0xE, 0x5, 0xB, 0xB,
156
157       0xA, 0x9, 0x6, 0xE, 0x6, 0xA, 0x4, 0xD,
158       0x7, 0xA, 0xE, 0xF, 0xF, 0x0, 0x1, 0x9,
159       0x6, 0x6, 0x1, 0xC, 0xA, 0xF, 0xC, 0x3,
160       0x3, 0x3, 0xB, 0x4, 0x7, 0xD, 0x7, 0x8,
161     }
162   },
163   { "CryptoPro_D", "1.2.643.2.2.31.4", {
164       0xF, 0xB, 0x1, 0x1, 0x0, 0x8, 0x3, 0x1,
165       0xC, 0x6, 0xC, 0x5, 0xC, 0x0, 0x0, 0xA,
166       0x2, 0x3, 0xB, 0xE, 0x8, 0xF, 0x6, 0x6,
167       0xA, 0x4, 0x0, 0xC, 0x9, 0x3, 0xF, 0x8,
168
169       0x6, 0xC, 0xF, 0xA, 0xD, 0x2, 0x1, 0xF,
170       0x4, 0xF, 0xE, 0x7, 0x2, 0x5, 0xE, 0xB,
171       0x5, 0xE, 0x6, 0x0, 0xA, 0xE, 0x9, 0x0,
172       0x0, 0x2, 0x5, 0xD, 0xB, 0xB, 0x2, 0x4,
173
174       0x7, 0x7, 0xA, 0x6, 0x7, 0x1, 0xD, 0xC,
175       0x9, 0xD, 0xD, 0x2, 0x3, 0xA, 0x8, 0x3,
176       0xE, 0x8, 0x4, 0xB, 0x6, 0x4, 0xC, 0x5,
177       0xD, 0x0, 0x8, 0x4, 0x5, 0x7, 0x4, 0x9,
178
179       0x1, 0x5, 0x9, 0x9, 0x4, 0xC, 0xB, 0x7,
180       0xB, 0xA, 0x3, 0x3, 0xE, 0x9, 0xA, 0xD,
181       0x8, 0x9, 0x7, 0xF, 0xF, 0xD, 0x5, 0x2,
182       0x3, 0x1, 0x2, 0x8, 0x1, 0x6, 0x7, 0xE,
183     }
184   },
185   { "TC26_Z", "1.2.643.7.1.2.5.1.1", {
186       0xc, 0x6, 0xb, 0xc, 0x7, 0x5, 0x8, 0x1,
187       0x4, 0x8, 0x3, 0x8, 0xf, 0xd, 0xe, 0x7,
188       0x6, 0x2, 0x5, 0x2, 0x5, 0xf, 0x2, 0xe,
189       0x2, 0x3, 0x8, 0x1, 0xa, 0x6, 0x5, 0xd,
190
191       0xa, 0x9, 0x2, 0xd, 0x8, 0x9, 0x6, 0x0,
192       0x5, 0xa, 0xf, 0x4, 0x1, 0x2, 0x9, 0x5,
193       0xb, 0x5, 0xa, 0xf, 0x6, 0xc, 0x1, 0x8,
194       0x9, 0xc, 0xd, 0x6, 0xd, 0xa, 0xc, 0x3,
195
196       0xe, 0x1, 0xe, 0x7, 0x0, 0xb, 0xf, 0x4,
197       0x8, 0xe, 0x1, 0x0, 0x9, 0x7, 0x4, 0xf,
198       0xd, 0x4, 0x7, 0xa, 0x3, 0x8, 0xb, 0xa,
199       0x7, 0x7, 0x4, 0x5, 0xe, 0x1, 0x0, 0x6,
200
201       0x0, 0xb, 0xc, 0x3, 0xb, 0x4, 0xd, 0x9,
202       0x3, 0xd, 0x9, 0xe, 0x4, 0x3, 0xa, 0xc,
203       0xf, 0x0, 0x6, 0x9, 0x2, 0xe, 0x3, 0xb,
204       0x1, 0xf, 0x0, 0xb, 0xc, 0x0, 0x7, 0x2,
205     }
206   },
207 };
208
209 int main(int argc, char **argv)
210 {
211   unsigned int i, j, s;
212   FILE *f;
213
214   if (argc == 1)
215     f = stdin;
216   else
217     f = fopen(argv[1], "w");
218
219   if (!f)
220     {
221       perror("fopen");
222       exit(1);
223     }
224
225   for (s = 0; s < DIM(gost_sboxes); s++)
226     {
227       unsigned char *sbox = gost_sboxes[s].sbox;
228       fprintf (f, "static const u32 sbox_%s[4*256] =\n  {", gost_sboxes[s].name);
229       for (i = 0; i < 4; i++) {
230         fprintf (f,     "\n    /* %d */\n   ", i);
231         for (j = 0; j < 256; j++) {
232           unsigned int val;
233           if (j % 4 == 0 && j != 0)
234             fprintf (f, "\n   ");
235           val = sbox[ (j & 0xf) * 8 + 2 * i + 0] |
236                (sbox[ (j >> 4)  * 8 + 2 * i + 1] << 4);
237           val <<= (8*i);
238           val = (val << 11) | (val >> 21);
239           fprintf (f, " 0x%08x,", val);
240         }
241       }
242       fprintf (f, "\n  };\n\n");
243     }
244
245   fprintf (f, "static struct\n{\n  const char *oid;\n  const u32 *sbox;\n} gost_oid_map[] = {\n");
246
247   for (s = 0; s < DIM(gost_sboxes); s++)
248     {
249       fprintf (f, "  { \"%s\", sbox_%s },\n", gost_sboxes[s].oid, gost_sboxes[s].name );
250     }
251
252   fprintf(f, "  { NULL, NULL }\n};\n");
253
254   fclose (f);
255
256   return 0;
257 }