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