~ubuntu-branches/ubuntu/dapper/nettle/dapper

« back to all changes in this revision

Viewing changes to desCode.h

  • Committer: Bazaar Package Importer
  • Author(s): Marek Habersack
  • Date: 2004-05-04 15:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20040504155602-7jbhw5mabvwksl3j
Tags: upstream-1.10
ImportĀ upstreamĀ versionĀ 1.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* desCode.h
 
2
 *
 
3
 * $Id: desCode.h,v 1.3 2003/08/17 15:31:51 nisse Exp $ */
 
4
 
 
5
/*      des - fast & portable DES encryption & decryption.
 
6
 *      Copyright (C) 1992  Dana L. How
 
7
 *      Please see the file `descore.README' for the complete copyright notice.
 
8
 */
 
9
 
 
10
#include "des.h"
 
11
 
 
12
/* optional customization:
 
13
 * the idea here is to alter the code so it will still run correctly
 
14
 * on any machine,  but the quickest on the specific machine in mind.
 
15
 * note that these silly tweaks can give you a 15%-20% speed improvement
 
16
 * on the sparc -- it's probably even more significant on the 68000. */
 
17
 
 
18
/* take care of machines with incredibly few registers */
 
19
#if     defined(i386)
 
20
#define REGISTER                /* only x, y, z will be declared register */
 
21
#else
 
22
#define REGISTER        register
 
23
#endif  /* i386 */
 
24
 
 
25
/* is auto inc/dec faster than 7bit unsigned indexing? */
 
26
#if     defined(vax) || defined(mc68000)
 
27
#define FIXR            r += 32;
 
28
#define FIXS            s +=  8;
 
29
#define PREV(v,o)       *--v
 
30
#define NEXT(v,o)       *v++
 
31
#else
 
32
#define FIXR
 
33
#define FIXS
 
34
#define PREV(v,o)       v[o]
 
35
#define NEXT(v,o)       v[o]
 
36
#endif
 
37
 
 
38
/* if no machine type, default is indexing, 6 registers and cheap literals */
 
39
#if     !defined(i386) && !defined(vax) && !defined(mc68000) && !defined(sparc)
 
40
#define vax
 
41
#endif
 
42
 
 
43
 
 
44
/* handle a compiler which can't reallocate registers */
 
45
/* The BYTE type is used as parameter for the encrypt/decrypt functions.
 
46
 * It's pretty bad to have the function prototypes depend on
 
47
 * a macro definition that the users of the function doesn't
 
48
 * know about. /Niels */
 
49
#if     0                       /* didn't feel like deleting */
 
50
#define SREGFREE        ; s = (uint8_t *) D
 
51
#define DEST            s
 
52
#define D               m0
 
53
#define BYTE            uint32_t
 
54
#else
 
55
#define SREGFREE
 
56
#define DEST            d
 
57
#define D               d
 
58
#define BYTE            uint8_t
 
59
#endif
 
60
 
 
61
/* handle constants in the optimal way for 386 & vax */
 
62
/* 386: we declare 3 register variables (see above) and use 3 more variables;
 
63
 * vax: we use 6 variables, all declared register;
 
64
 * we assume address literals are cheap & unrestricted;
 
65
 * we assume immediate constants are cheap & unrestricted. */
 
66
#if     defined(i386) || defined(vax)
 
67
#define MQ0      des_bigmap
 
68
#define MQ1     (des_bigmap +  64)
 
69
#define MQ2     (des_bigmap + 128)
 
70
#define MQ3     (des_bigmap + 192)
 
71
#define HQ0(z)                          /*      z |= 0x01000000L; */
 
72
#define HQ2(z)                          /*      z |= 0x03000200L; */
 
73
#define LQ0(z)  0xFCFC & z
 
74
#define LQ1(z)  0xFCFC & z
 
75
#define LQ2(z)  0xFCFC & z
 
76
#define LQ3(z)  0xFCFC & z
 
77
#define SQ      16
 
78
#define MS0      des_keymap 
 
79
#define MS1     (des_keymap +  64)
 
80
#define MS2     (des_keymap + 128)
 
81
#define MS3     (des_keymap + 192)
 
82
#define MS4     (des_keymap + 256)
 
83
#define MS5     (des_keymap + 320)
 
