1 package org.feistymeow.encryption;
\r
3 import java.util.ArrayList;
\r
5 /****************************************************************************
\r
6 * Java-based implementation of the unix UnixCrypt(3) command
\r
8 * Based upon C source code written by Eric Young, eay@psych.uq.oz.au
\r
9 * Java conversion by John F. Dumas, jdumas@zgs.com
\r
11 * Found at http://locutus.kingwoodcable.com/jfd/UnixCrypt.html
\r
12 * Minor optimizations by Wes Biggs, wes@cacas.org
\r
14 * Eric's original code is licensed under the BSD license. As this is
\r
15 * derivative, the same license applies.
\r
17 * Note: UnixCrypt.class is much smaller when compiled with javac -O
\r
18 ****************************************************************************/
\r
20 public class UnixCrypt
\r
22 private UnixCrypt() {} // defined so class can't be instantiated.
\r
24 private static final int ITERATIONS = 16;
\r
26 private static final boolean shifts2[] = {
\r
27 false, false, true, true, true, true, true, true,
\r
28 false, true, true, true, true, true, true, false
\r
31 private static final int skb[][] = {
\r
33 /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
\r
34 0x00000000, 0x00000010, 0x20000000, 0x20000010,
\r
35 0x00010000, 0x00010010, 0x20010000, 0x20010010,
\r
36 0x00000800, 0x00000810, 0x20000800, 0x20000810,
\r
37 0x00010800, 0x00010810, 0x20010800, 0x20010810,
\r
38 0x00000020, 0x00000030, 0x20000020, 0x20000030,
\r
39 0x00010020, 0x00010030, 0x20010020, 0x20010030,
\r
40 0x00000820, 0x00000830, 0x20000820, 0x20000830,
\r
41 0x00010820, 0x00010830, 0x20010820, 0x20010830,
\r
42 0x00080000, 0x00080010, 0x20080000, 0x20080010,
\r
43 0x00090000, 0x00090010, 0x20090000, 0x20090010,
\r
44 0x00080800, 0x00080810, 0x20080800, 0x20080810,
\r
45 0x00090800, 0x00090810, 0x20090800, 0x20090810,
\r
46 0x00080020, 0x00080030, 0x20080020, 0x20080030,
\r
47 0x00090020, 0x00090030, 0x20090020, 0x20090030,
\r
48 0x00080820, 0x00080830, 0x20080820, 0x20080830,
\r
49 0x00090820, 0x00090830, 0x20090820, 0x20090830,
\r
52 /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
\r
53 0x00000000, 0x02000000, 0x00002000, 0x02002000,
\r
54 0x00200000, 0x02200000, 0x00202000, 0x02202000,
\r
55 0x00000004, 0x02000004, 0x00002004, 0x02002004,
\r
56 0x00200004, 0x02200004, 0x00202004, 0x02202004,
\r
57 0x00000400, 0x02000400, 0x00002400, 0x02002400,
\r
58 0x00200400, 0x02200400, 0x00202400, 0x02202400,
\r
59 0x00000404, 0x02000404, 0x00002404, 0x02002404,
\r
60 0x00200404, 0x02200404, 0x00202404, 0x02202404,
\r
61 0x10000000, 0x12000000, 0x10002000, 0x12002000,
\r
62 0x10200000, 0x12200000, 0x10202000, 0x12202000,
\r
63 0x10000004, 0x12000004, 0x10002004, 0x12002004,
\r
64 0x10200004, 0x12200004, 0x10202004, 0x12202004,
\r
65 0x10000400, 0x12000400, 0x10002400, 0x12002400,
\r
66 0x10200400, 0x12200400, 0x10202400, 0x12202400,
\r
67 0x10000404, 0x12000404, 0x10002404, 0x12002404,
\r
68 0x10200404, 0x12200404, 0x10202404, 0x12202404,
\r
71 /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
\r
72 0x00000000, 0x00000001, 0x00040000, 0x00040001,
\r
73 0x01000000, 0x01000001, 0x01040000, 0x01040001,
\r
74 0x00000002, 0x00000003, 0x00040002, 0x00040003,
\r
75 0x01000002, 0x01000003, 0x01040002, 0x01040003,
\r
76 0x00000200, 0x00000201, 0x00040200, 0x00040201,
\r
77 0x01000200, 0x01000201, 0x01040200, 0x01040201,
\r
78 0x00000202, 0x00000203, 0x00040202, 0x00040203,
\r
79 0x01000202, 0x01000203, 0x01040202, 0x01040203,
\r
80 0x08000000, 0x08000001, 0x08040000, 0x08040001,
\r
81 0x09000000, 0x09000001, 0x09040000, 0x09040001,
\r
82 0x08000002, 0x08000003, 0x08040002, 0x08040003,
\r
83 0x09000002, 0x09000003, 0x09040002, 0x09040003,
\r
84 0x08000200, 0x08000201, 0x08040200, 0x08040201,
\r
85 0x09000200, 0x09000201, 0x09040200, 0x09040201,
\r
86 0x08000202, 0x08000203, 0x08040202, 0x08040203,
\r
87 0x09000202, 0x09000203, 0x09040202, 0x09040203,
\r
90 /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
\r
91 0x00000000, 0x00100000, 0x00000100, 0x00100100,
\r
92 0x00000008, 0x00100008, 0x00000108, 0x00100108,
\r
93 0x00001000, 0x00101000, 0x00001100, 0x00101100,
\r
94 0x00001008, 0x00101008, 0x00001108, 0x00101108,
\r
95 0x04000000, 0x04100000, 0x04000100, 0x04100100,
\r
96 0x04000008, 0x04100008, 0x04000108, 0x04100108,
\r
97 0x04001000, 0x04101000, 0x04001100, 0x04101100,
\r
98 0x04001008, 0x04101008, 0x04001108, 0x04101108,
\r
99 0x00020000, 0x00120000, 0x00020100, 0x00120100,
\r
100 0x00020008, 0x00120008, 0x00020108, 0x00120108,
\r
101 0x00021000, 0x00121000, 0x00021100, 0x00121100,
\r
102 0x00021008, 0x00121008, 0x00021108, 0x00121108,
\r
103 0x04020000, 0x04120000, 0x04020100, 0x04120100,
\r
104 0x04020008, 0x04120008, 0x04020108, 0x04120108,
\r
105 0x04021000, 0x04121000, 0x04021100, 0x04121100,
\r
106 0x04021008, 0x04121008, 0x04021108, 0x04121108,
\r
109 /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
\r
110 0x00000000, 0x10000000, 0x00010000, 0x10010000,
\r
111 0x00000004, 0x10000004, 0x00010004, 0x10010004,
\r
112 0x20000000, 0x30000000, 0x20010000, 0x30010000,
\r
113 0x20000004, 0x30000004, 0x20010004, 0x30010004,
\r
114 0x00100000, 0x10100000, 0x00110000, 0x10110000,
\r
115 0x00100004, 0x10100004, 0x00110004, 0x10110004,
\r
116 0x20100000, 0x30100000, 0x20110000, 0x30110000,
\r
117 0x20100004, 0x30100004, 0x20110004, 0x30110004,
\r
118 0x00001000, 0x10001000, 0x00011000, 0x10011000,
\r
119 0x00001004, 0x10001004, 0x00011004, 0x10011004,
\r
120 0x20001000, 0x30001000, 0x20011000, 0x30011000,
\r
121 0x20001004, 0x30001004, 0x20011004, 0x30011004,
\r
122 0x00101000, 0x10101000, 0x00111000, 0x10111000,
\r
123 0x00101004, 0x10101004, 0x00111004, 0x10111004,
\r
124 0x20101000, 0x30101000, 0x20111000, 0x30111000,
\r
125 0x20101004, 0x30101004, 0x20111004, 0x30111004,
\r
128 /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
\r
129 0x00000000, 0x08000000, 0x00000008, 0x08000008,
\r
130 0x00000400, 0x08000400, 0x00000408, 0x08000408,
\r
131 0x00020000, 0x08020000, 0x00020008, 0x08020008,
\r
132 0x00020400, 0x08020400, 0x00020408, 0x08020408,
\r
133 0x00000001, 0x08000001, 0x00000009, 0x08000009,
\r
134 0x00000401, 0x08000401, 0x00000409, 0x08000409,
\r
135 0x00020001, 0x08020001, 0x00020009, 0x08020009,
\r
136 0x00020401, 0x08020401, 0x00020409, 0x08020409,
\r
137 0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
\r
138 0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
\r
139 0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
\r
140 0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
\r
141 0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
\r
142 0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
\r
143 0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
\r
144 0x02020401, 0x0A020401, 0x02020409, 0x0A020409,
\r
147 /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
\r
148 0x00000000, 0x00000100, 0x00080000, 0x00080100,
\r
149 0x01000000, 0x01000100, 0x01080000, 0x01080100,
\r
150 0x00000010, 0x00000110, 0x00080010, 0x00080110,
\r
151 0x01000010, 0x01000110, 0x01080010, 0x01080110,
\r
152 0x00200000, 0x00200100, 0x00280000, 0x00280100,
\r
153 0x01200000, 0x01200100, 0x01280000, 0x01280100,
\r
154 0x00200010, 0x00200110, 0x00280010, 0x00280110,
\r
155 0x01200010, 0x01200110, 0x01280010, 0x01280110,
\r
156 0x00000200, 0x00000300, 0x00080200, 0x00080300,
\r
157 0x01000200, 0x01000300, 0x01080200, 0x01080300,
\r
158 0x00000210, 0x00000310, 0x00080210, 0x00080310,
\r
159 0x01000210, 0x01000310, 0x01080210, 0x01080310,
\r
160 0x00200200, 0x00200300, 0x00280200, 0x00280300,
\r
161 0x01200200, 0x01200300, 0x01280200, 0x01280300,
\r
162 0x00200210, 0x00200310, 0x00280210, 0x00280310,
\r
163 0x01200210, 0x01200310, 0x01280210, 0x01280310,
\r
166 /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
\r
167 0x00000000, 0x04000000, 0x00040000, 0x04040000,
\r
168 0x00000002, 0x04000002, 0x00040002, 0x04040002,
\r
169 0x00002000, 0x04002000, 0x00042000, 0x04042000,
\r
170 0x00002002, 0x04002002, 0x00042002, 0x04042002,
\r
171 0x00000020, 0x04000020, 0x00040020, 0x04040020,
\r
172 0x00000022, 0x04000022, 0x00040022, 0x04040022,
\r
173 0x00002020, 0x04002020, 0x00042020, 0x04042020,
\r
174 0x00002022, 0x04002022, 0x00042022, 0x04042022,
\r
175 0x00000800, 0x04000800, 0x00040800, 0x04040800,
\r
176 0x00000802, 0x04000802, 0x00040802, 0x04040802,
\r
177 0x00002800, 0x04002800, 0x00042800, 0x04042800,
\r
178 0x00002802, 0x04002802, 0x00042802, 0x04042802,
\r
179 0x00000820, 0x04000820, 0x00040820, 0x04040820,
\r
180 0x00000822, 0x04000822, 0x00040822, 0x04040822,
\r
181 0x00002820, 0x04002820, 0x00042820, 0x04042820,
\r
182 0x00002822, 0x04002822, 0x00042822, 0x04042822,
\r
186 private static final int SPtrans[][] = {
\r
189 0x00820200, 0x00020000, 0x80800000, 0x80820200,
\r
190 0x00800000, 0x80020200, 0x80020000, 0x80800000,
\r
191 0x80020200, 0x00820200, 0x00820000, 0x80000200,
\r
192 0x80800200, 0x00800000, 0x00000000, 0x80020000,
\r
193 0x00020000, 0x80000000, 0x00800200, 0x00020200,
\r
194 0x80820200, 0x00820000, 0x80000200, 0x00800200,
\r
195 0x80000000, 0x00000200, 0x00020200, 0x80820000,
\r
196 0x00000200, 0x80800200, 0x80820000, 0x00000000,
\r
197 0x00000000, 0x80820200, 0x00800200, 0x80020000,
\r
198 0x00820200, 0x00020000, 0x80000200, 0x00800200,
\r
199 0x80820000, 0x00000200, 0x00020200, 0x80800000,
\r
200 0x80020200, 0x80000000, 0x80800000, 0x00820000,
\r
201 0x80820200, 0x00020200, 0x00820000, 0x80800200,
\r
202 0x00800000, 0x80000200, 0x80020000, 0x00000000,
\r
203 0x00020000, 0x00800000, 0x80800200, 0x00820200,
\r
204 0x80000000, 0x80820000, 0x00000200, 0x80020200,
\r
208 0x10042004, 0x00000000, 0x00042000, 0x10040000,
\r
209 0x10000004, 0x00002004, 0x10002000, 0x00042000,
\r
210 0x00002000, 0x10040004, 0x00000004, 0x10002000,
\r
211 0x00040004, 0x10042000, 0x10040000, 0x00000004,
\r
212 0x00040000, 0x10002004, 0x10040004, 0x00002000,
\r
213 0x00042004, 0x10000000, 0x00000000, 0x00040004,
\r
214 0x10002004, 0x00042004, 0x10042000, 0x10000004,
\r
215 0x10000000, 0x00040000, 0x00002004, 0x10042004,
\r
216 0x00040004, 0x10042000, 0x10002000, 0x00042004,
\r
217 0x10042004, 0x00040004, 0x10000004, 0x00000000,
\r
218 0x10000000, 0x00002004, 0x00040000, 0x10040004,
\r
219 0x00002000, 0x10000000, 0x00042004, 0x10002004,
\r
220 0x10042000, 0x00002000, 0x00000000, 0x10000004,
\r
221 0x00000004, 0x10042004, 0x00042000, 0x10040000,
\r
222 0x10040004, 0x00040000, 0x00002004, 0x10002000,
\r
223 0x10002004, 0x00000004, 0x10040000, 0x00042000,
\r
227 0x41000000, 0x01010040, 0x00000040, 0x41000040,
\r
228 0x40010000, 0x01000000, 0x41000040, 0x00010040,
\r
229 0x01000040, 0x00010000, 0x01010000, 0x40000000,
\r
230 0x41010040, 0x40000040, 0x40000000, 0x41010000,
\r
231 0x00000000, 0x40010000, 0x01010040, 0x00000040,
\r
232 0x40000040, 0x41010040, 0x00010000, 0x41000000,
\r
233 0x41010000, 0x01000040, 0x40010040, 0x01010000,
\r
234 0x00010040, 0x00000000, 0x01000000, 0x40010040,
\r
235 0x01010040, 0x00000040, 0x40000000, 0x00010000,
\r
236 0x40000040, 0x40010000, 0x01010000, 0x41000040,
\r
237 0x00000000, 0x01010040, 0x00010040, 0x41010000,
\r
238 0x40010000, 0x01000000, 0x41010040, 0x40000000,
\r
239 0x40010040, 0x41000000, 0x01000000, 0x41010040,
\r
240 0x00010000, 0x01000040, 0x41000040, 0x00010040,
\r
241 0x01000040, 0x00000000, 0x41010000, 0x40000040,
\r
242 0x41000000, 0x40010040, 0x00000040, 0x01010000,
\r
246 0x00100402, 0x04000400, 0x00000002, 0x04100402,
\r
247 0x00000000, 0x04100000, 0x04000402, 0x00100002,
\r
248 0x04100400, 0x04000002, 0x04000000, 0x00000402,
\r
249 0x04000002, 0x00100402, 0x00100000, 0x04000000,
\r
250 0x04100002, 0x00100400, 0x00000400, 0x00000002,
\r
251 0x00100400, 0x04000402, 0x04100000, 0x00000400,
\r
252 0x00000402, 0x00000000, 0x00100002, 0x04100400,
\r
253 0x04000400, 0x04100002, 0x04100402, 0x00100000,
\r
254 0x04100002, 0x00000402, 0x00100000, 0x04000002,
\r
255 0x00100400, 0x04000400, 0x00000002, 0x04100000,
\r
256 0x04000402, 0x00000000, 0x00000400, 0x00100002,
\r
257 0x00000000, 0x04100002, 0x04100400, 0x00000400,
\r
258 0x04000000, 0x04100402, 0x00100402, 0x00100000,
\r
259 0x04100402, 0x00000002, 0x04000400, 0x00100402,
\r
260 0x00100002, 0x00100400, 0x04100000, 0x04000402,
\r
261 0x00000402, 0x04000000, 0x04000002, 0x04100400,
\r
265 0x02000000, 0x00004000, 0x00000100, 0x02004108,
\r
266 0x02004008, 0x02000100, 0x00004108, 0x02004000,
\r
267 0x00004000, 0x00000008, 0x02000008, 0x00004100,
\r
268 0x02000108, 0x02004008, 0x02004100, 0x00000000,
\r
269 0x00004100, 0x02000000, 0x00004008, 0x00000108,
\r
270 0x02000100, 0x00004108, 0x00000000, 0x02000008,
\r
271 0x00000008, 0x02000108, 0x02004108, 0x00004008,
\r
272 0x02004000, 0x00000100, 0x00000108, 0x02004100,
\r
273 0x02004100, 0x02000108, 0x00004008, 0x02004000,
\r
274 0x00004000, 0x00000008, 0x02000008, 0x02000100,
\r
275 0x02000000, 0x00004100, 0x02004108, 0x00000000,
\r
276 0x00004108, 0x02000000, 0x00000100, 0x00004008,
\r
277 0x02000108, 0x00000100, 0x00000000, 0x02004108,
\r
278 0x02004008, 0x02004100, 0x00000108, 0x00004000,
\r
279 0x00004100, 0x02004008, 0x02000100, 0x00000108,
\r
280 0x00000008, 0x00004108, 0x02004000, 0x02000008,
\r
284 0x20000010, 0x00080010, 0x00000000, 0x20080800,
\r
285 0x00080010, 0x00000800, 0x20000810, 0x00080000,
\r
286 0x00000810, 0x20080810, 0x00080800, 0x20000000,
\r
287 0x20000800, 0x20000010, 0x20080000, 0x00080810,
\r
288 0x00080000, 0x20000810, 0x20080010, 0x00000000,
\r
289 0x00000800, 0x00000010, 0x20080800, 0x20080010,
\r
290 0x20080810, 0x20080000, 0x20000000, 0x00000810,
\r
291 0x00000010, 0x00080800, 0x00080810, 0x20000800,
\r
292 0x00000810, 0x20000000, 0x20000800, 0x00080810,
\r
293 0x20080800, 0x00080010, 0x00000000, 0x20000800,
\r
294 0x20000000, 0x00000800, 0x20080010, 0x00080000,
\r
295 0x00080010, 0x20080810, 0x00080800, 0x00000010,
\r
296 0x20080810, 0x00080800, 0x00080000, 0x20000810,
\r
297 0x20000010, 0x20080000, 0x00080810, 0x00000000,
\r
298 0x00000800, 0x20000010, 0x20000810, 0x20080800,
\r
299 0x20080000, 0x00000810, 0x00000010, 0x20080010,
\r
303 0x00001000, 0x00000080, 0x00400080, 0x00400001,
\r
304 0x00401081, 0x00001001, 0x00001080, 0x00000000,
\r
305 0x00400000, 0x00400081, 0x00000081, 0x00401000,
\r
306 0x00000001, 0x00401080, 0x00401000, 0x00000081,
\r
307 0x00400081, 0x00001000, 0x00001001, 0x00401081,
\r
308 0x00000000, 0x00400080, 0x00400001, 0x00001080,
\r
309 0x00401001, 0x00001081, 0x00401080, 0x00000001,
\r
310 0x00001081, 0x00401001, 0x00000080, 0x00400000,
\r
311 0x00001081, 0x00401000, 0x00401001, 0x00000081,
\r
312 0x00001000, 0x00000080, 0x00400000, 0x00401001,
\r
313 0x00400081, 0x00001081, 0x00001080, 0x00000000,
\r
314 0x00000080, 0x00400001, 0x00000001, 0x00400080,
\r
315 0x00000000, 0x00400081, 0x00400080, 0x00001080,
\r
316 0x00000081, 0x00001000, 0x00401081, 0x00400000,
\r
317 0x00401080, 0x00000001, 0x00001001, 0x00401081,
\r
318 0x00400001, 0x00401080, 0x00401000, 0x00001001,
\r
322 0x08200020, 0x08208000, 0x00008020, 0x00000000,
\r
323 0x08008000, 0x00200020, 0x08200000, 0x08208020,
\r
324 0x00000020, 0x08000000, 0x00208000, 0x00008020,
\r
325 0x00208020, 0x08008020, 0x08000020, 0x08200000,
\r
326 0x00008000, 0x00208020, 0x00200020, 0x08008000,
\r
327 0x08208020, 0x08000020, 0x00000000, 0x00208000,
\r
328 0x08000000, 0x00200000, 0x08008020, 0x08200020,
\r
329 0x00200000, 0x00008000, 0x08208000, 0x00000020,
\r
330 0x00200000, 0x00008000, 0x08000020, 0x08208020,
\r
331 0x00008020, 0x08000000, 0x00000000, 0x00208000,
\r
332 0x08200020, 0x08008020, 0x08008000, 0x00200020,
\r
333 0x08208000, 0x00000020, 0x00200020, 0x08008000,
\r
334 0x08208020, 0x00200000, 0x08200000, 0x08000020,
\r
335 0x00208000, 0x00008020, 0x08008020, 0x08200000,
\r
336 0x00000020, 0x08208000, 0x00208020, 0x00000000,
\r
337 0x08000000, 0x08200020, 0x00008000, 0x00208020
\r
341 private static final int byteToUnsigned(byte b) {
\r
342 int value = (int) b;
\r
343 return (value >= 0) ? value : value + 256;
\r
346 private static int fourBytesToInt(byte b[], int offset) {
\r
347 return byteToUnsigned(b[offset++])
\r
348 | (byteToUnsigned(b[offset++]) << 8)
\r
349 | (byteToUnsigned(b[offset++]) << 16)
\r
350 | (byteToUnsigned(b[offset]) << 24);
\r
353 private static final void intToFourBytes(int iValue, byte b[], int offset) {
\r
354 b[offset++] = (byte)((iValue) & 0xff);
\r
355 b[offset++] = (byte)((iValue >>> 8 ) & 0xff);
\r
356 b[offset++] = (byte)((iValue >>> 16) & 0xff);
\r
357 b[offset] = (byte)((iValue >>> 24) & 0xff);
\r
360 private static final void PERM_OP(int a, int b, int n, int m, int results[]) {
\r
363 t = ((a >>> n) ^ b) & m;
\r
371 private static final int HPERM_OP(int a, int n, int m) {
\r
374 t = ((a << (16 - n)) ^ a) & m;
\r
375 a = a ^ t ^ (t >>> (16 - n));
\r
380 private static int [] des_set_key(byte key[]) {
\r
381 int schedule[] = new int [ITERATIONS * 2];
\r
383 int c = fourBytesToInt(key, 0);
\r
384 int d = fourBytesToInt(key, 4);
\r
386 int results[] = new int[2];
\r
388 PERM_OP(d, c, 4, 0x0f0f0f0f, results);
\r
389 d = results[0]; c = results[1];
\r
391 c = HPERM_OP(c, -2, 0xcccc0000);
\r
392 d = HPERM_OP(d, -2, 0xcccc0000);
\r
394 PERM_OP(d, c, 1, 0x55555555, results);
\r
395 d = results[0]; c = results[1];
\r
397 PERM_OP(c, d, 8, 0x00ff00ff, results);
\r
398 c = results[0]; d = results[1];
\r
400 PERM_OP(d, c, 1, 0x55555555, results);
\r
401 d = results[0]; c = results[1];
\r
403 d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
\r
404 ((d & 0x00ff0000) >>> 16) | ((c & 0xf0000000) >>> 4));
\r
410 for(int i = 0; i < ITERATIONS; i ++) {
\r
412 c = (c >>> 2) | (c << 26);
\r
413 d = (d >>> 2) | (d << 26);
\r
415 c = (c >>> 1) | (c << 27);
\r
416 d = (d >>> 1) | (d << 27);
\r
422 s = skb[0][ (c ) & 0x3f ]|
\r
423 skb[1][((c >>> 6) & 0x03) | ((c >>> 7) & 0x3c)]|
\r
424 skb[2][((c >>> 13) & 0x0f) | ((c >>> 14) & 0x30)]|
\r
425 skb[3][((c >>> 20) & 0x01) | ((c >>> 21) & 0x06) |
\r
426 ((c >>> 22) & 0x38)];
\r
428 t = skb[4][ (d ) & 0x3f ]|
\r
429 skb[5][((d >>> 7) & 0x03) | ((d >>> 8) & 0x3c)]|
\r
430 skb[6][ (d >>>15) & 0x3f ]|
\r
431 skb[7][((d >>>21) & 0x0f) | ((d >>> 22) & 0x30)];
\r
433 schedule[j++] = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
\r
434 s = ((s >>> 16) | (t & 0xffff0000));
\r
436 s = (s << 4) | (s >>> 28);
\r
437 schedule[j++] = s & 0xffffffff;
\r
442 private static final int D_ENUnixCrypt(int L, int R, int S, int E0, int E1, int s[]) {
\r
445 v = R ^ (R >>> 16);
\r
448 u = (u ^ (u << 16)) ^ R ^ s[S];
\r
449 t = (v ^ (v << 16)) ^ R ^ s[S + 1];
\r
450 t = (t >>> 4) | (t << 28);
\r
452 L ^= SPtrans[1][(t ) & 0x3f] |
\r
453 SPtrans[3][(t >>> 8) & 0x3f] |
\r
454 SPtrans[5][(t >>> 16) & 0x3f] |
\r
455 SPtrans[7][(t >>> 24) & 0x3f] |
\r
456 SPtrans[0][(u ) & 0x3f] |
\r
457 SPtrans[2][(u >>> 8) & 0x3f] |
\r
458 SPtrans[4][(u >>> 16) & 0x3f] |
\r
459 SPtrans[6][(u >>> 24) & 0x3f];
\r
464 private static final int [] body(int schedule[], int Eswap0, int Eswap1)
\r
470 for (int j = 0; j < 25; j ++) {
\r
471 for (int i = 0; i < ITERATIONS * 2; i += 4) {
\r
472 left = D_ENUnixCrypt(left, right, i, Eswap0, Eswap1, schedule);
\r
473 right = D_ENUnixCrypt(right, left, i + 2, Eswap0, Eswap1, schedule);
\r
482 right = (left >>> 1) | (left << 31);
\r
483 left = (t >>> 1) | (t << 31);
\r
485 left &= 0xffffffff;
\r
486 right &= 0xffffffff;
\r
488 int results[] = new int[2];
\r
490 PERM_OP(right, left, 1, 0x55555555, results);
\r
491 right = results[0]; left = results[1];
\r
493 PERM_OP(left, right, 8, 0x00ff00ff, results);
\r
494 left = results[0]; right = results[1];
\r
496 PERM_OP(right, left, 2, 0x33333333, results);
\r
497 right = results[0]; left = results[1];
\r
499 PERM_OP(left, right, 16, 0x0000ffff, results);
\r
500 left = results[0]; right = results[1];
\r
502 PERM_OP(right, left, 4, 0x0f0f0f0f, results);
\r
503 right = results[0]; left = results[1];
\r
505 int out[] = new int[2];
\r
513 public static final String alphabet = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
\r
515 public static final String encrypt(String salt, String original)
\r
517 // wwb -- Should do some sanity checks: salt needs to be 2 chars, in alpha.
\r
518 while(salt.length() < 2)
\r
521 char[] buffer = new char [13];
\r
523 char charZero = salt.charAt(0);
\r
524 char charOne = salt.charAt(1);
\r
526 buffer[0] = charZero;
\r
527 buffer[1] = charOne;
\r
529 int Eswap0 = alphabet.indexOf(charZero);
\r
530 int Eswap1 = alphabet.indexOf(charOne) << 4;
\r
531 byte key[] = new byte[8];
\r
533 for(int i = 0; i < key.length; i ++)
\r
536 for(int i = 0; i < key.length && i < original.length(); i ++)
\r
537 key[i] = (byte) (((int) original.charAt(i)) << 1);
\r
539 int schedule[] = des_set_key(key);
\r
540 int out[] = body(schedule, Eswap0, Eswap1);
\r
542 byte b[] = new byte[9];
\r
544 intToFourBytes(out[0], b, 0);
\r
545 intToFourBytes(out[1], b, 4);
\r
548 for(int i = 2, y = 0, u = 0x80; i < 13; i ++) {
\r
549 for(int j = 0, c = 0; j < 6; j ++) {
\r
552 if(((int)b[y] & u) != 0)
\r
561 buffer[i] = alphabet.charAt(c);
\r
564 return new String(buffer);
\r
567 public static void main(String [] args)
\r
569 if ( (1 == args.length) && ("list".equalsIgnoreCase(args[0])) )
\r
571 StringBuffer listChars = new StringBuffer(alphabet);
\r
572 final String password = "italianroast";
\r
574 ArrayList<String []> pws = new ArrayList<String []>();
\r
575 while( listChars.length() > 0 )
\r
577 int startLen = listChars.length();
\r
578 String pw = UnixCrypt.encrypt(Integer.toString(salt), password);
\r
579 for( int i = 0; i < pw.length(); ++i )
\r
581 int pos = listChars.indexOf(pw.substring(i, i+1));
\r
583 listChars.deleteCharAt(pos);
\r
585 if( listChars.length() == startLen )
\r
588 pws.add(new String [] { password, pw });
\r
590 for( String [] pw : pws )
\r
591 System.out.println(pw[0] + " : " + pw[1]);
\r
593 else if ( 2 == args.length )
\r
595 System.out.println(UnixCrypt.encrypt(args[0], args[1]));
\r
599 System.out.println("usage: UnixCrypt <salt> <password>");
\r
600 System.out.println("or: \"UnixCrypt list\" to generate a list of password with all possible characters.");
\r