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