84
#define MS6     (des_keymap + 384)
 
85
#define MS7     (des_keymap + 448)
 
86
#define HS(z)
 
87
#define LS0(z)  0xFC & z
 
88
#define LS1(z)  0xFC & z
 
89
#define LS2(z)  0xFC & z
 
90
#define LS3(z)  0xFC & z
 
91
#define REGQUICK
 
92
#define SETQUICK
 
93
#define REGSMALL
 
94
#define SETSMALL
 
95
#endif  /* defined(i386) || defined(vax) */
 
96
 
 
97
/* handle constants in the optimal way for mc68000 */
 
98
/* in addition to the core 6 variables, we declare 3 registers holding constants
 
99
 * and 4 registers holding address literals.
 
100
 * at most 6 data values and 5 address values are actively used at once.
 
101
 * we assume address literals are so expensive we never use them;
 
102
 * we assume constant index offsets > 127 are expensive, so they are not used.
 
103
 * we assume all constants are expensive and put them in registers,
 
104
 * including shift counts greater than 8. */
 
105
#if     defined(mc68000)
 
106
#define MQ0     m0
 
107
#define MQ1     m1
 
108
#define MQ2     m2
 
109
#define MQ3     m3
 
110
#define HQ0(z)
 
111
#define HQ2(z)
 
112
#define LQ0(z)  k0 & z
 
113
#define LQ1(z)  k0 & z
 
114
#define LQ2(z)  k0 & z
 
115
#define LQ3(z)  k0 & z
 
116
#define SQ      k1
 
117
#define MS0     m0
 
118
#define MS1     m0
 
119
#define MS2     m1
 
120
#define MS3     m1
 
121
#define MS4     m2
 
122
#define MS5     m2
 
123
#define MS6     m3
 
124
#define MS7     m3
 
125
#define HS(z)   z |= k0;
 
126
#define LS0(z)  k1 & z
 
127
#define LS1(z)  k2 & z
 
128
#define LS2(z)  k1 & z
 
129
#define LS3(z)  k2 & z
 
130
#define REGQUICK                                \
 
131
        register uint32_t k0, k1;               \
 
132
        register uint32_t *m0, *m1, *m2, *m3;
 
133
#define SETQUICK                                \
 
134
        ; k0 = 0xFCFC                           \
 
135
        ; k1 = 16                               \
 
136
        /*k2 = 28 to speed up ROL */            \
 
137
        ; m0 = des_bigmap                       \
 
138
        ; m1 = m0 + 64                          \
 
139
        ; m2 = m1 + 64                          \
 
140
        ; m3 = m2 + 64
 
141
#define REGSMALL                                \
 
142
        register uint32_t k0, k1, k2;           \
 
143
        register uint32_t *m0, *m1, *m2, *m3;
 
144
#define SETSMALL                                \
 
145
        ; k0 = 0x01000100L                      \
 
146
        ; k1 = 0x0FC                            \
 
147
        ; k2 = 0x1FC                            \
 
148
        ; m0 = des_keymap                       \
 
149
        ; m1 = m0 + 128                         \
 
150
        ; m2 = m1 + 128                         \
 
151
        ; m3 = m2 + 128
 
152
#endif  /* defined(mc68000) */
 
153
 
 
154
/* handle constants in the optimal way for sparc */
 
155
/* in addition to the core 6 variables, we either declare:
 
156
 * 4 registers holding address literals and 1 register holding a constant, or
 
157
 * 8 registers holding address literals.
 
158
 * up to 14 register variables are declared (sparc has %i0-%i5, %l0-%l7).
 
159
 * we assume address literals are so expensive we never use them;
 
160
 * we assume any constant with >10 bits is expensive and put it in a register,
 
161
 * and any other is cheap and is coded in-line. */
 
162
#if     defined(sparc)
 
163
#define MQ0     m0
 
164
#define MQ1     m1
 
165
#define MQ2     m2
 
166
#define MQ3     m3
 
167
#define HQ0(z)
 
168
#define HQ2(z)
 
169
#define LQ0(z)  k0 & z
 
170
#define LQ1(z)  k0 & z
 
171
#define LQ2(z)  k0 & z
 
172
#define LQ3(z)  k0 & z
 
173
#define SQ      16
 
174
#define MS0     m0
 
