OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [crypto/] [cipher/] [Cast5.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* Cast5.java --
2
   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
3
 
4
This file is a part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or (at
9
your option) any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19
USA
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version.  */
37
 
38
 
39
package gnu.javax.crypto.cipher;
40
 
41
import gnu.java.security.Registry;
42
import gnu.java.security.util.Util;
43
 
44
import java.security.InvalidKeyException;
45
import java.util.ArrayList;
46
import java.util.Collections;
47
import java.util.Iterator;
48
 
49
/**
50
 * An implmenetation of the <code>CAST5</code> (a.k.a. CAST-128) algorithm,
51
 * as per <i>RFC-2144</i>, dated May 1997.
52
 * <p>
53
 * In this RFC, <i>Carlisle Adams</i> (the CA in CAST, ST stands for
54
 * <i>Stafford Tavares</i>) describes CAST5 as:
55
 * <blockquote>
56
 *    "...a DES-like Substitution-Permutation Network (SPN) cryptosystem which
57
 *    appears to have good resistance to differential cryptanalysis, linear
58
 *    cryptanalysis, and related-key cryptanalysis. This cipher also possesses
59
 *    a number of other desirable cryptographic properties, including avalanche,
60
 *    Strict Avalanche Criterion (SAC), Bit Independence Criterion (BIC), no
61
 *    complementation property, and an absence of weak and semi-weak keys."
62
 * </blockquote>
63
 * <p>
64
 * <code>CAST5</code> is a symmetric block cipher with a block-size of 8
65
 * bytes and a variable key-size of up to 128 bits. Its authors, and their
66
 * employer (Entrust Technologies, a Nortel majority-owned company), made it
67
 * available worldwide on a royalty-free basis for commercial and non-commercial
68
 * uses.
69
 * <p>
70
 * The <code>CAST5</code> encryption algorithm has been designed to allow a
71
 * key size that can vary from <code>40</code> bits to <code>128</code> bits,
72
 * in 8-bit increments (that is, the allowable key sizes are <code>40, 48, 56,
73
 * 64, ..., 112, 120,</code> and <code>128</code> bits. For variable keysize
74
 * operation, the specification is as follows:
75
 * <ol>
76
 *   <li>For key sizes up to and including <code>80</code> bits (i.e.,
77
 *    <code>40, 48, 56, 64, 72,</code> and <code>80</code> bits), the algorithm
78
 *    is exactly as specified but uses <code>12</code> rounds instead of
79
 *    <code>16</code>;</li>
80
 *   <li>For key sizes greater than <code>80</code> bits, the algorithm uses
81
 *    the full <code>16</code> rounds;</li>
82
 *   <li>For key sizes less than <code>128</code> bits, the key is padded with
83
 *    zero bytes (in the rightmost, or least significant, positions) out to
84
 *    <code>128</code> bits (since the <code>CAST5</code> key schedule assumes
85
 *    an input key of <code>128</code> bits).</li>
86
 * </ol>
87
 * <p>
88
 * References:
89
 * <ol>
90
 *    <li><a href="http://www.ietf.org/rfc/rfc2144.txt">The CAST-128 Encryption
91
 *    Algorithm</a>.<br>
92
 *    <a href="mailto:cadams@entrust.com">Carlisle Adams</a>.</li>
93
 * </ol>
94
 */
95
public class Cast5
96
    extends BaseCipher
97
{
98
  private static final int DEFAULT_BLOCK_SIZE = 8; // in bytes
99
  private static final int DEFAULT_KEY_SIZE = 5; // in bytes
100
  /**
101
   * KAT vector (from rfc-2144):
102
   * 40-bit  key         = 01 23 45 67 12
103
   *                     = 01 23 45 67 12 00 00 00 00 00 00 00 00 00 00 00
104
   *         plaintext   = 01 23 45 67 89 AB CD EF
105
   *         ciphertext  = 7A C8 16 D1 6E 9B 30 2E
106
   */
107
  private static final byte[] KAT_KEY = Util.toBytesFromString("0123456712");
108
  private static final byte[] KAT_PT = Util.toBytesFromString("0123456789ABCDEF");
109
  private static final byte[] KAT_CT = Util.toBytesFromString("7AC816D16E9B302E");
110
  /** caches the result of the correctness test, once executed. */
111
  private static Boolean valid;
112
  // CAST5 S-boxes
113
  private static final int[] S1 = {
114
      0x30FB40D4, 0x9FA0FF0B, 0x6BECCD2F, 0x3F258C7A, 0x1E213F2F, 0x9C004DD3,
115
      0x6003E540, 0xCF9FC949, 0xBFD4AF27, 0x88BBBDB5, 0xE2034090, 0x98D09675,
116
      0x6E63A0E0, 0x15C361D2, 0xC2E7661D, 0x22D4FF8E, 0x28683B6F, 0xC07FD059,
117
      0xFF2379C8, 0x775F50E2, 0x43C340D3, 0xDF2F8656, 0x887CA41A, 0xA2D2BD2D,
118
      0xA1C9E0D6, 0x346C4819, 0x61B76D87, 0x22540F2F, 0x2ABE32E1, 0xAA54166B,
119
      0x22568E3A, 0xA2D341D0, 0x66DB40C8, 0xA784392F, 0x004DFF2F, 0x2DB9D2DE,
120
      0x97943FAC, 0x4A97C1D8, 0x527644B7, 0xB5F437A7, 0xB82CBAEF, 0xD751D159,
121
      0x6FF7F0ED, 0x5A097A1F, 0x827B68D0, 0x90ECF52E, 0x22B0C054, 0xBC8E5935,
122
      0x4B6D2F7F, 0x50BB64A2, 0xD2664910, 0xBEE5812D, 0xB7332290, 0xE93B159F,
123
      0xB48EE411, 0x4BFF345D, 0xFD45C240, 0xAD31973F, 0xC4F6D02E, 0x55FC8165,
124
      0xD5B1CAAD, 0xA1AC2DAE, 0xA2D4B76D, 0xC19B0C50, 0x882240F2, 0x0C6E4F38,
125
      0xA4E4BFD7, 0x4F5BA272, 0x564C1D2F, 0xC59C5319, 0xB949E354, 0xB04669FE,
126
      0xB1B6AB8A, 0xC71358DD, 0x6385C545, 0x110F935D, 0x57538AD5, 0x6A390493,
127
      0xE63D37E0, 0x2A54F6B3, 0x3A787D5F, 0x6276A0B5, 0x19A6FCDF, 0x7A42206A,
128
      0x29F9D4D5, 0xF61B1891, 0xBB72275E, 0xAA508167, 0x38901091, 0xC6B505EB,
129
      0x84C7CB8C, 0x2AD75A0F, 0x874A1427, 0xA2D1936B, 0x2AD286AF, 0xAA56D291,
130
      0xD7894360, 0x425C750D, 0x93B39E26, 0x187184C9, 0x6C00B32D, 0x73E2BB14,
131
      0xA0BEBC3C, 0x54623779, 0x64459EAB, 0x3F328B82, 0x7718CF82, 0x59A2CEA6,
132
      0x04EE002E, 0x89FE78E6, 0x3FAB0950, 0x325FF6C2, 0x81383F05, 0x6963C5C8,
133
      0x76CB5AD6, 0xD49974C9, 0xCA180DCF, 0x380782D5, 0xC7FA5CF6, 0x8AC31511,
134
      0x35E79E13, 0x47DA91D0, 0xF40F9086, 0xA7E2419E, 0x31366241, 0x051EF495,
135
      0xAA573B04, 0x4A805D8D, 0x548300D0, 0x00322A3C, 0xBF64CDDF, 0xBA57A68E,
136
      0x75C6372B, 0x50AFD341, 0xA7C13275, 0x915A0BF5, 0x6B54BFAB, 0x2B0B1426,
137
      0xAB4CC9D7, 0x449CCD82, 0xF7FBF265, 0xAB85C5F3, 0x1B55DB94, 0xAAD4E324,
138
      0xCFA4BD3F, 0x2DEAA3E2, 0x9E204D02, 0xC8BD25AC, 0xEADF55B3, 0xD5BD9E98,
139
      0xE31231B2, 0x2AD5AD6C, 0x954329DE, 0xADBE4528, 0xD8710F69, 0xAA51C90F,
140
      0xAA786BF6, 0x22513F1E, 0xAA51A79B, 0x2AD344CC, 0x7B5A41F0, 0xD37CFBAD,
141
      0x1B069505, 0x41ECE491, 0xB4C332E6, 0x032268D4, 0xC9600ACC, 0xCE387E6D,
142
      0xBF6BB16C, 0x6A70FB78, 0x0D03D9C9, 0xD4DF39DE, 0xE01063DA, 0x4736F464,
143
      0x5AD328D8, 0xB347CC96, 0x75BB0FC3, 0x98511BFB, 0x4FFBCC35, 0xB58BCF6A,
144
      0xE11F0ABC, 0xBFC5FE4A, 0xA70AEC10, 0xAC39570A, 0x3F04442F, 0x6188B153,
145
      0xE0397A2E, 0x5727CB79, 0x9CEB418F, 0x1CACD68D, 0x2AD37C96, 0x0175CB9D,
146
      0xC69DFF09, 0xC75B65F0, 0xD9DB40D8, 0xEC0E7779, 0x4744EAD4, 0xB11C3274,
147
      0xDD24CB9E, 0x7E1C54BD, 0xF01144F9, 0xD2240EB1, 0x9675B3FD, 0xA3AC3755,
148
      0xD47C27AF, 0x51C85F4D, 0x56907596, 0xA5BB15E6, 0x580304F0, 0xCA042CF1,
149
      0x011A37EA, 0x8DBFAADB, 0x35BA3E4A, 0x3526FFA0, 0xC37B4D09, 0xBC306ED9,
150
      0x98A52666, 0x5648F725, 0xFF5E569D, 0x0CED63D0, 0x7C63B2CF, 0x700B45E1,
151
      0xD5EA50F1, 0x85A92872, 0xAF1FBDA7, 0xD4234870, 0xA7870BF3, 0x2D3B4D79,
152
      0x42E04198, 0x0CD0EDE7, 0x26470DB8, 0xF881814C, 0x474D6AD7, 0x7C0C5E5C,
153
      0xD1231959, 0x381B7298, 0xF5D2F4DB, 0xAB838653, 0x6E2F1E23, 0x83719C9E,
154
      0xBD91E046, 0x9A56456E, 0xDC39200C, 0x20C8C571, 0x962BDA1C, 0xE1E696FF,
155
      0xB141AB08, 0x7CCA89B9, 0x1A69E783, 0x02CC4843, 0xA2F7C579, 0x429EF47D,
156
      0x427B169C, 0x5AC9F049, 0xDD8F0F00, 0x5C8165BF };
157
  private static final int[] S2 = {
158
      0x1F201094, 0xEF0BA75B, 0x69E3CF7E, 0x393F4380, 0xFE61CF7A, 0xEEC5207A,
159
      0x55889C94, 0x72FC0651, 0xADA7EF79, 0x4E1D7235, 0xD55A63CE, 0xDE0436BA,
160
      0x99C430EF, 0x5F0C0794, 0x18DCDB7D, 0xA1D6EFF3, 0xA0B52F7B, 0x59E83605,
161
      0xEE15B094, 0xE9FFD909, 0xDC440086, 0xEF944459, 0xBA83CCB3, 0xE0C3CDFB,
162
      0xD1DA4181, 0x3B092AB1, 0xF997F1C1, 0xA5E6CF7B, 0x01420DDB, 0xE4E7EF5B,
163
      0x25A1FF41, 0xE180F806, 0x1FC41080, 0x179BEE7A, 0xD37AC6A9, 0xFE5830A4,
164
      0x98DE8B7F, 0x77E83F4E, 0x79929269, 0x24FA9F7B, 0xE113C85B, 0xACC40083,
165
      0xD7503525, 0xF7EA615F, 0x62143154, 0x0D554B63, 0x5D681121, 0xC866C359,
166
      0x3D63CF73, 0xCEE234C0, 0xD4D87E87, 0x5C672B21, 0x071F6181, 0x39F7627F,
167
      0x361E3084, 0xE4EB573B, 0x602F64A4, 0xD63ACD9C, 0x1BBC4635, 0x9E81032D,
168
      0x2701F50C, 0x99847AB4, 0xA0E3DF79, 0xBA6CF38C, 0x10843094, 0x2537A95E,
169
      0xF46F6FFE, 0xA1FF3B1F, 0x208CFB6A, 0x8F458C74, 0xD9E0A227, 0x4EC73A34,
170
      0xFC884F69, 0x3E4DE8DF, 0xEF0E0088, 0x3559648D, 0x8A45388C, 0x1D804366,
171
      0x721D9BFD, 0xA58684BB, 0xE8256333, 0x844E8212, 0x128D8098, 0xFED33FB4,
172
      0xCE280AE1, 0x27E19BA5, 0xD5A6C252, 0xE49754BD, 0xC5D655DD, 0xEB667064,
173
      0x77840B4D, 0xA1B6A801, 0x84DB26A9, 0xE0B56714, 0x21F043B7, 0xE5D05860,
174
      0x54F03084, 0x066FF472, 0xA31AA153, 0xDADC4755, 0xB5625DBF, 0x68561BE6,
175
      0x83CA6B94, 0x2D6ED23B, 0xECCF01DB, 0xA6D3D0BA, 0xB6803D5C, 0xAF77A709,
176
      0x33B4A34C, 0x397BC8D6, 0x5EE22B95, 0x5F0E5304, 0x81ED6F61, 0x20E74364,
177
      0xB45E1378, 0xDE18639B, 0x881CA122, 0xB96726D1, 0x8049A7E8, 0x22B7DA7B,
178
      0x5E552D25, 0x5272D237, 0x79D2951C, 0xC60D894C, 0x488CB402, 0x1BA4FE5B,
179
      0xA4B09F6B, 0x1CA815CF, 0xA20C3005, 0x8871DF63, 0xB9DE2FCB, 0x0CC6C9E9,
180
      0x0BEEFF53, 0xE3214517, 0xB4542835, 0x9F63293C, 0xEE41E729, 0x6E1D2D7C,
181
      0x50045286, 0x1E6685F3, 0xF33401C6, 0x30A22C95, 0x31A70850, 0x60930F13,
182
      0x73F98417, 0xA1269859, 0xEC645C44, 0x52C877A9, 0xCDFF33A6, 0xA02B1741,
183
      0x7CBAD9A2, 0x2180036F, 0x50D99C08, 0xCB3F4861, 0xC26BD765, 0x64A3F6AB,
184
      0x80342676, 0x25A75E7B, 0xE4E6D1FC, 0x20C710E6, 0xCDF0B680, 0x17844D3B,
185
      0x31EEF84D, 0x7E0824E4, 0x2CCB49EB, 0x846A3BAE, 0x8FF77888, 0xEE5D60F6,
186
      0x7AF75673, 0x2FDD5CDB, 0xA11631C1, 0x30F66F43, 0xB3FAEC54, 0x157FD7FA,
187
      0xEF8579CC, 0xD152DE58, 0xDB2FFD5E, 0x8F32CE19, 0x306AF97A, 0x02F03EF8,
188
      0x99319AD5, 0xC242FA0F, 0xA7E3EBB0, 0xC68E4906, 0xB8DA230C, 0x80823028,
189
      0xDCDEF3C8, 0xD35FB171, 0x088A1BC8, 0xBEC0C560, 0x61A3C9E8, 0xBCA8F54D,
190
      0xC72FEFFA, 0x22822E99, 0x82C570B4, 0xD8D94E89, 0x8B1C34BC, 0x301E16E6,
191
      0x273BE979, 0xB0FFEAA6, 0x61D9B8C6, 0x00B24869, 0xB7FFCE3F, 0x08DC283B,
192
      0x43DAF65A, 0xF7E19798, 0x7619B72F, 0x8F1C9BA4, 0xDC8637A0, 0x16A7D3B1,
193
      0x9FC393B7, 0xA7136EEB, 0xC6BCC63E, 0x1A513742, 0xEF6828BC, 0x520365D6,
194
      0x2D6A77AB, 0x3527ED4B, 0x821FD216, 0x095C6E2E, 0xDB92F2FB, 0x5EEA29CB,
195
      0x145892F5, 0x91584F7F, 0x5483697B, 0x2667A8CC, 0x85196048, 0x8C4BACEA,
196
      0x833860D4, 0x0D23E0F9, 0x6C387E8A, 0x0AE6D249, 0xB284600C, 0xD835731D,
197
      0xDCB1C647, 0xAC4C56EA, 0x3EBD81B3, 0x230EABB0, 0x6438BC87, 0xF0B5B1FA,
198
      0x8F5EA2B3, 0xFC184642, 0x0A036B7A, 0x4FB089BD, 0x649DA589, 0xA345415E,
199
      0x5C038323, 0x3E5D3BB9, 0x43D79572, 0x7E6DD07C, 0x06DFDF1E, 0x6C6CC4EF,
200
      0x7160A539, 0x73BFBE70, 0x83877605, 0x4523ECF1 };
201
  private static final int[] S3 = {
202
      0x8DEFC240, 0x25FA5D9F, 0xEB903DBF, 0xE810C907, 0x47607FFF, 0x369FE44B,
203
      0x8C1FC644, 0xAECECA90, 0xBEB1F9BF, 0xEEFBCAEA, 0xE8CF1950, 0x51DF07AE,
204
      0x920E8806, 0xF0AD0548, 0xE13C8D83, 0x927010D5, 0x11107D9F, 0x07647DB9,
205
      0xB2E3E4D4, 0x3D4F285E, 0xB9AFA820, 0xFADE82E0, 0xA067268B, 0x8272792E,
206
      0x553FB2C0, 0x489AE22B, 0xD4EF9794, 0x125E3FBC, 0x21FFFCEE, 0x825B1BFD,
207
      0x9255C5ED, 0x1257A240, 0x4E1A8302, 0xBAE07FFF, 0x528246E7, 0x8E57140E,
208
      0x3373F7BF, 0x8C9F8188, 0xA6FC4EE8, 0xC982B5A5, 0xA8C01DB7, 0x579FC264,
209
      0x67094F31, 0xF2BD3F5F, 0x40FFF7C1, 0x1FB78DFC, 0x8E6BD2C1, 0x437BE59B,
210
      0x99B03DBF, 0xB5DBC64B, 0x638DC0E6, 0x55819D99, 0xA197C81C, 0x4A012D6E,
211
      0xC5884A28, 0xCCC36F71, 0xB843C213, 0x6C0743F1, 0x8309893C, 0x0FEDDD5F,
212
      0x2F7FE850, 0xD7C07F7E, 0x02507FBF, 0x5AFB9A04, 0xA747D2D0, 0x1651192E,
213
      0xAF70BF3E, 0x58C31380, 0x5F98302E, 0x727CC3C4, 0x0A0FB402, 0x0F7FEF82,
214
      0x8C96FDAD, 0x5D2C2AAE, 0x8EE99A49, 0x50DA88B8, 0x8427F4A0, 0x1EAC5790,
215
      0x796FB449, 0x8252DC15, 0xEFBD7D9B, 0xA672597D, 0xADA840D8, 0x45F54504,
216
      0xFA5D7403, 0xE83EC305, 0x4F91751A, 0x925669C2, 0x23EFE941, 0xA903F12E,
217
      0x60270DF2, 0x0276E4B6, 0x94FD6574, 0x927985B2, 0x8276DBCB, 0x02778176,
218
      0xF8AF918D, 0x4E48F79E, 0x8F616DDF, 0xE29D840E, 0x842F7D83, 0x340CE5C8,
219
      0x96BBB682, 0x93B4B148, 0xEF303CAB, 0x984FAF28, 0x779FAF9B, 0x92DC560D,
220
      0x224D1E20, 0x8437AA88, 0x7D29DC96, 0x2756D3DC, 0x8B907CEE, 0xB51FD240,
221
      0xE7C07CE3, 0xE566B4A1, 0xC3E9615E, 0x3CF8209D, 0x6094D1E3, 0xCD9CA341,
222
      0x5C76460E, 0x00EA983B, 0xD4D67881, 0xFD47572C, 0xF76CEDD9, 0xBDA8229C,
223
      0x127DADAA, 0x438A074E, 0x1F97C090, 0x081BDB8A, 0x93A07EBE, 0xB938CA15,
224
      0x97B03CFF, 0x3DC2C0F8, 0x8D1AB2EC, 0x64380E51, 0x68CC7BFB, 0xD90F2788,
225
      0x12490181, 0x5DE5FFD4, 0xDD7EF86A, 0x76A2E214, 0xB9A40368, 0x925D958F,
226
      0x4B39FFFA, 0xBA39AEE9, 0xA4FFD30B, 0xFAF7933B, 0x6D498623, 0x193CBCFA,
227
      0x27627545, 0x825CF47A, 0x61BD8BA0, 0xD11E42D1, 0xCEAD04F4, 0x127EA392,
228
      0x10428DB7, 0x8272A972, 0x9270C4A8, 0x127DE50B, 0x285BA1C8, 0x3C62F44F,
229
      0x35C0EAA5, 0xE805D231, 0x428929FB, 0xB4FCDF82, 0x4FB66A53, 0x0E7DC15B,
230
      0x1F081FAB, 0x108618AE, 0xFCFD086D, 0xF9FF2889, 0x694BCC11, 0x236A5CAE,
231
      0x12DECA4D, 0x2C3F8CC5, 0xD2D02DFE, 0xF8EF5896, 0xE4CF52DA, 0x95155B67,
232
      0x494A488C, 0xB9B6A80C, 0x5C8F82BC, 0x89D36B45, 0x3A609437, 0xEC00C9A9,
233
      0x44715253, 0x0A874B49, 0xD773BC40, 0x7C34671C, 0x02717EF6, 0x4FEB5536,
234
      0xA2D02FFF, 0xD2BF60C4, 0xD43F03C0, 0x50B4EF6D, 0x07478CD1, 0x006E1888,
235
      0xA2E53F55, 0xB9E6D4BC, 0xA2048016, 0x97573833, 0xD7207D67, 0xDE0F8F3D,
236
      0x72F87B33, 0xABCC4F33, 0x7688C55D, 0x7B00A6B0, 0x947B0001, 0x570075D2,
237
      0xF9BB88F8, 0x8942019E, 0x4264A5FF, 0x856302E0, 0x72DBD92B, 0xEE971B69,
238
      0x6EA22FDE, 0x5F08AE2B, 0xAF7A616D, 0xE5C98767, 0xCF1FEBD2, 0x61EFC8C2,
239
      0xF1AC2571, 0xCC8239C2, 0x67214CB8, 0xB1E583D1, 0xB7DC3E62, 0x7F10BDCE,
240
      0xF90A5C38, 0x0FF0443D, 0x606E6DC6, 0x60543A49, 0x5727C148, 0x2BE98A1D,
241
      0x8AB41738, 0x20E1BE24, 0xAF96DA0F, 0x68458425, 0x99833BE5, 0x600D457D,
242
      0x282F9350, 0x8334B362, 0xD91D1120, 0x2B6D8DA0, 0x642B1E31, 0x9C305A00,
243
      0x52BCE688, 0x1B03588A, 0xF7BAEFD5, 0x4142ED9C, 0xA4315C11, 0x83323EC5,
244
      0xDFEF4636, 0xA133C501, 0xE9D3531C, 0xEE353783 };
245
  private static final int[] S4 = {
246
      0x9DB30420, 0x1FB6E9DE, 0xA7BE7BEF, 0xD273A298, 0x4A4F7BDB, 0x64AD8C57,
247
      0x85510443, 0xFA020ED1, 0x7E287AFF, 0xE60FB663, 0x095F35A1, 0x79EBF120,
248
      0xFD059D43, 0x6497B7B1, 0xF3641F63, 0x241E4ADF, 0x28147F5F, 0x4FA2B8CD,
249
      0xC9430040, 0x0CC32220, 0xFDD30B30, 0xC0A5374F, 0x1D2D00D9, 0x24147B15,
250
      0xEE4D111A, 0x0FCA5167, 0x71FF904C, 0x2D195FFE, 0x1A05645F, 0x0C13FEFE,
251
      0x081B08CA, 0x05170121, 0x80530100, 0xE83E5EFE, 0xAC9AF4F8, 0x7FE72701,
252
      0xD2B8EE5F, 0x06DF4261, 0xBB9E9B8A, 0x7293EA25, 0xCE84FFDF, 0xF5718801,
253
      0x3DD64B04, 0xA26F263B, 0x7ED48400, 0x547EEBE6, 0x446D4CA0, 0x6CF3D6F5,
254
      0x2649ABDF, 0xAEA0C7F5, 0x36338CC1, 0x503F7E93, 0xD3772061, 0x11B638E1,
255
      0x72500E03, 0xF80EB2BB, 0xABE0502E, 0xEC8D77DE, 0x57971E81, 0xE14F6746,
256
      0xC9335400, 0x6920318F, 0x081DBB99, 0xFFC304A5, 0x4D351805, 0x7F3D5CE3,
257
      0xA6C866C6, 0x5D5BCCA9, 0xDAEC6FEA, 0x9F926F91, 0x9F46222F, 0x3991467D,
258
      0xA5BF6D8E, 0x1143C44F, 0x43958302, 0xD0214EEB, 0x022083B8, 0x3FB6180C,
259
      0x18F8931E, 0x281658E6, 0x26486E3E, 0x8BD78A70, 0x7477E4C1, 0xB506E07C,
260
      0xF32D0A25, 0x79098B02, 0xE4EABB81, 0x28123B23, 0x69DEAD38, 0x1574CA16,
261
      0xDF871B62, 0x211C40B7, 0xA51A9EF9, 0x0014377B, 0x041E8AC8, 0x09114003,
262
      0xBD59E4D2, 0xE3D156D5, 0x4FE876D5, 0x2F91A340, 0x557BE8DE, 0x00EAE4A7,
263
      0x0CE5C2EC, 0x4DB4BBA6, 0xE756BDFF, 0xDD3369AC, 0xEC17B035, 0x06572327,
264
      0x99AFC8B0, 0x56C8C391, 0x6B65811C, 0x5E146119, 0x6E85CB75, 0xBE07C002,
265
      0xC2325577, 0x893FF4EC, 0x5BBFC92D, 0xD0EC3B25, 0xB7801AB7, 0x8D6D3B24,
266
      0x20C763EF, 0xC366A5FC, 0x9C382880, 0x0ACE3205, 0xAAC9548A, 0xECA1D7C7,
267
      0x041AFA32, 0x1D16625A, 0x6701902C, 0x9B757A54, 0x31D477F7, 0x9126B031,
268
      0x36CC6FDB, 0xC70B8B46, 0xD9E66A48, 0x56E55A79, 0x026A4CEB, 0x52437EFF,
269
      0x2F8F76B4, 0x0DF980A5, 0x8674CDE3, 0xEDDA04EB, 0x17A9BE04, 0x2C18F4DF,
270
      0xB7747F9D, 0xAB2AF7B4, 0xEFC34D20, 0x2E096B7C, 0x1741A254, 0xE5B6A035,
271
      0x213D42F6, 0x2C1C7C26, 0x61C2F50F, 0x6552DAF9, 0xD2C231F8, 0x25130F69,
272
      0xD8167FA2, 0x0418F2C8, 0x001A96A6, 0x0D1526AB, 0x63315C21, 0x5E0A72EC,
273
      0x49BAFEFD, 0x187908D9, 0x8D0DBD86, 0x311170A7, 0x3E9B640C, 0xCC3E10D7,
274
      0xD5CAD3B6, 0x0CAEC388, 0xF73001E1, 0x6C728AFF, 0x71EAE2A1, 0x1F9AF36E,
275
      0xCFCBD12F, 0xC1DE8417, 0xAC07BE6B, 0xCB44A1D8, 0x8B9B0F56, 0x013988C3,
276
      0xB1C52FCA, 0xB4BE31CD, 0xD8782806, 0x12A3A4E2, 0x6F7DE532, 0x58FD7EB6,
277
      0xD01EE900, 0x24ADFFC2, 0xF4990FC5, 0x9711AAC5, 0x001D7B95, 0x82E5E7D2,
278
      0x109873F6, 0x00613096, 0xC32D9521, 0xADA121FF, 0x29908415, 0x7FBB977F,
279
      0xAF9EB3DB, 0x29C9ED2A, 0x5CE2A465, 0xA730F32C, 0xD0AA3FE8, 0x8A5CC091,
280
      0xD49E2CE7, 0x0CE454A9, 0xD60ACD86, 0x015F1919, 0x77079103, 0xDEA03AF6,
281
      0x78A8565E, 0xDEE356DF, 0x21F05CBE, 0x8B75E387, 0xB3C50651, 0xB8A5C3EF,
282
      0xD8EEB6D2, 0xE523BE77, 0xC2154529, 0x2F69EFDF, 0xAFE67AFB, 0xF470C4B2,
283
      0xF3E0EB5B, 0xD6CC9876, 0x39E4460C, 0x1FDA8538, 0x1987832F, 0xCA007367,
284
      0xA99144F8, 0x296B299E, 0x492FC295, 0x9266BEAB, 0xB5676E69, 0x9BD3DDDA,
285
      0xDF7E052F, 0xDB25701C, 0x1B5E51EE, 0xF65324E6, 0x6AFCE36C, 0x0316CC04,
286
      0x8644213E, 0xB7DC59D0, 0x7965291F, 0xCCD6FD43, 0x41823979, 0x932BCDF6,
287
      0xB657C34D, 0x4EDFD282, 0x7AE5290C, 0x3CB9536B, 0x851E20FE, 0x9833557E,
288
      0x13ECF0B0, 0xD3FFB372, 0x3F85C5C1, 0x0AEF7ED2 };
289
  private static final int[] S5 = {
290
      0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911, 0xB86A7FFF, 0x1DD358F5,
291
      0x44DD9D44, 0x1731167F, 0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00,
292
      0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A, 0xE6A2E77F, 0xF0C720CD,
293
      0xC4494816, 0xCCF5C180, 0x38851640, 0x15B0A848, 0xE68B18CB, 0x4CAADEFF,
294
      0x5F480A01, 0x0412B2AA, 0x259814FC, 0x41D0EFE2, 0x4E40B48D, 0x248EB6FB,
295
      0x8DBA1CFE, 0x41A99B02, 0x1A550A04, 0xBA8F65CB, 0x7251F4E7, 0x95A51725,
296
      0xC106ECD7, 0x97A5980A, 0xC539B9AA, 0x4D79FE6A, 0xF2F3F763, 0x68AF8040,
297
      0xED0C9E56, 0x11B4958B, 0xE1EB5A88, 0x8709E6B0, 0xD7E07156, 0x4E29FEA7,
298
      0x6366E52D, 0x02D1C000, 0xC4AC8E05, 0x9377F571, 0x0C05372A, 0x578535F2,
299
      0x2261BE02, 0xD642A0C9, 0xDF13A280, 0x74B55BD2, 0x682199C0, 0xD421E5EC,
300
      0x53FB3CE8, 0xC8ADEDB3, 0x28A87FC9, 0x3D959981, 0x5C1FF900, 0xFE38D399,
301
      0x0C4EFF0B, 0x062407EA, 0xAA2F4FB1, 0x4FB96976, 0x90C79505, 0xB0A8A774,
302
      0xEF55A1FF, 0xE59CA2C2, 0xA6B62D27, 0xE66A4263, 0xDF65001F, 0x0EC50966,
303
      0xDFDD55BC, 0x29DE0655, 0x911E739A, 0x17AF8975, 0x32C7911C, 0x89F89468,
304
      0x0D01E980, 0x524755F4, 0x03B63CC9, 0x0CC844B2, 0xBCF3F0AA, 0x87AC36E9,
305
      0xE53A7426, 0x01B3D82B, 0x1A9E7449, 0x64EE2D7E, 0xCDDBB1DA, 0x01C94910,
306
      0xB868BF80, 0x0D26F3FD, 0x9342EDE7, 0x04A5C284, 0x636737B6, 0x50F5B616,
307
      0xF24766E3, 0x8ECA36C1, 0x136E05DB, 0xFEF18391, 0xFB887A37, 0xD6E7F7D4,
308
      0xC7FB7DC9, 0x3063FCDF, 0xB6F589DE, 0xEC2941DA, 0x26E46695, 0xB7566419,
309
      0xF654EFC5, 0xD08D58B7, 0x48925401, 0xC1BACB7F, 0xE5FF550F, 0xB6083049,
310
      0x5BB5D0E8, 0x87D72E5A, 0xAB6A6EE1, 0x223A66CE, 0xC62BF3CD, 0x9E0885F9,
311
      0x68CB3E47, 0x086C010F, 0xA21DE820, 0xD18B69DE, 0xF3F65777, 0xFA02C3F6,
312
      0x407EDAC3, 0xCBB3D550, 0x1793084D, 0xB0D70EBA, 0x0AB378D5, 0xD951FB0C,
313
      0xDED7DA56, 0x4124BBE4, 0x94CA0B56, 0x0F5755D1, 0xE0E1E56E, 0x6184B5BE,
314
      0x580A249F, 0x94F74BC0, 0xE327888E, 0x9F7B5561, 0xC3DC0280, 0x05687715,
315
      0x646C6BD7, 0x44904DB3, 0x66B4F0A3, 0xC0F1648A, 0x697ED5AF, 0x49E92FF6,
316
      0x309E374F, 0x2CB6356A, 0x85808573, 0x4991F840, 0x76F0AE02, 0x083BE84D,
317
      0x28421C9A, 0x44489406, 0x736E4CB8, 0xC1092910, 0x8BC95FC6, 0x7D869CF4,
318
      0x134F616F, 0x2E77118D, 0xB31B2BE1, 0xAA90B472, 0x3CA5D717, 0x7D161BBA,
319
      0x9CAD9010, 0xAF462BA2, 0x9FE459D2, 0x45D34559, 0xD9F2DA13, 0xDBC65487,
320
      0xF3E4F94E, 0x176D486F, 0x097C13EA, 0x631DA5C7, 0x445F7382, 0x175683F4,
321
      0xCDC66A97, 0x70BE0288, 0xB3CDCF72, 0x6E5DD2F3, 0x20936079, 0x459B80A5,
322
      0xBE60E2DB, 0xA9C23101, 0xEBA5315C, 0x224E42F2, 0x1C5C1572, 0xF6721B2C,
323
      0x1AD2FFF3, 0x8C25404E, 0x324ED72F, 0x4067B7FD, 0x0523138E, 0x5CA3BC78,
324
      0xDC0FD66E, 0x75922283, 0x784D6B17, 0x58EBB16E, 0x44094F85, 0x3F481D87,
325
      0xFCFEAE7B, 0x77B5FF76, 0x8C2302BF, 0xAAF47556, 0x5F46B02A, 0x2B092801,
326
      0x3D38F5F7, 0x0CA81F36, 0x52AF4A8A, 0x66D5E7C0, 0xDF3B0874, 0x95055110,
327
      0x1B5AD7A8, 0xF61ED5AD, 0x6CF6E479, 0x20758184, 0xD0CEFA65, 0x88F7BE58,
328
      0x4A046826, 0x0FF6F8F3, 0xA09C7F70, 0x5346ABA0, 0x5CE96C28, 0xE176EDA3,
329
      0x6BAC307F, 0x376829D2, 0x85360FA9, 0x17E3FE2A, 0x24B79767, 0xF5A96B20,
330
      0xD6CD2595, 0x68FF1EBF, 0x7555442C, 0xF19F06BE, 0xF9E0659A, 0xEEB9491D,
331
      0x34010718, 0xBB30CAB8, 0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55,
332
      0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4 };
333
  private static final int[] S6 = {
334
      0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C, 0x95DB08E7, 0x016843B4,
335
      0xECED5CBC, 0x325553AC, 0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9,
336
      0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138, 0x33F14961, 0xC01937BD,
337
      0xF506C6DA, 0xE4625E7E, 0xA308EA99, 0x4E23E33C, 0x79CBD7CC, 0x48A14367,
338
      0xA3149619, 0xFEC94BD5, 0xA114174A, 0xEAA01866, 0xA084DB2D, 0x09A8486F,
339
      0xA888614A, 0x2900AF98, 0x01665991, 0xE1992863, 0xC8F30C60, 0x2E78EF3C,
340
      0xD0D51932, 0xCF0FEC14, 0xF7CA07D2, 0xD0A82072, 0xFD41197E, 0x9305A6B0,
341
      0xE86BE3DA, 0x74BED3CD, 0x372DA53C, 0x4C7F4448, 0xDAB5D440, 0x6DBA0EC3,
342
      0x083919A7, 0x9FBAEED9, 0x49DBCFB0, 0x4E670C53, 0x5C3D9C01, 0x64BDB941,
343
      0x2C0E636A, 0xBA7DD9CD, 0xEA6F7388, 0xE70BC762, 0x35F29ADB, 0x5C4CDD8D,
344
      0xF0D48D8C, 0xB88153E2, 0x08A19866, 0x1AE2EAC8, 0x284CAF89, 0xAA928223,
345
      0x9334BE53, 0x3B3A21BF, 0x16434BE3, 0x9AEA3906, 0xEFE8C36E, 0xF890CDD9,
346
      0x80226DAE, 0xC340A4A3, 0xDF7E9C09, 0xA694A807, 0x5B7C5ECC, 0x221DB3A6,
347
      0x9A69A02F, 0x68818A54, 0xCEB2296F, 0x53C0843A, 0xFE893655, 0x25BFE68A,
348
      0xB4628ABC, 0xCF222EBF, 0x25AC6F48, 0xA9A99387, 0x53BDDB65, 0xE76FFBE7,
349
      0xE967FD78, 0x0BA93563, 0x8E342BC1, 0xE8A11BE9, 0x4980740D, 0xC8087DFC,
350
      0x8DE4BF99, 0xA11101A0, 0x7FD37975, 0xDA5A26C0, 0xE81F994F, 0x9528CD89,
351
      0xFD339FED, 0xB87834BF, 0x5F04456D, 0x22258698, 0xC9C4C83B, 0x2DC156BE,
352
      0x4F628DAA, 0x57F55EC5, 0xE2220ABE, 0xD2916EBF, 0x4EC75B95, 0x24F2C3C0,
353
      0x42D15D99, 0xCD0D7FA0, 0x7B6E27FF, 0xA8DC8AF0, 0x7345C106, 0xF41E232F,
354
      0x35162386, 0xE6EA8926, 0x3333B094, 0x157EC6F2, 0x372B74AF, 0x692573E4,
355
      0xE9A9D848, 0xF3160289, 0x3A62EF1D, 0xA787E238, 0xF3A5F676, 0x74364853,
356
      0x20951063, 0x4576698D, 0xB6FAD407, 0x592AF950, 0x36F73523, 0x4CFB6E87,
357
      0x7DA4CEC0, 0x6C152DAA, 0xCB0396A8, 0xC50DFE5D, 0xFCD707AB, 0x0921C42F,
358
      0x89DFF0BB, 0x5FE2BE78, 0x448F4F33, 0x754613C9, 0x2B05D08D, 0x48B9D585,
359
      0xDC049441, 0xC8098F9B, 0x7DEDE786, 0xC39A3373, 0x42410005, 0x6A091751,
360
      0x0EF3C8A6, 0x890072D6, 0x28207682, 0xA9A9F7BE, 0xBF32679D, 0xD45B5B75,
361
      0xB353FD00, 0xCBB0E358, 0x830F220A, 0x1F8FB214, 0xD372CF08, 0xCC3C4A13,
362
      0x8CF63166, 0x061C87BE, 0x88C98F88, 0x6062E397, 0x47CF8E7A, 0xB6C85283,
363
      0x3CC2ACFB, 0x3FC06976, 0x4E8F0252, 0x64D8314D, 0xDA3870E3, 0x1E665459,
364
      0xC10908F0, 0x513021A5, 0x6C5B68B7, 0x822F8AA0, 0x3007CD3E, 0x74719EEF,
365
      0xDC872681, 0x073340D4, 0x7E432FD9, 0x0C5EC241, 0x8809286C, 0xF592D891,
366
      0x08A930F6, 0x957EF305, 0xB7FBFFBD, 0xC266E96F, 0x6FE4AC98, 0xB173ECC0,
367
      0xBC60B42A, 0x953498DA, 0xFBA1AE12, 0x2D4BD736, 0x0F25FAAB, 0xA4F3FCEB,
368
      0xE2969123, 0x257F0C3D, 0x9348AF49, 0x361400BC, 0xE8816F4A, 0x3814F200,
369
      0xA3F94043, 0x9C7A54C2, 0xBC704F57, 0xDA41E7F9, 0xC25AD33A, 0x54F4A084,
370
      0xB17F5505, 0x59357CBE, 0xEDBD15C8, 0x7F97C5AB, 0xBA5AC7B5, 0xB6F6DEAF,
371
      0x3A479C3A, 0x5302DA25, 0x653D7E6A, 0x54268D49, 0x51A477EA, 0x5017D55B,
372
      0xD7D25D88, 0x44136C76, 0x0404A8C8, 0xB8E5A121, 0xB81A928A, 0x60ED5869,
373
      0x97C55B96, 0xEAEC991B, 0x29935913, 0x01FDB7F1, 0x088E8DFA, 0x9AB6F6F5,
374
      0x3B4CBF9F, 0x4A5DE3AB, 0xE6051D35, 0xA0E1D855, 0xD36B4CF1, 0xF544EDEB,
375
      0xB0E93524, 0xBEBB8FBD, 0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454,
376
      0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F };
377
  private static final int[] S7 = {
378
      0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693, 0x2A8D7F6F, 0xAB9BC912,
379
      0xDE6008A1, 0x2028DA1F, 0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82,
380
      0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE, 0xA05FBCF6, 0xCD4181E9,
381
      0xE150210C, 0xE24EF1BD, 0xB168C381, 0xFDE4E789, 0x5C79B0D8, 0x1E8BFD43,
382
      0x4D495001, 0x38BE4341, 0x913CEE1D, 0x92A79C3F, 0x089766BE, 0xBAEEADF4,
383
      0x1286BECF, 0xB6EACB19, 0x2660C200, 0x7565BDE4, 0x64241F7A, 0x8248DCA9,
384
      0xC3B3AD66, 0x28136086, 0x0BD8DFA8, 0x356D1CF2, 0x107789BE, 0xB3B2E9CE,
385
      0x0502AA8F, 0x0BC0351E, 0x166BF52A, 0xEB12FF82, 0xE3486911, 0xD34D7516,
386
      0x4E7B3AFF, 0x5F43671B, 0x9CF6E037, 0x4981AC83, 0x334266CE, 0x8C9341B7,
387
      0xD0D854C0, 0xCB3A6C88, 0x47BC2829, 0x4725BA37, 0xA66AD22B, 0x7AD61F1E,
388
      0x0C5CBAFA, 0x4437F107, 0xB6E79962, 0x42D2D816, 0x0A961288, 0xE1A5C06E,
389
      0x13749E67, 0x72FC081A, 0xB1D139F7, 0xF9583745, 0xCF19DF58, 0xBEC3F756,
390
      0xC06EBA30, 0x07211B24, 0x45C28829, 0xC95E317F, 0xBC8EC511, 0x38BC46E9,
391
      0xC6E6FA14, 0xBAE8584A, 0xAD4EBC46, 0x468F508B, 0x7829435F, 0xF124183B,
392
      0x821DBA9F, 0xAFF60FF4, 0xEA2C4E6D, 0x16E39264, 0x92544A8B, 0x009B4FC3,
393
      0xABA68CED, 0x9AC96F78, 0x06A5B79A, 0xB2856E6E, 0x1AEC3CA9, 0xBE838688,
394
      0x0E0804E9, 0x55F1BE56, 0xE7E5363B, 0xB3A1F25D, 0xF7DEBB85, 0x61FE033C,
395
      0x16746233, 0x3C034C28, 0xDA6D0C74, 0x79AAC56C, 0x3CE4E1AD, 0x51F0C802,
396
      0x98F8F35A, 0x1626A49F, 0xEED82B29, 0x1D382FE3, 0x0C4FB99A, 0xBB325778,
397
      0x3EC6D97B, 0x6E77A6A9, 0xCB658B5C, 0xD45230C7, 0x2BD1408B, 0x60C03EB7,
398
      0xB9068D78, 0xA33754F4, 0xF430C87D, 0xC8A71302, 0xB96D8C32, 0xEBD4E7BE,
399
      0xBE8B9D2D, 0x7979FB06, 0xE7225308, 0x8B75CF77, 0x11EF8DA4, 0xE083C858,
400
      0x8D6B786F, 0x5A6317A6, 0xFA5CF7A0, 0x5DDA0033, 0xF28EBFB0, 0xF5B9C310,
401
      0xA0EAC280, 0x08B9767A, 0xA3D9D2B0, 0x79D34217, 0x021A718D, 0x9AC6336A,
402
      0x2711FD60, 0x438050E3, 0x069908A8, 0x3D7FEDC4, 0x826D2BEF, 0x4EEB8476,
403
      0x488DCF25, 0x36C9D566, 0x28E74E41, 0xC2610ACA, 0x3D49A9CF, 0xBAE3B9DF,
404
      0xB65F8DE6, 0x92AEAF64, 0x3AC7D5E6, 0x9EA80509, 0xF22B017D, 0xA4173F70,
405
      0xDD1E16C3, 0x15E0D7F9, 0x50B1B887, 0x2B9F4FD5, 0x625ABA82, 0x6A017962,
406
      0x2EC01B9C, 0x15488AA9, 0xD716E740, 0x40055A2C, 0x93D29A22, 0xE32DBF9A,
407
      0x058745B9, 0x3453DC1E, 0xD699296E, 0x496CFF6F, 0x1C9F4986, 0xDFE2ED07,
408
      0xB87242D1, 0x19DE7EAE, 0x053E561A, 0x15AD6F8C, 0x66626C1C, 0x7154C24C,
409
      0xEA082B2A, 0x93EB2939, 0x17DCB0F0, 0x58D4F2AE, 0x9EA294FB, 0x52CF564C,
410
      0x9883FE66, 0x2EC40581, 0x763953C3, 0x01D6692E, 0xD3A0C108, 0xA1E7160E,
411
      0xE4F2DFA6, 0x693ED285, 0x74904698, 0x4C2B0EDD, 0x4F757656, 0x5D393378,
412
      0xA132234F, 0x3D321C5D, 0xC3F5E194, 0x4B269301, 0xC79F022F, 0x3C997E7E,
413
      0x5E4F9504, 0x3FFAFBBD, 0x76F7AD0E, 0x296693F4, 0x3D1FCE6F, 0xC61E45BE,
414
      0xD3B5AB34, 0xF72BF9B7, 0x1B0434C0, 0x4E72B567, 0x5592A33D, 0xB5229301,
415
      0xCFD2A87F, 0x60AEB767, 0x1814386B, 0x30BCC33D, 0x38A0C07D, 0xFD1606F2,
416
      0xC363519B, 0x589DD390, 0x5479F8E6, 0x1CB8D647, 0x97FD61A9, 0xEA7759F4,
417
      0x2D57539D, 0x569A58CF, 0xE84E63AD, 0x462E1B78, 0x6580F87E, 0xF3817914,
418
      0x91DA55F4, 0x40A230F3, 0xD1988F35, 0xB6E318D2, 0x3FFA50BC, 0x3D40F021,
419
      0xC3C0BDAE, 0x4958C24C, 0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA,
420
      0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3 };
421
  private static final int[] S8 = {
422
      0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095, 0x7789F8B7, 0xE6C1121B,
423
      0x0E241600, 0x052CE8B5, 0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174,
424
      0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC, 0xDE9ADEB1, 0x0A0CC32C,
425
      0xBE197029, 0x84A00940, 0xBB243A0F, 0xB4D137CF, 0xB44E79F0, 0x049EEDFD,
426
      0x0B15A15D, 0x480D3168, 0x8BBBDE5A, 0x669DED42, 0xC7ECE831, 0x3F8F95E7,
427
      0x72DF191B, 0x7580330D, 0x94074251, 0x5C7DCDFA, 0xABBE6D63, 0xAA402164,
428
      0xB301D40A, 0x02E7D1CA, 0x53571DAE, 0x7A3182A2, 0x12A8DDEC, 0xFDAA335D,
429
      0x176F43E8, 0x71FB46D4, 0x38129022, 0xCE949AD4, 0xB84769AD, 0x965BD862,
430
      0x82F3D055, 0x66FB9767, 0x15B80B4E, 0x1D5B47A0, 0x4CFDE06F, 0xC28EC4B8,
431
      0x57E8726E, 0x647A78FC, 0x99865D44, 0x608BD593, 0x6C200E03, 0x39DC5FF6,
432
      0x5D0B00A3, 0xAE63AFF2, 0x7E8BD632, 0x70108C0C, 0xBBD35049, 0x2998DF04,
433
      0x980CF42A, 0x9B6DF491, 0x9E7EDD53, 0x06918548, 0x58CB7E07, 0x3B74EF2E,
434
      0x522FFFB1, 0xD24708CC, 0x1C7E27CD, 0xA4EB215B, 0x3CF1D2E2, 0x19B47A38,
435
      0x424F7618, 0x35856039, 0x9D17DEE7, 0x27EB35E6, 0xC9AFF67B, 0x36BAF5B8,
436
      0x09C467CD, 0xC18910B1, 0xE11DBF7B, 0x06CD1AF8, 0x7170C608, 0x2D5E3354,
437
      0xD4DE495A, 0x64C6D006, 0xBCC0C62C, 0x3DD00DB3, 0x708F8F34, 0x77D51B42,
438
      0x264F620F, 0x24B8D2BF, 0x15C1B79E, 0x46A52564, 0xF8D7E54E, 0x3E378160,
439
      0x7895CDA5, 0x859C15A5, 0xE6459788, 0xC37BC75F, 0xDB07BA0C, 0x0676A3AB,
440
      0x7F229B1E, 0x31842E7B, 0x24259FD7, 0xF8BEF472, 0x835FFCB8, 0x6DF4C1F2,
441
      0x96F5B195, 0xFD0AF0FC, 0xB0FE134C, 0xE2506D3D, 0x4F9B12EA, 0xF215F225,
442
      0xA223736F, 0x9FB4C428, 0x25D04979, 0x34C713F8, 0xC4618187, 0xEA7A6E98,
443
      0x7CD16EFC, 0x1436876C, 0xF1544107, 0xBEDEEE14, 0x56E9AF27, 0xA04AA441,
444
      0x3CF7C899, 0x92ECBAE6, 0xDD67016D, 0x151682EB, 0xA842EEDF, 0xFDBA60B4,
445
      0xF1907B75, 0x20E3030F, 0x24D8C29E, 0xE139673B, 0xEFA63FB8, 0x71873054,
446
      0xB6F2CF3B, 0x9F326442, 0xCB15A4CC, 0xB01A4504, 0xF1E47D8D, 0x844A1BE5,
447
      0xBAE7DFDC, 0x42CBDA70, 0xCD7DAE0A, 0x57E85B7A, 0xD53F5AF6, 0x20CF4D8C,
448
      0xCEA4D428, 0x79D130A4, 0x3486EBFB, 0x33D3CDDC, 0x77853B53, 0x37EFFCB5,
449
      0xC5068778, 0xE580B3E6, 0x4E68B8F4, 0xC5C8B37E, 0x0D809EA2, 0x398FEB7C,
450
      0x132A4F94, 0x43B7950E, 0x2FEE7D1C, 0x223613BD, 0xDD06CAA2, 0x37DF932B,
451
      0xC4248289, 0xACF3EBC3, 0x5715F6B7, 0xEF3478DD, 0xF267616F, 0xC148CBE4,
452
      0x9052815E, 0x5E410FAB, 0xB48A2465, 0x2EDA7FA4, 0xE87B40E4, 0xE98EA084,
453
      0x5889E9E1, 0xEFD390FC, 0xDD07D35B, 0xDB485694, 0x38D7E5B2, 0x57720101,
454
      0x730EDEBC, 0x5B643113, 0x94917E4F, 0x503C2FBA, 0x646F1282, 0x7523D24A,
455
      0xE0779695, 0xF9C17A8F, 0x7A5B2121, 0xD187B896, 0x29263A4D, 0xBA510CDF,
456
      0x81F47C9F, 0xAD1163ED, 0xEA7B5965, 0x1A00726E, 0x11403092, 0x00DA6D77,
457
      0x4A0CDD61, 0xAD1F4603, 0x605BDFB0, 0x9EEDC364, 0x22EBE6A8, 0xCEE7D28A,
458
      0xA0E736A0, 0x5564A6B9, 0x10853209, 0xC7EB8F37, 0x2DE705CA, 0x8951570F,
459
      0xDF09822B, 0xBD691A6C, 0xAA12E4F2, 0x87451C0F, 0xE0F6A27A, 0x3ADA4819,
460
      0x4CF1764F, 0x0D771C2B, 0x67CDB156, 0x350D8384, 0x5938FA0F, 0x42399EF3,
461
      0x36997B07, 0x0E84093D, 0x4AA93E61, 0x8360D87B, 0x1FA98B0C, 0x1149382C,
462
      0xE97625A5, 0x0614D1B7, 0x0E25244B, 0x0C768347, 0x589E8D82, 0x0D2059D1,
463
      0xA466BB1E, 0xF8DA0A82, 0x04F19130, 0xBA6E4EC0, 0x99265164, 0x1EE7230D,
464
      0x50B2AD80, 0xEAEE6801, 0x8DB2A283, 0xEA8BF59E };
465
  private static final int _12_ROUNDS = 12;
466
  private static final int _16_ROUNDS = 16;
467
 
468
  /** Trivial 0-arguments constructor. */
469
  public Cast5()
470
  {
471
    super(Registry.CAST5_CIPHER, DEFAULT_BLOCK_SIZE, DEFAULT_KEY_SIZE);
472
  }
473
 
474
  /**
475
   * Assuming the input is a 32-bit block organised as: b31b30b29...b0, this
476
   * method returns an array of 4 Java ints, containing from position 0 onward
477
   * the values: {b31b30b29b28, b27b26b25b24, ... , b3b2b1b0}.
478
   *
479
   * @param x a 32-bit block.
480
   * @return an array of 4 ints, each being the contents of an 8-bit block from
481
   * the input.
482
   */
483
  private static final int[] unscramble(int x)
484
  {
485
    return new int[] { x >>> 24, (x >>> 16) & 0xFF, (x >>> 8) & 0xFF, x & 0xFF };
486
  }
487
 
488
  public Object clone()
489
  {
490
    Cast5 result = new Cast5();
491
    result.currentBlockSize = this.currentBlockSize;
492
    return result;
493
  }
494
 
495
  public Iterator blockSizes()
496
  {
497
    ArrayList al = new ArrayList();
498
    al.add(Integer.valueOf(DEFAULT_BLOCK_SIZE));
499
    return Collections.unmodifiableList(al).iterator();
500
  }
501
 
502
  public Iterator keySizes()
503
  {
504
    ArrayList al = new ArrayList();
505
    for (int n = 5; n < 17; n++)
506
      al.add(Integer.valueOf(n));
507
    return Collections.unmodifiableList(al).iterator();
508
  }
509
 
510
  public Object makeKey(byte[] uk, int bs) throws InvalidKeyException
511
  {
512
    if (bs != DEFAULT_BLOCK_SIZE)
513
      throw new IllegalArgumentException();
514
    if (uk == null)
515
      throw new InvalidKeyException("Empty key");
516
    int len = uk.length;
517
    if (len < 5 || len > 16)
518
      throw new InvalidKeyException("Key size (in bytes) is not in the range [5..16]");
519
    Cast5Key result = new Cast5Key();
520
    result.rounds = (len < 11) ? _12_ROUNDS : _16_ROUNDS;
521
    byte[] kk = new byte[16];
522
    System.arraycopy(uk, 0, kk, 0, len);
523
    int z0z1z2z3, z4z5z6z7, z8z9zAzB, zCzDzEzF;
524
    int z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, zA, zB, zC, zD, zE, zF;
525
    int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xA, xB, xC, xD, xE, xF;
526
    int[] b;
527
    int x0x1x2x3 =  kk[0 ]         << 24
528
                 | (kk[1 ] & 0xFF) << 16
529
                 | (kk[2 ] & 0xFF) << 8
530
                 | (kk[3 ] & 0xFF);
531
    int x4x5x6x7 =  kk[4 ]         << 24
532
                 | (kk[5 ] & 0xFF) << 16
533
                 | (kk[6 ] & 0xFF) << 8
534
                 | (kk[7 ] & 0xFF);
535
    int x8x9xAxB =  kk[8 ]         << 24
536
                 | (kk[9 ] & 0xFF) << 16
537
                 | (kk[10] & 0xFF) << 8
538
                 | (kk[11] & 0xFF);
539
    int xCxDxExF =  kk[12]         << 24
540
                 | (kk[13] & 0xFF) << 16
541
                 | (kk[14] & 0xFF) << 8
542
                 | (kk[15] & 0xFF);
543
    b = unscramble(x0x1x2x3);
544
    x0 = b[0];
545
    x1 = b[1];
546
    x2 = b[2];
547
    x3 = b[3];
548
    b = unscramble(x4x5x6x7);
549
    x4 = b[0];
550
    x5 = b[1];
551
    x6 = b[2];
552
    x7 = b[3];
553
    b = unscramble(x8x9xAxB);
554
    x8 = b[0];
555
    x9 = b[1];
556
    xA = b[2];
557
    xB = b[3];
558
    b = unscramble(xCxDxExF);
559
    xC = b[0];
560
    xD = b[1];
561
    xE = b[2];
562
    xF = b[3];
563
    z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
564
    b = unscramble(z0z1z2z3);
565
    z0 = b[0];
566
    z1 = b[1];
567
    z2 = b[2];
568
    z3 = b[3];
569
    z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
570
    b = unscramble(z4z5z6z7);
571
    z4 = b[0];
572
    z5 = b[1];
573
    z6 = b[2];
574
    z7 = b[3];
575
    z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
576
    b = unscramble(z8z9zAzB);
577
    z8 = b[0];
578
    z9 = b[1];
579
    zA = b[2];
580
    zB = b[3];
581
    zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
582
    b = unscramble(zCzDzEzF);
583
    zC = b[0];
584
    zD = b[1];
585
    zE = b[2];
586
    zF = b[3];
587
    result.Km0 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2];
588
    result.Km1 = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6];
589
    result.Km2 = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9];
