KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ch > ethz > ssh2 > crypto > cipher > DES


1
2 package ch.ethz.ssh2.crypto.cipher;
3
4 /*
5  This file is based on the 3DES implementation from the Bouncy Castle Crypto package.
6  Their licence file states the following:
7
8  Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
9  (http://www.bouncycastle.org)
10
11  Permission is hereby granted, free of charge, to any person obtaining a copy
12  of this software and associated documentation files (the "Software"), to deal
13  in the Software without restriction, including without limitation the rights
14  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  copies of the Software, and to permit persons to whom the Software is
16  furnished to do so, subject to the following conditions:
17
18  The above copyright notice and this permission notice shall be included in
19  all copies or substantial portions of the Software.
20
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27  THE SOFTWARE.
28  */

29
30 /**
31  * DES.
32  *
33  * @author See comments in the source file
34  * @version $Id: DES.java,v 1.3 2005/12/05 17:13:27 cplattne Exp $ethz.ch
35  *
36  */

37 public class DES implements BlockCipher
38 {
39     private int[] workingKey = null;
40
41     /**
42      * standard constructor.
43      */

44     public DES()
45     {
46     }
47
48     /**
49      * initialise a DES cipher.
50      *
51      * @param encrypting
52      * whether or not we are for encryption.
53      * @param key
54      * the parameters required to set up the cipher.
55      * @exception IllegalArgumentException
56      * if the params argument is inappropriate.
57      */

58     public void init(boolean encrypting, byte[] key)
59     {
60         this.workingKey = generateWorkingKey(encrypting, key, 0);
61     }
62
63     public String JavaDoc getAlgorithmName()
64     {
65         return "DES";
66     }
67
68     public int getBlockSize()
69     {
70         return 8;
71     }
72
73     public void transformBlock(byte[] in, int inOff, byte[] out, int outOff)
74     {
75         if (workingKey == null)
76         {
77             throw new IllegalStateException JavaDoc("DES engine not initialised!");
78         }
79
80         desFunc(workingKey, in, inOff, out, outOff);
81     }
82
83     public void reset()
84     {
85     }
86
87     /**
88      * what follows is mainly taken from "Applied Cryptography", by Bruce
89      * Schneier, however it also bears great resemblance to Richard
90      * Outerbridge's D3DES...
91      */

92
93     static short[] Df_Key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
94             0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 };
95
96     static short[] bytebit = { 0200, 0100, 040, 020, 010, 04, 02, 01 };
97
98     static int[] bigbyte = { 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
99             0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
100
101     /*
102      * Use the key schedule specified in the Standard (ANSI X3.92-1981).
103      */

104
105     static byte[] pc1 = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2,
106             59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12,
107             4, 27, 19, 11, 3 };
108
109     static byte[] totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
110
111     static byte[] pc2 = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40,
112             51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
113
114     static int[] SP1 = { 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004,
115             0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
116             0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004,
117             0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
118             0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
119             0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
120             0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004,
121             0x00010400, 0x00000000, 0x01010004 };
122
123     static int[] SP2 = { 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020,
124             0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
125             0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020,
126             0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
127             0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
128             0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
129             0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000,
130             0x80100020, 0x80108020, 0x00108000 };
131
132     static int[] SP3 = { 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208,
133             0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
134             0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208,
135             0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
136             0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
137             0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
138             0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208,
139             0x00000008, 0x08020008, 0x00020200 };
140
141     static int[] SP4 = { 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001,
142             0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
143             0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081,
144             0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
145             0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
146             0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
147             0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080,
148             0x00800000, 0x00002000, 0x00802080 };
149
150     static int[] SP5 = { 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000,
151             0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
152             0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000,
153             0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100,
154             0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,
155             0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100,
156             0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000,
157             0x40080000, 0x02080100, 0x40000100 };
158
159     static int[] SP6 = { 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010,
160             0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
161             0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010,
162             0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
163             0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
164             0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
165             0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000,
166             0x20000000, 0x00400010, 0x20004010 };
167
168     static int[] SP7 = { 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802,
169             0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
170             0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000,
171             0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
172             0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
173             0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
174             0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002,
175             0x04000800, 0x00000800, 0x00200002 };
176
177     static int[] SP8 = { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040,
178             0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
179             0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040,
180             0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
181             0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
182             0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
183             0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040,
184             0x00040040, 0x10000000, 0x10041000 };
185
186     /**
187      * generate an integer based working key based on our secret key and what we
188      * processing we are planning to do.
189      *
190      * Acknowledgements for this routine go to James Gillogly & Phil Karn.
191      * (whoever, and wherever they are!).
192      */

