PluginProbe
ManageWP Worker / 3.9.28
ManageWP Worker v3.9.28
4.9.38 4.9.37 4.9.36 4.9.35 4.9.34 3.8.7 3.8.8 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24 All 73 releases
worker / lib / PHPSecLib / Crypt / Twofish.php

Twofish.php in ManageWP Worker 3.9.28, at lib/PHPSecLib/Crypt/Twofish.php

1,665 lines 69.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 /**
5 * Pure-PHP implementation of Twofish.
6 *
7 * Uses mcrypt, if available, and an internal implementation, otherwise.
8 *
9 * PHP versions 4 and 5
10 *
11 * Useful resources are as follows:
12 *
13 * - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
14 *
15 * Here's a short example of how to use this library:
16 * <code>
17 * <?php
18 * include('Crypt/Twofish.php');
19 *
20 * $Twofish = new Crypt_Twofish();
21 *
22 * $Twofish->setKey('12345678901234567890123456789012');
23 *
24 * $plaintext = str_repeat('a', 1024);
25 *
26 * echo $Twofish->decrypt($Twofish->encrypt($plaintext));
27 * ?>
28 * </code>
29 *
30 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
31 * of this software and associated documentation files (the "Software"), to deal
32 * in the Software without restriction, including without limitation the rights
33 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34 * copies of the Software, and to permit persons to whom the Software is
35 * furnished to do so, subject to the following conditions:
36 *
37 * The above copyright notice and this permission notice shall be included in
38 * all copies or substantial portions of the Software.
39 *
40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46 * THE SOFTWARE.
47 *
48 * @category Crypt
49 * @package Crypt_Twofish
50 * @author Jim Wigginton <terrafrost@php.net>
51 * @author Hans-Juergen Petrich <petrich@tronic-media.com>
52 * @copyright MMVII Jim Wigginton
53 * @license http://www.opensource.org/licenses/mit-license.html MIT License
54 * @version 1.0
55 * @link http://phpseclib.sourceforge.net
56 */
57
58 /**#@+
59 * @access public
60 * @see Crypt_Twofish::encrypt()
61 * @see Crypt_Twofish::decrypt()
62 */
63 /**
64 * Encrypt / decrypt using the Counter mode.
65 *
66 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
67 *
68 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
69 */
70 define('CRYPT_TWOFISH_MODE_CTR', -1);
71 /**
72 * Encrypt / decrypt using the Electronic Code Book mode.
73 *
74 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
75 */
76 define('CRYPT_TWOFISH_MODE_ECB', 1);
77 /**
78 * Encrypt / decrypt using the Code Book Chaining mode.
79 *
80 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
81 */
82 define('CRYPT_TWOFISH_MODE_CBC', 2);
83 /**
84 * Encrypt / decrypt using the Cipher Feedback mode.
85 *
86 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
87 */
88 define('CRYPT_TWOFISH_MODE_CFB', 3);
89 /**
90 * Encrypt / decrypt using the Cipher Feedback mode.
91 *
92 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
93 */
94 define('CRYPT_TWOFISH_MODE_OFB', 4);
95 /**#@-*/
96
97 /**#@+
98 * @access private
99 * @see Crypt_Twofish::Crypt_Twofish()
100 */
101 /**
102 * Toggles the internal implementation
103 */
104 define('CRYPT_TWOFISH_MODE_INTERNAL', 1);
105 /**
106 * Toggles the mcrypt implementation
107 */
108 define('CRYPT_TWOFISH_MODE_MCRYPT', 2);
109 /**#@-*/
110
111 /**
112 * Pure-PHP implementation of Twofish.
113 *
114 * @author Jim Wigginton <terrafrost@php.net>
115 * @author Hans-Juergen Petrich <petrich@tronic-media.com>
116 * @version 1.0
117 * @access public
118 * @package Crypt_Twofish
119 */
120 class Crypt_Twofish {
121 /**
122 * The Key as String
123 *
124 * @see Crypt_Twofish::setKey()
125 * @var Array
126 * @access private
127 */
128 var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
129
130 /**
131 * The Encryption Mode
132 *
133 * @see Crypt_Twofish::Crypt_Twofish()
134 * @var Integer
135 * @access private
136 */
137 var $mode;
138
139 /**
140 * Continuous Buffer status
141 *
142 * @see Crypt_Twofish::enableContinuousBuffer()
143 * @var Boolean
144 * @access private
145 */
146 var $continuousBuffer = false;
147
148 /**
149 * Padding status
150 *
151 * @see Crypt_Twofish::enablePadding()
152 * @var Boolean
153 * @access private
154 */
155 var $padding = true;
156
157 /**
158 * The Initialization Vector
159 *
160 * @see Crypt_Twofish::setIV()
161 * @var String
162 * @access private
163 */
164 var $iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
165
166 /**
167 * A "sliding" Initialization Vector
168 *
169 * @see Crypt_Twofish::enableContinuousBuffer()
170 * @var String
171 * @access private
172 */
173 var $encryptIV = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
174
175 /**
176 * A "sliding" Initialization Vector
177 *
178 * @see Crypt_Twofish::enableContinuousBuffer()
179 * @var String
180 * @access private
181 */
182 var $decryptIV = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
183
184 /**
185 * mcrypt resource for encryption
186 *
187 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
188 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
189 *
190 * @see Crypt_Twofish::encrypt()
191 * @var String
192 * @access private
193 */
194 var $enmcrypt;
195
196 /**
197 * mcrypt resource for decryption
198 *
199 * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
200 * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
201 *
202 * @see Crypt_Twofish::decrypt()
203 * @var String
204 * @access private
205 */
206 var $demcrypt;
207
208 /**
209 * Does the enmcrypt resource need to be (re)initialized?
210 *
211 * @see Crypt_Twofish::setKey()
212 * @see Crypt_Twofish::setIV()
213 * @var Boolean
214 * @access private
215 */
216 var $enchanged = true;
217
218 /**
219 * Does the demcrypt resource need to be (re)initialized?
220 *
221 * @see Crypt_Twofish::setKey()
222 * @see Crypt_Twofish::setIV()
223 * @var Boolean
224 * @access private
225 */
226 var $dechanged = true;
227
228 /**
229 * Is the mode one that is paddable?
230 *
231 * @see Crypt_Twofish::Crypt_Twofish()
232 * @var Boolean
233 * @access private
234 */
235 var $paddable = false;
236
237 /**
238 * Encryption buffer for CTR, OFB and CFB modes
239 *
240 * @see Crypt_Twofish::encrypt()
241 * @var Array
242 * @access private
243 */
244 var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
245
246 /**
247 * Decryption buffer for CTR, OFB and CFB modes
248 *
249 * @see Crypt_Twofish::decrypt()
250 * @var Array
251 * @access private
252 */
253 var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
254
255 /**
256 * mcrypt resource for CFB mode
257 *
258 * @see Crypt_Twofish::encrypt()
259 * @see Crypt_Twofish::decrypt()
260 * @var String
261 * @access private
262 */
263 var $ecb;
264
265 /**
266 * Performance-optimized callback function for en/decrypt()
267 *
268 * @var Callback
269 * @access private
270 */
271 var $inline_crypt;
272
273 /**
274 * Q-Table
275 *
276 * @var Array
277 * @access private
278 */
279 var $q0 = array (
280 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
281 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
282 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
283 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
284 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
285 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
286 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
287 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
288 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
289 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
290 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
291 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
292 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
293 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
294 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
295 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
296 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
297 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
298 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
299 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
300 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
301 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
302 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
303 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
304 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
305 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
306 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
307 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
308 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
309 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
310 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
311 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
312 );
313
314 /**
315 * Q-Table
316 *
317 * @var Array
318 * @access private
319 */
320 var $q1 = array (
321 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
322 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
323 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
324 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
325 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
326 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
327 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
328 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
329 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
330 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
331 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
332 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
333 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
334 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
335 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
336 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
337 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
338 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
339 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
340 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
341 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
342 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
343 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
344 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
345 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
346 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
347 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
348 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
349 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
350 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
351 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
352 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
353 );
354
355 /**
356 * M-Table
357 *
358 * @var Array
359 * @access private
360 */
361 var $m0 = array (
362 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
363 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
364 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
365 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
366 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
367 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
368 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
369 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
370 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
371 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
372 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
373 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
374 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
375 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
376 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
377 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
378 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
379 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
380 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
381 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
382 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
383 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
384 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
385 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
386 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
387 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
388 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
389 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
390 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
391 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
392 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
393 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
394 );
395
396 /**
397 * M-Table
398 *
399 * @var Array
400 * @access private
401 */
402 var $m1 = array (
403 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
404 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
405 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
406 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
407 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
408 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
409 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
410 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
411 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
412 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
413 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
414 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
415 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
416 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
417 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
418 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
419 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
420 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
421 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
422 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
423 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
424 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
425 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
426 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
427 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
428 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
429 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
430 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
431 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
432 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
433 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
434 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
435 );
436
437 /**
438 * M-Table
439 *
440 * @var Array
441 * @access private
442 */
443 var $m2 = array (
444 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
445 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
446 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
447 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
448 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
449 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
450 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
451 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
452 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
453 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
454 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
455 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
456 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
457 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
458 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
459 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
460 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
461 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
462 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
463 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
464 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
465 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
466 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
467 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
468 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
469 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
470 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
471 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
472 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
473 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
474 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
475 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
476 );
477
478 /**
479 * M-Table
480 *
481 * @var Array
482 * @access private
483 */
484 var $m3 = array (
485 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
486 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
487 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
488 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
489 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
490 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
491 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
492 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
493 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
494 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
495 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
496 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
497 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
498 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
499 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
500 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
501 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
502 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
503 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
504 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
505 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
506 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
507 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
508 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
509 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
510 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
511 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
512 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
513 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
514 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
515 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
516 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
517 );
518
519 /**
520 * The Key Schedule Array
521 *
522 * @var Array
523 * @access private
524 */
525 var $K = array();
526
527 /**
528 * The Key depended S-Table 0
529 *
530 * @var Array
531 * @access private
532 */
533 var $S0 = array();
534
535 /**
536 * The Key depended S-Table 1
537 *
538 * @var Array
539 * @access private
540 */
541 var $S1 = array();
542
543 /**
544 * The Key depended S-Table 2
545 *
546 * @var Array
547 * @access private
548 */
549 var $S2 = array();
550
551 /**
552 * The Key depended S-Table 3
553 *
554 * @var Array
555 * @access private
556 */
557 var $S3 = array();
558
559 /**
560 * Default Constructor.
561 *
562 * Determines whether or not the mcrypt extension should be used.
563 * If not explictly set, CRYPT_TWOFISH_MODE_CBC will be used.
564 *
565 * @param optional Integer $mode
566 * @access public
567 */
568 function Crypt_Twofish($mode = CRYPT_TWOFISH_MODE_CBC)
569 {
570 if ( !defined('CRYPT_TWOFISH_MODE') ) {
571 switch (true) {
572 case extension_loaded('mcrypt') && in_array('twofish', mcrypt_list_algorithms()):
573 define('CRYPT_TWOFISH_MODE', CRYPT_TWOFISH_MODE_MCRYPT);
574 break;
575 default:
576 define('CRYPT_TWOFISH_MODE', CRYPT_TWOFISH_MODE_INTERNAL);
577 }
578 }
579
580 switch ( CRYPT_TWOFISH_MODE ) {
581 case CRYPT_TWOFISH_MODE_MCRYPT:
582 switch ($mode) {
583 case CRYPT_TWOFISH_MODE_ECB:
584 $this->paddable = true;
585 $this->mode = MCRYPT_MODE_ECB;
586 break;
587 case CRYPT_TWOFISH_MODE_CTR:
588 $this->mode = 'ctr';
589 break;
590 case CRYPT_TWOFISH_MODE_CFB:
591 $this->mode = 'ncfb';
592 $this->ecb = mcrypt_module_open(MCRYPT_TWOFISH, '', MCRYPT_MODE_ECB, '');
593 break;
594 case CRYPT_TWOFISH_MODE_OFB:
595 $this->mode = MCRYPT_MODE_NOFB;
596 break;
597 case CRYPT_TWOFISH_MODE_CBC:
598 default:
599 $this->paddable = true;
600 $this->mode = MCRYPT_MODE_CBC;
601 }
602 $this->enmcrypt = mcrypt_module_open(MCRYPT_TWOFISH, '', $this->mode, '');
603 $this->demcrypt = mcrypt_module_open(MCRYPT_TWOFISH, '', $this->mode, '');
604
605 break;
606 default:
607 switch ($mode) {
608 case CRYPT_TWOFISH_MODE_ECB:
609 case CRYPT_TWOFISH_MODE_CBC:
610 $this->paddable = true;
611 $this->mode = $mode;
612 break;
613 case CRYPT_TWOFISH_MODE_CTR:
614 case CRYPT_TWOFISH_MODE_CFB:
615 case CRYPT_TWOFISH_MODE_OFB:
616 $this->mode = $mode;
617 break;
618 default:
619 $this->paddable = true;
620 $this->mode = CRYPT_TWOFISH_MODE_CBC;
621 }
622 $this->inline_crypt_setup();
623 }
624 }
625
626 /**
627 * Sets the key.
628 *
629 * Keys can be of any length. Twofish, itself, requires the use of a key that's 128, 192 or 256-bits long.
630 * If the key is less than 256-bits we round the length up to the closest valid key length,
631 * padding $key with null bytes. If the key is more than 256-bits, we trim the excess bits.
632 *
633 * If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
634 *
635 * @access public
636 * @param String $key
637 */
638 function setKey($key)
639 {
640 $keylength = strlen($key);
641 switch (true) {
642 case $keylength <= 16:
643 $key.= str_repeat("\0", 16 - $keylength);
644 break;
645 case $keylength <= 24:
646 $key.= str_repeat("\0", 24 - $keylength);
647 break;
648 case $keylength <= 32:
649 $key.= str_repeat("\0", 32 - $keylength);
650 break;
651 default:
652 $key = substr($key, 0, 32);
653 }
654 $this->key = $key;
655
656 $this->enchanged = true;
657 $this->dechanged = true;
658
659 if (CRYPT_TWOFISH_MODE == CRYPT_TWOFISH_MODE_MCRYPT) {
660 return;
661 }
662
663 /* Key expanding and generating the key-depended s-boxes */
664 $le_longs = unpack('V*', $key);
665 $key = unpack('C*', $key);
666 $m0 = $this->m0;
667 $m1 = $this->m1;
668 $m2 = $this->m2;
669 $m3 = $this->m3;
670 $q0 = $this->q0;
671 $q1 = $this->q1;
672
673 $K = $S0 = $S1 = $S2 = $S3 = array();
674
675 switch (strlen($this->key)) {
676 case 16:
677 list ($s7, $s6, $s5, $s4) = $this->mds_rem($le_longs[1], $le_longs[2]);
678 list ($s3, $s2, $s1, $s0) = $this->mds_rem($le_longs[3], $le_longs[4]);
679 for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
680 $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
681 $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
682 $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
683 $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
684 $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
685 $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
686 $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
687 $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
688 $B = ($B << 8) | ($B >> 24 & 0xff);
689 $K[] = $A+= $B;
690 $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
691 }
692 for ($i = 0; $i < 256; ++$i) {
693 $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
694 $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
695 $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
696 $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
697 }
698 break;
699 case 24:
700 list ($sb, $sa, $s9, $s8) = $this->mds_rem($le_longs[1], $le_longs[2]);
701 list ($s7, $s6, $s5, $s4) = $this->mds_rem($le_longs[3], $le_longs[4]);
702 list ($s3, $s2, $s1, $s0) = $this->mds_rem($le_longs[5], $le_longs[6]);
703 for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
704 $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
705 $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
706 $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
707 $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
708 $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
709 $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
710 $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
711 $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
712 $B = ($B << 8) | ($B >> 24 & 0xff);
713 $K[] = $A+= $B;
714 $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
715 }
716 for ($i = 0; $i < 256; ++$i) {
717 $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
718 $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
719 $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
720 $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
721 }
722 break;
723 default: // 32
724 list ($sf, $se, $sd, $sc) = $this->mds_rem($le_longs[1], $le_longs[2]);
725 list ($sb, $sa, $s9, $s8) = $this->mds_rem($le_longs[3], $le_longs[4]);
726 list ($s7, $s6, $s5, $s4) = $this->mds_rem($le_longs[5], $le_longs[6]);
727 list ($s3, $s2, $s1, $s0) = $this->mds_rem($le_longs[7], $le_longs[8]);
728 for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
729 $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
730 $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
731 $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
732 $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
733 $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
734 $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
735 $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
736 $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
737 $B = ($B << 8) | ($B >> 24 & 0xff);
738 $K[] = $A+= $B;
739 $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
740 }
741 for ($i = 0; $i < 256; ++$i) {
742 $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
743 $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
744 $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
745 $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
746 }
747 }
748
749 $this->K = $K;
750 $this->S0 = $S0;
751 $this->S1 = $S1;
752 $this->S2 = $S2;
753 $this->S3 = $S3;
754 }
755
756 /**
757 * Sets the password.
758 *
759 * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
760 * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
761 * $hash, $salt, $count
762 *
763 * @param String $password
764 * @param optional String $method
765 * @access public
766 */
767 function setPassword($password, $method = 'pbkdf2')
768 {
769 $key = '';
770
771 switch ($method) {
772 default: // 'pbkdf2'
773 list(, , $hash, $salt, $count) = func_get_args();
774 if (!isset($hash)) {
775 $hash = 'sha1';
776 }
777 // WPA and WPA2 use the SSID as the salt
778 if (!isset($salt)) {
779 $salt = 'phpseclib/salt';
780 }
781 // RFC2898#section-4.2 uses 1,000 iterations by default
782 // WPA and WPA2 use 4,096.
783 if (!isset($count)) {
784 $count = 1000;
785 }
786
787 if (!class_exists('Crypt_Hash')) {
788 require_once('Crypt/Hash.php');
789 }
790
791 $i = 1;
792 while (strlen($key) < 32) {
793 $hmac = new Crypt_Hash();
794 $hmac->setHash($hash);
795 $hmac->setKey($password);
796 $f = $u = $hmac->hash($salt . pack('N', $i++));
797 for ($j = 2; $j <= $count; ++$j) {
798 $u = $hmac->hash($u);
799 $f^= $u;
800 }
801 $key.= $f;
802 }
803 }
804
805 $this->setKey($key);
806 }
807
808 /**
809 * Sets the initialization vector. (optional)
810 *
811 * SetIV is not required when CRYPT_TWOFISH_MODE_ECB is being used. If not explictly set, it'll be assumed
812 * to be all null bytes.
813 *
814 * @access public
815 * @param String $iv
816 */
817 function setIV($iv)
818 {
819 $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 16), 16, chr(0));
820 $this->enchanged = true;
821 $this->dechanged = true;
822 }
823
824 /**
825 * Encrypts a message.
826 *
827 * $plaintext will be padded with up to 16 additional bytes. Other Twofish implementations may or may not pad in the
828 * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
829 * URL:
830 *
831 * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
832 *
833 * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
834 * strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
835 * length.
836 *
837 * @see Crypt_Twofish::decrypt()
838 * @access public
839 * @param String $plaintext
840 */
841 function encrypt($plaintext)
842 {
843 if ( CRYPT_TWOFISH_MODE == CRYPT_TWOFISH_MODE_MCRYPT ) {
844 if ($this->paddable) {
845 $plaintext = $this->_pad($plaintext);
846 }
847
848 if ($this->enchanged) {
849 mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
850 if ($this->mode == 'ncfb') {
851 mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
852 }
853 $this->enchanged = false;
854 }
855
856 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
857 $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
858 } else {
859 $iv = &$this->encryptIV;
860 $pos = &$this->enbuffer['pos'];
861 $len = strlen($plaintext);
862 $ciphertext = '';
863 $i = 0;
864 if ($pos) {
865 $orig_pos = $pos;
866 $max = 16 - $pos;
867 if ($len >= $max) {
868 $i = $max;
869 $len-= $max;
870 $pos = 0;
871 } else {
872 $i = $len;
873 $pos+= $len;
874 $len = 0;
875 }
876 $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
877 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
878 $this->enbuffer['enmcrypt_init'] = true;
879 }
880 if ($len >= 16) {
881 if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {
882 if ($this->enbuffer['enmcrypt_init'] === true) {
883 mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
884 $this->enbuffer['enmcrypt_init'] = false;
885 }
886 $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 16));
887 $iv = substr($ciphertext, -16);
888 $len%= 16;
889 } else {
890 while ($len >= 16) {
891 $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 16);
892 $ciphertext.= $iv;
893 $len-= 16;
894 $i+= 16;
895 }
896 }
897 }
898 if ($len) {
899 $iv = mcrypt_generic($this->ecb, $iv);
900 $block = $iv ^ substr($plaintext, -$len);
901 $iv = substr_replace($iv, $block, 0, $len);
902 $ciphertext.= $block;
903 $pos = $len;
904 }
905 return $ciphertext;
906 }
907
908 if (!$this->continuousBuffer) {
909 mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
910 }
911
912 return $ciphertext;
913 }
914
915 if (empty($this->K)) {
916 $this->setKey($this->key);
917 }
918
919 $inline = $this->inline_crypt;
920 return $inline('encrypt', $this, $plaintext);
921 }
922
923 /**
924 * Decrypts a message.
925 *
926 * If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
927 *
928 * @see Crypt_Twofish::encrypt()
929 * @access public
930 * @param String $ciphertext
931 */
932 function decrypt($ciphertext)
933 {
934 if ( CRYPT_TWOFISH_MODE == CRYPT_TWOFISH_MODE_MCRYPT ) {
935 if ($this->paddable) {
936 // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
937 // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
938 $ciphertext = str_pad($ciphertext, strlen($ciphertext) + (16 - strlen($ciphertext) % 16) % 16, chr(0));
939 }
940
941 if ($this->dechanged) {
942 mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
943 if ($this->mode == 'ncfb') {
944 mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
945 }
946 $this->dechanged = false;
947 }
948
949 if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
950 $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
951 } else {
952 $iv = &$this->decryptIV;
953 $pos = &$this->debuffer['pos'];
954 $len = strlen($ciphertext);
955 $plaintext = '';
956 $i = 0;
957 if ($pos) {
958 $orig_pos = $pos;
959 $max = 16 - $pos;
960 if ($len >= $max) {
961 $i = $max;
962 $len-= $max;
963 $pos = 0;
964 } else {
965 $i = $len;
966 $pos+= $len;
967 $len = 0;
968 }
969 $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
970 $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
971 }
972 if ($len >= 16) {
973 $cb = substr($ciphertext, $i, $len - $len % 16);
974 $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
975 $iv = substr($cb, -16);
976 $len%= 16;
977 }
978 if ($len) {
979 $iv = mcrypt_generic($this->ecb, $iv);
980 $plaintext.= $iv ^ substr($ciphertext, -$len);
981 $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
982 $pos = $len;
983 }
984 return $plaintext;
985 }
986
987 if (!$this->continuousBuffer) {
988 mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
989 }
990
991 return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
992 }
993
994 if (empty($this->K)) {
995 $this->setKey($this->key);
996 }
997
998 $inline = $this->inline_crypt;
999 return $inline('decrypt', $this, $ciphertext);
1000 }
1001
1002 /**
1003 * Treat consecutive "packets" as if they are a continuous buffer.
1004 *
1005 * @see Crypt_Twofish::disableContinuousBuffer()
1006 * @access public
1007 */
1008 function enableContinuousBuffer()
1009 {
1010 $this->continuousBuffer = true;
1011 }
1012
1013 /**
1014 * Treat consecutive packets as if they are a discontinuous buffer.
1015 *
1016 * The default behavior.
1017 *
1018 * @see Crypt_Twofish::enableContinuousBuffer()
1019 * @access public
1020 */
1021 function disableContinuousBuffer()
1022 {
1023 $this->continuousBuffer = false;
1024 $this->encryptIV = $this->iv;
1025 $this->decryptIV = $this->iv;
1026 $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
1027 $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
1028
1029 if (CRYPT_TWOFISH_MODE == CRYPT_TWOFISH_MODE_MCRYPT) {
1030 mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
1031 mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
1032 }
1033 }
1034
1035 /**
1036 * Pad "packets".
1037 *
1038 * Twofish works by encrypting 16 bytes at a time. If you ever need to encrypt or decrypt something that's not
1039 * a multiple of 16, it becomes necessary to pad the input so that it's length is a multiple of eight.
1040 *
1041 * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
1042 * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
1043 * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
1044 * transmitted separately)
1045 *
1046 * @see Crypt_Twofish::disablePadding()
1047 * @access public
1048 */
1049 function enablePadding()
1050 {
1051 $this->padding = true;
1052 }
1053
1054 /**
1055 * Do not pad packets.
1056 *
1057 * @see Crypt_Twofish::enablePadding()
1058 * @access public
1059 */
1060 function disablePadding()
1061 {
1062 $this->padding = false;
1063 }
1064
1065 /**
1066 * Pads a string
1067 *
1068 * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (16).
1069 *
1070 * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
1071 * and padding will, hence forth, be enabled.
1072 *
1073 * @see Crypt_Twofish::_unpad()
1074 * @access private
1075 */
1076 function _pad($text)
1077 {
1078 $length = strlen($text);
1079
1080 if (!$this->padding) {
1081 if ($length % 16 == 0) {
1082 return $text;
1083 } else {
1084 user_error("The plaintext's length ($length) is not a multiple of the block size (16)");
1085 $this->padding = true;
1086 }
1087 }
1088
1089 $pad = 16 - ($length % 16);
1090
1091 return str_pad($text, $length + $pad, chr($pad));
1092 }
1093
1094 /**
1095 * Unpads a string
1096 *
1097 * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
1098 * and false will be returned.
1099 *
1100 * @see Crypt_Twofish::_pad()
1101 * @access private
1102 */
1103 function _unpad($text)
1104 {
1105 if (!$this->padding) {
1106 return $text;
1107 }
1108
1109 $length = ord($text[strlen($text) - 1]);
1110
1111 if (!$length || $length > 16) {
1112 return false;
1113 }
1114
1115 return substr($text, 0, -$length);
1116 }
1117
1118 /**
1119 * String Shift
1120 *
1121 * Inspired by array_shift
1122 *
1123 * @param String $string
1124 * @return String
1125 * @access private
1126 */
1127 function _string_shift(&$string)
1128 {
1129 $substr = substr($string, 0, 16);
1130 $string = substr($string, 16);
1131 return $substr;
1132 }
1133
1134 /**
1135 * Generate CTR XOR encryption key
1136 *
1137 * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
1138 * plaintext / ciphertext in CTR mode.
1139 *
1140 * @see Crypt_Twofish::decrypt()
1141 * @see Crypt_Twofish::encrypt()
1142 * @access public
1143 * @param String $iv
1144 */
1145 function _generate_xor(&$iv)
1146 {
1147 $xor = $iv;
1148 for ($j = 4; $j <= 16; $j+=4) {
1149 $temp = substr($iv, -$j, 4);
1150 switch ($temp) {
1151 case "\xFF\xFF\xFF\xFF":
1152 $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
1153 break;
1154 case "\x7F\xFF\xFF\xFF":
1155 $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
1156 break 2;
1157 default:
1158 extract(unpack('Ncount', $temp));
1159 $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
1160 break 2;
1161 }
1162 }
1163
1164 return $xor;
1165 }
1166
1167 /**
1168 * mds_rem function using by the twofish cipher algorithm
1169 *
1170 * @access private
1171 * @param String $A
1172 * @param String $B
1173 * @return Array
1174 */
1175 function mds_rem($A, $B)
1176 {
1177 // No gain by unrolling this loop.
1178 for ($i = 0; $i < 8; ++$i) {
1179 // Get most significant coefficient.
1180 $t = 0xff & ($B >> 24);
1181
1182 // Shift the others up.
1183 $B = ($B << 8) | (0xff & ($A >> 24));
1184 $A<<= 8;
1185
1186 $u = $t << 1;
1187
1188 // Subtract the modular polynomial on overflow.
1189 if ($t & 0x80) {
1190 $u^= 0x14d;
1191 }
1192
1193 // Remove t * (a * x^2 + 1).
1194 $B ^= $t ^ ($u << 16);
1195
1196 // Form u = a*t + t/a = t*(a + 1/a).
1197 $u^= 0x7fffffff & ($t >> 1);
1198
1199 // Add the modular polynomial on underflow.
1200 if ($t & 0x01) $u^= 0xa6 ;
1201
1202 // Remove t * (a + 1/a) * (x^3 + x).
1203 $B^= ($u << 24) | ($u << 8);
1204 }
1205
1206 return array(
1207 0xff & $B >> 24,
1208 0xff & $B >> 16,
1209 0xff & $B >> 8,
1210 0xff & $B);
1211 }
1212
1213 /**
1214 * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
1215 *
1216 * @access private
1217 */
1218 function inline_crypt_setup()
1219 {
1220 $lambda_functions =& Crypt_Twofish::get_lambda_functions();
1221 $block_size = 16;
1222 $mode = $this->mode;
1223 $code_hash = "$mode";
1224
1225 if (!isset($lambda_functions[$code_hash])) {
1226 $init_cryptBlock = '
1227 $S0 = $self->S0;
1228 $S1 = $self->S1;
1229 $S2 = $self->S2;
1230 $S3 = $self->S3;
1231 extract($self->K, EXTR_PREFIX_ALL, "K");
1232 ';
1233
1234 // Generating encrypt code:
1235 $_encryptBlock = '
1236 $in = unpack("V4", $in);
1237 $R0 = $K_0 ^ $in[1];
1238 $R1 = $K_1 ^ $in[2];
1239 $R2 = $K_2 ^ $in[3];
1240 $R3 = $K_3 ^ $in[4];
1241 ';
1242 for ($ki = 7, $i = 0; $i < 8; ++$i) {
1243 $_encryptBlock.= '
1244 $t0 = $S0[ $R0 & 0xff] ^
1245 $S1[($R0 >> 8) & 0xff] ^
1246 $S2[($R0 >> 16) & 0xff] ^
1247 $S3[($R0 >> 24) & 0xff];
1248 $t1 = $S0[($R1 >> 24) & 0xff] ^
1249 $S1[ $R1 & 0xff] ^
1250 $S2[($R1 >> 8) & 0xff] ^
1251 $S3[($R1 >> 16) & 0xff];
1252 $R2^= ($t0 + $t1 + $K_'.(++$ki).');
1253 $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
1254 $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K_'.(++$ki).');
1255
1256 $t0 = $S0[ $R2 & 0xff] ^
1257 $S1[($R2 >> 8) & 0xff] ^
1258 $S2[($R2 >> 16) & 0xff] ^
1259 $S3[($R2 >> 24) & 0xff];
1260 $t1 = $S0[($R3 >> 24) & 0xff] ^
1261 $S1[ $R3 & 0xff] ^
1262 $S2[($R3 >> 8) & 0xff] ^
1263 $S3[($R3 >> 16) & 0xff];
1264 $R0^= ($t0 + $t1 + $K_'.(++$ki).');
1265 $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
1266 $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K_'.(++$ki).');
1267 ';
1268 }
1269 $_encryptBlock.= '
1270 $in = pack("V4", $K_4 ^ $R2,
1271 $K_5 ^ $R3,
1272 $K_6 ^ $R0,
1273 $K_7 ^ $R1);
1274 ';
1275
1276 // Generating decrypt code:
1277 $_decryptBlock = '
1278 $in = unpack("V4", $in);
1279 $R0 = $K_4 ^ $in[1];
1280 $R1 = $K_5 ^ $in[2];
1281 $R2 = $K_6 ^ $in[3];
1282 $R3 = $K_7 ^ $in[4];
1283 ';
1284 for ($ki = 40, $i = 0; $i < 8; ++$i) {
1285 $_decryptBlock.= '
1286 $t0 = $S0[$R0 & 0xff] ^
1287 $S1[$R0 >> 8 & 0xff] ^
1288 $S2[$R0 >> 16 & 0xff] ^
1289 $S3[$R0 >> 24 & 0xff];
1290 $t1 = $S0[$R1 >> 24 & 0xff] ^
1291 $S1[$R1 & 0xff] ^
1292 $S2[$R1 >> 8 & 0xff] ^
1293 $S3[$R1 >> 16 & 0xff];
1294 $R3^= $t0 + ($t1 << 1) + $K_'.(--$ki).';
1295 $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
1296 $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K_'.(--$ki).');
1297
1298 $t0 = $S0[$R2 & 0xff] ^
1299 $S1[$R2 >> 8 & 0xff] ^
1300 $S2[$R2 >> 16 & 0xff] ^
1301 $S3[$R2 >> 24 & 0xff];
1302 $t1 = $S0[$R3 >> 24 & 0xff] ^
1303 $S1[$R3 & 0xff] ^
1304 $S2[$R3 >> 8 & 0xff] ^
1305 $S3[$R3 >> 16 & 0xff];
1306 $R1^= $t0 + ($t1 << 1) + $K_'.(--$ki).';
1307 $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
1308 $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K_'.(--$ki).');
1309 ';
1310 }
1311 $_decryptBlock.= '
1312 $in = pack("V4", $K_0 ^ $R2,
1313 $K_1 ^ $R3,
1314 $K_2 ^ $R0,
1315 $K_3 ^ $R1);
1316 ';
1317
1318 // Generating mode of operation code:
1319 switch ($mode) {
1320 case CRYPT_TWOFISH_MODE_ECB:
1321 $encrypt = '
1322 $ciphertext = "";
1323 $text = $self->_pad($text);
1324 $plaintext_len = strlen($text);
1325
1326 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1327 $in = substr($text, $i, '.$block_size.');
1328 '.$_encryptBlock.'
1329 $ciphertext.= $in;
1330 }
1331
1332 return $ciphertext;
1333 ';
1334
1335 $decrypt = '
1336 $plaintext = "";
1337 $text = str_pad($text, strlen($text) + ('.$block_size.' - strlen($text) % '.$block_size.') % '.$block_size.', chr(0));
1338 $ciphertext_len = strlen($text);
1339
1340 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1341 $in = substr($text, $i, '.$block_size.');
1342 '.$_decryptBlock.'
1343 $plaintext.= $in;
1344 }
1345
1346 return $self->_unpad($plaintext);
1347 ';
1348 break;
1349 case CRYPT_TWOFISH_MODE_CBC:
1350 $encrypt = '
1351 $ciphertext = "";
1352 $text = $self->_pad($text);
1353 $plaintext_len = strlen($text);
1354
1355 $in = $self->encryptIV;
1356
1357 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1358 $in = substr($text, $i, '.$block_size.') ^ $in;
1359 '.$_encryptBlock.'
1360 $ciphertext.= $in;
1361 }
1362
1363 if ($self->continuousBuffer) {
1364 $self->encryptIV = $in;
1365 }
1366
1367 return $ciphertext;
1368 ';
1369
1370 $decrypt = '
1371 $plaintext = "";
1372 $text = str_pad($text, strlen($text) + ('.$block_size.' - strlen($text) % '.$block_size.') % '.$block_size.', chr(0));
1373 $ciphertext_len = strlen($text);
1374
1375 $iv = $self->decryptIV;
1376
1377 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1378 $in = $block = substr($text, $i, '.$block_size.');
1379 '.$_decryptBlock.'
1380 $plaintext.= $in ^ $iv;
1381 $iv = $block;
1382 }
1383
1384 if ($self->continuousBuffer) {
1385 $self->decryptIV = $iv;
1386 }
1387
1388 return $self->_unpad($plaintext);
1389 ';
1390 break;
1391 case CRYPT_TWOFISH_MODE_CTR:
1392 $encrypt = '
1393 $ciphertext = "";
1394 $plaintext_len = strlen($text);
1395 $xor = $self->encryptIV;
1396 $buffer = &$self->enbuffer;
1397
1398 if (strlen($buffer["encrypted"])) {
1399 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1400 $block = substr($text, $i, '.$block_size.');
1401 if (strlen($block) > strlen($buffer["encrypted"])) {
1402 $in = $self->_generate_xor($xor);
1403 '.$_encryptBlock.'
1404 $buffer["encrypted"].= $in;
1405 }
1406 $key = $self->_string_shift($buffer["encrypted"]);
1407 $ciphertext.= $block ^ $key;
1408 }
1409 } else {
1410 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1411 $block = substr($text, $i, '.$block_size.');
1412 $in = $self->_generate_xor($xor);
1413 '.$_encryptBlock.'
1414 $key = $in;
1415 $ciphertext.= $block ^ $key;
1416 }
1417 }
1418 if ($self->continuousBuffer) {
1419 $self->encryptIV = $xor;
1420 if ($start = $plaintext_len % '.$block_size.') {
1421 $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];
1422 }
1423 }
1424
1425 return $ciphertext;
1426 ';
1427
1428 $decrypt = '
1429 $plaintext = "";
1430 $ciphertext_len = strlen($text);
1431 $xor = $self->decryptIV;
1432 $buffer = &$self->debuffer;
1433
1434 if (strlen($buffer["ciphertext"])) {
1435 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1436 $block = substr($text, $i, '.$block_size.');
1437 if (strlen($block) > strlen($buffer["ciphertext"])) {
1438 $in = $self->_generate_xor($xor);
1439 '.$_encryptBlock.'
1440 $buffer["ciphertext"].= $in;
1441 }
1442 $key = $self->_string_shift($buffer["ciphertext"]);
1443 $plaintext.= $block ^ $key;
1444 }
1445 } else {
1446 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1447 $block = substr($text, $i, '.$block_size.');
1448 $in = $self->_generate_xor($xor);
1449 '.$_encryptBlock.'
1450 $key = $in;
1451 $plaintext.= $block ^ $key;
1452 }
1453 }
1454 if ($self->continuousBuffer) {
1455 $self->decryptIV = $xor;
1456 if ($start = $ciphertext_len % '.$block_size.') {
1457 $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];
1458 }
1459 }
1460
1461 return $plaintext;
1462 ';
1463 break;
1464 case CRYPT_TWOFISH_MODE_CFB:
1465 $encrypt = '
1466 $ciphertext = "";
1467 $buffer = &$self->enbuffer;
1468
1469 if ($self->continuousBuffer) {
1470 $iv = &$self->encryptIV;
1471 $pos = &$buffer["pos"];
1472 } else {
1473 $iv = $self->encryptIV;
1474 $pos = 0;
1475 }
1476 $len = strlen($text);
1477 $i = 0;
1478 if ($pos) {
1479 $orig_pos = $pos;
1480 $max = '.$block_size.' - $pos;
1481 if ($len >= $max) {
1482 $i = $max;
1483 $len-= $max;
1484 $pos = 0;
1485 } else {
1486 $i = $len;
1487 $pos+= $len;
1488 $len = 0;
1489 }
1490 $ciphertext = substr($iv, $orig_pos) ^ $text;
1491 $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
1492 }
1493 while ($len >= '.$block_size.') {
1494 $in = $iv;
1495 '.$_encryptBlock.';
1496 $iv = $in ^ substr($text, $i, '.$block_size.');
1497 $ciphertext.= $iv;
1498 $len-= '.$block_size.';
1499 $i+= '.$block_size.';
1500 }
1501 if ($len) {
1502 $in = $iv;
1503 '.$_encryptBlock.'
1504 $iv = $in;
1505 $block = $iv ^ substr($text, $i);
1506 $iv = substr_replace($iv, $block, 0, $len);
1507 $ciphertext.= $block;
1508 $pos = $len;
1509 }
1510 return $ciphertext;
1511 ';
1512
1513 $decrypt = '
1514 $plaintext = "";
1515 $buffer = &$self->debuffer;
1516
1517 if ($self->continuousBuffer) {
1518 $iv = &$self->decryptIV;
1519 $pos = &$buffer["pos"];
1520 } else {
1521 $iv = $self->decryptIV;
1522 $pos = 0;
1523 }
1524 $len = strlen($text);
1525 $i = 0;
1526 if ($pos) {
1527 $orig_pos = $pos;
1528 $max = '.$block_size.' - $pos;
1529 if ($len >= $max) {
1530 $i = $max;
1531 $len-= $max;
1532 $pos = 0;
1533 } else {
1534 $i = $len;
1535 $pos+= $len;
1536 $len = 0;
1537 }
1538 $plaintext = substr($iv, $orig_pos) ^ $text;
1539 $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);
1540 }
1541 while ($len >= '.$block_size.') {
1542 $in = $iv;
1543 '.$_encryptBlock.'
1544 $iv = $in;
1545 $cb = substr($text, $i, '.$block_size.');
1546 $plaintext.= $iv ^ $cb;
1547 $iv = $cb;
1548 $len-= '.$block_size.';
1549 $i+= '.$block_size.';
1550 }
1551 if ($len) {
1552 $in = $iv;
1553 '.$_encryptBlock.'
1554 $iv = $in;
1555 $plaintext.= $iv ^ substr($text, $i);
1556 $iv = substr_replace($iv, substr($text, $i), 0, $len);
1557 $pos = $len;
1558 }
1559
1560 return $plaintext;
1561 ';
1562 break;
1563 case CRYPT_TWOFISH_MODE_OFB:
1564 $encrypt = '
1565 $ciphertext = "";
1566 $plaintext_len = strlen($text);
1567 $xor = $self->encryptIV;
1568 $buffer = &$self->enbuffer;
1569
1570 if (strlen($buffer["xor"])) {
1571 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1572 $block = substr($text, $i, '.$block_size.');
1573 if (strlen($block) > strlen($buffer["xor"])) {
1574 $in = $xor;
1575 '.$_encryptBlock.'
1576 $xor = $in;
1577 $buffer["xor"].= $xor;
1578 }
1579 $key = $self->_string_shift($buffer["xor"]);
1580 $ciphertext.= $block ^ $key;
1581 }
1582 } else {
1583 for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1584 $in = $xor;
1585 '.$_encryptBlock.'
1586 $xor = $in;
1587 $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor;
1588 }
1589 $key = $xor;
1590 }
1591 if ($self->continuousBuffer) {
1592 $self->encryptIV = $xor;
1593 if ($start = $plaintext_len % '.$block_size.') {
1594 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
1595 }
1596 }
1597 return $ciphertext;
1598 ';
1599
1600 $decrypt = '
1601 $plaintext = "";
1602 $ciphertext_len = strlen($text);
1603 $xor = $self->decryptIV;
1604 $buffer = &$self->debuffer;
1605
1606 if (strlen($buffer["xor"])) {
1607 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1608 $block = substr($text, $i, '.$block_size.');
1609 if (strlen($block) > strlen($buffer["xor"])) {
1610 $in = $xor;
1611 '.$_encryptBlock.'
1612 $xor = $in;
1613 $buffer["xor"].= $xor;
1614 }
1615 $key = $self->_string_shift($buffer["xor"]);
1616 $plaintext.= $block ^ $key;
1617 }
1618 } else {
1619 for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1620 $in = $xor;
1621 '.$_encryptBlock.'
1622 $xor = $in;
1623 $plaintext.= substr($text, $i, '.$block_size.') ^ $xor;
1624 }
1625 $key = $xor;
1626 }
1627 if ($self->continuousBuffer) {
1628 $self->decryptIV = $xor;
1629 if ($start = $ciphertext_len % '.$block_size.') {
1630 $buffer["xor"] = substr($key, $start) . $buffer["xor"];
1631 }
1632 }
1633 return $plaintext;
1634 ';
1635 break;
1636 }
1637 $fnc_head = '$action, &$self, $text';
1638 $fnc_body = $init_cryptBlock . 'if ($action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }';
1639
1640 if (function_exists('create_function') && is_callable('create_function')) {
1641 $lambda_functions[$code_hash] = create_function($fnc_head, $fnc_body);
1642 } else {
1643 eval('function ' . ($lambda_functions[$code_hash] = 'f' . md5(microtime())) . '(' . $fnc_head . ') { ' . $fnc_body . ' }');
1644 }
1645 }
1646 $this->inline_crypt = $lambda_functions[$code_hash];
1647 }
1648
1649 /**
1650 * Holds the lambda_functions table (classwide)
1651 *
1652 * @see inline_crypt_setup()
1653 * @return Array
1654 * @access private
1655 */
1656 function &get_lambda_functions()
1657 {
1658 static $functions = array();
1659 return $functions;
1660 }
1661 }
1662
1663 // vim: ts=4:sw=4:et:
1664 // vim6: fdl=1:
1665