590
    result.Km3 = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC];
591
    x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
592
    b = unscramble(x0x1x2x3);
593
    x0 = b[0];
594
    x1 = b[1];
595
    x2 = b[2];
596
    x3 = b[3];
597
    x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
598
    b = unscramble(x4x5x6x7);
599
    x4 = b[0];
600
    x5 = b[1];
601
    x6 = b[2];
602
    x7 = b[3];
603
    x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
604
    b = unscramble(x8x9xAxB);
605
    x8 = b[0];
606
    x9 = b[1];
607
    xA = b[2];
608
    xB = b[3];
609
    xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
610
    b = unscramble(xCxDxExF);
611
    xC = b[0];
612
    xD = b[1];
613
    xE = b[2];
614
    xF = b[3];
615
    result.Km4 = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8];
616
    result.Km5 = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD];
617
    result.Km6 = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3];
618
    result.Km7 = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7];
619
    z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
620
    b = unscramble(z0z1z2z3);
621
    z0 = b[0];
622
    z1 = b[1];
623
    z2 = b[2];
624
    z3 = b[3];
625
    z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
626
    b = unscramble(z4z5z6z7);
627
    z4 = b[0];
628
    z5 = b[1];
629
    z6 = b[2];
630
    z7 = b[3];
631
    z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