193     protected int[] generateWorkingKey(boolean encrypting, byte[] key, int off)
194     {
195         int[] newKey = new int[32];
196         boolean[] pc1m = new boolean[56], pcr = new boolean[56];
197
198         for (int j = 0; j < 56; j++)
199         {
200             int l = pc1[j];
201
202             pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
203         }
204
205         for (int i = 0; i < 16; i++)
206         {
207             int l, m, n;
208
209             if (encrypting)
210             {
211                 m = i << 1;
212             }
213             else
214             {
215                 m = (15 - i) << 1;
216             }
217
218             n = m + 1;
219             newKey[m] = newKey[n] = 0;
220
221             for (int j = 0; j < 28; j++)
222             {
223                 l = j + totrot[i];
224                 if (l < 28)
225                 {
226                     pcr[j] = pc1m[l];
227                 }
228                 else
229                 {
230                     pcr[j] = pc1m[l - 28];
231                 }
232             }
233
234             for (int j = 28; j < 56; j++)
235             {
236                 l = j + totrot[i];
237                 if (l < 56)
238                 {
239                     pcr[j] = pc1m[l];
240                 }
241                 else
242                 {
243                     pcr[j] = pc1m[l - 28];
244                 }
245             }
246
247             for (int j = 0; j < 24; j++)
248             {
249                 if (pcr[pc2[j]])
250                 {
251                     newKey[m] |= bigbyte[j];
252                 }
253
254                 if (pcr[pc2[j + 24]])
255                 {
256                     newKey[n] |= bigbyte[j];
257                 }
258             }
259         }
260
261         //
262
// store the processed key
263
//
264
for (int i = 0; i != 32; i += 2)
265         {
266             int i1, i2;
267
268             i1 = newKey[i];
269             i2 = newKey[i + 1];
270
271             newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
272                     | ((i2 & 0x00000fc0) >>> 6);
273
274             newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
275                     | (i2 & 0x0000003f);
276         }
277
278         return newKey;
279     }
280
281     /**
282      * the DES engine.
283      */

284     protected void desFunc(int[] wKey, byte[] in, int inOff, byte[] out, int outOff)
285     {
286         int work, right, left;
287
288         left = (in[inOff + 0] & 0xff) << 24;
289         left |= (in[inOff + 1] & 0xff) << 16;
290         left |= (in[inOff + 2] & 0xff) << 8;
291         left |= (in[inOff + 3] & 0xff);
292
293         right = (in[inOff + 4] & 0xff) << 24;
294         right |= (in[inOff + 5] & 0xff) << 16;
295         right |= (in[inOff + 6] & 0xff) << 8;
296         right |= (in[inOff + 7] & 0xff);
297
298         work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
299         right ^= work;
300         left ^= (work << 4);
301         work = ((left >>> 16) ^ right) & 0x0000ffff;
302         right ^= work;
303         left ^= (work << 16);
304         work = ((right >>> 2) ^ left) & 0x33333333;
305         left ^= work;
306         right ^= (work << 2);
307         work = ((right >>> 8) ^ left) & 0x00ff00ff;
308         left ^= work;
309         right ^= (work << 8);
310         right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
311         work = (left ^ right) & 0xaaaaaaaa;
312         left ^= work;
313         right ^= work;
314         left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
315
316         for (int round = 0; round < 8; round++)
317         {
318             int fval;
319
320             work = (right << 28) | (right >>> 4);
321             work ^= wKey[round * 4 + 0];
322             fval = SP7[work & 0x3f];
323             fval |= SP5[(work >>> 8) & 0x3f];
324             fval |= SP3[(work >>> 16) & 0x3f];
325             fval |= SP1[(work >>> 24) & 0x3f];
326             work = right ^ wKey[round * 4 + 1];
327             fval |= SP8[work & 0x3f];
328             fval |= SP6[(work >>> 8) & 0x3f];
329             fval |= SP4[(work >>> 16) & 0x3f];
330             fval |= SP2[(work >>> 24) & 0x3f];
331             left ^= fval;
332             work = (left << 28) | (left >>> 4);
333             work ^= wKey[round * 4 + 2];
334             fval = SP7[work & 0x3f];
335             fval |= SP5[(work >>> 8) & 0x3f];
336             fval |= SP3[(work >>> 16) & 0x3f];
337             fval |= SP1[(work >>> 24) & 0x3f];
338             work = left ^ wKey[round * 4 + 3];
339             fval |= SP8[work & 0x3f];
340             fval |= SP6[(work >>> 8) & 0x3f];
341             fval |= SP4[(work >>> 16) & 0x3f];
342             fval |= SP2[(work >>> 24) & 0x3f];
343             right ^= fval;
344         }
345
346         right = (right << 31) | (right >>> 1);
347         work = (left ^ right) & 0xaaaaaaaa;
348         left ^= work;
349         right ^= work;
350         left = (left << 31) | (left >>> 1);
351         work = ((left >>> 8) ^ right) & 0x00ff00ff;
352         right ^= work;
353         left ^= (work << 8);
354         work = ((left >>> 2) ^ right) & 0x33333333;
355         right ^= work;
356         left ^= (work << 2);
357         work = ((right >>> 16) ^ left) & 0x0000ffff;
358         left ^= work;
359         right ^= (work << 16);
360         work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
361         left ^= work;
362         right ^= (work << 4);
363
364         out[outOff + 0] = (byte) ((right >>> 24) & 0xff);
365         out[outOff + 1] = (byte) ((right >>> 16) & 0xff);
366         out[outOff + 2] = (byte) ((right >>> 8) & 0xff);
367         out[outOff + 3] = (byte) (right & 0xff);
368         out[outOff + 4] = (byte) ((left >>> 24) & 0xff);
369         out[outOff + 5] = (byte) ((left >>> 16) & 0xff);
370         out[outOff + 6] = (byte) ((left >>> 8) & 0xff);
371         out[outOff + 7] = (byte) (left & 0xff);
372     }
373 }
374
Popular Tags