1/*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.crypto.provider;
27
28import java.security.InvalidKeyException;
29
30/**
31 * This is the internal DES class responsible for encryption and
32 * decryption of a byte array of size <code>DES_BLOCK_SIZE</code>.
33 *
34 * @author Gigi Ankeny
35 * @author Jan Luehe
36 *
37 *
38 * @see DESConstants
39 * @see DESCipher
40 */
41
42class DESCrypt extends SymmetricCipher implements DESConstants {
43    private static final int s0p[] = {
44        0x00410100, 0x00010000, 0x40400000, 0x40410100, 0x00400000,
45        0x40010100, 0x40010000, 0x40400000, 0x40010100, 0x00410100,
46        0x00410000, 0x40000100, 0x40400100, 0x00400000, 0x00000000,
47        0x40010000, 0x00010000, 0x40000000, 0x00400100, 0x00010100,
48        0x40410100, 0x00410000, 0x40000100, 0x00400100, 0x40000000,
49        0x00000100, 0x00010100, 0x40410000, 0x00000100, 0x40400100,
50        0x40410000, 0x00000000, 0x00000000, 0x40410100, 0x00400100,
51        0x40010000, 0x00410100, 0x00010000, 0x40000100, 0x00400100,
52        0x40410000, 0x00000100, 0x00010100, 0x40400000, 0x40010100,
53        0x40000000, 0x40400000, 0x00410000, 0x40410100, 0x00010100,
54        0x00410000, 0x40400100, 0x00400000, 0x40000100, 0x40010000,
55        0x00000000, 0x00010000, 0x00400000, 0x40400100, 0x00410100,
56        0x40000000, 0x40410000, 0x00000100, 0x40010100,
57    };
58
59    private static final int s1p[] = {
60        0x08021002, 0x00000000, 0x00021000, 0x08020000, 0x08000002,
61        0x00001002, 0x08001000, 0x00021000, 0x00001000, 0x08020002,
62        0x00000002, 0x08001000, 0x00020002, 0x08021000, 0x08020000,
63        0x00000002, 0x00020000, 0x08001002, 0x08020002, 0x00001000,
64        0x00021002, 0x08000000, 0x00000000, 0x00020002, 0x08001002,
65        0x00021002, 0x08021000, 0x08000002, 0x08000000, 0x00020000,
66        0x00001002, 0x08021002, 0x00020002, 0x08021000, 0x08001000,
67        0x00021002, 0x08021002, 0x00020002, 0x08000002, 0x00000000,
68        0x08000000, 0x00001002, 0x00020000, 0x08020002, 0x00001000,
69        0x08000000, 0x00021002, 0x08001002, 0x08021000, 0x00001000,
70        0x00000000, 0x08000002, 0x00000002, 0x08021002, 0x00021000,
71        0x08020000, 0x08020002, 0x00020000, 0x00001002, 0x08001000,
72        0x08001002, 0x00000002, 0x08020000, 0x00021000,
73    };
74
75    private static final int s2p[] = {
76        0x20800000, 0x00808020, 0x00000020, 0x20800020, 0x20008000,
77        0x00800000, 0x20800020, 0x00008020, 0x00800020, 0x00008000,
78        0x00808000, 0x20000000, 0x20808020, 0x20000020, 0x20000000,
79        0x20808000, 0x00000000, 0x20008000, 0x00808020, 0x00000020,
80        0x20000020, 0x20808020, 0x00008000, 0x20800000, 0x20808000,
81        0x00800020, 0x20008020, 0x00808000, 0x00008020, 0x00000000,
82        0x00800000, 0x20008020, 0x00808020, 0x00000020, 0x20000000,
83        0x00008000, 0x20000020, 0x20008000, 0x00808000, 0x20800020,
84        0x00000000, 0x00808020, 0x00008020, 0x20808000, 0x20008000,
85        0x00800000, 0x20808020, 0x20000000, 0x20008020, 0x20800000,
86        0x00800000, 0x20808020, 0x00008000, 0x00800020, 0x20800020,
87        0x00008020, 0x00800020, 0x00000000, 0x20808000, 0x20000020,
88        0x20800000, 0x20008020, 0x00000020, 0x00808000,
89    };
90
91    private static final int s3p[] = {
92        0x00080201, 0x02000200, 0x00000001, 0x02080201, 0x00000000,
93        0x02080000, 0x02000201, 0x00080001, 0x02080200, 0x02000001,
94        0x02000000, 0x00000201, 0x02000001, 0x00080201, 0x00080000,
95        0x02000000, 0x02080001, 0x00080200, 0x00000200, 0x00000001,
96        0x00080200, 0x02000201, 0x02080000, 0x00000200, 0x00000201,
97        0x00000000, 0x00080001, 0x02080200, 0x02000200, 0x02080001,
98        0x02080201, 0x00080000, 0x02080001, 0x00000201, 0x00080000,
99        0x02000001, 0x00080200, 0x02000200, 0x00000001, 0x02080000,
100        0x02000201, 0x00000000, 0x00000200, 0x00080001, 0x00000000,
101        0x02080001, 0x02080200, 0x00000200, 0x02000000, 0x02080201,
102        0x00080201, 0x00080000, 0x02080201, 0x00000001, 0x02000200,
103        0x00080201, 0x00080001, 0x00080200, 0x02080000, 0x02000201,
104        0x00000201, 0x02000000, 0x02000001, 0x02080200,
105    };
106
107    private static final int s4p[] = {
108        0x01000000, 0x00002000, 0x00000080, 0x01002084, 0x01002004,
109        0x01000080, 0x00002084, 0x01002000, 0x00002000, 0x00000004,
110        0x01000004, 0x00002080, 0x01000084, 0x01002004, 0x01002080,
111        0x00000000, 0x00002080, 0x01000000, 0x00002004, 0x00000084,
112        0x01000080, 0x00002084, 0x00000000, 0x01000004, 0x00000004,
113        0x01000084, 0x01002084, 0x00002004, 0x01002000, 0x00000080,
114        0x00000084, 0x01002080, 0x01002080, 0x01000084, 0x00002004,
115        0x01002000, 0x00002000, 0x00000004, 0x01000004, 0x01000080,
116        0x01000000, 0x00002080, 0x01002084, 0x00000000, 0x00002084,
117        0x01000000, 0x00000080, 0x00002004, 0x01000084, 0x00000080,
118        0x00000000, 0x01002084, 0x01002004, 0x01002080, 0x00000084,
119        0x00002000, 0x00002080, 0x01002004, 0x01000080, 0x00000084,
120        0x00000004, 0x00002084, 0x01002000, 0x01000004,
121    };
122
123    private static final int s5p[] = {
124        0x10000008, 0x00040008, 0x00000000, 0x10040400, 0x00040008,
125        0x00000400, 0x10000408, 0x00040000, 0x00000408, 0x10040408,
126        0x00040400, 0x10000000, 0x10000400, 0x10000008, 0x10040000,
127        0x00040408, 0x00040000, 0x10000408, 0x10040008, 0x00000000,
128        0x00000400, 0x00000008, 0x10040400, 0x10040008, 0x10040408,
129        0x10040000, 0x10000000, 0x00000408, 0x00000008, 0x00040400,
130        0x00040408, 0x10000400, 0x00000408, 0x10000000, 0x10000400,
131        0x00040408, 0x10040400, 0x00040008, 0x00000000, 0x10000400,
132        0x10000000, 0x00000400, 0x10040008, 0x00040000, 0x00040008,
133        0x10040408, 0x00040400, 0x00000008, 0x10040408, 0x00040400,
134        0x00040000, 0x10000408, 0x10000008, 0x10040000, 0x00040408,
135        0x00000000, 0x00000400, 0x10000008, 0x10000408, 0x10040400,
136        0x10040000, 0x00000408, 0x00000008, 0x10040008,
137    };
138
139    private static final int s6p[] = {
140        0x00000800, 0x00000040, 0x00200040, 0x80200000, 0x80200840,
141        0x80000800, 0x00000840, 0x00000000, 0x00200000, 0x80200040,
142        0x80000040, 0x00200800, 0x80000000, 0x00200840, 0x00200800,
143        0x80000040, 0x80200040, 0x00000800, 0x80000800, 0x80200840,
144        0x00000000, 0x00200040, 0x80200000, 0x00000840, 0x80200800,
145        0x80000840, 0x00200840, 0x80000000, 0x80000840, 0x80200800,
146        0x00000040, 0x00200000, 0x80000840, 0x00200800, 0x80200800,
147        0x80000040, 0x00000800, 0x00000040, 0x00200000, 0x80200800,
148        0x80200040, 0x80000840, 0x00000840, 0x00000000, 0x00000040,
149        0x80200000, 0x80000000, 0x00200040, 0x00000000, 0x80200040,
150        0x00200040, 0x00000840, 0x80000040, 0x00000800, 0x80200840,
151        0x00200000, 0x00200840, 0x80000000, 0x80000800, 0x80200840,
152        0x80200000, 0x00200840, 0x00200800, 0x80000800,
153    };
154
155    private static final int s7p[] = {
156        0x04100010, 0x04104000, 0x00004010, 0x00000000, 0x04004000,
157        0x00100010, 0x04100000, 0x04104010, 0x00000010, 0x04000000,
158        0x00104000, 0x00004010, 0x00104010, 0x04004010, 0x04000010,
159        0x04100000, 0x00004000, 0x00104010, 0x00100010, 0x04004000,
160        0x04104010, 0x04000010, 0x00000000, 0x00104000, 0x04000000,
161        0x00100000, 0x04004010, 0x04100010, 0x00100000, 0x00004000,
162        0x04104000, 0x00000010, 0x00100000, 0x00004000, 0x04000010,
163        0x04104010, 0x00004010, 0x04000000, 0x00000000, 0x00104000,
164        0x04100010, 0x04004010, 0x04004000, 0x00100010, 0x04104000,
165        0x00000010, 0x00100010, 0x04004000, 0x04104010, 0x00100000,
166        0x04100000, 0x04000010, 0x00104000, 0x00004010, 0x04004010,
167        0x04100000, 0x00000010, 0x04104000, 0x00104010, 0x00000000,
168        0x04000000, 0x04100010, 0x00004000, 0x00104010,
169    };
170
171    private static final int permRight0[] = {
172        0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000,
173        0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
174        0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040,
175        0x40404040,
176    };
177
178    private static final int permLeft1[] = {
179        0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000,
180        0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
181        0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040,
182        0x40404040,
183    };
184
185    private static final int permRight2[] = {
186        0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000,
187        0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
188        0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010,
189        0x10101010,
190    };
191
192    private static final int permLeft3[] = {
193        0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000,
194        0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
195        0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010,
196        0x10101010,
197    };
198
199    private static final int permRight4[] = {
200        0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400,
201        0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
202        0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404,
203        0x04040404,
204    };
205
206    private static final int permLeft5[] = {
207        0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400,
208        0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
209        0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404,
210        0x04040404,
211    };
212
213    private static final int permRight6[] = {
214        0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100,
215        0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
216        0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101,
217        0x01010101,
218    };
219
220    private static final int permLeft7[] = {
221        0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100,
222        0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
223        0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101,
224        0x01010101,
225    };
226
227    private static final int permRight8[] = {
228        0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000,
229        0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
230        0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080,
231        0x80808080,
232    };
233
234    private static final int permLeft9[] = {
235        0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000,
236        0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
237        0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080,
238        0x80808080,
239    };
240
241    private static final int permRightA[] = {
242        0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000,
243        0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
244        0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020,
245        0x20202020,
246    };
247
248    private static final int permLeftB[] = {
249        0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000,
250        0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
251        0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020,
252        0x20202020,
253    };
254
255    private static final int permRightC[] = {
256        0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800,
257        0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
258        0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808,
259        0x08080808,
260    };
261
262    private static final int permLeftD[] = {
263        0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800,
264        0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
265        0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808,
266        0x08080808,
267    };
268
269    private static final int permRightE[] = {
270        0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200,
271        0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
272        0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202,
273        0x02020202,
274    };
275
276    private static final int permLeftF[] = {
277        0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200,
278        0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
279        0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202,
280        0x02020202,
281    };
282
283    /*
284     *        Initial Permutation
285     */
286    private static final int initPermLeft0[] = {
287       0x00000000, 0x00008000, 0x00000000, 0x00008000, 0x00000080,
288       0x00008080, 0x00000080, 0x00008080, 0x00000000, 0x00008000,
289       0x00000000, 0x00008000, 0x00000080, 0x00008080, 0x00000080,
290       0x00008080,
291    };
292
293    private static final int initPermRight0[] = {
294       0x00000000, 0x00000000, 0x00008000, 0x00008000, 0x00000000,
295       0x00000000, 0x00008000, 0x00008000, 0x00000080, 0x00000080,
296       0x00008080, 0x00008080, 0x00000080, 0x00000080, 0x00008080,
297       0x00008080,
298    };
299
300    private static final int initPermLeft1[] = {
301       0x00000000, 0x80000000, 0x00000000, 0x80000000, 0x00800000,
302       0x80800000, 0x00800000, 0x80800000, 0x00000000, 0x80000000,
303       0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00800000,
304       0x80800000,
305    };
306
307    private static final int initPermRight1[] = {
308       0x00000000, 0x00000000, 0x80000000, 0x80000000, 0x00000000,
309       0x00000000, 0x80000000, 0x80000000, 0x00800000, 0x00800000,
310       0x80800000, 0x80800000, 0x00800000, 0x00800000, 0x80800000,
311       0x80800000,
312    };
313
314    private static final int initPermLeft2[] = {
315       0x00000000, 0x00004000, 0x00000000, 0x00004000, 0x00000040,
316       0x00004040, 0x00000040, 0x00004040, 0x00000000, 0x00004000,
317       0x00000000, 0x00004000, 0x00000040, 0x00004040, 0x00000040,
318       0x00004040,
319    };
320
321    private static final int initPermRight2[] = {
322       0x00000000, 0x00000000, 0x00004000, 0x00004000, 0x00000000,
323       0x00000000, 0x00004000, 0x00004000, 0x00000040, 0x00000040,
324       0x00004040, 0x00004040, 0x00000040, 0x00000040, 0x00004040,
325       0x00004040,
326    };
327
328    private static final int initPermLeft3[] = {
329       0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00400000,
330       0x40400000, 0x00400000, 0x40400000, 0x00000000, 0x40000000,
331       0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00400000,
332       0x40400000,
333    };
334
335    private static final int initPermRight3[] = {
336       0x00000000, 0x00000000, 0x40000000, 0x40000000, 0x00000000,
337       0x00000000, 0x40000000, 0x40000000, 0x00400000, 0x00400000,
338       0x40400000, 0x40400000, 0x00400000, 0x00400000, 0x40400000,
339       0x40400000,
340    };
341
342    private static final int initPermLeft4[] = {
343       0x00000000, 0x00002000, 0x00000000, 0x00002000, 0x00000020,
344       0x00002020, 0x00000020, 0x00002020, 0x00000000, 0x00002000,
345       0x00000000, 0x00002000, 0x00000020, 0x00002020, 0x00000020,
346       0x00002020,
347    };
348
349    private static final int initPermRight4[] = {
350       0x00000000, 0x00000000, 0x00002000, 0x00002000, 0x00000000,
351       0x00000000, 0x00002000, 0x00002000, 0x00000020, 0x00000020,
352       0x00002020, 0x00002020, 0x00000020, 0x00000020, 0x00002020,
353       0x00002020,
354    };
355
356    private static final int initPermLeft5[] = {
357       0x00000000, 0x20000000, 0x00000000, 0x20000000, 0x00200000,
358       0x20200000, 0x00200000, 0x20200000, 0x00000000, 0x20000000,
359       0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00200000,
360       0x20200000,
361    };
362
363    private static final int initPermRight5[] = {
364       0x00000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
365       0x00000000, 0x20000000, 0x20000000, 0x00200000, 0x00200000,
366       0x20200000, 0x20200000, 0x00200000, 0x00200000, 0x20200000,
367       0x20200000,
368    };
369
370    private static final int initPermLeft6[] = {
371       0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00000010,
372       0x00001010, 0x00000010, 0x00001010, 0x00000000, 0x00001000,
373       0x00000000, 0x00001000, 0x00000010, 0x00001010, 0x00000010,
374       0x00001010,
375    };
376
377    private static final int initPermRight6[] = {
378       0x00000000, 0x00000000, 0x00001000, 0x00001000, 0x00000000,
379       0x00000000, 0x00001000, 0x00001000, 0x00000010, 0x00000010,
380       0x00001010, 0x00001010, 0x00000010, 0x00000010, 0x00001010,
381       0x00001010,
382    };
383
384    private static final int initPermLeft7[] = {
385       0x00000000, 0x10000000, 0x00000000, 0x10000000, 0x00100000,
386       0x10100000, 0x00100000, 0x10100000, 0x00000000, 0x10000000,
387       0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00100000,
388       0x10100000,
389    };
390
391    private static final int initPermRight7[] = {
392       0x00000000, 0x00000000, 0x10000000, 0x10000000, 0x00000000,
393       0x00000000, 0x10000000, 0x10000000, 0x00100000, 0x00100000,
394       0x10100000, 0x10100000, 0x00100000, 0x00100000, 0x10100000,
395       0x10100000,
396    };
397
398    private static final int initPermLeft8[] = {
399       0x00000000, 0x00000800, 0x00000000, 0x00000800, 0x00000008,
400       0x00000808, 0x00000008, 0x00000808, 0x00000000, 0x00000800,
401       0x00000000, 0x00000800, 0x00000008, 0x00000808, 0x00000008,
402       0x00000808,
403    };
404
405    private static final int initPermRight8[] = {
406       0x00000000, 0x00000000, 0x00000800, 0x00000800, 0x00000000,
407       0x00000000, 0x00000800, 0x00000800, 0x00000008, 0x00000008,
408       0x00000808, 0x00000808, 0x00000008, 0x00000008, 0x00000808,
409       0x00000808,
410    };
411
412    private static final int initPermLeft9[] = {
413       0x00000000, 0x08000000, 0x00000000, 0x08000000, 0x00080000,
414       0x08080000, 0x00080000, 0x08080000, 0x00000000, 0x08000000,
415       0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00080000,
416       0x08080000,
417    };
418
419    private static final int initPermRight9[] = {
420       0x00000000, 0x00000000, 0x08000000, 0x08000000, 0x00000000,
421       0x00000000, 0x08000000, 0x08000000, 0x00080000, 0x00080000,
422       0x08080000, 0x08080000, 0x00080000, 0x00080000, 0x08080000,
423       0x08080000,
424    };
425
426    private static final int initPermLeftA[] = {
427       0x00000000, 0x00000400, 0x00000000, 0x00000400, 0x00000004,
428       0x00000404, 0x00000004, 0x00000404, 0x00000000, 0x00000400,
429       0x00000000, 0x00000400, 0x00000004, 0x00000404, 0x00000004,
430       0x00000404,
431    };
432
433    private static final int initPermRightA[] = {
434       0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000000,
435       0x00000000, 0x00000400, 0x00000400, 0x00000004, 0x00000004,
436       0x00000404, 0x00000404, 0x00000004, 0x00000004, 0x00000404,
437       0x00000404,
438    };
439
440    private static final int initPermLeftB[] = {
441       0x00000000, 0x04000000, 0x00000000, 0x04000000, 0x00040000,
442       0x04040000, 0x00040000, 0x04040000, 0x00000000, 0x04000000,
443       0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00040000,
444       0x04040000,
445    };
446
447    private static final int initPermRightB[] = {
448       0x00000000, 0x00000000, 0x04000000, 0x04000000, 0x00000000,
449       0x00000000, 0x04000000, 0x04000000, 0x00040000, 0x00040000,
450       0x04040000, 0x04040000, 0x00040000, 0x00040000, 0x04040000,
451       0x04040000,
452    };
453
454    private static final int initPermLeftC[] = {
455       0x00000000, 0x00000200, 0x00000000, 0x00000200, 0x00000002,
456       0x00000202, 0x00000002, 0x00000202, 0x00000000, 0x00000200,
457       0x00000000, 0x00000200, 0x00000002, 0x00000202, 0x00000002,
458       0x00000202,
459    };
460
461    private static final int initPermRightC[] = {
462       0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000000,
463       0x00000000, 0x00000200, 0x00000200, 0x00000002, 0x00000002,
464       0x00000202, 0x00000202, 0x00000002, 0x00000002, 0x00000202,
465       0x00000202,
466    };
467
468    private static final int initPermLeftD[] = {
469       0x00000000, 0x02000000, 0x00000000, 0x02000000, 0x00020000,
470       0x02020000, 0x00020000, 0x02020000, 0x00000000, 0x02000000,
471       0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00020000,
472       0x02020000,
473    };
474
475    private static final int initPermRightD[] = {
476       0x00000000, 0x00000000, 0x02000000, 0x02000000, 0x00000000,
477       0x00000000, 0x02000000, 0x02000000, 0x00020000, 0x00020000,
478       0x02020000, 0x02020000, 0x00020000, 0x00020000, 0x02020000,
479       0x02020000,
480    };
481
482    private static final int initPermLeftE[] = {
483       0x00000000, 0x00000100, 0x00000000, 0x00000100, 0x00000001,
484       0x00000101, 0x00000001, 0x00000101, 0x00000000, 0x00000100,
485       0x00000000, 0x00000100, 0x00000001, 0x00000101, 0x00000001,
486       0x00000101,
487    };
488
489    private static final int initPermRightE[] = {
490       0x00000000, 0x00000000, 0x00000100, 0x00000100, 0x00000000,
491       0x00000000, 0x00000100, 0x00000100, 0x00000001, 0x00000001,
492       0x00000101, 0x00000101, 0x00000001, 0x00000001, 0x00000101,
493       0x00000101,
494    };
495
496    private static final int initPermLeftF[] = {
497       0x00000000, 0x01000000, 0x00000000, 0x01000000, 0x00010000,
498       0x01010000, 0x00010000, 0x01010000, 0x00000000, 0x01000000,
499       0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00010000,
500       0x01010000,
501    };
502
503    private static final int initPermRightF[] = {
504       0x00000000, 0x00000000, 0x01000000, 0x01000000, 0x00000000,
505       0x00000000, 0x01000000, 0x01000000, 0x00010000, 0x00010000,
506       0x01010000, 0x01010000, 0x00010000, 0x00010000, 0x01010000,
507       0x01010000,
508    };
509
510    /*
511     * the encryption key array after expansion and permutation
512     */
513    byte[] expandedKey = null;
514
515    /*
516     * Are we encrypting or decrypting?
517     */
518    boolean decrypting = false;
519
520    /**
521     * Returns this cipher's block size.
522     *
523     * @return this cipher's block size
524     */
525    int getBlockSize() {
526        return DES_BLOCK_SIZE;
527    }
528
529    void init(boolean decrypting, String algorithm, byte[] rawKey)
530            throws InvalidKeyException {
531        this.decrypting = decrypting;
532        if (!algorithm.equalsIgnoreCase("DES")) {
533            throw new InvalidKeyException("Wrong algorithm: DES required");
534        }
535        if (rawKey.length != DES_BLOCK_SIZE) {
536            throw new InvalidKeyException("Wrong key size");
537        }
538        expandKey(rawKey);
539    }
540
541    /**
542     * Performs encryption operation.
543     *
544     * <p>The input plain text <code>plain</code>, starting at
545     * <code>plainOffset</code> and ending at
546     * <code>(plainOffset + len - 1)</code>, is encrypted.
547     * The result is stored in <code>cipher</code>, starting at
548     * <code>cipherOffset</code>.
549     *
550     * <p>The subclass that implements Cipher should ensure that
551     * <code>init</code> has been called before this method is called.
552     *
553     * @param plain the buffer with the input data to be encrypted
554     * @param plainOffset the offset in <code>plain</code>
555     * @param plainLen the length of the input data
556     * @param cipher the buffer for the result
557     * @param cipherOffset the offset in <code>cipher</code>
558     *
559     * @exception IllegalBlockSizeException if the input length is different
560     * from the cipher's block size
561     */
562    void encryptBlock(byte[] plain, int plainOffset,
563                 byte[] cipher, int cipherOffset)
564    {
565        cipherBlock(plain, plainOffset, cipher, cipherOffset);
566    }
567
568    /**
569     * Performs decryption operation.
570     *
571     * <p>The input cipher text <code>cipher</code>, starting at
572     * <code>cipherOffset</code> and ending at
573     * <code>(cipherOffset + len - 1)</code>, is decrypted.
574     * The result is stored in <code>plain</code>, starting at
575     * <code>plainOffset</code>.
576     *
577     * <p>The subclass that implements Cipher should ensure that
578     * <code>init</code> has been called before this method is called.
579     *
580     * @param cipher the buffer with the input data to be decrypted
581     * @param cipherOffset the offset in <code>cipherOffset</code>
582     * @param cipherLen the length of the input data
583     * @param plain the buffer for the result
584     * @param plainOffset the offset in <code>plain</code>
585     *
586     * @exception IllegalBlockSizeException if the input length is different
587     * from the cipher's block size
588     */
589    void decryptBlock(byte[] cipher, int cipherOffset,
590                 byte[] plain, int plainOffset)
591    {
592        cipherBlock(cipher, cipherOffset, plain, plainOffset);
593    }
594
595
596    void cipherBlock(byte[] in, int inOffset, byte[] out, int outOffset) {
597        byte key[];
598        int temp;
599        int i, j;
600        int offset;
601        int left, right;
602
603        left = initialPermutationLeft(in, inOffset);
604        right = initialPermutationRight(in, inOffset);
605
606        key = expandedKey;
607
608        if (decrypting) {
609            offset = 16 - DES_BLOCK_SIZE;
610            j = 128 - DES_BLOCK_SIZE;
611
612        } else {
613            offset = 0 - DES_BLOCK_SIZE;
614            j = 0;
615        }
616
617        for (i = 0; i < 16; i++) {
618            // make the first and last bit adjacent
619            // move the first bit to the last
620            temp = (right << 1) | ((right >> 31) & 1);
621
622            // mangler function:
623            // every 6 bit is fed into the sbox, which
624            // produces 4-bit output
625            left ^= s0p[(temp & 0x3f) ^ key[j+0]]
626                ^ s1p[((temp >>  4) & 0x3f) ^ key[j+1]]
627                ^ s2p[((temp >>  8) & 0x3f) ^ key[j+2]]
628                ^ s3p[((temp >> 12) & 0x3f) ^ key[j+3]]
629                ^ s4p[((temp >> 16) & 0x3f) ^ key[j+4]]
630                ^ s5p[((temp >> 20) & 0x3f) ^ key[j+5]]
631                ^ s6p[((temp >> 24) & 0x3f) ^ key[j+6]];
632
633            // make the last sbox input the last bit from right[0]
634            temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
635            left ^= s7p[temp ^ key[j+7]];
636            temp = left;
637            left = right;
638            right = temp;
639            j -= offset;
640        }
641
642        temp = left;
643        left = right;
644        right = temp;
645        perm(left, right, out, outOffset);
646    }
647
648    private static void perm(int left, int right,
649                             byte out[], int offset) {
650        int low, high, temp;
651
652        temp = left;
653        high = permRight0[temp & 0x0000000f];
654        temp >>= 4;
655        low  = permLeft1[temp & 0x0000000f];
656        temp >>= 4;
657        high |= permRight2[temp & 0x0000000f];
658        temp >>= 4;
659        low  |= permLeft3[temp & 0x0000000f];
660        temp >>= 4;
661        high |= permRight4[temp & 0x0000000f];
662        temp >>= 4;
663        low  |= permLeft5[temp & 0x0000000f];
664        temp >>= 4;
665        high |= permRight6[temp & 0x0000000f];
666        temp >>= 4;
667        low  |= permLeft7[temp & 0x0000000f];
668
669        temp = right;
670        high |= permRight8[temp & 0x0000000f];
671        temp >>= 4;
672        low  |= permLeft9[temp & 0x0000000f];
673        temp >>= 4;
674        high |= permRightA[temp & 0x0000000f];
675        temp >>= 4;
676        low  |= permLeftB[temp & 0x0000000f];
677        temp >>= 4;
678        high |= permRightC[temp & 0x0000000f];
679        temp >>= 4;
680        low  |= permLeftD[temp & 0x0000000f];
681        temp >>= 4;
682        high |= permRightE[temp & 0x0000000f];
683        temp >>= 4;
684        low  |= permLeftF[temp & 0x0000000f];
685
686
687        out[offset + 0] = (byte)low;
688        out[offset + 1] = (byte)(low >> 8);
689        out[offset + 2] = (byte)(low >> 16);
690        out[offset + 3] = (byte)(low >> 24);
691        out[offset + 4] = (byte)high;
692        out[offset + 5] = (byte)(high >> 8);
693        out[offset + 6] = (byte)(high >> 16);
694        out[offset + 7] = (byte)(high >> 24);
695
696    }
697
698    private static int initialPermutationLeft(byte block[], int offset) {
699        int l;
700
701        l  = initPermLeft1[block[offset] & 0xf];
702        l |= initPermLeft0[(block[offset] >> 4) & 0xf];
703        l |= initPermLeft3[block[offset + 1] & 0xf];
704        l |= initPermLeft2[(block[offset + 1] >> 4) & 0xf];
705        l |= initPermLeft5[block[offset + 2] & 0xf];
706        l |= initPermLeft4[(block[offset + 2] >> 4) & 0xf];
707        l |= initPermLeft7[block[offset + 3] & 0xf];
708        l |= initPermLeft6[(block[offset + 3] >> 4) & 0xf];
709        l |= initPermLeft9[block[offset + 4] & 0xf];
710        l |= initPermLeft8[(block[offset + 4] >> 4) & 0xf];
711        l |= initPermLeftB[block[offset + 5] & 0xf];
712        l |= initPermLeftA[(block[offset + 5] >> 4) & 0xf];
713        l |= initPermLeftD[block[offset + 6] & 0xf];
714        l |= initPermLeftC[(block[offset + 6] >> 4) & 0xf];
715        l |= initPermLeftF[block[offset + 7] & 0xf];
716        l |= initPermLeftE[(block[offset + 7] >> 4) & 0xf];
717        return l;
718    }
719
720    private static int initialPermutationRight(byte block[], int offset) {
721        int l;
722
723        l  = initPermRight1[block[offset] & 0xf];
724        l |= initPermRight0[(block[offset] >> 4) & 0xf];
725        l |= initPermRight3[block[offset + 1] & 0xf];
726        l |= initPermRight2[(block[offset + 1] >> 4) & 0xf];
727        l |= initPermRight5[block[offset + 2] & 0xf];
728        l |= initPermRight4[(block[offset + 2] >> 4) & 0xf];
729        l |= initPermRight7[block[offset + 3] & 0xf];
730        l |= initPermRight6[(block[offset + 3] >> 4) & 0xf];
731        l |= initPermRight9[block[offset + 4] & 0xf];
732        l |= initPermRight8[(block[offset + 4] >> 4) & 0xf];
733        l |= initPermRightB[block[offset + 5] & 0xf];
734        l |= initPermRightA[(block[offset + 5] >> 4) & 0xf];
735        l |= initPermRightD[block[offset + 6] & 0xf];
736        l |= initPermRightC[(block[offset + 6] >> 4) & 0xf];
737        l |= initPermRightF[block[offset + 7] & 0xf];
738        l |= initPermRightE[(block[offset + 7] >> 4) & 0xf];
739        return l;
740    }
741
742    void expandKey(byte key[]) {
743        int octet;
744        byte ek[] = new byte[128];
745
746        octet = key[0];
747        if ((octet & 0x80) != 0) {
748            ek[  3] |=  2; ek[  9] |=  8; ek[ 18] |=  8;
749            ek[ 27] |= 32; ek[ 33] |=  2; ek[ 42] |= 16;
750            ek[ 48] |=  8; ek[ 65] |= 16; ek[ 74] |=  2;
751            ek[ 80] |=  2; ek[ 89] |=  4; ek[ 99] |= 16;
752            ek[104] |=  4; ek[122] |= 32;
753        }
754        if ((octet & 0x40) != 0) {
755            ek[  1] |=  4; ek[  8] |=  1; ek[ 18] |=  4;
756            ek[ 25] |= 32; ek[ 34] |= 32; ek[ 41] |=  8;
757            ek[ 50] |=  8; ek[ 59] |= 32; ek[ 64] |= 16;
758            ek[ 75] |=  4; ek[ 90] |=  1; ek[ 97] |= 16;
759            ek[106] |=  2; ek[112] |=  2; ek[123] |=  1;
760        }
761        if ((octet & 0x20) != 0) {
762            ek[  2] |=  1; ek[ 19] |=  8; ek[ 35] |=  1;
763            ek[ 40] |=  1; ek[ 50] |=  4; ek[ 57] |= 32;
764            ek[ 75] |=  2; ek[ 80] |= 32; ek[ 89] |=  1;
765            ek[ 96] |= 16; ek[107] |=  4; ek[120] |=  8;
766        }
767        if ((octet & 0x10) != 0) {
768            ek[  4] |= 32; ek[ 20] |=  2; ek[ 31] |=  4;
769            ek[ 37] |= 32; ek[ 47] |=  1; ek[ 54] |=  1;
770            ek[ 63] |=  2; ek[ 68] |=  1; ek[ 78] |=  4;
771            ek[ 84] |=  8; ek[101] |= 16; ek[108] |=  4;
772            ek[119] |= 16; ek[126] |=  8;
773        }
774        if ((octet & 0x8) != 0) {
775            ek[  5] |=  4; ek[ 15] |=  4; ek[ 21] |= 32;
776            ek[ 31] |=  1; ek[ 38] |=  1; ek[ 47] |=  2;
777            ek[ 53] |=  2; ek[ 68] |=  8; ek[ 85] |= 16;
778            ek[ 92] |=  4; ek[103] |= 16; ek[108] |= 32;
779            ek[118] |= 32; ek[124] |=  2;
780        }
781        if ((octet & 0x4) != 0) {
782            ek[ 15] |=  2; ek[ 21] |=  2; ek[ 39] |=  8;
783            ek[ 46] |= 16; ek[ 55] |= 32; ek[ 61] |=  1;
784            ek[ 71] |= 16; ek[ 76] |= 32; ek[ 86] |= 32;
785            ek[ 93] |=  4; ek[102] |=  2; ek[108] |= 16;
786            ek[117] |=  8; ek[126] |=  1;
787        }
788        if ((octet & 0x2) != 0) {
789            ek[ 14] |= 16; ek[ 23] |= 32; ek[ 29] |=  1;
790            ek[ 38] |=  8; ek[ 52] |=  2; ek[ 63] |=  4;
791            ek[ 70] |=  2; ek[ 76] |= 16; ek[ 85] |=  8;
792            ek[100] |=  1; ek[110] |=  4; ek[116] |=  8;
793            ek[127] |=  8;
794        }
795        octet = key[1];
796        if ((octet & 0x80) != 0) {
797            ek[  1] |=  8; ek[  8] |= 32; ek[ 17] |=  1;
798            ek[ 24] |= 16; ek[ 35] |=  4; ek[ 50] |=  1;
799            ek[ 57] |= 16; ek[ 67] |=  8; ek[ 83] |=  1;
800            ek[ 88] |=  1; ek[ 98] |=  4; ek[105] |= 32;
801            ek[114] |= 32; ek[123] |=  2;
802        }
803        if ((octet & 0x40) != 0) {
804            ek[  0] |=  1; ek[ 11] |= 16; ek[ 16] |=  4;
805            ek[ 35] |=  2; ek[ 40] |= 32; ek[ 49] |=  1;
806            ek[ 56] |= 16; ek[ 65] |=  2; ek[ 74] |= 16;
807            ek[ 80] |=  8; ek[ 99] |=  8; ek[115] |=  1;
808            ek[121] |=  4;
809        }
810        if ((octet & 0x20) != 0) {
811            ek[  9] |= 16; ek[ 18] |=  2; ek[ 24] |=  2;
812            ek[ 33] |=  4; ek[ 43] |= 16; ek[ 48] |=  4;
813            ek[ 66] |= 32; ek[ 73] |=  8; ek[ 82] |=  8;
814            ek[ 91] |= 32; ek[ 97] |=  2; ek[106] |= 16;
815            ek[112] |=  8; ek[122] |=  1;
816        }
817        if ((octet & 0x10) != 0) {
818            ek[ 14] |= 32; ek[ 21] |=  4; ek[ 30] |=  2;
819            ek[ 36] |= 16; ek[ 45] |=  8; ek[ 60] |=  1;
820            ek[ 69] |=  2; ek[ 87] |=  8; ek[ 94] |= 16;
821            ek[103] |= 32; ek[109] |=  1; ek[118] |=  8;
822            ek[124] |= 32;
823        }
824        if ((octet & 0x8) != 0) {
825            ek[  7] |=  4; ek[ 14] |=  2; ek[ 20] |= 16;
826            ek[ 29] |=  8; ek[ 44] |=  1; ek[ 54] |=  4;
827            ek[ 60] |=  8; ek[ 71] |=  8; ek[ 78] |= 16;
828            ek[ 87] |= 32; ek[ 93] |=  1; ek[102] |=  8;
829            ek[116] |=  2; ek[125] |=  4;
830        }
831        if ((octet & 0x4) != 0) {
832            ek[  7] |=  2; ek[ 12] |=  1; ek[ 22] |=  4;
833            ek[ 28] |=  8; ek[ 45] |= 16; ek[ 52] |=  4;
834            ek[ 63] |= 16; ek[ 70] |=  8; ek[ 84] |=  2;
835            ek[ 95] |=  4; ek[101] |= 32; ek[111] |=  1;
836            ek[118] |=  1;
837        }
838        if ((octet & 0x2) != 0) {
839            ek[  6] |= 16; ek[ 13] |= 16; ek[ 20] |=  4;
840            ek[ 31] |= 16; ek[ 36] |= 32; ek[ 46] |= 32;
841            ek[ 53] |=  4; ek[ 62] |=  2; ek[ 69] |= 32;
842            ek[ 79] |=  1; ek[ 86] |=  1; ek[ 95] |=  2;
843            ek[101] |=  2; ek[119] |=  8;
844        }
845        octet = key[2];
846        if ((octet & 0x80) != 0) {
847            ek[  0] |= 32; ek[ 10] |=  8; ek[ 19] |= 32;
848            ek[ 25] |=  2; ek[ 34] |= 16; ek[ 40] |=  8;
849            ek[ 59] |=  8; ek[ 66] |=  2; ek[ 72] |=  2;
850            ek[ 81] |=  4; ek[ 91] |= 16; ek[ 96] |=  4;
851            ek[115] |=  2; ek[121] |=  8;
852        }
853        if ((octet & 0x40) != 0) {
854            ek[  3] |= 16; ek[ 10] |=  4; ek[ 17] |= 32;
855            ek[ 26] |= 32; ek[ 33] |=  8; ek[ 42] |=  8;
856            ek[ 51] |= 32; ek[ 57] |=  2; ek[ 67] |=  4;
857            ek[ 82] |=  1; ek[ 89] |= 16; ek[ 98] |=  2;
858            ek[104] |=  2; ek[113] |=  4; ek[120] |=  1;
859        }
860        if ((octet & 0x20) != 0) {
861            ek[  1] |= 16; ek[ 11] |=  8; ek[ 27] |=  1;
862            ek[ 32] |=  1; ek[ 42] |=  4; ek[ 49] |= 32;
863            ek[ 58] |= 32; ek[ 67] |=  2; ek[ 72] |= 32;
864            ek[ 81] |=  1; ek[ 88] |= 16; ek[ 99] |=  4;
865            ek[114] |=  1;
866        }
867        if ((octet & 0x10) != 0) {
868            ek[  6] |= 32; ek[ 12] |=  2; ek[ 23] |=  4;
869            ek[ 29] |= 32; ek[ 39] |=  1; ek[ 46] |=  1;
870            ek[ 55] |=  2; ek[ 61] |=  2; ek[ 70] |=  4;
871            ek[ 76] |=  8; ek[ 93] |= 16; ek[100] |=  4;
872            ek[111] |= 16; ek[116] |= 32;
873        }
874        if ((octet & 0x8) != 0) {
875            ek[  6] |=  2; ek[ 13] |= 32; ek[ 23] |=  1;
876            ek[ 30] |=  1; ek[ 39] |=  2; ek[ 45] |=  2;
877            ek[ 63] |=  8; ek[ 77] |= 16; ek[ 84] |=  4;
878            ek[ 95] |= 16; ek[100] |= 32; ek[110] |= 32;
879            ek[117] |=  4; ek[127] |=  4;
880        }
881        if ((octet & 0x4) != 0) {
882            ek[  4] |=  1; ek[ 13] |=  2; ek[ 31] |=  8;
883            ek[ 38] |= 16; ek[ 47] |= 32; ek[ 53] |=  1;
884            ek[ 62] |=  8; ek[ 68] |= 32; ek[ 78] |= 32;
885            ek[ 85] |=  4; ek[ 94] |=  2; ek[100] |= 16;
886            ek[109] |=  8; ek[127] |=  2;
887        }
888        if ((octet & 0x2) != 0) {
889            ek[  5] |= 16; ek[ 15] |= 32; ek[ 21] |=  1;
890            ek[ 30] |=  8; ek[ 44] |=  2; ek[ 55] |=  4;
891            ek[ 61] |= 32; ek[ 68] |= 16; ek[ 77] |=  8;
892            ek[ 92] |=  1; ek[102] |=  4; ek[108] |=  8;
893            ek[126] |= 16;
894        }
895        octet = key[3];
896        if ((octet & 0x80) != 0) {
897            ek[  2] |=  8; ek[  9] |=  1; ek[ 16] |= 16;
898            ek[ 27] |=  4; ek[ 42] |=  1; ek[ 49] |= 16;
899            ek[ 58] |=  2; ek[ 75] |=  1; ek[ 80] |=  1;
900            ek[ 90] |=  4; ek[ 97] |= 32; ek[106] |= 32;
901            ek[113] |=  8; ek[120] |= 32;
902        }
903        if ((octet & 0x40) != 0) {
904            ek[  2] |=  4; ek[  8] |=  4; ek[ 27] |=  2;
905            ek[ 32] |= 32; ek[ 41] |=  1; ek[ 48] |= 16;
906            ek[ 59] |=  4; ek[ 66] |= 16; ek[ 72] |=  8;
907            ek[ 91] |=  8; ek[107] |=  1; ek[112] |=  1;
908            ek[123] |= 16;
909        }
910        if ((octet & 0x20) != 0) {
911            ek[  3] |=  8; ek[ 10] |=  2; ek[ 16] |=  2;
912            ek[ 25] |=  4; ek[ 35] |= 16; ek[ 40] |=  4;
913            ek[ 59] |=  2; ek[ 65] |=  8; ek[ 74] |=  8;
914            ek[ 83] |= 32; ek[ 89] |=  2; ek[ 98] |= 16;
915            ek[104] |=  8; ek[121] |= 16;
916        }
917        if ((octet & 0x10) != 0) {
918            ek[  4] |=  2; ek[ 13] |=  4; ek[ 22] |=  2;
919            ek[ 28] |= 16; ek[ 37] |=  8; ek[ 52] |=  1;
920            ek[ 62] |=  4; ek[ 79] |=  8; ek[ 86] |= 16;
921            ek[ 95] |= 32; ek[101] |=  1; ek[110] |=  8;
922            ek[126] |= 32;
923        }
924        if ((octet & 0x8) != 0) {
925            ek[  5] |= 32; ek[ 12] |= 16; ek[ 21] |=  8;
926            ek[ 36] |=  1; ek[ 46] |=  4; ek[ 52] |=  8;
927            ek[ 70] |= 16; ek[ 79] |= 32; ek[ 85] |=  1;
928            ek[ 94] |=  8; ek[108] |=  2; ek[119] |=  4;
929            ek[126] |=  2;
930        }
931        if ((octet & 0x4) != 0) {
932            ek[  5] |=  2; ek[ 14] |=  4; ek[ 20] |=  8;
933            ek[ 37] |= 16; ek[ 44] |=  4; ek[ 55] |= 16;
934            ek[ 60] |= 32; ek[ 76] |=  2; ek[ 87] |=  4;
935            ek[ 93] |= 32; ek[103] |=  1; ek[110] |=  1;
936            ek[119] |=  2; ek[124] |=  1;
937        }
938        if ((octet & 0x2) != 0) {
939            ek[  7] |= 32; ek[ 12] |=  4; ek[ 23] |= 16;
940            ek[ 28] |= 32; ek[ 38] |= 32; ek[ 45] |=  4;
941            ek[ 54] |=  2; ek[ 60] |= 16; ek[ 71] |=  1;
942            ek[ 78] |=  1; ek[ 87] |=  2; ek[ 93] |=  2;
943            ek[111] |=  8; ek[118] |= 16; ek[125] |= 16;
944        }
945        octet = key[4];
946        if ((octet & 0x80) != 0) {
947            ek[  1] |=  1; ek[ 11] |= 32; ek[ 17] |=  2;
948            ek[ 26] |= 16; ek[ 32] |=  8; ek[ 51] |=  8;
949            ek[ 64] |=  2; ek[ 73] |=  4; ek[ 83] |= 16;
950            ek[ 88] |=  4; ek[107] |=  2; ek[112] |= 32;
951            ek[122] |=  8;
952        }
953        if ((octet & 0x40) != 0) {
954            ek[  0] |=  4; ek[  9] |= 32; ek[ 18] |= 32;
955            ek[ 25] |=  8; ek[ 34] |=  8; ek[ 43] |= 32;
956            ek[ 49] |=  2; ek[ 58] |= 16; ek[ 74] |=  1;
957            ek[ 81] |= 16; ek[ 90] |=  2; ek[ 96] |=  2;
958            ek[105] |=  4; ek[115] |= 16; ek[122] |=  4;
959        }
960        if ((octet & 0x20) != 0) {
961            ek[  2] |=  2; ek[ 19] |=  1; ek[ 24] |=  1;
962            ek[ 34] |=  4; ek[ 41] |= 32; ek[ 50] |= 32;
963            ek[ 57] |=  8; ek[ 64] |= 32; ek[ 73] |=  1;
964            ek[ 80] |= 16; ek[ 91] |=  4; ek[106] |=  1;
965            ek[113] |= 16; ek[123] |=  8;
966        }
967        if ((octet & 0x10) != 0) {
968            ek[  3] |=  4; ek[ 10] |= 16; ek[ 16] |=  8;
969            ek[ 35] |=  8; ek[ 51] |=  1; ek[ 56] |=  1;
970            ek[ 67] |= 16; ek[ 72] |=  4; ek[ 91] |=  2;
971            ek[ 96] |= 32; ek[105] |=  1; ek[112] |= 16;
972            ek[121] |=  2;
973        }
974        if ((octet & 0x8) != 0) {
975            ek[  4] |= 16; ek[ 15] |=  1; ek[ 22] |=  1;
976            ek[ 31] |=  2; ek[ 37] |=  2; ek[ 55] |=  8;
977            ek[ 62] |= 16; ek[ 69] |= 16; ek[ 76] |=  4;
978            ek[ 87] |= 16; ek[ 92] |= 32; ek[102] |= 32;
979            ek[109] |=  4; ek[118] |=  2; ek[125] |= 32;
980        }
981        if ((octet & 0x4) != 0) {
982            ek[  6] |=  4; ek[ 23] |=  8; ek[ 30] |= 16;
983            ek[ 39] |= 32; ek[ 45] |=  1; ek[ 54] |=  8;
984            ek[ 70] |= 32; ek[ 77] |=  4; ek[ 86] |=  2;
985            ek[ 92] |= 16; ek[101] |=  8; ek[116] |=  1;
986            ek[125] |=  2;
987        }
988        if ((octet & 0x2) != 0) {
989            ek[  4] |=  4; ek[ 13] |=  1; ek[ 22] |=  8;
990            ek[ 36] |=  2; ek[ 47] |=  4; ek[ 53] |= 32;
991            ek[ 63] |=  1; ek[ 69] |=  8; ek[ 84] |=  1;
992            ek[ 94] |=  4; ek[100] |=  8; ek[117] |= 16;
993            ek[127] |= 32;
994        }
995        octet = key[5];
996        if ((octet & 0x80) != 0) {
997            ek[  3] |= 32; ek[  8] |= 16; ek[ 19] |=  4;
998            ek[ 34] |=  1; ek[ 41] |= 16; ek[ 50] |=  2;
999            ek[ 56] |=  2; ek[ 67] |=  1; ek[ 72] |=  1;
1000            ek[ 82] |=  4; ek[ 89] |= 32; ek[ 98] |= 32;
1001            ek[105] |=  8; ek[114] |=  8; ek[121] |=  1;
1002        }
1003        if ((octet & 0x40) != 0) {
1004            ek[  1] |= 32; ek[ 19] |=  2; ek[ 24] |= 32;
1005            ek[ 33] |=  1; ek[ 40] |= 16; ek[ 51] |=  4;
1006            ek[ 64] |=  8; ek[ 83] |=  8; ek[ 99] |=  1;
1007            ek[104] |=  1; ek[114] |=  4; ek[120] |=  4;
1008        }
1009        if ((octet & 0x20) != 0) {
1010            ek[  8] |=  2; ek[ 17] |=  4; ek[ 27] |= 16;
1011            ek[ 32] |=  4; ek[ 51] |=  2; ek[ 56] |= 32;
1012            ek[ 66] |=  8; ek[ 75] |= 32; ek[ 81] |=  2;
1013            ek[ 90] |= 16; ek[ 96] |=  8; ek[115] |=  8;
1014            ek[122] |=  2;
1015        }
1016        if ((octet & 0x10) != 0) {
1017            ek[  2] |= 16; ek[ 18] |=  1; ek[ 25] |= 16;
1018            ek[ 34] |=  2; ek[ 40] |=  2; ek[ 49] |=  4;
1019            ek[ 59] |= 16; ek[ 66] |=  4; ek[ 73] |= 32;
1020            ek[ 82] |= 32; ek[ 89] |=  8; ek[ 98] |=  8;
1021            ek[107] |= 32; ek[113] |=  2; ek[123] |=  4;
1022        }
1023        if ((octet & 0x8) != 0) {
1024            ek[  7] |=  1; ek[ 13] |=  8; ek[ 28] |=  1;
1025            ek[ 38] |=  4; ek[ 44] |=  8; ek[ 61] |= 16;
1026            ek[ 71] |= 32; ek[ 77] |=  1; ek[ 86] |=  8;
1027            ek[100] |=  2; ek[111] |=  4; ek[117] |= 32;
1028            ek[124] |= 16;
1029        }
1030        if ((octet & 0x4) != 0) {
1031            ek[ 12] |=  8; ek[ 29] |= 16; ek[ 36] |=  4;
1032            ek[ 47] |= 16; ek[ 52] |= 32; ek[ 62] |= 32;
1033            ek[ 68] |=  2; ek[ 79] |=  4; ek[ 85] |= 32;
1034            ek[ 95] |=  1; ek[102] |=  1; ek[111] |=  2;
1035            ek[117] |=  2; ek[126] |=  4;
1036        }
1037        if ((octet & 0x2) != 0) {
1038            ek[  5] |=  1; ek[ 15] |= 16; ek[ 20] |= 32;
1039            ek[ 30] |= 32; ek[ 37] |=  4; ek[ 46] |=  2;
1040            ek[ 52] |= 16; ek[ 61] |=  8; ek[ 70] |=  1;
1041            ek[ 79] |=  2; ek[ 85] |=  2; ek[103] |=  8;
1042            ek[110] |= 16; ek[119] |= 32; ek[124] |=  4;
1043        }
1044        octet = key[6];
1045        if ((octet & 0x80) != 0) {
1046            ek[  0] |= 16; ek[  9] |=  2; ek[ 18] |= 16;
1047            ek[ 24] |=  8; ek[ 43] |=  8; ek[ 59] |=  1;
1048            ek[ 65] |=  4; ek[ 75] |= 16; ek[ 80] |=  4;
1049            ek[ 99] |=  2; ek[104] |= 32; ek[113] |=  1;
1050            ek[123] |= 32;
1051        }
1052        if ((octet & 0x40) != 0) {
1053            ek[ 10] |= 32; ek[ 17] |=  8; ek[ 26] |=  8;
1054            ek[ 35] |= 32; ek[ 41] |=  2; ek[ 50] |= 16;
1055            ek[ 56] |=  8; ek[ 66] |=  1; ek[ 73] |= 16;
1056            ek[ 82] |=  2; ek[ 88] |=  2; ek[ 97] |=  4;
1057            ek[107] |= 16; ek[112] |=  4; ek[121] |= 32;
1058        }
1059        if ((octet & 0x20) != 0) {
1060            ek[  0] |=  2; ek[ 11] |=  1; ek[ 16] |=  1;
1061            ek[ 26] |=  4; ek[ 33] |= 32; ek[ 42] |= 32;
1062            ek[ 49] |=  8; ek[ 58] |=  8; ek[ 65] |=  1;
1063            ek[ 72] |= 16; ek[ 83] |=  4; ek[ 98] |=  1;
1064            ek[105] |= 16; ek[114] |=  2;
1065        }
1066        if ((octet & 0x10) != 0) {
1067            ek[  8] |=  8; ek[ 27] |=  8; ek[ 43] |=  1;
1068            ek[ 48] |=  1; ek[ 58] |=  4; ek[ 64] |=  4;
1069            ek[ 83] |=  2; ek[ 88] |= 32; ek[ 97] |=  1;
1070            ek[104] |= 16; ek[115] |=  4; ek[122] |= 16;
1071        }
1072        if ((octet & 0x8) != 0) {
1073            ek[  5] |=  8; ek[ 14] |=  1; ek[ 23] |=  2;
1074            ek[ 29] |=  2; ek[ 47] |=  8; ek[ 54] |= 16;
1075            ek[ 63] |= 32; ek[ 68] |=  4; ek[ 79] |= 16;
1076            ek[ 84] |= 32; ek[ 94] |= 32; ek[101] |=  4;
1077            ek[110] |=  2; ek[116] |= 16; ek[127] |=  1;
1078        }
1079        if ((octet & 0x4) != 0) {
1080            ek[  4] |=  8; ek[ 15] |=  8; ek[ 22] |= 16;
1081            ek[ 31] |= 32; ek[ 37] |=  1; ek[ 46] |=  8;
1082            ek[ 60] |=  2; ek[ 69] |=  4; ek[ 78] |=  2;
1083            ek[ 84] |= 16; ek[ 93] |=  8; ek[108] |=  1;
1084            ek[118] |=  4;
1085        }
1086        if ((octet & 0x2) != 0) {
1087            ek[  7] |= 16; ek[ 14] |=  8; ek[ 28] |=  2;
1088            ek[ 39] |=  4; ek[ 45] |= 32; ek[ 55] |=  1;
1089            ek[ 62] |=  1; ek[ 76] |=  1; ek[ 86] |=  4;
1090            ek[ 92] |=  8; ek[109] |= 16; ek[116] |=  4;
1091            ek[125] |=  1;
1092        }
1093        octet = key[7];
1094        if ((octet & 0x80) != 0) {
1095            ek[  1] |=  2; ek[ 11] |=  4; ek[ 26] |=  1;
1096            ek[ 33] |= 16; ek[ 42] |=  2; ek[ 48] |=  2;
1097            ek[ 57] |=  4; ek[ 64] |=  1; ek[ 74] |=  4;
1098            ek[ 81] |= 32; ek[ 90] |= 32; ek[ 97] |=  8;
1099            ek[106] |=  8; ek[115] |= 32; ek[120] |= 16;
1100        }
1101        if ((octet & 0x40) != 0) {
1102            ek[  2] |= 32; ek[ 11] |=  2; ek[ 16] |= 32;
1103            ek[ 25] |=  1; ek[ 32] |= 16; ek[ 43] |=  4;
1104            ek[ 58] |=  1; ek[ 75] |=  8; ek[ 91] |=  1;
1105            ek[ 96] |=  1; ek[106] |=  4; ek[113] |= 32;
1106        }
1107        if ((octet & 0x20) != 0) {
1108            ek[  3] |=  1; ek[  9] |=  4; ek[ 19] |= 16;
1109            ek[ 24] |=  4; ek[ 43] |=  2; ek[ 48] |= 32;
1110            ek[ 57] |=  1; ek[ 67] |= 32; ek[ 73] |=  2;
1111            ek[ 82] |= 16; ek[ 88] |=  8; ek[107] |=  8;
1112            ek[120] |=  2;
1113        }
1114        if ((octet & 0x10) != 0) {
1115            ek[  0] |=  8; ek[ 10] |=  1; ek[ 17] |= 16;
1116            ek[ 26] |=  2; ek[ 32] |=  2; ek[ 41] |=  4;
1117            ek[ 51] |= 16; ek[ 56] |=  4; ek[ 65] |= 32;
1118            ek[ 74] |= 32; ek[ 81] |=  8; ek[ 90] |=  8;
1119            ek[ 99] |= 32; ek[105] |=  2; ek[114] |= 16;
1120        }
1121        if ((octet & 0x8) != 0) {
1122            ek[  6] |=  1; ek[ 20] |=  1; ek[ 30] |=  4;
1123            ek[ 36] |=  8; ek[ 53] |= 16; ek[ 60] |=  4;
1124            ek[ 69] |=  1; ek[ 78] |=  8; ek[ 92] |=  2;
1125            ek[103] |=  4; ek[109] |= 32; ek[119] |=  1;
1126            ek[125] |=  8;
1127        }
1128        if ((octet & 0x4) != 0) {
1129            ek[  7] |=  8; ek[ 21] |= 16; ek[ 28] |=  4;
1130            ek[ 39] |= 16; ek[ 44] |= 32; ek[ 54] |= 32;
1131            ek[ 61] |=  4; ek[ 71] |=  4; ek[ 77] |= 32;
1132            ek[ 87] |=  1; ek[ 94] |=  1; ek[103] |=  2;
1133            ek[109] |=  2; ek[124] |=  8;
1134        }
1135        if ((octet & 0x2) != 0) {
1136            ek[  6] |=  8; ek[ 12] |= 32; ek[ 22] |= 32;
1137            ek[ 29] |=  4; ek[ 38] |=  2; ek[ 44] |= 16;
1138            ek[ 53] |=  8; ek[ 71] |=  2; ek[ 77] |=  2;
1139            ek[ 95] |=  8; ek[102] |= 16; ek[111] |= 32;
1140            ek[117] |=  1; ek[127] |= 16;
1141        }
1142
1143        expandedKey = ek;
1144    }
1145}
1146