632
    b = unscramble(z8z9zAzB);
633
    z8 = b[0];
634
    z9 = b[1];
635
    zA = b[2];
636
    zB = b[3];
637
    zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
638
    b = unscramble(zCzDzEzF);
639
    zC = b[0];
640
    zD = b[1];
641
    zE = b[2];
642
    zF = b[3];
643
    result.Km8 = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9];
644
    result.Km9 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC];
645
    result.Km10 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2];
646
    result.Km11 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6];
647
    x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
648
    b = unscramble(x0x1x2x3);
649
    x0 = b[0];
650
    x1 = b[1];
651
    x2 = b[2];
652
    x3 = b[3];
653
    x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
654
    b = unscramble(x4x5x6x7);
655
    x4 = b[0];
656
    x5 = b[1];
657
    x6 = b[2];
658
    x7 = b[3];
659
    x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
660
    b = unscramble(x8x9xAxB);
661
    x8 = b[0];
662
    x9 = b[1];
663
    xA = b[2];
664
    xB = b[3];
665
    xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
666
    b = unscramble(xCxDxExF);
667
    xC = b[0];
668
    xD = b[1];
669
    xE = b[2];
670
    xF = b[3];
671
    result.Km12 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3];
672
    result.Km13 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7];
673
    result.Km14 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8];
