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