Pull the copyright from the tightvnc-java package
[invirt/packages/invirt-vnc-client.git] / DesCipher.java
1 //
2 // This DES class has been extracted from package Acme.Crypto for use in VNC.
3 // The bytebit[] array has been reversed so that the most significant bit
4 // in each byte of the key is ignored, not the least significant.  Also the
5 // unnecessary odd parity code has been removed.
6 //
7 // These changes are:
8 //  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
9 //
10 // This software is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 //
14
15 // DesCipher - the DES encryption method
16 //
17 // The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
18 //
19 // Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
20 //
21 // Permission to use, copy, modify, and distribute this software
22 // and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
23 // without fee is hereby granted, provided that this copyright notice is kept 
24 // intact. 
25 // 
26 // WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
27 // OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
28 // TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29 // PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
30 // FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31 // DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
32 // 
33 // THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
34 // CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
35 // PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
36 // NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
37 // SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
38 // SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
39 // PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  WIDGET WORKSHOP
40 // SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
41 // HIGH RISK ACTIVITIES.
42 //
43 //
44 // The rest is:
45 //
46 // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights reserved.
47 //
48 // Redistribution and use in source and binary forms, with or without
49 // modification, are permitted provided that the following conditions
50 // are met:
51 // 1. Redistributions of source code must retain the above copyright
52 //    notice, this list of conditions and the following disclaimer.
53 // 2. Redistributions in binary form must reproduce the above copyright
54 //    notice, this list of conditions and the following disclaimer in the
55 //    documentation and/or other materials provided with the distribution.
56 //
57 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
58 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60 // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
61 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67 // SUCH DAMAGE.
68 //
69 // Visit the ACME Labs Java page for up-to-date versions of this and other
70 // fine Java utilities: http://www.acme.com/java/
71
72
73 import java.io.*;
74
75 /// The DES encryption method.
76 // <P>
77 // This is surprisingly fast, for pure Java.  On a SPARC 20, wrapped
78 // in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream,
79 // it does around 7000 bytes/second.
80 // <P>
81 // Most of this code is by Dave Zimmerman <dzimm@widget.com>, and is
82 // Copyright (c) 1996 Widget Workshop, Inc.  See the source file for details.
83 // <P>
84 // <A HREF="/resources/classes/Acme/Crypto/DesCipher.java">Fetch the software.</A><BR>
85 // <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A>
86 // <P>
87 // @see Des3Cipher
88 // @see EncryptedOutputStream
89 // @see EncryptedInputStream
90
91 public class DesCipher
92     {
93
94     // Constructor, byte-array key.
95     public DesCipher( byte[] key )
96         {
97         setKey( key );
98         }
99
100     // Key routines.
101
102     private int[] encryptKeys = new int[32];
103     private int[] decryptKeys = new int[32];
104
105     /// Set the key.
106     public void setKey( byte[] key )
107         {
108         deskey( key, true, encryptKeys );
109         deskey( key, false, decryptKeys );
110         }
111
112     // Turn an 8-byte key into internal keys.
113     private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL )
114         {
115         int i, j, l, m, n;
116         int[] pc1m = new int[56];
117         int[] pcr = new int[56];
118         int[] kn = new int[32];
119
120         for ( j = 0; j < 56; ++j )
121             {
122             l = pc1[j];
123             m = l & 07;
124             pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0;
125             }
126
127         for ( i = 0; i < 16; ++i )
128             {
129             if ( encrypting )
130                 m = i << 1;
131             else
132                 m = (15-i) << 1;
133             n = m+1;
134             kn[m] = kn[n] = 0;
135             for ( j = 0; j < 28; ++j )
136                 {
137                 l = j+totrot[i];
138                 if ( l < 28 )
139                     pcr[j] = pc1m[l];
140                 else
141                     pcr[j] = pc1m[l-28];
142                 }
143             for ( j=28; j < 56; ++j )
144                 {
145                 l = j+totrot[i];
146                 if ( l < 56 )
147                     pcr[j] = pc1m[l];
148                 else
149                     pcr[j] = pc1m[l-28];
150                 }
151             for ( j = 0; j < 24; ++j )
152                 {
153                 if ( pcr[pc2[j]] != 0 )
154                     kn[m] |= bigbyte[j];
155                 if ( pcr[pc2[j+24]] != 0 )
156                     kn[n] |= bigbyte[j];
157                 }
158             }
159         cookey( kn, KnL );
160         }
161
162     private void cookey( int[] raw, int KnL[] )
163         {
164         int raw0, raw1;
165         int rawi, KnLi;
166         int i;
167
168         for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i )
169             {
170             raw0 = raw[rawi++];
171             raw1 = raw[rawi++];
172             KnL[KnLi]  = (raw0 & 0x00fc0000) <<   6;
173             KnL[KnLi] |= (raw0 & 0x00000fc0) <<  10;
174             KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
175             KnL[KnLi] |= (raw1 & 0x00000fc0) >>>  6;
176             ++KnLi;
177             KnL[KnLi]  = (raw0 & 0x0003f000) <<  12;
178             KnL[KnLi] |= (raw0 & 0x0000003f) <<  16;
179             KnL[KnLi] |= (raw1 & 0x0003f000) >>>  4;
180             KnL[KnLi] |= (raw1 & 0x0000003f);
181             ++KnLi;
182             }
183         }
184
185
186     // Block encryption routines.
187
188     private int[] tempInts = new int[2];
189
190     /// Encrypt a block of eight bytes.
191     public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff )
192         {
193         squashBytesToInts( clearText, clearOff, tempInts, 0, 2 );
194         des( tempInts, tempInts, encryptKeys );
195         spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 );
196         }
197
198     /// Decrypt a block of eight bytes.
199     public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff )
200         {
201         squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 );
202         des( tempInts, tempInts, decryptKeys );
203         spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 );
204         }
205
206     // The DES function.
207     private void des( int[] inInts, int[] outInts, int[] keys )
208         {
209         int fval, work, right, leftt;
210         int round;
211         int keysi = 0;
212
213         leftt = inInts[0];
214         right = inInts[1];
215
216         work   = ((leftt >>>  4) ^ right) & 0x0f0f0f0f;
217         right ^= work;
218         leftt ^= (work << 4);
219
220         work   = ((leftt >>> 16) ^ right) & 0x0000ffff;
221         right ^= work;
222         leftt ^= (work << 16);
223
224         work   = ((right >>>  2) ^ leftt) & 0x33333333;
225         leftt ^= work;
226         right ^= (work << 2);
227
228         work   = ((right >>>  8) ^ leftt) & 0x00ff00ff;
229         leftt ^= work;
230         right ^= (work << 8);
231         right  = (right << 1) | ((right >>> 31) & 1);
232
233         work   = (leftt ^ right) & 0xaaaaaaaa;
234         leftt ^= work;
235         right ^= work;
236         leftt  = (leftt << 1) | ((leftt >>> 31) & 1);
237
238         for ( round = 0; round < 8; ++round )
239             {
240             work   = (right << 28) | (right >>> 4);
241             work  ^= keys[keysi++];
242             fval   = SP7[ work         & 0x0000003f ];
243             fval  |= SP5[(work >>>  8) & 0x0000003f ];
244             fval  |= SP3[(work >>> 16) & 0x0000003f ];
245             fval  |= SP1[(work >>> 24) & 0x0000003f ];
246             work   = right ^ keys[keysi++];
247             fval  |= SP8[ work         & 0x0000003f ];
248             fval  |= SP6[(work >>>  8) & 0x0000003f ];
249             fval  |= SP4[(work >>> 16) & 0x0000003f ];
250             fval  |= SP2[(work >>> 24) & 0x0000003f ];
251             leftt ^= fval;
252             work   = (leftt << 28) | (leftt >>> 4);
253             work  ^= keys[keysi++];
254             fval   = SP7[ work         & 0x0000003f ];
255             fval  |= SP5[(work >>>  8) & 0x0000003f ];
256             fval  |= SP3[(work >>> 16) & 0x0000003f ];
257             fval  |= SP1[(work >>> 24) & 0x0000003f ];
258             work   = leftt ^ keys[keysi++];
259             fval  |= SP8[ work         & 0x0000003f ];
260             fval  |= SP6[(work >>>  8) & 0x0000003f ];
261             fval  |= SP4[(work >>> 16) & 0x0000003f ];
262             fval  |= SP2[(work >>> 24) & 0x0000003f ];
263             right ^= fval;
264             }
265
266         right  = (right << 31) | (right >>> 1);
267         work   = (leftt ^ right) & 0xaaaaaaaa;
268         leftt ^= work;
269         right ^= work;
270         leftt  = (leftt << 31) | (leftt >>> 1);
271         work   = ((leftt >>>  8) ^ right) & 0x00ff00ff;
272         right ^= work;
273         leftt ^= (work << 8);
274         work   = ((leftt >>>  2) ^ right) & 0x33333333;
275         right ^= work;
276         leftt ^= (work << 2);
277         work   = ((right >>> 16) ^ leftt) & 0x0000ffff;
278         leftt ^= work;
279         right ^= (work << 16);
280         work   = ((right >>>  4) ^ leftt) & 0x0f0f0f0f;
281         leftt ^= work;
282         right ^= (work << 4);
283         outInts[0] = right;
284         outInts[1] = leftt;
285         }
286
287
288     // Tables, permutations, S-boxes, etc.
289
290     private static byte[] bytebit = {
291         (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08,
292         (byte)0x10, (byte)0x20, (byte)0x40, (byte)0x80
293         };
294     private static int[] bigbyte = {
295         0x800000, 0x400000, 0x200000, 0x100000,
296         0x080000, 0x040000, 0x020000, 0x010000,
297         0x008000, 0x004000, 0x002000, 0x001000,
298         0x000800, 0x000400, 0x000200, 0x000100,
299         0x000080, 0x000040, 0x000020, 0x000010,
300         0x000008, 0x000004, 0x000002, 0x000001
301         };
302     private static byte[] pc1 = {
303          (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8,
304       (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17,
305          (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26,
306       (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35,
307          (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14,
308       (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21,
309          (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28,
310       (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3
311         };
312     private static int[] totrot = {
313         1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
314         };
315
316     private static byte[] pc2 = {
317         (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4,
318                   (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9,
319         (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7,
320                   (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1,
321         (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54,
322                   (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47,
323         (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52,
324                   (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31,
325         };
326
327     private static int[] SP1 = {
328         0x01010400, 0x00000000, 0x00010000, 0x01010404,
329         0x01010004, 0x00010404, 0x00000004, 0x00010000,
330         0x00000400, 0x01010400, 0x01010404, 0x00000400,
331         0x01000404, 0x01010004, 0x01000000, 0x00000004,
332         0x00000404, 0x01000400, 0x01000400, 0x00010400,
333         0x00010400, 0x01010000, 0x01010000, 0x01000404,
334         0x00010004, 0x01000004, 0x01000004, 0x00010004,
335         0x00000000, 0x00000404, 0x00010404, 0x01000000,
336         0x00010000, 0x01010404, 0x00000004, 0x01010000,
337         0x01010400, 0x01000000, 0x01000000, 0x00000400,
338         0x01010004, 0x00010000, 0x00010400, 0x01000004,
339         0x00000400, 0x00000004, 0x01000404, 0x00010404,
340         0x01010404, 0x00010004, 0x01010000, 0x01000404,
341         0x01000004, 0x00000404, 0x00010404, 0x01010400,
342         0x00000404, 0x01000400, 0x01000400, 0x00000000,
343         0x00010004, 0x00010400, 0x00000000, 0x01010004
344         };
345     private static int[] SP2 = {
346         0x80108020, 0x80008000, 0x00008000, 0x00108020,
347         0x00100000, 0x00000020, 0x80100020, 0x80008020,
348         0x80000020, 0x80108020, 0x80108000, 0x80000000,
349         0x80008000, 0x00100000, 0x00000020, 0x80100020,
350         0x00108000, 0x00100020, 0x80008020, 0x00000000,
351         0x80000000, 0x00008000, 0x00108020, 0x80100000,
352         0x00100020, 0x80000020, 0x00000000, 0x00108000,
353         0x00008020, 0x80108000, 0x80100000, 0x00008020,
354         0x00000000, 0x00108020, 0x80100020, 0x00100000,
355         0x80008020, 0x80100000, 0x80108000, 0x00008000,
356         0x80100000, 0x80008000, 0x00000020, 0x80108020,
357         0x00108020, 0x00000020, 0x00008000, 0x80000000,
358         0x00008020, 0x80108000, 0x00100000, 0x80000020,
359         0x00100020, 0x80008020, 0x80000020, 0x00100020,
360         0x00108000, 0x00000000, 0x80008000, 0x00008020,
361         0x80000000, 0x80100020, 0x80108020, 0x00108000
362         };
363     private static int[] SP3 = {
364         0x00000208, 0x08020200, 0x00000000, 0x08020008,
365         0x08000200, 0x00000000, 0x00020208, 0x08000200,
366         0x00020008, 0x08000008, 0x08000008, 0x00020000,
367         0x08020208, 0x00020008, 0x08020000, 0x00000208,
368         0x08000000, 0x00000008, 0x08020200, 0x00000200,
369         0x00020200, 0x08020000, 0x08020008, 0x00020208,
370         0x08000208, 0x00020200, 0x00020000, 0x08000208,
371         0x00000008, 0x08020208, 0x00000200, 0x08000000,
372         0x08020200, 0x08000000, 0x00020008, 0x00000208,
373         0x00020000, 0x08020200, 0x08000200, 0x00000000,
374         0x00000200, 0x00020008, 0x08020208, 0x08000200,
375         0x08000008, 0x00000200, 0x00000000, 0x08020008,
376         0x08000208, 0x00020000, 0x08000000, 0x08020208,
377         0x00000008, 0x00020208, 0x00020200, 0x08000008,
378         0x08020000, 0x08000208, 0x00000208, 0x08020000,
379         0x00020208, 0x00000008, 0x08020008, 0x00020200
380         };
381     private static int[] SP4 = {
382         0x00802001, 0x00002081, 0x00002081, 0x00000080,
383         0x00802080, 0x00800081, 0x00800001, 0x00002001,
384         0x00000000, 0x00802000, 0x00802000, 0x00802081,
385         0x00000081, 0x00000000, 0x00800080, 0x00800001,
386         0x00000001, 0x00002000, 0x00800000, 0x00802001,
387         0x00000080, 0x00800000, 0x00002001, 0x00002080,
388         0x00800081, 0x00000001, 0x00002080, 0x00800080,
389         0x00002000, 0x00802080, 0x00802081, 0x00000081,
390         0x00800080, 0x00800001, 0x00802000, 0x00802081,
391         0x00000081, 0x00000000, 0x00000000, 0x00802000,
392         0x00002080, 0x00800080, 0x00800081, 0x00000001,
393         0x00802001, 0x00002081, 0x00002081, 0x00000080,
394         0x00802081, 0x00000081, 0x00000001, 0x00002000,
395         0x00800001, 0x00002001, 0x00802080, 0x00800081,
396         0x00002001, 0x00002080, 0x00800000, 0x00802001,
397         0x00000080, 0x00800000, 0x00002000, 0x00802080
398         };
399     private static int[] SP5 = {
400         0x00000100, 0x02080100, 0x02080000, 0x42000100,
401         0x00080000, 0x00000100, 0x40000000, 0x02080000,
402         0x40080100, 0x00080000, 0x02000100, 0x40080100,
403         0x42000100, 0x42080000, 0x00080100, 0x40000000,
404         0x02000000, 0x40080000, 0x40080000, 0x00000000,
405         0x40000100, 0x42080100, 0x42080100, 0x02000100,
406         0x42080000, 0x40000100, 0x00000000, 0x42000000,
407         0x02080100, 0x02000000, 0x42000000, 0x00080100,
408         0x00080000, 0x42000100, 0x00000100, 0x02000000,
409         0x40000000, 0x02080000, 0x42000100, 0x40080100,
410         0x02000100, 0x40000000, 0x42080000, 0x02080100,
411         0x40080100, 0x00000100, 0x02000000, 0x42080000,
412         0x42080100, 0x00080100, 0x42000000, 0x42080100,
413         0x02080000, 0x00000000, 0x40080000, 0x42000000,
414         0x00080100, 0x02000100, 0x40000100, 0x00080000,
415         0x00000000, 0x40080000, 0x02080100, 0x40000100
416         };
417     private static int[] SP6 = {
418         0x20000010, 0x20400000, 0x00004000, 0x20404010,
419         0x20400000, 0x00000010, 0x20404010, 0x00400000,
420         0x20004000, 0x00404010, 0x00400000, 0x20000010,
421         0x00400010, 0x20004000, 0x20000000, 0x00004010,
422         0x00000000, 0x00400010, 0x20004010, 0x00004000,
423         0x00404000, 0x20004010, 0x00000010, 0x20400010,
424         0x20400010, 0x00000000, 0x00404010, 0x20404000,
425         0x00004010, 0x00404000, 0x20404000, 0x20000000,
426         0x20004000, 0x00000010, 0x20400010, 0x00404000,
427         0x20404010, 0x00400000, 0x00004010, 0x20000010,
428         0x00400000, 0x20004000, 0x20000000, 0x00004010,
429         0x20000010, 0x20404010, 0x00404000, 0x20400000,
430         0x00404010, 0x20404000, 0x00000000, 0x20400010,
431         0x00000010, 0x00004000, 0x20400000, 0x00404010,
432         0x00004000, 0x00400010, 0x20004010, 0x00000000,
433         0x20404000, 0x20000000, 0x00400010, 0x20004010
434         };
435     private static int[] SP7 = {
436         0x00200000, 0x04200002, 0x04000802, 0x00000000,
437         0x00000800, 0x04000802, 0x00200802, 0x04200800,
438         0x04200802, 0x00200000, 0x00000000, 0x04000002,
439         0x00000002, 0x04000000, 0x04200002, 0x00000802,
440         0x04000800, 0x00200802, 0x00200002, 0x04000800,
441         0x04000002, 0x04200000, 0x04200800, 0x00200002,
442         0x04200000, 0x00000800, 0x00000802, 0x04200802,
443         0x00200800, 0x00000002, 0x04000000, 0x00200800,
444         0x04000000, 0x00200800, 0x00200000, 0x04000802,
445         0x04000802, 0x04200002, 0x04200002, 0x00000002,
446         0x00200002, 0x04000000, 0x04000800, 0x00200000,
447         0x04200800, 0x00000802, 0x00200802, 0x04200800,
448         0x00000802, 0x04000002, 0x04200802, 0x04200000,
449         0x00200800, 0x00000000, 0x00000002, 0x04200802,
450         0x00000000, 0x00200802, 0x04200000, 0x00000800,
451         0x04000002, 0x04000800, 0x00000800, 0x00200002
452         };
453     private static int[] SP8 = {
454         0x10001040, 0x00001000, 0x00040000, 0x10041040,
455         0x10000000, 0x10001040, 0x00000040, 0x10000000,
456         0x00040040, 0x10040000, 0x10041040, 0x00041000,
457         0x10041000, 0x00041040, 0x00001000, 0x00000040,
458         0x10040000, 0x10000040, 0x10001000, 0x00001040,
459         0x00041000, 0x00040040, 0x10040040, 0x10041000,
460         0x00001040, 0x00000000, 0x00000000, 0x10040040,
461         0x10000040, 0x10001000, 0x00041040, 0x00040000,
462         0x00041040, 0x00040000, 0x10041000, 0x00001000,
463         0x00000040, 0x10040040, 0x00001000, 0x00041040,
464         0x10001000, 0x00000040, 0x10000040, 0x10040000,
465         0x10040040, 0x10000000, 0x00040000, 0x10001040,
466         0x00000000, 0x10041040, 0x00040040, 0x10000040,
467         0x10040000, 0x10001000, 0x10001040, 0x00000000,
468         0x10041040, 0x00041000, 0x00041000, 0x00001040,
469         0x00001040, 0x00040040, 0x10000000, 0x10041000
470         };
471
472     // Routines taken from other parts of the Acme utilities.
473
474     /// Squash bytes down to ints.
475     public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, int outOff, int intLen )
476         {
477         for ( int i = 0; i < intLen; ++i )
478             outInts[outOff + i] = 
479                 ( ( inBytes[inOff + i * 4    ] & 0xff ) << 24 ) |
480                 ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) |
481                 ( ( inBytes[inOff + i * 4 + 2] & 0xff ) <<  8 ) |
482                   ( inBytes[inOff + i * 4 + 3] & 0xff );
483         }
484
485     /// Spread ints into bytes.
486     public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, int outOff, int intLen )
487         {
488         for ( int i = 0; i < intLen; ++i )
489             {
490             outBytes[outOff + i * 4    ] = (byte) ( inInts[inOff + i] >>> 24 );
491             outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 );
492             outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>>  8 );
493             outBytes[outOff + i * 4 + 3] = (byte)   inInts[inOff + i];
494             }
495         }
496     }