674
    result.Km15 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD];
675
    // The remaining half is identical to what is given above, carrying on
676
    // from the last created x0..xF to generate keys K17 - K32. These keys
677
    // will be used as the 'rotation' keys and as such only the five least
678
    // significant bits are to be considered.
679
    z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
680
    b = unscramble(z0z1z2z3);
681
    z0 = b[0];
682
    z1 = b[1];
683
    z2 = b[2];
684
    z3 = b[3];
685
    z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
686
    b = unscramble(z4z5z6z7);
687
    z4 = b[0];
688
    z5 = b[1];
689
    z6 = b[2];
690
    z7 = b[3];
691
    z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
692
    b = unscramble(z8z9zAzB);
693
    z8 = b[0];
694
    z9 = b[1];
695
    zA = b[2];
696
    zB = b[3];
697
    zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
698
    b = unscramble(zCzDzEzF);
699
    zC = b[0];
700
    zD = b[1];
701
    zE = b[2];
702
    zF = b[3];
703
    result.Kr0 = (S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]) & 0x1F;
704
    result.Kr1 = (S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]) & 0x1F;
705
    result.Kr2 = (S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]) & 0x1F;
706
    result.Kr3 = (S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]) & 0x1F;
707
    x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
708
    b = unscramble(x0x1x2x3);
