chiark / gitweb /
ec-bin (ec_binproj): Make curve setup faster.
[catacomb] / des-base.h
1 /* -*-c-*-
2  *
3  * $Id: des-base.h,v 1.4 2004/04/08 01:36:15 mdw Exp $
4  *
5  * Common features for DES implementation
6  *
7  * (c) 1999 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 #ifndef CATACOMB_DES_BASE_H
31 #define CATACOMB_DES_BASE_H
32
33 #ifdef __cplusplus
34   extern "C" {
35 #endif
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #include <mLib/bits.h>
40
41 /*----- External data -----------------------------------------------------*/
42
43 extern const uint32 des_sp[8][64];
44
45 /*----- Macros ------------------------------------------------------------*/
46
47 /* --- @DES_ROUND@ --- *
48  *
49  * This is the basic DES round function.  The inputs are the two subkey
50  * halves, and the left and right block halves.  Note that the block halves
51  * are rotated left one place at this point.  This wraps what's meant to be
52  * the top bit around to the bottom, so I get a clear run at the S-boxes.
53  */
54
55 #define DES_ROUND(ka, kb, x, y) do {                                    \
56   uint32 _t = (y) ^ (ka);                                               \
57   (x) ^= des_sp[7][(_t >>  0) & 0x3f] ^                                 \
58          des_sp[5][(_t >>  8) & 0x3f] ^                                 \
59          des_sp[3][(_t >> 16) & 0x3f] ^                                 \
60          des_sp[1][(_t >> 24) & 0x3f];                                  \
61   _t = ROR32((y), 4) ^ (kb);                                            \
62   (x) ^= des_sp[6][(_t >>  0) & 0x3f] ^                                 \
63          des_sp[4][(_t >>  8) & 0x3f] ^                                 \
64          des_sp[2][(_t >> 16) & 0x3f] ^                                 \
65          des_sp[0][(_t >> 24) & 0x3f];                                  \
66 } while (0)
67
68 /* --- @DES_IP@, @DES_IPINV@ --- *
69  *
70  * The cryptographically useless initial and final permutations.  The initial
71  * permutation also rotates the two block halves left by one place.  This is
72  * undone by the inverse permutation at the end.
73  */
74
75 #define DES_IP(x, y) do {                                               \
76   uint32 _t;                                                            \
77   _t = (y ^ (x >> 4)) & 0x0f0f0f0f; y ^= _t; x ^= _t << 4;              \
78   _t = (x ^ (x >> 18)) & 0x00003333; x ^= _t; x ^= _t << 18;            \
79   _t = (y ^ (y >> 18)) & 0x00003333; y ^= _t; y ^= _t << 18;            \
80   _t = (x ^ (x >> 9)) & 0x00550055; x ^= _t; x ^= _t << 9;              \
81   _t = (y ^ (y >> 9)) & 0x00550055; y ^= _t; y ^= _t << 9;              \
82   _t = (x ^ (x >> 24)) & 0x000000ff; x ^= _t; x ^= _t << 24;            \
83   _t = (y ^ (y >> 24)) & 0x000000ff; y ^= _t; y ^= _t << 24;            \
84   _t = (y ^ (x >> 16)) & 0x0000ffff; y ^= _t; x ^= _t << 16;            \
85   x = ROL32(x, 1); y = ROL32(y, 1);                                     \
86 } while (0)
87
88 #define DES_IPINV(x, y) do {                                            \
89   uint32 _t;                                                            \
90   x = ROR32(x, 1); y = ROR32(y, 1);                                     \
91   _t = (y ^ (x >> 16)) & 0x0000ffff; y ^= _t; x ^= _t << 16;            \
92   _t = (x ^ (x >> 24)) & 0x000000ff; x ^= _t; x ^= _t << 24;            \
93   _t = (y ^ (y >> 24)) & 0x000000ff; y ^= _t; y ^= _t << 24;            \
94   _t = (y ^ (x >> 4)) & 0x0f0f0f0f; y ^= _t; x ^= _t << 4;              \
95   _t = (x ^ (x >> 18)) & 0x00003333; x ^= _t; x ^= _t << 18;            \
96   _t = (y ^ (y >> 18)) & 0x00003333; y ^= _t; y ^= _t << 18;            \
97   _t = (x ^ (x >> 9)) & 0x00550055; x ^= _t; x ^= _t << 9;              \
98   _t = (y ^ (y >> 9)) & 0x00550055; y ^= _t; y ^= _t << 9;              \
99 } while (0)
100
101 /* --- @DES_EBLK@, @DES_DBLK@ --- *
102  *
103  * Whole block encryption and decryption.
104  */
105
106 #define DES_EBLK(k, a, b, c, d) do {                                    \
107   const uint32 *_k = (k);                                               \
108   uint32 _x = (a), _y = (b);                                            \
109   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
110   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
111   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
112   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
113   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
114   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
115   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
116   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
117   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
118   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
119   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
120   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
121   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
122   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
123   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
124   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
125   (c) = _y;                                                             \
126   (d) = _x;                                                             \
127 } while (0)
128
129 #define DES_DBLK(k, a, b, c, d) do {                                    \
130   const uint32 *_k = (k) + 32;                                          \
131   uint32 _x = (a), _y = (b);                                            \
132   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
133   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
134   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
135   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
136   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
137   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
138   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
139   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
140   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
141   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
142   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
143   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
144   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
145   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
146   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
147   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
148   (c) = _y;                                                             \
149   (d) = _x;                                                             \
150 } while (0)
151
152 /*----- That's all, folks -------------------------------------------------*/
153
154 #ifdef __cplusplus
155   }
156 #endif
157
158 #endif