Source code: com/neuron/jaffer/DES.java
1 package com.neuron.jaffer;
2
3 import java.util.*;
4
5 public final class DES
6 {
7 // public object api
8
9 public DES(byte key[])
10 {
11 schedule = genSchedule(key);
12 }
13
14 public void encrypt(byte b[])
15 {
16 fencrypt(b, false, schedule);
17 }
18
19 public void decrypt(byte b[])
20 {
21 fencrypt(b, true, schedule);
22 }
23
24 private Schedule schedule;
25
26 // public static methods
27
28 public static void main(String args[])
29 {
30 byte key[] = longToBytes(Long.parseLong(args[0], 16));
31 byte data[] = longToBytes(Long.parseLong(args[1], 16));
32
33 System.out.println("key="+args[0]+" data="+args[1]);
34 printBytes("key", key);
35 printBytes("data", data);
36
37 DES des = new DES(key);
38
39 des.encrypt(data);
40 printBytes("encrypted", data);
41
42 des.decrypt(data);
43 printBytes("decrypted", data);
44
45 }
46
47 public static Schedule genSchedule(byte key[])
48 {
49 Schedule s = new Schedule();
50 fsetkey(key, s);
51 return s;
52 }
53
54 public static void encrypt(Schedule s, byte b[])
55 {
56 fencrypt(b, false, s);
57 }
58
59 public static void decrypt(Schedule s, byte b[])
60 {
61 fencrypt(b, true, s);
62 }
63
64 // private fields and methods
65
66 private static int built;
67
68 private static class Stage
69 {
70 int h, l;
71 }
72
73 public static class Schedule
74 {
75 Stage KS[];
76 Schedule()
77 {
78 KS = new Stage[16];
79 for (int i=0; i<KS.length; i++)
80 {
81 KS[i] = new Stage();
82 }
83 }
84 }
85
86 private final static byte bK_C[] = {
87 57, 49, 41, 33, 25, 17, 9,
88 1, 58, 50, 42, 34, 26, 18,
89 10, 2, 59, 51, 43, 35, 27,
90 19, 11, 3, 60, 52, 44, 36,
91 };
92 private final static byte bK_D[] = {
93 63, 55, 47, 39, 31, 23, 15,
94 7, 62, 54, 46, 38, 30, 22,
95 14, 6, 61, 53, 45, 37, 29,
96 21, 13, 5, 28, 20, 12, 4,
97 };
98
99 private static int wC_K4[][] = new int[8][16];
100 private static int wC_K3[][] = new int[8][8];
101 private static int wD_K4[][] = new int[8][16];
102 private static int wD_K3[][] = new int[8][8];
103
104 private static byte preshift[] = {
105 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
106 };
107
108 private static byte bCD_KS[] = {
109 14, 17, 11, 24, 1, 5,
110 3, 28, 15, 6, 21, 10,
111 23, 19, 12, 4, 26, 8,
112 16, 7, 27, 20, 13, 2,
113 41, 52, 31, 37, 47, 55,
114 30, 40, 51, 45, 33, 48,
115 44, 49, 39, 56, 34, 53,
116 46, 42, 50, 36, 29, 32,
117 };
118
119 private static int hKS_C4[][] = new int[7][16];
120 private static int lKS_D4[][] = new int[7][16];
121 private static int wL_I8[] = new int[0x55 + 1];
122 private static int wO_L4[] = new int[16];
123 private static int wPS[][] = new int[8][64];
124
125 private static byte P[] = {
126 16, 7, 20, 21,
127 29, 12, 28, 17,
128 1, 15, 23, 26,
129 5, 18, 31, 10,
130 2, 8, 24, 14,
131 32, 27, 3, 9,
132 19, 13, 30, 6,
133 22, 11, 4, 25,
134 };
135
136 private static byte S[][] = {
137 {
138 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
139 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
140 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
141 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
142 },
143
144 {
145 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
146 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
147 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
148 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
149 },
150
151 {
152 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
153 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
154 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
155 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
156 },
157
158 {
159 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
160 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
161 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
162 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
163 },
164
165 {
166 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
167 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
168 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
169 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
170 },
171
172 {
173 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
174 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
175 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
176 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
177 },
178
179 {
180 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
181 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
182 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
183 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
184 },
185
186 {
187 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
188 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
189 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
190 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
191 },
192 };
193
194 private static void buildtables()
195 {
196 int i, j, v;
197 int wC_K[] = new int[64];
198 int wD_K[] = new int[64];
199 int hKS_C[] = new int[28];
200 int lKS_D[] = new int[28];
201 int Smap[] = new int[64];
202 int wP[] = new int[32];
203
204 /* Invert permuted-choice-1 (key => C,D) */
205
206 v = 1;
207 for (j = 28; --j >= 0; )
208 {
209 wC_K[ bK_C[j] - 1 ] = wD_K[ bK_D[j] - 1 ] = v;
210 v += v; /* (i.e. v <<= 1) */
211 }
212
213 for (i = 0; i < 64; i++)
214 {
215 int t = 8 >>> (i & 3);
216 for (j = 0; j < 16; j++)
217 {
218 if ((j & t) != 0)
219 {
220 wC_K4[i >>> 3][j] |= wC_K[i];
221 wD_K4[i >>> 3][j] |= wD_K[i];
222 if (j < 8)
223 {
224 wC_K3[i >>> 3][j] |= wC_K[i + 3];
225 wD_K3[i >>> 3][j] |= wD_K[i + 3];
226 }
227 }
228 }
229 /* Generate the sequence 0,1,2,3, 8,9,10,11, ..., 56,57,58,59. */
230 if (t == 1)
231 {
232 i += 4;
233 }
234 }
235
236 /* Invert permuted-choice-2 */
237
238 v = 1;
239 for (i = 24; (i -= 6) >= 0; )
240 {
241 j = i+5;
242 do
243 {
244 hKS_C[ bCD_KS[j] - 1 ] = lKS_D[ bCD_KS[j+24] - 28 - 1 ] = v;
245 v += v; /* Like v <<= 1 but may be faster */
246 }
247 while(--j >= i);
248 v <<= 2; /* Keep byte aligned */
249 }
250
251 for (i = 0; i < 28; i++)
252 {
253 v = 8 >>> (i & 3);
254 for (j = 0; j < 16; j++)
255 {
256 if ((j & v) != 0)
257 {
258 hKS_C4[i >>> 2][j] |= hKS_C[i];
259 lKS_D4[i >>> 2][j] |= lKS_D[i];
260 }
261 }
262 }
263
264 /* Initial permutation */
265
266 for (i = 0; i <= 0x55; i++)
267 {
268 v = 0;
269 if ((i & 64) != 0) { v = 1 << 24; }
270 if ((i & 16) != 0) { v |= 1 << 16; }
271 if ((i & 4) != 0) { v |= 1 << 8; }
272 if ((i & 1) != 0) { v |= 1; }
273 wL_I8[i] = v;
274 }
275
276 /* Final permutation */
277
278 for (i = 0; i < 16; i++)
279 {
280 v = 0;
281 if ((i & 1) != 0) { v = 1 << 24; }
282 if ((i & 2) != 0) { v |= 1 << 16; }
283 if ((i & 4) != 0) { v |= 1 << 8; }
284 if ((i & 8) != 0) { v |= 1; }
285 wO_L4[i] = v;
286 }
287
288 /* Funny bit rearrangement on second index into S tables */
289
290 for (i = 0; i < 64; i++)
291 {
292 Smap[i] = (i & 0x20) | (i & 1) << 4 | (i & 0x1e) >>> 1;
293 }
294
295 /* Invert permutation P into mask indexed by R bit number */
296
297 v = 1;
298 for (i = 32; --i >= 0; )
299 {
300 wP[ P[i] - 1 ] = v;
301 v += v;
302 }
303
304 /* Build bit-mask versions of S tables, indexed in natural bit order */
305
306 for (i = 0; i < 8; i++)
307 {
308 for (j = 0; j < 64; j++)
309 {
310 int k, t;
311
312 t = S[i][ Smap[j] ];
313 for (k = 0; k < 4; k++)
314 {
315 if ((t & 8) != 0)
316 {
317 wPS[i][j] |= wP[4*i + k];
318 }
319 t += t;
320 }
321 }
322 }
323 }
324
325 private static byte[] longToBytes(long l)
326 {
327 return new byte[] {
328 (byte)((l >>> 56) & 0xff),
329 (byte)((l >>> 48) & 0xff),
330 (byte)((l >>> 40) & 0xff),
331 (byte)((l >>> 32) & 0xff),
332 (byte)((l >>> 24) & 0xff),
333 (byte)((l >>> 16) & 0xff),
334 (byte)((l >>> 8) & 0xff),
335 (byte)((l ) & 0xff),
336 };
337 }
338
339 private static void printBytes(String hdr, byte data[])
340 {
341 System.out.print(hdr+" = ");
342 for (int i=0; i<data.length; i++)
343 {
344 System.out.print(Integer.toHexString(data[i]&0xff)+",");
345 }
346 System.out.println();
347 }
348
349 private static void fsetkey(byte key[], Schedule ks)
350 {
351 int i;
352 int C, D;
353
354 if (built != 1)
355 {
356 buildtables();
357 built = 1;
358 }
359
360 C = D = 0;
361 for (i = 0; i < 8; i++)
362 {
363 int v;
364
365 v = key[i] >>> 1; /* Discard "parity" bit */
366 C |= wC_K4[i][(v>>>3) & 15] | wC_K3[i][v & 7];
367 D |= wD_K4[i][(v>>>3) & 15] | wD_K3[i][v & 7];
368 }
369
370 /*
371 * C and D now hold the suitably right-justified
372 * 28 permuted key bits each.
373 */
374 for (i = 0; i < 16; i++)
375 {
376 /* 28-bit left circular shift */
377 C <<= preshift[i];
378 C = ((C >>> 28) & 3) | (C & ((1<<28) - 1));
379 ks.KS[i].h = choice2(hKS_C4, C);
380
381 D <<= preshift[i];
382 D = ((D >>> 28) & 3) | (D & ((1<<28) - 1));
383 ks.KS[i].l = choice2(lKS_D4, D);
384 }
385 }
386
387 private static void fencrypt(byte block[], boolean decrypt, Schedule ks)
388 {
389 int i;
390 int L, R;
391 int kspp;
392 Stage ksp;
393
394 /* Initial permutation */
395
396 L = R = 0;
397 i = 7;
398 do
399 {
400 int v;
401 v = block[i]; /* Could optimize according to ENDIAN */
402 L = wL_I8[(v ) & 0x55] | (L << 1);
403 R = wL_I8[(v >>> 1) & 0x55] | (R << 1);
404 }
405 while(--i >= 0);
406
407 if (decrypt) {
408 kspp = 15;
409 } else {
410 kspp = 0;
411 }
412
413 i = 16;
414 do {
415 int k, tR;
416 ksp = ks.KS[kspp];
417
418 tR = (R >>> 15) | (R << 17);
419
420 k = ksp.h;
421 L ^= PS(0, ((tR >>> 12) ^ (k >>> 24)) & 63)
422 | PS(1, ((tR >>> 8) ^ (k >>> 16)) & 63)
423 | PS(2, ((tR >>> 4) ^ (k >>> 8)) & 63)
424 | PS(3, ((tR ) ^ (k )) & 63);
425
426 k = ksp.l;
427 L ^= PS(4, ((R >>> 11) ^ (k >>> 24)) & 63)
428 | PS(5, ((R >>> 7) ^ (k >>> 16)) & 63)
429 | PS(6, ((R >>> 3) ^ (k >>> 8)) & 63)
430 | PS(7, ((tR >>> 16) ^ (k )) & 63);
431
432 tR = L;
433 L = R;
434 R = tR;
435
436
437 if (decrypt) {
438 kspp--;
439 } else {
440 kspp++;
441 }
442 }
443 while (--i > 0);
444 {
445 int t;
446
447 t = FP(L,R,0) | (FP(L,R,8) | (FP(L,R,16) | (FP(L,R,24) << 2)) << 2) << 2;
448 R = FP(L,R,4) | (FP(L,R,12) | (FP(L,R,20) | (FP(L,R,28) << 2)) << 2) << 2;
449 L = t;
450 }
451 {
452 int t;
453
454 t = R;
455 block[7] = (byte)((t ) & 0xff);
456 block[6] = (byte)((t >>>= 8) & 0xff);
457 block[5] = (byte)((t >>>= 8) & 0xff);
458 block[4] = (byte)((t >>> 8) & 0xff);
459 t = L;
460 block[3] = (byte)((t ) & 0xff);
461 block[2] = (byte)((t >>>= 8) & 0xff);
462 block[1] = (byte)((t >>>= 8) & 0xff);
463 block[0] = (byte)((t >>> 8) & 0xff);
464 }
465 }
466
467 private static int choice2(int b[][], int v)
468 {
469 return
470 b[6][(v>>> 0)&15] |
471 b[5][(v>>> 4)&15] |
472 b[4][(v>>> 8)&15] |
473 b[3][(v>>>12)&15] |
474 b[2][(v>>>16)&15] |
475 b[1][(v>>>20)&15] |
476 b[0][(v>>>24)&15] ;
477 }
478
479 private static int PS(int i, int j)
480 {
481 return wPS[i][j];
482 }
483
484 private static int FP(int L, int R, int k)
485 {
486 return ((wO_L4[ (L >>> (k)) & 15 ] << 1) | wO_L4[ (R >>> (k)) & 15 ]);
487 }
488 }
489