Merge pull request #113 from tesselode/fix-multi-targets
[wdl/wdl-ol.git] / WDL / des.cpp
blobf86f0c35299a0881115d017796a0a23172ebc750
1 /* Loosely based on:
3 * D3DES (V5.09) -
5 * A portable, public domain, version of the Data Encryption Standard.
7 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
9 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
10 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
14 #include "des.h"
16 static const unsigned char pc1[56] = {
17 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
18 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
19 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
20 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
22 static const unsigned char totrot[16] = { 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
24 static const unsigned char pc2[48] = {
25 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
26 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
27 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
28 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
30 static unsigned int SP1[64] = {
31 0x01010400, 0x00000000, 0x00010000, 0x01010404,
32 0x01010004, 0x00010404, 0x00000004, 0x00010000,
33 0x00000400, 0x01010400, 0x01010404, 0x00000400,
34 0x01000404, 0x01010004, 0x01000000, 0x00000004,
35 0x00000404, 0x01000400, 0x01000400, 0x00010400,
36 0x00010400, 0x01010000, 0x01010000, 0x01000404,
37 0x00010004, 0x01000004, 0x01000004, 0x00010004,
38 0x00000000, 0x00000404, 0x00010404, 0x01000000,
39 0x00010000, 0x01010404, 0x00000004, 0x01010000,
40 0x01010400, 0x01000000, 0x01000000, 0x00000400,
41 0x01010004, 0x00010000, 0x00010400, 0x01000004,
42 0x00000400, 0x00000004, 0x01000404, 0x00010404,
43 0x01010404, 0x00010004, 0x01010000, 0x01000404,
44 0x01000004, 0x00000404, 0x00010404, 0x01010400,
45 0x00000404, 0x01000400, 0x01000400, 0x00000000,
46 0x00010004, 0x00010400, 0x00000000, 0x01010004
49 static unsigned int SP2[64] = {
50 0x80108020, 0x80008000, 0x00008000, 0x00108020,
51 0x00100000, 0x00000020, 0x80100020, 0x80008020,
52 0x80000020, 0x80108020, 0x80108000, 0x80000000,
53 0x80008000, 0x00100000, 0x00000020, 0x80100020,
54 0x00108000, 0x00100020, 0x80008020, 0x00000000,
55 0x80000000, 0x00008000, 0x00108020, 0x80100000,
56 0x00100020, 0x80000020, 0x00000000, 0x00108000,
57 0x00008020, 0x80108000, 0x80100000, 0x00008020,
58 0x00000000, 0x00108020, 0x80100020, 0x00100000,
59 0x80008020, 0x80100000, 0x80108000, 0x00008000,
60 0x80100000, 0x80008000, 0x00000020, 0x80108020,
61 0x00108020, 0x00000020, 0x00008000, 0x80000000,
62 0x00008020, 0x80108000, 0x00100000, 0x80000020,
63 0x00100020, 0x80008020, 0x80000020, 0x00100020,
64 0x00108000, 0x00000000, 0x80008000, 0x00008020,
65 0x80000000, 0x80100020, 0x80108020, 0x00108000
68 static unsigned int SP3[64] = {
69 0x00000208, 0x08020200, 0x00000000, 0x08020008,
70 0x08000200, 0x00000000, 0x00020208, 0x08000200,
71 0x00020008, 0x08000008, 0x08000008, 0x00020000,
72 0x08020208, 0x00020008, 0x08020000, 0x00000208,
73 0x08000000, 0x00000008, 0x08020200, 0x00000200,
74 0x00020200, 0x08020000, 0x08020008, 0x00020208,
75 0x08000208, 0x00020200, 0x00020000, 0x08000208,
76 0x00000008, 0x08020208, 0x00000200, 0x08000000,
77 0x08020200, 0x08000000, 0x00020008, 0x00000208,
78 0x00020000, 0x08020200, 0x08000200, 0x00000000,
79 0x00000200, 0x00020008, 0x08020208, 0x08000200,
80 0x08000008, 0x00000200, 0x00000000, 0x08020008,
81 0x08000208, 0x00020000, 0x08000000, 0x08020208,
82 0x00000008, 0x00020208, 0x00020200, 0x08000008,
83 0x08020000, 0x08000208, 0x00000208, 0x08020000,
84 0x00020208, 0x00000008, 0x08020008, 0x00020200
87 static unsigned int SP4[64] = {
88 0x00802001, 0x00002081, 0x00002081, 0x00000080,
89 0x00802080, 0x00800081, 0x00800001, 0x00002001,
90 0x00000000, 0x00802000, 0x00802000, 0x00802081,
91 0x00000081, 0x00000000, 0x00800080, 0x00800001,
92 0x00000001, 0x00002000, 0x00800000, 0x00802001,
93 0x00000080, 0x00800000, 0x00002001, 0x00002080,
94 0x00800081, 0x00000001, 0x00002080, 0x00800080,
95 0x00002000, 0x00802080, 0x00802081, 0x00000081,
96 0x00800080, 0x00800001, 0x00802000, 0x00802081,
97 0x00000081, 0x00000000, 0x00000000, 0x00802000,
98 0x00002080, 0x00800080, 0x00800081, 0x00000001,
99 0x00802001, 0x00002081, 0x00002081, 0x00000080,
100 0x00802081, 0x00000081, 0x00000001, 0x00002000,
101 0x00800001, 0x00002001, 0x00802080, 0x00800081,
102 0x00002001, 0x00002080, 0x00800000, 0x00802001,
103 0x00000080, 0x00800000, 0x00002000, 0x00802080
106 static unsigned int SP5[64] = {
107 0x00000100, 0x02080100, 0x02080000, 0x42000100,
108 0x00080000, 0x00000100, 0x40000000, 0x02080000,
109 0x40080100, 0x00080000, 0x02000100, 0x40080100,
110 0x42000100, 0x42080000, 0x00080100, 0x40000000,
111 0x02000000, 0x40080000, 0x40080000, 0x00000000,
112 0x40000100, 0x42080100, 0x42080100, 0x02000100,
113 0x42080000, 0x40000100, 0x00000000, 0x42000000,
114 0x02080100, 0x02000000, 0x42000000, 0x00080100,
115 0x00080000, 0x42000100, 0x00000100, 0x02000000,
116 0x40000000, 0x02080000, 0x42000100, 0x40080100,
117 0x02000100, 0x40000000, 0x42080000, 0x02080100,
118 0x40080100, 0x00000100, 0x02000000, 0x42080000,
119 0x42080100, 0x00080100, 0x42000000, 0x42080100,
120 0x02080000, 0x00000000, 0x40080000, 0x42000000,
121 0x00080100, 0x02000100, 0x40000100, 0x00080000,
122 0x00000000, 0x40080000, 0x02080100, 0x40000100
125 static unsigned int SP6[64] = {
126 0x20000010, 0x20400000, 0x00004000, 0x20404010,
127 0x20400000, 0x00000010, 0x20404010, 0x00400000,
128 0x20004000, 0x00404010, 0x00400000, 0x20000010,
129 0x00400010, 0x20004000, 0x20000000, 0x00004010,
130 0x00000000, 0x00400010, 0x20004010, 0x00004000,
131 0x00404000, 0x20004010, 0x00000010, 0x20400010,
132 0x20400010, 0x00000000, 0x00404010, 0x20404000,
133 0x00004010, 0x00404000, 0x20404000, 0x20000000,
134 0x20004000, 0x00000010, 0x20400010, 0x00404000,
135 0x20404010, 0x00400000, 0x00004010, 0x20000010,
136 0x00400000, 0x20004000, 0x20000000, 0x00004010,
137 0x20000010, 0x20404010, 0x00404000, 0x20400000,
138 0x00404010, 0x20404000, 0x00000000, 0x20400010,
139 0x00000010, 0x00004000, 0x20400000, 0x00404010,
140 0x00004000, 0x00400010, 0x20004010, 0x00000000,
141 0x20404000, 0x20000000, 0x00400010, 0x20004010
144 static unsigned int SP7[64] = {
145 0x00200000, 0x04200002, 0x04000802, 0x00000000,
146 0x00000800, 0x04000802, 0x00200802, 0x04200800,
147 0x04200802, 0x00200000, 0x00000000, 0x04000002,
148 0x00000002, 0x04000000, 0x04200002, 0x00000802,
149 0x04000800, 0x00200802, 0x00200002, 0x04000800,
150 0x04000002, 0x04200000, 0x04200800, 0x00200002,
151 0x04200000, 0x00000800, 0x00000802, 0x04200802,
152 0x00200800, 0x00000002, 0x04000000, 0x00200800,
153 0x04000000, 0x00200800, 0x00200000, 0x04000802,
154 0x04000802, 0x04200002, 0x04200002, 0x00000002,
155 0x00200002, 0x04000000, 0x04000800, 0x00200000,
156 0x04200800, 0x00000802, 0x00200802, 0x04200800,
157 0x00000802, 0x04000002, 0x04200802, 0x04200000,
158 0x00200800, 0x00000000, 0x00000002, 0x04200802,
159 0x00000000, 0x00200802, 0x04200000, 0x00000800,
160 0x04000002, 0x04000800, 0x00000800, 0x00200002
163 static unsigned int SP8[64] = {
164 0x10001040, 0x00001000, 0x00040000, 0x10041040,
165 0x10000000, 0x10001040, 0x00000040, 0x10000000,
166 0x00040040, 0x10040000, 0x10041040, 0x00041000,
167 0x10041000, 0x00041040, 0x00001000, 0x00000040,
168 0x10040000, 0x10000040, 0x10001000, 0x00001040,
169 0x00041000, 0x00040040, 0x10040040, 0x10041000,
170 0x00001040, 0x00000000, 0x00000000, 0x10040040,
171 0x10000040, 0x10001000, 0x00041040, 0x00040000,
172 0x00041040, 0x00040000, 0x10041000, 0x00001000,
173 0x00000040, 0x10040040, 0x00001000, 0x00041040,
174 0x10001000, 0x00000040, 0x10000040, 0x10040000,
175 0x10040040, 0x10000000, 0x00040000, 0x10001040,
176 0x00000000, 0x10041040, 0x00040040, 0x10000040,
177 0x10040000, 0x10001000, 0x10001040, 0x00000000,
178 0x10041040, 0x00041000, 0x00041000, 0x00001040,
179 0x00001040, 0x00040040, 0x10000000, 0x10041000
182 WDL_DES::WDL_DES()
185 WDL_DES::~WDL_DES()
189 void WDL_DES::SetKey(const unsigned char *key8, bool isEncrypt)
191 int i;
192 unsigned char pc1m[56], pcr[56];
193 for ( i = 0; i < 56; i++ )
195 int l = pc1[i];
196 int m = l & 07;
197 pc1m[i] = (key8[l >> 3] & (1<<m)) ? 1 : 0;
200 for (i = 0; i < 16; i++)
202 int m = (isEncrypt?i:15-i) << 1;
203 int n = m + 1;
204 m_keydata[m] = m_keydata[n] = 0;
205 int j;
206 for (j = 0; j < 28; j++)
208 int l = j + totrot[i];
209 if( l < 28 ) pcr[j] = pc1m[l];
210 else pcr[j] = pc1m[l - 28];
212 for (j = 28; j < 56; j++)
214 int l = j + totrot[i];
215 if( l < 56 ) pcr[j] = pc1m[l];
216 else pcr[j] = pc1m[l - 28];
218 for (j = 0; j < 24; j++)
220 int v= 1<<(23-j);
221 if( pcr[pc2[j]] ) m_keydata[m] |= v;
222 if( pcr[pc2[j+24]] ) m_keydata[n] |= v;
226 for( i = 0; i < 32; i+=2)
228 unsigned int a = ((m_keydata[i] & 0x00fc0000) << 6) |
229 ((m_keydata[i] & 0x00000fc0) << 10) |
230 ((m_keydata[i+1] & 0x00fc0000) >> 10) |
231 ((m_keydata[i+1] & 0x00000fc0) >> 6);
233 unsigned int b= ((m_keydata[i] & 0x0003f000) << 12) |
234 ((m_keydata[i] & 0x0000003f) << 16) |
235 ((m_keydata[i+1] & 0x0003f000) >> 4) |
236 (m_keydata[i+1] & 0x0000003f);
237 m_keydata[i]=a;
238 m_keydata[i+1]=b;
244 void WDL_DES::Process8(unsigned char *buf8)
246 unsigned int leftt=(buf8[0]<<24)|(buf8[1]<<16)|(buf8[2]<<8)|(buf8[3]);
247 unsigned int right=(buf8[4]<<24)|(buf8[5]<<16)|(buf8[6]<<8)|(buf8[7]);
249 unsigned int *keys = m_keydata;
250 unsigned int fval, work;
251 int round;
253 work = ((leftt >> 4) ^ right) & 0x0f0f0f0f;
254 right ^= work;
255 leftt ^= (work << 4);
256 work = ((leftt >> 16) ^ right) & 0x0000ffff;
257 right ^= work;
258 leftt ^= (work << 16);
259 work = ((right >> 2) ^ leftt) & 0x33333333;
260 leftt ^= work;
261 right ^= (work << 2);
262 work = ((right >> 8) ^ leftt) & 0x00ff00ff;
263 leftt ^= work;
264 right ^= (work << 8);
265 right = ((right << 1) | ((right >> 31) & 1)) & 0xffffffff;
266 work = (leftt ^ right) & 0xaaaaaaaa;
267 leftt ^= work;
268 right ^= work;
269 leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffff;
271 for (round = 0; round < 8; round++)
273 work = (right << 28) | (right >> 4);
274 work ^= *keys++;
275 fval = SP7[ work & 0x3f];
276 fval |= SP5[(work >> 8) & 0x3f];
277 fval |= SP3[(work >> 16) & 0x3f];
278 fval |= SP1[(work >> 24) & 0x3f];
279 work = right ^ *keys++;
280 fval |= SP8[ work & 0x3f];
281 fval |= SP6[(work >> 8) & 0x3f];
282 fval |= SP4[(work >> 16) & 0x3f];
283 fval |= SP2[(work >> 24) & 0x3f];
284 leftt ^= fval;
285 work = (leftt << 28) | (leftt >> 4);
286 work ^= *keys++;
287 fval = SP7[ work & 0x3f];
288 fval |= SP5[(work >> 8) & 0x3f];
289 fval |= SP3[(work >> 16) & 0x3f];
290 fval |= SP1[(work >> 24) & 0x3f];
291 work = leftt ^ *keys++;
292 fval |= SP8[ work & 0x3f];
293 fval |= SP6[(work >> 8) & 0x3f];
294 fval |= SP4[(work >> 16) & 0x3f];
295 fval |= SP2[(work >> 24) & 0x3f];
296 right ^= fval;
299 right = (right << 31) | (right >> 1);
300 work = (leftt ^ right) & 0xaaaaaaaa;
301 leftt ^= work;
302 right ^= work;
303 leftt = (leftt << 31) | (leftt >> 1);
304 work = ((leftt >> 8) ^ right) & 0x00ff00ff;
305 right ^= work;
306 leftt ^= (work << 8);
307 work = ((leftt >> 2) ^ right) & 0x33333333;
308 right ^= work;
309 leftt ^= (work << 2);
310 work = ((right >> 16) ^ leftt) & 0x0000ffff;
311 leftt ^= work;
312 right ^= (work << 16);
313 work = ((right >> 4) ^ leftt) & 0x0f0f0f0f;
314 leftt ^= work;
315 right ^= (work << 4);
317 buf8[0] = (right>>24)&0xff;
318 buf8[1] = (right>>16)&0xff;
319 buf8[2] = (right>>8)&0xff;
320 buf8[3] = (right)&0xff;
321 buf8[4] = (leftt>>24)&0xff;
322 buf8[5] = (leftt>>16)&0xff;
323 buf8[6] = (leftt>>8)&0xff;
324 buf8[7] = (leftt)&0xff;