chiark / gitweb /
Version bump.
[catacomb] / des-base.h
1 /* -*-c-*-
2  *
3  * $Id: des-base.h,v 1.2 1999/12/10 23:29:48 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 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: des-base.h,v $
33  * Revision 1.2  1999/12/10 23:29:48  mdw
34  * Change header file guard names.
35  *
36  * Revision 1.1  1999/09/03 08:41:11  mdw
37  * Initial import.
38  *
39  */
40
41 #ifndef CATACOMB_DES_BASE_H
42 #define CATACOMB_DES_BASE_H
43
44 #ifdef __cplusplus
45   extern "C" {
46 #endif
47
48 /*----- Header files ------------------------------------------------------*/
49
50 #include <mLib/bits.h>
51
52 /*----- External data -----------------------------------------------------*/
53
54 extern uint32 des_sp[8][64];
55
56 /*----- Macros ------------------------------------------------------------*/
57
58 /* --- @DES_ROUND@ --- *
59  *
60  * This is the basic DES round function.  The inputs are the two subkey
61  * halves, and the left and right block halves.  Note that the block halves
62  * are rotated left one place at this point.  This wraps what's meant to be
63  * the top bit around to the bottom, so I get a clear run at the S-boxes.
64  */
65
66 #define DES_ROUND(ka, kb, x, y) do {                                    \
67   uint32 _t = (y) ^ (ka);                                               \
68   (x) ^= des_sp[7][(_t >>  0) & 0x3f] ^                                 \
69          des_sp[5][(_t >>  8) & 0x3f] ^                                 \
70          des_sp[3][(_t >> 16) & 0x3f] ^                                 \
71          des_sp[1][(_t >> 24) & 0x3f];                                  \
72   _t = ROR32((y), 4) ^ (kb);                                            \
73   (x) ^= des_sp[6][(_t >>  0) & 0x3f] ^                                 \
74          des_sp[4][(_t >>  8) & 0x3f] ^                                 \
75          des_sp[2][(_t >> 16) & 0x3f] ^                                 \
76          des_sp[0][(_t >> 24) & 0x3f];                                  \
77 } while (0)
78
79 /* --- @DES_IP@, @DES_IPINV@ --- *
80  *
81  * The cryptographically useless initial and final permutations.  The initial
82  * permutation also rotates the two block halves left by one place.  This is
83  * undone by the inverse permutation at the end.
84  */
85
86 #define DES_IP(x, y) do {                                               \
87   uint32 _t;                                                            \
88   _t = (y ^ (x >> 4)) & 0x0f0f0f0f; y ^= _t; x ^= _t << 4;              \
89   _t = (x ^ (x >> 18)) & 0x00003333; x ^= _t; x ^= _t << 18;            \
90   _t = (y ^ (y >> 18)) & 0x00003333; y ^= _t; y ^= _t << 18;            \
91   _t = (x ^ (x >> 9)) & 0x00550055; x ^= _t; x ^= _t << 9;              \
92   _t = (y ^ (y >> 9)) & 0x00550055; y ^= _t; y ^= _t << 9;              \
93   _t = (x ^ (x >> 24)) & 0x000000ff; x ^= _t; x ^= _t << 24;            \
94   _t = (y ^ (y >> 24)) & 0x000000ff; y ^= _t; y ^= _t << 24;            \
95   _t = (y ^ (x >> 16)) & 0x0000ffff; y ^= _t; x ^= _t << 16;            \
96   x = ROL32(x, 1); y = ROL32(y, 1);                                     \
97 } while (0)
98
99 #define DES_IPINV(x, y) do {                                            \
100   uint32 _t;                                                            \
101   x = ROR32(x, 1); y = ROR32(y, 1);                                     \
102   _t = (y ^ (x >> 16)) & 0x0000ffff; y ^= _t; x ^= _t << 16;            \
103   _t = (x ^ (x >> 24)) & 0x000000ff; x ^= _t; x ^= _t << 24;            \
104   _t = (y ^ (y >> 24)) & 0x000000ff; y ^= _t; y ^= _t << 24;            \
105   _t = (y ^ (x >> 4)) & 0x0f0f0f0f; y ^= _t; x ^= _t << 4;              \
106   _t = (x ^ (x >> 18)) & 0x00003333; x ^= _t; x ^= _t << 18;            \
107   _t = (y ^ (y >> 18)) & 0x00003333; y ^= _t; y ^= _t << 18;            \
108   _t = (x ^ (x >> 9)) & 0x00550055; x ^= _t; x ^= _t << 9;              \
109   _t = (y ^ (y >> 9)) & 0x00550055; y ^= _t; y ^= _t << 9;              \
110 } while (0)
111
112 /* --- @DES_EBLK@, @DES_DBLK@ --- *
113  *
114  * Whole block encryption and decryption.
115  */
116
117 #define DES_EBLK(k, a, b, c, d) do {                                    \
118   const uint32 *_k = (k);                                               \
119   uint32 _x = (a), _y = (b);                                            \
120   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
121   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
122   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
123   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
124   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
125   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
126   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
127   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
128   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
129   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
130   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
131   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
132   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
133   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
134   DES_ROUND(_k[0], _k[1], _x, _y); _k += 2;                             \
135   DES_ROUND(_k[0], _k[1], _y, _x); _k += 2;                             \
136   (c) = _y;                                                             \
137   (d) = _x;                                                             \
138 } while (0)
139
140 #define DES_DBLK(k, a, b, c, d) do {                                    \
141   const uint32 *_k = (k) + 32;                                          \
142   uint32 _x = (a), _y = (b);                                            \
143   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
144   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
145   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
146   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
147   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
148   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
149   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
150   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
151   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
152   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
153   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
154   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
155   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
156   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
157   _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y);                             \
158   _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x);                             \
159   (c) = _y;                                                             \
160   (d) = _x;                                                             \
161 } while (0)
162
163 /*----- That's all, folks -------------------------------------------------*/
164
165 #ifdef __cplusplus
166   }
167 #endif
168
169 #endif