709
    x0 = b[0];
710
    x1 = b[1];
711
    x2 = b[2];
712
    x3 = b[3];
713
    x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
714
    b = unscramble(x4x5x6x7);
715
    x4 = b[0];
716
    x5 = b[1];
717
    x6 = b[2];
718
    x7 = b[3];
719
    x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
720
    b = unscramble(x8x9xAxB);
721
    x8 = b[0];
722
    x9 = b[1];
723
    xA = b[2];
724
    xB = b[3];
725
    xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
726
    b = unscramble(xCxDxExF);
727
    xC = b[0];
728
    xD = b[1];
729
    xE = b[2];
730
    xF = b[3];
731
    result.Kr4 = (S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]) & 0x1F;
732
    result.Kr5 = (S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]) & 0x1F;
733
    result.Kr6 = (S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]) & 0x1F;
734
    result.Kr7 = (S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]) & 0x1F;
735
    z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
736
    b = unscramble(z0z1z2z3);
737
    z0 = b[0];
738
    z1 = b[1];
739
    z2 = b[2];
740
    z3 = b[3];
741
    z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
742
    b = unscramble(z4z5z6z7);
743
    z4 = b[0];
744
    z5 = b[1];
745
    z6 = b[2];
746
    z7 = b[3];
747
    z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
