Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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