175
#define MS1     m1
 
176
#define MS2     m2
 
177
#define MS3     m3
 
178
#define MS4     m4
 
179
#define MS5     m5
 
180
#define MS6     m6
 
181
#define MS7     m7
 
182
#define HS(z)
 
183
#define LS0(z)  0xFC & z
 
184
#define LS1(z)  0xFC & z
 
185
#define LS2(z)  0xFC & z
 
186
#define LS3(z)  0xFC & z
 
187
#define REGQUICK                                \
 
188
        register uint32_t k0;                   \
 
189
        register uint32_t *m0, *m1, *m2, *m3;
 
190
#define SETQUICK                                \
 
191
        ; k0 = 0xFCFC                           \
 
192
        ; m0 = des_bigmap                       \
 
193
        ; m1 = m0 + 64                          \
 
194
        ; m2 = m1 + 64                          \
 
195
        ; m3 = m2 + 64
 
196
#define REGSMALL                                \
 
197
        register uint32_t *m0, *m1, *m2, *m3, *m4, *m5, *m6, *m7;
 
198
#define SETSMALL                                \
 
199
        ; m0 = des_keymap                       \
 
200
        ; m1 = m0 + 64                          \
 
201
        ; m2 = m1 + 64                          \
 
202
        ; m3 = m2 + 64                          \
 
203
        ; m4 = m3 + 64                          \
 
204
        ; m5 = m4 + 64                          \
 
205
        ; m6 = m5 + 64                          \
 
206
        ; m7 = m6 + 64
 
207
#endif  /* defined(sparc) */
 
208
 
 
209
 
 
210
/* some basic stuff */
 
211
 
 
212
/* generate addresses from a base and an index */
 
213
/* FIXME: This is used only as *ADD(msi,lsi(z)) or *ADD(mqi,lqi(z)).
 
214
 * Why not use plain indexing instead? /Niels */
 
215
#define ADD(b,x)        (uint32_t *) ((uint8_t *)b + (x))
 
216
 
 
217
/* low level rotate operations */
 
218
#define NOP(d,c,o)
 
219
#define ROL(d,c,o)      d = d << c | d >> o
 
220
#define ROR(d,c,o)      d = d >> c | d << o
 
221
#define ROL1(d)         ROL(d, 1, 31)
 
222
#define ROR1(d)         ROR(d, 1, 31)
 
223
 
 
224
/* elementary swap for doing IP/FP */
 
225
#define SWAP(x,y,m,b)                           \
 
226
        z  = ((x >> b) ^ y) & m;                \
 
227
        x ^= z << b;                            \
 
228
        y ^= z
 
229
 
 
230
 
 
231
/* the following macros contain all the important code fragments */
 
232
 
 
233
/* load input data, then setup special registers holding constants */
 
234
#define TEMPQUICK(LOAD)                         \
 
235
        REGQUICK                                \
 
236
        LOAD()                                  \
 
237
        SETQUICK
 
238
#define TEMPSMALL(LOAD)                         \
 
239
        REGSMALL                                \
 
240
        LOAD()                                  \
 
241
        SETSMALL
 
242
 
 
243
/* load data */
 
244
#define LOADDATA(x,y)                           \
 
245
        FIXS                                    \
 
246
        y  = PREV(s, 7); y<<= 8;                \
 
247
        y |= PREV(s, 6); y<<= 8;                \
 
248
        y |= PREV(s, 5); y<<= 8;                \
 
249
        y |= PREV(s, 4);                        \
 
250
        x  = PREV(s, 3); x<<= 8;                \
 
251
        x |= PREV(s, 2); x<<= 8;                \
 
252
        x |= PREV(s, 1); x<<= 8;                \
 
253
        x |= PREV(s, 0)                         \
 
254
        SREGFREE
 
255
/* load data without initial permutation and put into efficient position */
 
256
#define LOADCORE()                              \
 
257
        LOADDATA(x, y);                         \
 
258
        ROR1(x);                                \
 
259
        ROR1(y)
 
260
/* load data, do the initial permutation and put into efficient position */
 
261
#define LOADFIPS()                              \
 
262
        LOADDATA(y, x);                         \
 
263
        SWAP(x, y, 0x0F0F0F0FL, 004);           \
 
