/[mcrypt]/libmcrypt-nm/lib/gost.c
ViewVC logotype

Contents of /libmcrypt-nm/lib/gost.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Mon May 22 13:09:02 2000 UTC (23 years, 11 months ago) by nmav
Branch: MAIN, mcrypt
CVS Tags: start, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/plain

1 /*
2 * The GOST 28147-89 cipher
3 *
4 * This is based on the 25 Movember 1993 draft translation
5 * by Aleksandr Malchik, with Whitfield Diffie, of the Government
6 * Standard of the U.S.S.R. GOST 28149-89, "Cryptographic Transformation
7 * Algorithm", effective 1 July 1990. (Whitfield.Diffie@eng.sun.com)
8 *
9 * That is a draft, and may contain errors, which will be faithfully
10 * reflected here, along with possible exciting new bugs.
11 *
12 * Some details have been cleared up by the paper "Soviet Encryption
13 * Algorithm" by Josef Pieprzyk and Leonid Tombak of the University
14 * of Wollongong, New South Wales. (josef/leo@cs.adfa.oz.au)
15 *
16 * The standard is written by A. Zabotin (project leader), G.P. Glazkov,
17 * and V.B. Isaeva. It was accepted and introduced into use by the
18 * action of the State Standards Committee of the USSR on 2 June 89 as
19 * No. 1409. It was to be reviewed in 1993, but whether anyone wishes
20 * to take on this obligation from the USSR is questionable.
21 *
22 * This code is placed in the public domain.
23 */
24
25 /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
26 * All modifications are placed under the license of libmcrypt.
27 */
28
29 /* $Id: gost.c,v 1.6 2000/02/02 20:15:50 nikos Exp $ */
30
31 #include "libdefs.h"
32 #include "swap.h"
33 /*
34 * If you read the standard, it belabors the point of copying corresponding
35 * bits from point A to point B quite a bit. It helps to understand that
36 * the standard is uniformly little-endian, although it numbers bits from
37 * 1 rather than 0, so bit n has value 2^(n-1). The least significant bit
38 * of the 32-bit words that are manipulated in the algorithm is the first,
39 * lowest-numbered, in the bit string.
40 */
41
42 void _mcrypt_kboxinit(void);
43
44 /*
45 * The standard does not specify the contents of the 8 4 bit->4 bit
46 * substitution boxes, saying they're a parameter of the network
47 * being set up. For illustration purposes here, I have used
48 * the first rows of the 8 S-boxes from the DES. (Note that the
49 * DES S-boxes are numbered starting from 1 at the msb. In keeping
50 * with the rest of the GOST, I have used little-endian numbering.
51 * Thus, k8 is S-box 1.
52 *
53 * Obviously, a careful look at the cryptographic properties of the cipher
54 * must be undertaken before "production" substitution boxes are defined.
55 *
56 * The standard also does not specify a standard bit-string representation
57 * for the contents of these blocks.
58 */
59
60 /* These are NOT the original s-boxes. I replaced them with the ones
61 * found in Applied Cryptography book by Bruce Schneier. These were
62 * used in an application for the Central Bank of the Russian Federation
63 * --Nikos
64 */
65 static int init=0;
66
67 static unsigned char const k1[16] = {
68 1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 2
69 };
70 static unsigned char const k2[16] = {
71 13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12
72 };
73 static unsigned char const k3[16] = {
74 4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14
75 };
76 static unsigned char const k4[16] = {
77 6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2
78 };
79 static unsigned char const k5[16] = {
80 7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3
81 };
82 static unsigned char const k6[16] = {
83 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11
84 };
85 static unsigned char const k7[16] = {
86 14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9
87 };
88 static unsigned char const k8[16] = {
89 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3
90 };
91
92 /* Byte-at-a-time substitution boxes */
93 static unsigned char k87[256];
94 static unsigned char k65[256];
95 static unsigned char k43[256];
96 static unsigned char k21[256];
97
98 /*
99 * Build byte-at-a-time subtitution tables.
100 * This must be called once for global setup.
101 */
102
103 void _mcrypt_gost_set_key (word32 *inst, word32* key, int len) {
104
105 _mcrypt_kboxinit();
106 inst[0] = 0; inst[1] = 0;
107 inst[2] = 0; inst[3] = 0;
108 inst[4] = 0; inst[5] = 0;
109 inst[6] = 0; inst[7] = 0;
110 memmove( inst, key, len);
111 #ifdef WORDS_BIGENDIAN
112 inst[0] = byteswap(inst[0]);
113 inst[1] = byteswap(inst[1]);
114 inst[2] = byteswap(inst[2]);
115 inst[3] = byteswap(inst[3]);
116 inst[4] = byteswap(inst[4]);
117 inst[5] = byteswap(inst[5]);
118 inst[6] = byteswap(inst[6]);
119 inst[7] = byteswap(inst[7]);
120 #endif
121 }
122
123 void _mcrypt_kboxinit(void)
124 {
125 int i;
126
127 if (init==0) {
128 init=1;
129 for (i = 0; i < 256; i++) {
130 k87[i] = k8[i >> 4] << 4 | k7[i & 15];
131 k65[i] = k6[i >> 4] << 4 | k5[i & 15];
132 k43[i] = k4[i >> 4] << 4 | k3[i & 15];
133 k21[i] = k2[i >> 4] << 4 | k1[i & 15];
134 }
135 }
136
137 }
138
139 /*
140 * Do the substitution and rotation that are the core of the operation,
141 * like the expansion, substitution and permutation of the DES.
142 * It would be possible to perform DES-like optimisations and store
143 * the table entries as 32-bit words, already rotated, but the
144 * efficiency gain is questionable.
145 *
146 * This should be inlined for maximum speed
147 */
148 static word32 f(word32 x)
149 {
150 /* Do substitutions */
151 # if 0
152 /* This is annoyingly slow */
153 x = k8[x >> 28 & 15] << 28 | k7[x >> 24 & 15] << 24 |
154 k6[x >> 20 & 15] << 20 | k5[x >> 16 & 15] << 16 |
155 k4[x >> 12 & 15] << 12 | k3[x >> 8 & 15] << 8 |
156 k2[x >> 4 & 15] << 4 | k1[x & 15];
157 # else
158 /* This is faster */
159 x = k87[x >> 24 & 255] << 24 | k65[x >> 16 & 255] << 16 |
160 k43[x >> 8 & 255] << 8 | k21[x & 255];
161 # endif
162
163 /* Rotate left 11 bits */
164 return x << 11 | x >> (32 - 11);
165
166 }
167
168 /*
169 * The GOST standard defines the input in terms of bits 1..64, with
170 * bit 1 being the lsb of in[0] and bit 64 being the msb of in[1].
171 *
172 * The keys are defined similarly, with bit 256 being the msb of key[7].
173 */
174 void _mcrypt_gost_encrypt(word32 const key[8], word32 * in)
175 {
176 register word32 n1, n2; /* As named in the GOST */
177
178 /* Added to make it compatible with bigendian machines
179 * --nikos
180 */
181
182 #ifndef WORDS_BIGENDIAN
183 n1 = byteswap(in[0]);
184 n2 = byteswap(in[1]);
185 #else
186 n1 = in[0];
187 n2 = in[1];
188 #endif
189
190 /* Instead of swapping halves, swap names each round */
191 n2 ^= f(n1 + key[0]);
192 n1 ^= f(n2 + key[1]);
193 n2 ^= f(n1 + key[2]);
194 n1 ^= f(n2 + key[3]);
195 n2 ^= f(n1 + key[4]);
196 n1 ^= f(n2 + key[5]);
197 n2 ^= f(n1 + key[6]);
198 n1 ^= f(n2 + key[7]);
199
200 n2 ^= f(n1 + key[0]);
201 n1 ^= f(n2 + key[1]);
202 n2 ^= f(n1 + key[2]);
203 n1 ^= f(n2 + key[3]);
204 n2 ^= f(n1 + key[4]);
205 n1 ^= f(n2 + key[5]);
206 n2 ^= f(n1 + key[6]);
207 n1 ^= f(n2 + key[7]);
208
209 n2 ^= f(n1 + key[0]);
210 n1 ^= f(n2 + key[1]);
211 n2 ^= f(n1 + key[2]);
212 n1 ^= f(n2 + key[3]);
213 n2 ^= f(n1 + key[4]);
214 n1 ^= f(n2 + key[5]);
215 n2 ^= f(n1 + key[6]);
216 n1 ^= f(n2 + key[7]);
217
218 n2 ^= f(n1 + key[7]);
219 n1 ^= f(n2 + key[6]);
220 n2 ^= f(n1 + key[5]);
221 n1 ^= f(n2 + key[4]);
222 n2 ^= f(n1 + key[3]);
223 n1 ^= f(n2 + key[2]);
224 n2 ^= f(n1 + key[1]);
225 n1 ^= f(n2 + key[0]);
226
227 /* There is no swap after the last round */
228
229 #ifndef WORDS_BIGENDIAN
230 in[0] = byteswap(n2);
231 in[1] = byteswap(n1);
232 #else
233 in[0] = n2;
234 in[1] = n1;
235 #endif
236 }
237
238
239 /*
240 * The key schedule is somewhat different for decryption.
241 * (The key table is used once forward and three times backward.)
242 * You could define an expanded key, or just write the code twice,
243 * as done here.
244 */
245 void _mcrypt_gost_decrypt(word32 const key[8], word32 * in)
246 {
247 register word32 n1, n2; /* As named in the GOST */
248
249 #ifndef WORDS_BIGENDIAN
250 n1 = byteswap(in[0]);
251 n2 = byteswap(in[1]);
252 #else
253 n1 = in[0];
254 n2 = in[1];
255 #endif
256
257 n2 ^= f(n1 + key[0]);
258 n1 ^= f(n2 + key[1]);
259 n2 ^= f(n1 + key[2]);
260 n1 ^= f(n2 + key[3]);
261 n2 ^= f(n1 + key[4]);
262 n1 ^= f(n2 + key[5]);
263 n2 ^= f(n1 + key[6]);
264 n1 ^= f(n2 + key[7]);
265
266 n2 ^= f(n1 + key[7]);
267 n1 ^= f(n2 + key[6]);
268 n2 ^= f(n1 + key[5]);
269 n1 ^= f(n2 + key[4]);
270 n2 ^= f(n1 + key[3]);
271 n1 ^= f(n2 + key[2]);
272 n2 ^= f(n1 + key[1]);
273 n1 ^= f(n2 + key[0]);
274
275 n2 ^= f(n1 + key[7]);
276 n1 ^= f(n2 + key[6]);
277 n2 ^= f(n1 + key[5]);
278 n1 ^= f(n2 + key[4]);
279 n2 ^= f(n1 + key[3]);
280 n1 ^= f(n2 + key[2]);
281 n2 ^= f(n1 + key[1]);
282 n1 ^= f(n2 + key[0]);
283
284 n2 ^= f(n1 + key[7]);
285 n1 ^= f(n2 + key[6]);
286 n2 ^= f(n1 + key[5]);
287 n1 ^= f(n2 + key[4]);
288 n2 ^= f(n1 + key[3]);
289 n1 ^= f(n2 + key[2]);
290 n2 ^= f(n1 + key[1]);
291 n1 ^= f(n2 + key[0]);
292
293 #ifndef WORDS_BIGENDIAN
294 in[0] = byteswap(n2);
295 in[1] = byteswap(n1);
296 #else
297 in[0] = n2;
298 in[1] = n1;
299 #endif
300
301 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26