748
    b = unscramble(z8z9zAzB);
749
    z8 = b[0];
750
    z9 = b[1];
751
    zA = b[2];
752
    zB = b[3];
753
    zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
754
    b = unscramble(zCzDzEzF);
755
    zC = b[0];
756
    zD = b[1];
757
    zE = b[2];
758
    zF = b[3];
759
    result.Kr8 = (S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]) & 0x1F;
760
    result.Kr9 = (S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]) & 0x1F;
761
    result.Kr10 = (S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]) & 0x1F;
762
    result.Kr11 = (S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]) & 0x1F;
763
    x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
764
    b = unscramble(x0x1x2x3);
765
    x0 = b[0];
766
    x1 = b[1];
767
    x2 = b[2];
768
    x3 = b[3];
769
    x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
770
    b = unscramble(x4x5x6x7);
771
    x4 = b[0];
772
    x5 = b[1];
773
    x6 = b[2];
774
    x7 = b[3];
775
    x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
776
    b = unscramble(x8x9xAxB);
777
    x8 = b[0];
778
    x9 = b[1];
779
    xA = b[2];
780
    xB = b[3];
781
    xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
782
    b = unscramble(xCxDxExF);
783
    xC = b[0];
784
    xD = b[1];
785
    xE = b[2];
786
    xF = b[3];