264
        SWAP(y, x, 0x0000FFFFL, 020);           \
 
265
        SWAP(x, y, 0x33333333L, 002);           \
 
266
        SWAP(y, x, 0x00FF00FFL, 010);           \
 
267
        ROR1(x);                                \
 
268
        z  = (x ^ y) & 0x55555555L;             \
 
269
        y ^= z;                                 \
 
270
        x ^= z;                                 \
 
271
        ROR1(y)
 
272
 
 
273
 
 
274
/* core encryption/decryption operations */
 
275
/* S box mapping and P perm */
 
276
#define KEYMAPSMALL(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\
 
277
        hs(z)                                   \
 
278
        x ^= *ADD(ms3, ls3(z));                 \
 
279
        z>>= 8;                                 \
 
280
        x ^= *ADD(ms2, ls2(z));                 \
 
281
        z>>= 8;                                 \
 
282
        x ^= *ADD(ms1, ls1(z));                 \
 
283
        z>>= 8;                                 \
 
284
        x ^= *ADD(ms0, ls0(z))
 
285
/* alternate version: use 64k of tables */
 
286
#define KEYMAPQUICK(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\
 
287
        hq(z)                                   \
 
288
        x ^= *ADD(mq0, lq0(z));                 \
 
289
        z>>= sq;                                \
 
290
        x ^= *ADD(mq1, lq1(z))
 
291
/* apply 24 key bits and do the odd  s boxes */
 
292
#define S7S1(x,y,z,r,m,KEYMAP,LOAD)             \
 
293
        z  = LOAD(r, m);                        \
 
294
        z ^= y;                                 \
 
295
        KEYMAP(x,z,MQ0,MQ1,HQ0,LQ0,LQ1,SQ,MS0,MS1,MS2,MS3,HS,LS0,LS1,LS2,LS3)
 
296
/* apply 24 key bits and do the even s boxes */
 
297
#define S6S0(x,y,z,r,m,KEYMAP,LOAD)             \
 
298
        z  = LOAD(r, m);                        \
 
299
        z ^= y;                                 \
 
300
        ROL(z, 4, 28);                          \
 
301
        KEYMAP(x,z,MQ2,MQ3,HQ2,LQ2,LQ3,SQ,MS4,MS5,MS6,MS7,HS,LS0,LS1,LS2,LS3)
 
302
/* actual iterations.  equivalent except for UPDATE & swapping m and n */
 
303
#define ENCR(x,y,z,r,m,n,KEYMAP)                \
 
304
        S7S1(x,y,z,r,m,KEYMAP,NEXT);            \
 
305
        S6S0(x,y,z,r,n,KEYMAP,NEXT)
 
306
#define DECR(x,y,z,r,m,n,KEYMAP)                \
 
307
        S6S0(x,y,z,r,m,KEYMAP,PREV);            \
 
308
        S7S1(x,y,z,r,n,KEYMAP,PREV)
 
309
 
 
310
/* write out result in correct byte order */
 
311
#define SAVEDATA(x,y)                           \
 
312
        NEXT(DEST, 0) = x; x>>= 8;              \
 
313
        NEXT(DEST, 1) = x; x>>= 8;              \
 
314
        NEXT(DEST, 2) = x; x>>= 8;              \
 
315
        NEXT(DEST, 3) = x;                      \
 
316
        NEXT(DEST, 4) = y; y>>= 8;              \
 
317
        NEXT(DEST, 5) = y; y>>= 8;              \
 
318
        NEXT(DEST, 6) = y; y>>= 8;              \
 
319
        NEXT(DEST, 7) = y
 
320
/* write out result */
 
321
#define SAVECORE()                              \
 
322
        ROL1(x);                                \
 
323
        ROL1(y);                                \
 
324
        SAVEDATA(y, x)
 
325
/* do final permutation and write out result */
 
326
#define SAVEFIPS()                              \
 
327
        ROL1(x);                                \
 
328
        z  = (x ^ y) & 0x55555555L;             \
 
329
        y ^= z;                                 \
 
330
        x ^= z;                                 \
 
331
        ROL1(y);                                \
 
332
        SWAP(x, y, 0x00FF00FFL, 010);           \
 
333
        SWAP(y, x, 0x33333333L, 002);           \
 
