001    package railo.runtime.crypt;
002    
003    /****************************************************************************
004     * JCrypt.java
005     *
006     * Java-based implementation of the unix crypt command
007     *
008     * Based upon C source code written by Eric Young, eay@psych.uq.oz.au
009     *
010     ****************************************************************************/
011    
012    public final class JCrypt
013    {
014       private JCrypt() {}
015    
016       private static final int ITERATIONS = 16;
017    
018       private static final int con_salt[] =
019       {
020          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
021          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
022          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
023          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
024          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
025          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
026          0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
027          0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 
028          0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 
029          0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 
030          0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 
031          0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, 
032          0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 
033          0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 
034          0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 
035          0x3D, 0x3E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 
036       };
037    
038       private static final boolean shifts2[] =
039       {
040          false, false, true, true, true, true, true, true,
041          false, true,  true, true, true, true, true, false
042       };
043    
044       private static final int skb[][] =
045       {
046          {
047             /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
048             0x00000000, 0x00000010, 0x20000000, 0x20000010, 
049             0x00010000, 0x00010010, 0x20010000, 0x20010010, 
050             0x00000800, 0x00000810, 0x20000800, 0x20000810, 
051             0x00010800, 0x00010810, 0x20010800, 0x20010810, 
052             0x00000020, 0x00000030, 0x20000020, 0x20000030, 
053             0x00010020, 0x00010030, 0x20010020, 0x20010030, 
054             0x00000820, 0x00000830, 0x20000820, 0x20000830, 
055             0x00010820, 0x00010830, 0x20010820, 0x20010830, 
056             0x00080000, 0x00080010, 0x20080000, 0x20080010, 
057             0x00090000, 0x00090010, 0x20090000, 0x20090010, 
058             0x00080800, 0x00080810, 0x20080800, 0x20080810, 
059             0x00090800, 0x00090810, 0x20090800, 0x20090810, 
060             0x00080020, 0x00080030, 0x20080020, 0x20080030, 
061             0x00090020, 0x00090030, 0x20090020, 0x20090030, 
062             0x00080820, 0x00080830, 0x20080820, 0x20080830, 
063             0x00090820, 0x00090830, 0x20090820, 0x20090830, 
064          },
065          {
066             /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
067             0x00000000, 0x02000000, 0x00002000, 0x02002000, 
068             0x00200000, 0x02200000, 0x00202000, 0x02202000, 
069             0x00000004, 0x02000004, 0x00002004, 0x02002004, 
070             0x00200004, 0x02200004, 0x00202004, 0x02202004, 
071             0x00000400, 0x02000400, 0x00002400, 0x02002400, 
072             0x00200400, 0x02200400, 0x00202400, 0x02202400, 
073             0x00000404, 0x02000404, 0x00002404, 0x02002404, 
074             0x00200404, 0x02200404, 0x00202404, 0x02202404, 
075             0x10000000, 0x12000000, 0x10002000, 0x12002000, 
076             0x10200000, 0x12200000, 0x10202000, 0x12202000, 
077             0x10000004, 0x12000004, 0x10002004, 0x12002004, 
078             0x10200004, 0x12200004, 0x10202004, 0x12202004, 
079             0x10000400, 0x12000400, 0x10002400, 0x12002400, 
080             0x10200400, 0x12200400, 0x10202400, 0x12202400, 
081             0x10000404, 0x12000404, 0x10002404, 0x12002404, 
082             0x10200404, 0x12200404, 0x10202404, 0x12202404, 
083          },
084          {
085             /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
086             0x00000000, 0x00000001, 0x00040000, 0x00040001, 
087             0x01000000, 0x01000001, 0x01040000, 0x01040001, 
088             0x00000002, 0x00000003, 0x00040002, 0x00040003, 
089             0x01000002, 0x01000003, 0x01040002, 0x01040003, 
090             0x00000200, 0x00000201, 0x00040200, 0x00040201, 
091             0x01000200, 0x01000201, 0x01040200, 0x01040201, 
092             0x00000202, 0x00000203, 0x00040202, 0x00040203, 
093             0x01000202, 0x01000203, 0x01040202, 0x01040203, 
094             0x08000000, 0x08000001, 0x08040000, 0x08040001, 
095             0x09000000, 0x09000001, 0x09040000, 0x09040001, 
096             0x08000002, 0x08000003, 0x08040002, 0x08040003, 
097             0x09000002, 0x09000003, 0x09040002, 0x09040003, 
098             0x08000200, 0x08000201, 0x08040200, 0x08040201, 
099             0x09000200, 0x09000201, 0x09040200, 0x09040201, 
100             0x08000202, 0x08000203, 0x08040202, 0x08040203, 
101             0x09000202, 0x09000203, 0x09040202, 0x09040203, 
102          },
103          {
104             /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
105             0x00000000, 0x00100000, 0x00000100, 0x00100100, 
106             0x00000008, 0x00100008, 0x00000108, 0x00100108, 
107             0x00001000, 0x00101000, 0x00001100, 0x00101100, 
108             0x00001008, 0x00101008, 0x00001108, 0x00101108, 
109             0x04000000, 0x04100000, 0x04000100, 0x04100100, 
110             0x04000008, 0x04100008, 0x04000108, 0x04100108, 
111             0x04001000, 0x04101000, 0x04001100, 0x04101100, 
112             0x04001008, 0x04101008, 0x04001108, 0x04101108, 
113             0x00020000, 0x00120000, 0x00020100, 0x00120100, 
114             0x00020008, 0x00120008, 0x00020108, 0x00120108, 
115             0x00021000, 0x00121000, 0x00021100, 0x00121100, 
116             0x00021008, 0x00121008, 0x00021108, 0x00121108, 
117             0x04020000, 0x04120000, 0x04020100, 0x04120100, 
118             0x04020008, 0x04120008, 0x04020108, 0x04120108, 
119             0x04021000, 0x04121000, 0x04021100, 0x04121100, 
120             0x04021008, 0x04121008, 0x04021108, 0x04121108, 
121          },
122          {
123             /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
124             0x00000000, 0x10000000, 0x00010000, 0x10010000, 
125             0x00000004, 0x10000004, 0x00010004, 0x10010004, 
126             0x20000000, 0x30000000, 0x20010000, 0x30010000, 
127             0x20000004, 0x30000004, 0x20010004, 0x30010004, 
128             0x00100000, 0x10100000, 0x00110000, 0x10110000, 
129             0x00100004, 0x10100004, 0x00110004, 0x10110004, 
130             0x20100000, 0x30100000, 0x20110000, 0x30110000, 
131             0x20100004, 0x30100004, 0x20110004, 0x30110004, 
132             0x00001000, 0x10001000, 0x00011000, 0x10011000, 
133             0x00001004, 0x10001004, 0x00011004, 0x10011004, 
134             0x20001000, 0x30001000, 0x20011000, 0x30011000, 
135             0x20001004, 0x30001004, 0x20011004, 0x30011004, 
136             0x00101000, 0x10101000, 0x00111000, 0x10111000, 
137             0x00101004, 0x10101004, 0x00111004, 0x10111004, 
138             0x20101000, 0x30101000, 0x20111000, 0x30111000, 
139             0x20101004, 0x30101004, 0x20111004, 0x30111004, 
140          },
141          {
142             /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
143             0x00000000, 0x08000000, 0x00000008, 0x08000008, 
144             0x00000400, 0x08000400, 0x00000408, 0x08000408, 
145             0x00020000, 0x08020000, 0x00020008, 0x08020008, 
146             0x00020400, 0x08020400, 0x00020408, 0x08020408, 
147             0x00000001, 0x08000001, 0x00000009, 0x08000009, 
148             0x00000401, 0x08000401, 0x00000409, 0x08000409, 
149             0x00020001, 0x08020001, 0x00020009, 0x08020009, 
150             0x00020401, 0x08020401, 0x00020409, 0x08020409, 
151             0x02000000, 0x0A000000, 0x02000008, 0x0A000008, 
152             0x02000400, 0x0A000400, 0x02000408, 0x0A000408, 
153             0x02020000, 0x0A020000, 0x02020008, 0x0A020008, 
154             0x02020400, 0x0A020400, 0x02020408, 0x0A020408, 
155             0x02000001, 0x0A000001, 0x02000009, 0x0A000009, 
156             0x02000401, 0x0A000401, 0x02000409, 0x0A000409, 
157             0x02020001, 0x0A020001, 0x02020009, 0x0A020009, 
158             0x02020401, 0x0A020401, 0x02020409, 0x0A020409, 
159          },
160          {
161             /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
162             0x00000000, 0x00000100, 0x00080000, 0x00080100, 
163             0x01000000, 0x01000100, 0x01080000, 0x01080100, 
164             0x00000010, 0x00000110, 0x00080010, 0x00080110, 
165             0x01000010, 0x01000110, 0x01080010, 0x01080110, 
166             0x00200000, 0x00200100, 0x00280000, 0x00280100, 
167             0x01200000, 0x01200100, 0x01280000, 0x01280100, 
168             0x00200010, 0x00200110, 0x00280010, 0x00280110, 
169             0x01200010, 0x01200110, 0x01280010, 0x01280110, 
170             0x00000200, 0x00000300, 0x00080200, 0x00080300, 
171             0x01000200, 0x01000300, 0x01080200, 0x01080300, 
172             0x00000210, 0x00000310, 0x00080210, 0x00080310, 
173             0x01000210, 0x01000310, 0x01080210, 0x01080310, 
174             0x00200200, 0x00200300, 0x00280200, 0x00280300, 
175             0x01200200, 0x01200300, 0x01280200, 0x01280300, 
176             0x00200210, 0x00200310, 0x00280210, 0x00280310, 
177             0x01200210, 0x01200310, 0x01280210, 0x01280310, 
178          },
179          {
180             /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
181             0x00000000, 0x04000000, 0x00040000, 0x04040000, 
182             0x00000002, 0x04000002, 0x00040002, 0x04040002, 
183             0x00002000, 0x04002000, 0x00042000, 0x04042000, 
184             0x00002002, 0x04002002, 0x00042002, 0x04042002, 
185             0x00000020, 0x04000020, 0x00040020, 0x04040020, 
186             0x00000022, 0x04000022, 0x00040022, 0x04040022, 
187             0x00002020, 0x04002020, 0x00042020, 0x04042020, 
188             0x00002022, 0x04002022, 0x00042022, 0x04042022, 
189             0x00000800, 0x04000800, 0x00040800, 0x04040800, 
190             0x00000802, 0x04000802, 0x00040802, 0x04040802, 
191             0x00002800, 0x04002800, 0x00042800, 0x04042800, 
192             0x00002802, 0x04002802, 0x00042802, 0x04042802, 
193             0x00000820, 0x04000820, 0x00040820, 0x04040820, 
194             0x00000822, 0x04000822, 0x00040822, 0x04040822, 
195             0x00002820, 0x04002820, 0x00042820, 0x04042820, 
196             0x00002822, 0x04002822, 0x00042822, 0x04042822, 
197          },
198       };
199    
200       private static final int SPtrans[][] =
201       {
202          {
203             /* nibble 0 */
204             0x00820200, 0x00020000, 0x80800000, 0x80820200,
205             0x00800000, 0x80020200, 0x80020000, 0x80800000,
206             0x80020200, 0x00820200, 0x00820000, 0x80000200,
207             0x80800200, 0x00800000, 0x00000000, 0x80020000,
208             0x00020000, 0x80000000, 0x00800200, 0x00020200,
209             0x80820200, 0x00820000, 0x80000200, 0x00800200,
210             0x80000000, 0x00000200, 0x00020200, 0x80820000,
211             0x00000200, 0x80800200, 0x80820000, 0x00000000,
212             0x00000000, 0x80820200, 0x00800200, 0x80020000,
213             0x00820200, 0x00020000, 0x80000200, 0x00800200,
214             0x80820000, 0x00000200, 0x00020200, 0x80800000,
215             0x80020200, 0x80000000, 0x80800000, 0x00820000,
216             0x80820200, 0x00020200, 0x00820000, 0x80800200,
217             0x00800000, 0x80000200, 0x80020000, 0x00000000,
218             0x00020000, 0x00800000, 0x80800200, 0x00820200,
219             0x80000000, 0x80820000, 0x00000200, 0x80020200,
220          },
221          {
222             /* nibble 1 */
223             0x10042004, 0x00000000, 0x00042000, 0x10040000,
224             0x10000004, 0x00002004, 0x10002000, 0x00042000,
225             0x00002000, 0x10040004, 0x00000004, 0x10002000,
226             0x00040004, 0x10042000, 0x10040000, 0x00000004,
227             0x00040000, 0x10002004, 0x10040004, 0x00002000,
228             0x00042004, 0x10000000, 0x00000000, 0x00040004,
229             0x10002004, 0x00042004, 0x10042000, 0x10000004,
230             0x10000000, 0x00040000, 0x00002004, 0x10042004,
231             0x00040004, 0x10042000, 0x10002000, 0x00042004,
232             0x10042004, 0x00040004, 0x10000004, 0x00000000,
233             0x10000000, 0x00002004, 0x00040000, 0x10040004,
234             0x00002000, 0x10000000, 0x00042004, 0x10002004,
235             0x10042000, 0x00002000, 0x00000000, 0x10000004,
236             0x00000004, 0x10042004, 0x00042000, 0x10040000,
237             0x10040004, 0x00040000, 0x00002004, 0x10002000,
238             0x10002004, 0x00000004, 0x10040000, 0x00042000,
239          },
240          {
241             /* nibble 2 */
242             0x41000000, 0x01010040, 0x00000040, 0x41000040,
243             0x40010000, 0x01000000, 0x41000040, 0x00010040,
244             0x01000040, 0x00010000, 0x01010000, 0x40000000,
245             0x41010040, 0x40000040, 0x40000000, 0x41010000,
246             0x00000000, 0x40010000, 0x01010040, 0x00000040,
247             0x40000040, 0x41010040, 0x00010000, 0x41000000,
248             0x41010000, 0x01000040, 0x40010040, 0x01010000,
249             0x00010040, 0x00000000, 0x01000000, 0x40010040,
250             0x01010040, 0x00000040, 0x40000000, 0x00010000,
251             0x40000040, 0x40010000, 0x01010000, 0x41000040,
252             0x00000000, 0x01010040, 0x00010040, 0x41010000,
253             0x40010000, 0x01000000, 0x41010040, 0x40000000,
254             0x40010040, 0x41000000, 0x01000000, 0x41010040,
255             0x00010000, 0x01000040, 0x41000040, 0x00010040,
256             0x01000040, 0x00000000, 0x41010000, 0x40000040,
257             0x41000000, 0x40010040, 0x00000040, 0x01010000,
258          },
259          {
260             /* nibble 3 */
261             0x00100402, 0x04000400, 0x00000002, 0x04100402,
262             0x00000000, 0x04100000, 0x04000402, 0x00100002,
263             0x04100400, 0x04000002, 0x04000000, 0x00000402,
264             0x04000002, 0x00100402, 0x00100000, 0x04000000,
265             0x04100002, 0x00100400, 0x00000400, 0x00000002,
266             0x00100400, 0x04000402, 0x04100000, 0x00000400,
267             0x00000402, 0x00000000, 0x00100002, 0x04100400,
268             0x04000400, 0x04100002, 0x04100402, 0x00100000,
269             0x04100002, 0x00000402, 0x00100000, 0x04000002,
270             0x00100400, 0x04000400, 0x00000002, 0x04100000,
271             0x04000402, 0x00000000, 0x00000400, 0x00100002,
272             0x00000000, 0x04100002, 0x04100400, 0x00000400,
273             0x04000000, 0x04100402, 0x00100402, 0x00100000,
274             0x04100402, 0x00000002, 0x04000400, 0x00100402,
275             0x00100002, 0x00100400, 0x04100000, 0x04000402,
276             0x00000402, 0x04000000, 0x04000002, 0x04100400,
277          },
278          {
279             /* nibble 4 */
280             0x02000000, 0x00004000, 0x00000100, 0x02004108,
281             0x02004008, 0x02000100, 0x00004108, 0x02004000,
282             0x00004000, 0x00000008, 0x02000008, 0x00004100,
283             0x02000108, 0x02004008, 0x02004100, 0x00000000,
284             0x00004100, 0x02000000, 0x00004008, 0x00000108,
285             0x02000100, 0x00004108, 0x00000000, 0x02000008,
286             0x00000008, 0x02000108, 0x02004108, 0x00004008,
287             0x02004000, 0x00000100, 0x00000108, 0x02004100,
288             0x02004100, 0x02000108, 0x00004008, 0x02004000,
289             0x00004000, 0x00000008, 0x02000008, 0x02000100,
290             0x02000000, 0x00004100, 0x02004108, 0x00000000,
291             0x00004108, 0x02000000, 0x00000100, 0x00004008,
292             0x02000108, 0x00000100, 0x00000000, 0x02004108,
293             0x02004008, 0x02004100, 0x00000108, 0x00004000,
294             0x00004100, 0x02004008, 0x02000100, 0x00000108,
295             0x00000008, 0x00004108, 0x02004000, 0x02000008,
296          },
297          {
298             /* nibble 5 */
299             0x20000010, 0x00080010, 0x00000000, 0x20080800,
300             0x00080010, 0x00000800, 0x20000810, 0x00080000,
301             0x00000810, 0x20080810, 0x00080800, 0x20000000,
302             0x20000800, 0x20000010, 0x20080000, 0x00080810,
303             0x00080000, 0x20000810, 0x20080010, 0x00000000,
304             0x00000800, 0x00000010, 0x20080800, 0x20080010,
305             0x20080810, 0x20080000, 0x20000000, 0x00000810,
306             0x00000010, 0x00080800, 0x00080810, 0x20000800,
307             0x00000810, 0x20000000, 0x20000800, 0x00080810,
308             0x20080800, 0x00080010, 0x00000000, 0x20000800,
309             0x20000000, 0x00000800, 0x20080010, 0x00080000,
310             0x00080010, 0x20080810, 0x00080800, 0x00000010,
311             0x20080810, 0x00080800, 0x00080000, 0x20000810,
312             0x20000010, 0x20080000, 0x00080810, 0x00000000,
313             0x00000800, 0x20000010, 0x20000810, 0x20080800,
314             0x20080000, 0x00000810, 0x00000010, 0x20080010,
315          },
316          {
317             /* nibble 6 */
318             0x00001000, 0x00000080, 0x00400080, 0x00400001,
319             0x00401081, 0x00001001, 0x00001080, 0x00000000,
320             0x00400000, 0x00400081, 0x00000081, 0x00401000,
321             0x00000001, 0x00401080, 0x00401000, 0x00000081,
322             0x00400081, 0x00001000, 0x00001001, 0x00401081,
323             0x00000000, 0x00400080, 0x00400001, 0x00001080,
324             0x00401001, 0x00001081, 0x00401080, 0x00000001,
325             0x00001081, 0x00401001, 0x00000080, 0x00400000,
326             0x00001081, 0x00401000, 0x00401001, 0x00000081,
327             0x00001000, 0x00000080, 0x00400000, 0x00401001,
328             0x00400081, 0x00001081, 0x00001080, 0x00000000,
329             0x00000080, 0x00400001, 0x00000001, 0x00400080,
330             0x00000000, 0x00400081, 0x00400080, 0x00001080,
331             0x00000081, 0x00001000, 0x00401081, 0x00400000,
332             0x00401080, 0x00000001, 0x00001001, 0x00401081,
333             0x00400001, 0x00401080, 0x00401000, 0x00001001,
334          },
335          {
336             /* nibble 7 */
337             0x08200020, 0x08208000, 0x00008020, 0x00000000,
338             0x08008000, 0x00200020, 0x08200000, 0x08208020,
339             0x00000020, 0x08000000, 0x00208000, 0x00008020,
340             0x00208020, 0x08008020, 0x08000020, 0x08200000,
341             0x00008000, 0x00208020, 0x00200020, 0x08008000,
342             0x08208020, 0x08000020, 0x00000000, 0x00208000,
343             0x08000000, 0x00200000, 0x08008020, 0x08200020,
344             0x00200000, 0x00008000, 0x08208000, 0x00000020,
345             0x00200000, 0x00008000, 0x08000020, 0x08208020,
346             0x00008020, 0x08000000, 0x00000000, 0x00208000,
347             0x08200020, 0x08008020, 0x08008000, 0x00200020,
348             0x08208000, 0x00000020, 0x00200020, 0x08008000,
349             0x08208020, 0x00200000, 0x08200000, 0x08000020,
350             0x00208000, 0x00008020, 0x08008020, 0x08200000,
351             0x00000020, 0x08208000, 0x00208020, 0x00000000,
352             0x08000000, 0x08200020, 0x00008000, 0x00208020
353          }
354       };
355    
356       private static final int cov_2char[] =
357       {
358          0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 
359          0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 
360          0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 
361          0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 
362          0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 
363          0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 
364          0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 
365          0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
366       };
367    
368       private static final int byteToUnsigned(byte b)
369       {
370          int value = b;
371    
372          return(value >= 0 ? value : value + 256);
373       }
374    
375       private static int fourBytesToInt(byte b[], int offset)
376       {
377          int value;
378    
379          value  =  byteToUnsigned(b[offset++]);
380          value |= (byteToUnsigned(b[offset++]) <<  8);
381          value |= (byteToUnsigned(b[offset++]) << 16);
382          value |= (byteToUnsigned(b[offset++]) << 24);
383    
384          return(value);
385       }
386    
387       private static final void intToFourBytes(int iValue, byte b[], int offset)
388       {
389          b[offset++] = (byte)((iValue)        & 0xff);
390          b[offset++] = (byte)((iValue >>> 8 ) & 0xff);
391          b[offset++] = (byte)((iValue >>> 16) & 0xff);
392          b[offset++] = (byte)((iValue >>> 24) & 0xff);
393       }
394    
395       private static final void PERM_OP(int a, int b, int n, int m, int results[])
396       {
397          int t;
398    
399          t = ((a >>> n) ^ b) & m;
400          a ^= t << n;
401          b ^= t;
402    
403          results[0] = a;
404          results[1] = b;
405       }
406    
407       private static final int HPERM_OP(int a, int n, int m)
408       {
409          int t;
410    
411          t = ((a << (16 - n)) ^ a) & m;
412          a = a ^ t ^ (t >>> (16 - n));
413    
414          return(a);
415       }
416    
417       private static int [] des_set_key(byte key[])
418       {
419          int schedule[] = new int[ITERATIONS * 2];
420    
421          int c = fourBytesToInt(key, 0);
422          int d = fourBytesToInt(key, 4);
423    
424          int results[] = new int[2];
425    
426          PERM_OP(d, c, 4, 0x0f0f0f0f, results);
427          d = results[0]; c = results[1];
428    
429          c = HPERM_OP(c, -2, 0xcccc0000);
430          d = HPERM_OP(d, -2, 0xcccc0000);
431    
432          PERM_OP(d, c, 1, 0x55555555, results);
433          d = results[0]; c = results[1];
434    
435          PERM_OP(c, d, 8, 0x00ff00ff, results);
436          c = results[0]; d = results[1];
437    
438          PERM_OP(d, c, 1, 0x55555555, results);
439          d = results[0]; c = results[1];
440    
441          d = (((d & 0x000000ff) <<  16) |  (d & 0x0000ff00)     |
442               ((d & 0x00ff0000) >>> 16) | ((c & 0xf0000000) >>> 4));
443          c &= 0x0fffffff;
444    
445          int s, t;
446          int j = 0;
447    
448          for(int i = 0; i < ITERATIONS; i ++)
449          {
450             if(shifts2[i])
451             {
452                c = (c >>> 2) | (c << 26);
453                d = (d >>> 2) | (d << 26);
454             }
455             else
456             {
457                c = (c >>> 1) | (c << 27);
458                d = (d >>> 1) | (d << 27);
459             }
460    
461             c &= 0x0fffffff;
462             d &= 0x0fffffff;
463    
464             s = skb[0][ (c       ) & 0x3f                       ]|
465                 skb[1][((c >>>  6) & 0x03) | ((c >>>  7) & 0x3c)]|
466                 skb[2][((c >>> 13) & 0x0f) | ((c >>> 14) & 0x30)]|
467                 skb[3][((c >>> 20) & 0x01) | ((c >>> 21) & 0x06) |
468                                              ((c >>> 22) & 0x38)];
469    
470             t = skb[4][ (d     )  & 0x3f                       ]|
471                 skb[5][((d >>> 7) & 0x03) | ((d >>>  8) & 0x3c)]|
472                 skb[6][ (d >>>15) & 0x3f                       ]|
473                 skb[7][((d >>>21) & 0x0f) | ((d >>> 22) & 0x30)];
474    
475             schedule[j++] = ((t <<  16) | (s & 0x0000ffff)) & 0xffffffff;
476             s             = ((s >>> 16) | (t & 0xffff0000));
477    
478             s             = (s << 4) | (s >>> 28);
479             schedule[j++] = s & 0xffffffff;
480          }
481          return(schedule);
482       }
483    
484       private static final int D_ENCRYPT
485       (
486          int L, int R, int S, int E0, int E1, int s[]
487       )
488       {
489          int t, u, v;
490    
491          v = R ^ (R >>> 16);
492          u = v & E0;
493          v = v & E1;
494          u = (u ^ (u << 16)) ^ R ^ s[S];
495          t = (v ^ (v << 16)) ^ R ^ s[S + 1];
496          t = (t >>> 4) | (t << 28);
497    
498          L ^= SPtrans[1][(t       ) & 0x3f] |
499               SPtrans[3][(t >>>  8) & 0x3f] |
500               SPtrans[5][(t >>> 16) & 0x3f] |
501               SPtrans[7][(t >>> 24) & 0x3f] |
502               SPtrans[0][(u       ) & 0x3f] |
503               SPtrans[2][(u >>>  8) & 0x3f] |
504               SPtrans[4][(u >>> 16) & 0x3f] |
505               SPtrans[6][(u >>> 24) & 0x3f];
506    
507          return(L);
508       }
509    
510       private static final int [] body(int schedule[], int Eswap0, int Eswap1)
511       {
512          int left = 0;
513          int right = 0;
514          int t     = 0;
515    
516          for(int j = 0; j < 25; j ++)
517          {
518             for(int i = 0; i < ITERATIONS * 2; i += 4)
519             {
520                left  = D_ENCRYPT(left,  right, i,     Eswap0, Eswap1, schedule);
521                right = D_ENCRYPT(right, left,  i + 2, Eswap0, Eswap1, schedule);
522             }
523             t     = left; 
524             left  = right; 
525             right = t;
526          }
527    
528          t = right;
529    
530          right = (left >>> 1) | (left << 31);
531          left  = (t    >>> 1) | (t    << 31);
532    
533          left  &= 0xffffffff;
534          right &= 0xffffffff;
535    
536          int results[] = new int[2];
537    
538          PERM_OP(right, left, 1, 0x55555555, results); 
539          right = results[0]; left = results[1];
540    
541          PERM_OP(left, right, 8, 0x00ff00ff, results); 
542          left = results[0]; right = results[1];
543    
544          PERM_OP(right, left, 2, 0x33333333, results); 
545          right = results[0]; left = results[1];
546    
547          PERM_OP(left, right, 16, 0x0000ffff, results);
548          left = results[0]; right = results[1];
549    
550          PERM_OP(right, left, 4, 0x0f0f0f0f, results);
551          right = results[0]; left = results[1];
552    
553          int out[] = new int[2];
554    
555          out[0] = left; out[1] = right;
556    
557          return(out);
558       }
559    
560       public static final String crypt(String salt, String original)
561       {
562          while(salt.length() < 2)
563             salt += "A";
564    
565          StringBuffer buffer = new StringBuffer("             ");
566    
567          char charZero = salt.charAt(0);
568          char charOne  = salt.charAt(1);
569    
570          buffer.setCharAt(0, charZero);
571          buffer.setCharAt(1, charOne);
572    
573          int Eswap0 = con_salt[charZero];
574          int Eswap1 = con_salt[charOne] << 4;
575     
576          byte key[] = new byte[8];
577    
578          for(int i = 0; i < key.length; i ++)
579             key[i] = (byte)0;
580    
581          for(int i = 0; i < key.length && i < original.length(); i ++)
582          {
583             int iChar = original.charAt(i);
584    
585             key[i] = (byte)(iChar << 1);
586          }
587    
588          int schedule[] = des_set_key(key);
589          int out[]      = body(schedule, Eswap0, Eswap1);
590    
591          byte b[] = new byte[9];
592    
593          intToFourBytes(out[0], b, 0);
594          intToFourBytes(out[1], b, 4);
595          b[8] = 0;
596    
597          for(int i = 2, y = 0, u = 0x80; i < 13; i ++)
598          {
599             for(int j = 0, c = 0; j < 6; j ++)
600             {
601                c <<= 1;
602    
603                if((b[y] & u) != 0)
604                   c |= 1;
605    
606                u >>>= 1;
607    
608                if(u == 0)
609                {
610                   y++;
611                   u = 0x80;
612                }
613                buffer.setCharAt(i, (char)cov_2char[c]);
614             }
615          }
616          return(buffer.toString());
617       }
618    
619       
620    }