787
    result.Kr12 = (S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]) & 0x1F;
788
    result.Kr13 = (S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]) & 0x1F;
789
    result.Kr14 = (S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]) & 0x1F;
790
    result.Kr15 = (S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]) & 0x1F;
791
    return result;
792
  }
793
 
794
  /**
795
   * The full encryption algorithm is given in the following four steps.
796
   * <pre>
797
   *    INPUT:  plaintext m1...m64; key K = k1...k128.
798
   *    OUTPUT: ciphertext c1...c64.
799
   * </pre>
800
   * <ol>
801
   *   <li>(key schedule) Compute 16 pairs of subkeys {Kmi, Kri} from a user
802
   *    key (see makeKey() method).</li>
803
   *   <li>(L0,R0) <-- (m1...m64).  (Split the plaintext into left and right
804
   *    32-bit halves L0 = m1...m32 and R0 = m33...m64.).</li>
805
   *   <li>(16 rounds) for i from 1 to 16, compute Li and Ri as follows:
806
   *     <ul>
807
   *       <li>Li = Ri-1;</li>
808
   *       <li>Ri = Li-1 ^ F(Ri-1,Kmi,Kri), where F is defined in method F() --
809
   *       f is of Type 1, Type 2, or Type 3, depending on i, and ^ being the
810
   *       bitwise XOR function.</li>
811
   *     </ul>
812
   *   <li>c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
813
   *    concatenate to form the ciphertext.)</li>
814
   * </ol>
815
   * <p>
816
   * Decryption is identical to the encryption algorithm given above, except
817
   * that the rounds (and therefore the subkey pairs) are used in reverse order
818
   * to compute (L0,R0) from (R16,L16).
819
   * <p>
820
   * Looking at the iterations/rounds in pairs we have:
821
   * <pre>
822
   *    (1a)    Li = Ri-1;
823
   *    (1b)    Ri = Li-1 ^ Fi(Ri-1);
824
   *    (2a)    Li+1 = Ri;
825
   *    (2b)    Ri+1 = Li ^ Fi+1(Ri);
826
   * </pre>
827
   * which by substituting (2a) in (2b) becomes
828
   * <pre>
829
   *    (2c)    Ri+1 = Li ^ Fi+1(Li+1);
830
   * </pre>
831
   * by substituting (1b) in (2a) and (1a) in (2c), we get:
832
   * <pre>
833
   *    (3a)    Li+1 = Li-1 ^ Fi(Ri-1);
834
   *    (3b)    Ri+1 = Ri-1 ^ Fi+1(Li+1);
835
   * </pre>
836
   * Using only one couple of variables L and R, initialised to L0 and R0
837
   * respectively, the assignments for each pair of rounds become:
838
   * <pre>
839
   *    (4a)    L ^= Fi(R);
840
   *    (4b)    R ^= Fi+1(L);
841
   * </pre>
842
   *
843
   * @param in contains the plain-text 64-bit block.
844
   * @param i start index within input where data is considered.
845
   * @param out will contain the cipher-text block.
846
   * @param j index in out where cipher-text starts.
847
   * @param k the session key object.
848
   * @param bs the desired block size.
849
   */