334
        SWAP(x, y, 0x0000FFFFL, 020);           \
 
335
        SWAP(y, x, 0x0F0F0F0FL, 004);           \
 
336
        SAVEDATA(x, y)
 
337
 
 
338
 
 
339
/* the following macros contain the encryption/decryption skeletons */
 
340
 
 
341
#define ENCRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
 
342
                                                \
 
343
void                                            \
 
344
NAME(REGISTER BYTE *D,                          \
 
345
     REGISTER const uint32_t *r,                \
 
346
     REGISTER const uint8_t *s)                 \
 
347
{                                               \
 
348
        register uint32_t x, y, z;              \
 
349
                                                \
 
350
        /* declare temps & load data */         \
 
351
        TEMP(LOAD);                             \
 
352
                                                \
 
353
        /* do the 16 iterations */              \
 
354
        ENCR(x,y,z,r, 0, 1,KEYMAP);             \
 
355
        ENCR(y,x,z,r, 2, 3,KEYMAP);             \
 
356
        ENCR(x,y,z,r, 4, 5,KEYMAP);             \
 
357
        ENCR(y,x,z,r, 6, 7,KEYMAP);             \
 
358
        ENCR(x,y,z,r, 8, 9,KEYMAP);             \
 
359
        ENCR(y,x,z,r,10,11,KEYMAP);             \
 
360
        ENCR(x,y,z,r,12,13,KEYMAP);             \
 
361
        ENCR(y,x,z,r,14,15,KEYMAP);             \
 
362
        ENCR(x,y,z,r,16,17,KEYMAP);             \
 
363
        ENCR(y,x,z,r,18,19,KEYMAP);             \
 
364
        ENCR(x,y,z,r,20,21,KEYMAP);             \
 
365
        ENCR(y,x,z,r,22,23,KEYMAP);             \
 
366
        ENCR(x,y,z,r,24,25,KEYMAP);             \
 
367
        ENCR(y,x,z,r,26,27,KEYMAP);             \
 
368
        ENCR(x,y,z,r,28,29,KEYMAP);             \
 
369
        ENCR(y,x,z,r,30,31,KEYMAP);             \
 
370
                                                \
 
371
        /* save result */                       \
 
372
        SAVE();                                 \
 
373
                                                \
 
374
        return;                                 \
 
375
}
 
376
 
 
377
#define DECRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
 
378
                                                \
 
379
void                                            \
 
380
NAME(REGISTER BYTE *D,                          \
 
381
     REGISTER const uint32_t *r,                \
 
382
     REGISTER const uint8_t *s)                 \
 
383
{                                               \
 
384
        register uint32_t x, y, z;              \
 
385
                                                \
 
386
        /* declare temps & load data */         \
 
387
        TEMP(LOAD);                             \
 
388
                                                \
 
389
        /* do the 16 iterations */              \
 
390
        FIXR                                    \
 
391
        DECR(x,y,z,r,31,30,KEYMAP);             \
 
392
        DECR(y,x,z,r,29,28,KEYMAP);             \
 
393
        DECR(x,y,z,r,27,26,KEYMAP);             \
 
394
        DECR(y,x,z,r,25,24,KEYMAP);             \
 
395
        DECR(x,y,z,r,23,22,KEYMAP);             \
 
396
        DECR(y,x,z,r,21,20,KEYMAP);             \
 
397
        DECR(x,y,z,r,19,18,KEYMAP);             \
 
398
        DECR(y,x,z,r,17,16,KEYMAP);             \
 
399
        DECR(x,y,z,r,15,14,KEYMAP);             \
 
400
        DECR(y,x,z,r,13,12,KEYMAP);             \
 
401
        DECR(x,y,z,r,11,10,KEYMAP);             \
 
402
        DECR(y,x,z,r, 9, 8,KEYMAP);             \
 
403
        DECR(x,y,z,r, 7, 6,KEYMAP);             \
 
404
        DECR(y,x,z,r, 5, 4,KEYMAP);             \
 
405
        DECR(x,y,z,r, 3, 2,KEYMAP);             \
 
406
        DECR(y,x,z,r, 1, 0,KEYMAP);             \
 
407
                                                \
 
408
        /* save result */                       \
 
409
        SAVE();                                 \
 
410
                                                \
 
411
        return;                                 \
 
412
}