850
  public void encrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
851
  {
852
    if (bs != DEFAULT_BLOCK_SIZE)
853
      throw new IllegalArgumentException();
854
    Cast5Key K = (Cast5Key) k;
855
    int L = (in[i++] & 0xFF) << 24
856
          | (in[i++] & 0xFF) << 16
857
          | (in[i++] & 0xFF) << 8
858
          |  in[i++] & 0xFF;
859
    int R = (in[i++] & 0xFF) << 24
860
          | (in[i++] & 0xFF) << 16
861
          | (in[i++] & 0xFF) << 8
862
          |  in[i  ] & 0xFF;
863
    L ^= f1(R, K.Km0, K.Kr0);
864
    R ^= f2(L, K.Km1, K.Kr1); // round 2
865
    L ^= f3(R, K.Km2, K.Kr2);
866
    R ^= f1(L, K.Km3, K.Kr3); // round 4
867
    L ^= f2(R, K.Km4, K.Kr4);
868
    R ^= f3(L, K.Km5, K.Kr5); // round 6
869
    L ^= f1(R, K.Km6, K.Kr6);
870
    R ^= f2(L, K.Km7, K.Kr7); // round 8
871
    L ^= f3(R, K.Km8, K.Kr8);
872
    R ^= f1(L, K.Km9, K.Kr9); // round 10
873
    L ^= f2(R, K.Km10, K.Kr10);
874
    R ^= f3(L, K.Km11, K.Kr11); // round 12
875
    if (K.rounds == _16_ROUNDS)
876
      {
877
        L ^= f1(R, K.Km12, K.Kr12);
878
        R ^= f2(L, K.Km13, K.Kr13); // round 14
879
        L ^= f3(R, K.Km14, K.Kr14);
880
        R ^= f1(L, K.Km15, K.Kr15); // round 16
881
      }
882
    out[j++] = (byte)(R >>> 24);
883
    out[j++] = (byte)(R >>> 16);
884
    out[j++] = (byte)(R >>> 8);
885
    out[j++] = (byte) R;
886
    out[j++] = (byte)(L >>> 24);
887
    out[j++] = (byte)(L >>> 16);
888
    out[j++] = (byte)(L >>> 8);
889
    out[j  ] = (byte) L;
890
  }
891
 
892
  public void decrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
893
  {
894
    if (bs != DEFAULT_BLOCK_SIZE)
895
      throw new IllegalArgumentException();
896
    Cast5Key K = (Cast5Key) k;
897
    int L = (in[i++] & 0xFF) << 24
898
          | (in[i++] & 0xFF) << 16
899
          | (in[i++] & 0xFF) << 8
900
          |  in[i++] & 0xFF;
901
    int R = (in[i++] & 0xFF) << 24
902
          | (in[i++] & 0xFF) << 16
903
          | (in[i++] & 0xFF) << 8
904
          |  in[i  ] & 0xFF;
905
    if (K.rounds == _16_ROUNDS)
906
      {
907
        L ^= f1(R, K.Km15, K.Kr15);
908
        R ^= f3(L, K.Km14, K.Kr14);
909
        L ^= f2(R, K.Km13, K.Kr13);
910
        R ^= f1(L, K.Km12, K.Kr12);
911
      }
912
    L ^= f3(R, K.Km11, K.Kr11);
913
    R ^= f2(L, K.Km10, K.Kr10);
914
    L ^= f1(R, K.Km9, K.Kr9);
915
    R ^= f3(L, K.Km8, K.Kr8);
916
    L ^= f2(R, K.Km7, K.Kr7);
917
    R ^= f1(L, K.Km6, K.Kr6);
918
    L ^= f3(R, K.Km5, K.Kr5);
919
    R ^= f2(L, K.Km4, K.Kr4);
920
    L ^= f1(R, K.Km3, K.Kr3);
921
    R ^= f3(L, K.Km2, K.Kr2);
922
    L ^= f2(R, K.Km1, K.Kr1);
923
    R ^= f1(L, K.Km0, K.Kr0);
924
    out[j++] = (byte)(R >>> 24);
925
    out[j++] = (byte)(R >>> 16);
926
    out[j++] = (byte)(R >>> 8);
927
    out[j++] = (byte) R;
928
    out[j++] = (byte)(L >>> 24);
929
    out[j++] = (byte)(L >>> 16);
930
    out[j++] = (byte)(L >>> 8);
931
    out[j  ] = (byte) L;
932
  }
933
 
934
  public boolean selfTest()
935
  {
936
    if (valid == null)
937
      {
938
        boolean result = super.selfTest(); // do symmetry tests
939
        if (result)
940
          result = testKat(KAT_KEY, KAT_CT, KAT_PT);
941
        valid = Boolean.valueOf(result);
942
      }
943
    return valid.booleanValue();
944
  }
945
 
946
  private final int f1(int I, int m, int r)
947
  {
948
    I = m + I;
949
    I = I << r | I >>> (32 - r);
950
    return (((S1[(I >>> 24) & 0xFF])
951
            ^ S2[(I >>> 16) & 0xFF])
952
            - S3[(I >>>  8) & 0xFF])
953
            + S4[ I         & 0xFF];
954
  }
955
 
956
  private final int f2(int I, int m, int r)
957
  {
958
    I = m ^ I;
959
    I = I << r | I >>> (32 - r);
960
    return (((S1[(I >>> 24) & 0xFF])
961
            - S2[(I >>> 16) & 0xFF])
962
            + S3[(I >>>  8) & 0xFF])
963
            ^ S4[ I         & 0xFF];
964
  }
965
 
966
  private final int f3(int I, int m, int r)
967
  {
968
    I = m - I;
969
    I = I << r | I >>> (32 - r);
970
    return (((S1[(I >>> 24) & 0xFF])
971
            + S2[(I >>> 16) & 0xFF])
972
            ^ S3[(I >>>  8) & 0xFF])
973
            - S4[ I         & 0xFF];
974
  }
975
 
976
  /** An opaque CAST5 key object. */
977
  private class Cast5Key
978
  {
979
    int rounds;
980
    /** Masking session keys. */
981
    int Km0, Km1, Km2,  Km3,  Km4,  Km5,  Km6,  Km7,
982
        Km8, Km9, Km10, Km11, Km12, Km13, Km14, Km15;
983
    /** Rotation session keys. */
984
    int Kr0, Kr1, Kr2,  Kr3,  Kr4,  Kr5,  Kr6,  Kr7,
985
        Kr8, Kr9, Kr10, Kr11, Kr12, Kr13, Kr14, Kr15;
986
  }
987
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.