Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 260
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Crypt_Twofish
0.00% covered (danger)
0.00%
0 / 253
0.00% covered (danger)
0.00%
0 / 6
1122
0.00% covered (danger)
0.00%
0 / 1
 setKey
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
 _setupKey
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 1
156
 _mdsrem
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 _encryptBlock
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
6
 _decryptBlock
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
6
 _setupInlineCrypt
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3/**
4 * Pure-PHP implementation of Twofish.
5 *
6 * Uses mcrypt, if available, and an internal implementation, otherwise.
7 *
8 * PHP versions 4 and 5
9 *
10 * Useful resources are as follows:
11 *
12 *  - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
13 *
14 * Here's a short example of how to use this library:
15 * <code>
16 * <?php
17 *    include 'Crypt/Twofish.php';
18 *
19 *    $twofish = new Crypt_Twofish();
20 *
21 *    $twofish->setKey('12345678901234567890123456789012');
22 *
23 *    $plaintext = str_repeat('a', 1024);
24 *
25 *    echo $twofish->decrypt($twofish->encrypt($plaintext));
26 * ?>
27 * </code>
28 *
29 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
30 * of this software and associated documentation files (the "Software"), to deal
31 * in the Software without restriction, including without limitation the rights
32 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33 * copies of the Software, and to permit persons to whom the Software is
34 * furnished to do so, subject to the following conditions:
35 *
36 * The above copyright notice and this permission notice shall be included in
37 * all copies or substantial portions of the Software.
38 *
39 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45 * THE SOFTWARE.
46 *
47 * @category  Crypt
48 * @package   Crypt_Twofish
49 * @author    Jim Wigginton <terrafrost@php.net>
50 * @author    Hans-Juergen Petrich <petrich@tronic-media.com>
51 * @copyright 2007 Jim Wigginton
52 * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
53 * @link      http://phpseclib.sourceforge.net
54 */
55
56/**
57 * Include Crypt_Base
58 *
59 * Base cipher class
60 */
61if (!class_exists('Crypt_Base')) {
62    include_once 'Base.php';
63}
64
65/**#@+
66 * @access public
67 * @see Crypt_Twofish::encrypt()
68 * @see Crypt_Twofish::decrypt()
69 */
70/**
71 * Encrypt / decrypt using the Counter mode.
72 *
73 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
74 *
75 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
76 */
77define('CRYPT_TWOFISH_MODE_CTR', CRYPT_MODE_CTR);
78/**
79 * Encrypt / decrypt using the Electronic Code Book mode.
80 *
81 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
82 */
83define('CRYPT_TWOFISH_MODE_ECB', CRYPT_MODE_ECB);
84/**
85 * Encrypt / decrypt using the Code Book Chaining mode.
86 *
87 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
88 */
89define('CRYPT_TWOFISH_MODE_CBC', CRYPT_MODE_CBC);
90/**
91 * Encrypt / decrypt using the Cipher Feedback mode.
92 *
93 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
94 */
95define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
96/**
97 * Encrypt / decrypt using the Cipher Feedback mode.
98 *
99 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
100 */
101define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
102/**#@-*/
103
104/**
105 * Pure-PHP implementation of Twofish.
106 *
107 * @package Crypt_Twofish
108 * @author  Jim Wigginton <terrafrost@php.net>
109 * @author  Hans-Juergen Petrich <petrich@tronic-media.com>
110 * @access  public
111 */
112class Crypt_Twofish extends Crypt_Base
113{
114    /**
115     * The namespace used by the cipher for its constants.
116     *
117     * @see Crypt_Base::const_namespace
118     * @var String
119     * @access private
120     */
121    var $const_namespace = 'TWOFISH';
122
123    /**
124     * The mcrypt specific name of the cipher
125     *
126     * @see Crypt_Base::cipher_name_mcrypt
127     * @var String
128     * @access private
129     */
130    var $cipher_name_mcrypt = 'twofish';
131
132    /**
133     * Optimizing value while CFB-encrypting
134     *
135     * @see Crypt_Base::cfb_init_len
136     * @var Integer
137     * @access private
138     */
139    var $cfb_init_len = 800;
140
141    /**
142     * Q-Table
143     *
144     * @var Array
145     * @access private
146     */
147    var $q0 = array (
148        0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
149        0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
150        0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
151        0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
152        0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
153        0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
154        0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
155        0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
156        0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
157        0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
158        0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
159        0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
160        0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
161        0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
162        0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
163        0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
164        0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
165        0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
166        0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
167        0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
168        0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
169        0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
170        0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
171        0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
172        0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
173        0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
174        0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
175        0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
176        0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
177        0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
178        0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
179        0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
180    );
181
182    /**
183     * Q-Table
184     *
185     * @var Array
186     * @access private
187     */
188    var $q1 = array (
189        0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
190        0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
191        0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
192        0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
193        0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
194        0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
195        0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
196        0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
197        0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
198        0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
199        0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
200        0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
201        0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
202        0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
203        0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
204        0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
205        0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
206        0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
207        0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
208        0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
209        0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
210        0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
211        0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
212        0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
213        0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
214        0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
215        0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
216        0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
217        0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
218        0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
219        0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
220        0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
221    );
222
223    /**
224     * M-Table
225     *
226     * @var Array
227     * @access private
228     */
229    var $m0 = array (
230        0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
231        0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
232        0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
233        0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
234        0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
235        0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
236        0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
237        0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
238        0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
239        0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
240        0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
241        0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
242        0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
243        0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
244        0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
245        0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
246        0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
247        0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
248        0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
249        0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
250        0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
251        0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
252        0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
253        0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
254        0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
255        0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
256        0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
257        0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
258        0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
259        0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
260        0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
261        0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
262    );
263
264    /**
265     * M-Table
266     *
267     * @var Array
268     * @access private
269     */
270    var $m1 = array (
271        0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
272        0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
273        0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
274        0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
275        0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
276        0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
277        0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
278        0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
279        0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
280        0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
281        0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
282        0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
283        0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
284        0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
285        0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
286        0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
287        0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
288        0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
289        0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
290        0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
291        0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
292        0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
293        0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
294        0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
295        0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
296        0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
297        0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
298        0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
299        0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
300        0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
301        0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
302        0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
303    );
304
305    /**
306     * M-Table
307     *
308     * @var Array
309     * @access private
310     */
311    var $m2 = array (
312        0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
313        0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
314        0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
315        0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
316        0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
317        0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
318        0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
319        0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
320        0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
321        0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
322        0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
323        0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
324        0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
325        0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
326        0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
327        0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
328        0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
329        0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
330        0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
331        0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
332        0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
333        0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
334        0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
335        0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
336        0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
337        0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
338        0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
339        0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
340        0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
341        0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
342        0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
343        0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
344    );
345
346    /**
347     * M-Table
348     *
349     * @var Array
350     * @access private
351     */
352    var $m3 = array (
353        0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
354        0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
355        0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
356        0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
357        0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
358        0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
359        0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
360        0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
361        0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
362        0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
363        0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
364        0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
365        0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
366        0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
367        0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
368        0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
369        0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
370        0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
371        0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
372        0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
373        0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
374        0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
375        0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
376        0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
377        0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
378        0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
379        0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
380        0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
381        0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
382        0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
383        0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
384        0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
385    );
386
387    /**
388     * The Key Schedule Array
389     *
390     * @var Array
391     * @access private
392     */
393    var $K = array();
394
395    /**
396     * The Key depended S-Table 0
397     *
398     * @var Array
399     * @access private
400     */
401    var $S0 = array();
402
403    /**
404     * The Key depended S-Table 1
405     *
406     * @var Array
407     * @access private
408     */
409    var $S1 = array();
410
411    /**
412     * The Key depended S-Table 2
413     *
414     * @var Array
415     * @access private
416     */
417    var $S2 = array();
418
419    /**
420     * The Key depended S-Table 3
421     *
422     * @var Array
423     * @access private
424     */
425    var $S3 = array();
426
427    /**
428     * Holds the last used key
429     *
430     * @var Array
431     * @access private
432     */
433    var $kl;
434
435    /**
436     * Sets the key.
437     *
438     * Keys can be of any length. Twofish, itself, requires the use of a key that's 128, 192 or 256-bits long.
439     * If the key is less than 256-bits we round the length up to the closest valid key length,
440     * padding $key with null bytes. If the key is more than 256-bits, we trim the excess bits.
441     *
442     * If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
443     *
444     * @access public
445     * @see Crypt_Base::setKey()
446     * @param String $key
447     */
448    function setKey($key)
449    {
450        $keylength = strlen($key);
451        switch (true) {
452            case $keylength <= 16:
453                $key = str_pad($key, 16, "\0");
454                break;
455            case $keylength <= 24:
456                $key = str_pad($key, 24, "\0");
457                break;
458            case $keylength < 32:
459                $key = str_pad($key, 32, "\0");
460                break;
461            case $keylength > 32:
462                $key = substr($key, 0, 32);
463        }
464        parent::setKey($key);
465    }
466
467    /**
468     * Setup the key (expansion)
469     *
470     * @see Crypt_Base::_setupKey()
471     * @access private
472     */
473    function _setupKey()
474    {
475        if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
476            // already expanded
477            return;
478        }
479        $this->kl = array('key' => $this->key);
480
481        /* Key expanding and generating the key-depended s-boxes */
482        $le_longs = unpack('V*', $this->key);
483        $key = unpack('C*', $this->key);
484        $m0 = $this->m0;
485        $m1 = $this->m1;
486        $m2 = $this->m2;
487        $m3 = $this->m3;
488        $q0 = $this->q0;
489        $q1 = $this->q1;
490
491        $K = $S0 = $S1 = $S2 = $S3 = array();
492
493        switch (strlen($this->key)) {
494            case 16:
495                list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
496                list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
497                for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
498                    $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
499                         $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
500                         $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
501                         $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
502                    $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
503                         $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
504                         $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
505                         $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
506                    $B = ($B << 8) | ($B >> 24 & 0xff);
507                    $K[] = $A+= $B;
508                    $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
509                }
510                for ($i = 0; $i < 256; ++$i) {
511                    $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
512                    $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
513                    $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
514                    $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
515                }
516                break;
517            case 24:
518                list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
519                list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
520                list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
521                for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
522                    $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
523                         $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
524                         $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
525                         $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
526                    $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
527                         $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
528                         $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
529                         $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
530                    $B = ($B << 8) | ($B >> 24 & 0xff);
531                    $K[] = $A+= $B;
532                    $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
533                }
534                for ($i = 0; $i < 256; ++$i) {
535                    $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
536                    $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
537                    $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
538                    $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
539                }
540                break;
541            default: // 32
542                list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
543                list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
544                list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
545                list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
546                for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
547                    $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
548                         $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
549                         $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
550                         $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
551                    $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
552                         $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
553                         $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
554                         $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
555                    $B = ($B << 8) | ($B >> 24 & 0xff);
556                    $K[] = $A+= $B;
557                    $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
558                }
559                for ($i = 0; $i < 256; ++$i) {
560                    $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
561                    $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
562                    $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
563                    $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
564                }
565        }
566
567        $this->K  = $K;
568        $this->S0 = $S0;
569        $this->S1 = $S1;
570        $this->S2 = $S2;
571        $this->S3 = $S3;
572    }
573
574    /**
575     * _mdsrem function using by the twofish cipher algorithm
576     *
577     * @access private
578     * @param String $A
579     * @param String $B
580     * @return Array
581     */
582    function _mdsrem($A, $B)
583    {
584        // No gain by unrolling this loop.
585        for ($i = 0; $i < 8; ++$i) {
586            // Get most significant coefficient.
587            $t = 0xff & ($B >> 24);
588
589            // Shift the others up.
590            $B = ($B << 8) | (0xff & ($A >> 24));
591            $A<<= 8;
592
593            $u = $t << 1;
594
595            // Subtract the modular polynomial on overflow.
596            if ($t & 0x80) {
597                $u^= 0x14d;
598            }
599
600            // Remove t * (a * x^2 + 1).
601            $B ^= $t ^ ($u << 16);
602
603            // Form u = a*t + t/a = t*(a + 1/a).
604            $u^= 0x7fffffff & ($t >> 1);
605
606            // Add the modular polynomial on underflow.
607            if ($t & 0x01) {
608                $u^= 0xa6 ;
609            }
610
611            // Remove t * (a + 1/a) * (x^3 + x).
612            $B^= ($u << 24) | ($u << 8);
613        }
614
615        return array(
616            0xff & $B >> 24,
617            0xff & $B >> 16,
618            0xff & $B >>  8,
619            0xff & $B);
620    }
621
622    /**
623     * Encrypts a block
624     *
625     * @access private
626     * @param String $in
627     * @return String
628     */
629    function _encryptBlock($in)
630    {
631        $S0 = $this->S0;
632        $S1 = $this->S1;
633        $S2 = $this->S2;
634        $S3 = $this->S3;
635        $K  = $this->K;
636
637        $in = unpack("V4", $in);
638        $R0 = $K[0] ^ $in[1];
639        $R1 = $K[1] ^ $in[2];
640        $R2 = $K[2] ^ $in[3];
641        $R3 = $K[3] ^ $in[4];
642
643        $ki = 7;
644        while ($ki < 39) {
645            $t0 = $S0[ $R0        & 0xff] ^
646                  $S1[($R0 >>  8) & 0xff] ^
647                  $S2[($R0 >> 16) & 0xff] ^
648                  $S3[($R0 >> 24) & 0xff];
649            $t1 = $S0[($R1 >> 24) & 0xff] ^
650                  $S1[ $R1        & 0xff] ^
651                  $S2[($R1 >>  8) & 0xff] ^
652                  $S3[($R1 >> 16) & 0xff];
653            $R2^= $t0 + $t1 + $K[++$ki];
654            $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
655            $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
656
657            $t0 = $S0[ $R2        & 0xff] ^
658                  $S1[($R2 >>  8) & 0xff] ^
659                  $S2[($R2 >> 16) & 0xff] ^
660                  $S3[($R2 >> 24) & 0xff];
661            $t1 = $S0[($R3 >> 24) & 0xff] ^
662                  $S1[ $R3        & 0xff] ^
663                  $S2[($R3 >>  8) & 0xff] ^
664                  $S3[($R3 >> 16) & 0xff];
665            $R0^= ($t0 + $t1 + $K[++$ki]);
666            $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
667            $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
668        }
669
670        // @codingStandardsIgnoreStart
671        return pack("V4", $K[4] ^ $R2,
672                          $K[5] ^ $R3,
673                          $K[6] ^ $R0,
674                          $K[7] ^ $R1);
675        // @codingStandardsIgnoreEnd
676    }
677
678    /**
679     * Decrypts a block
680     *
681     * @access private
682     * @param String $in
683     * @return String
684     */
685    function _decryptBlock($in)
686    {
687        $S0 = $this->S0;
688        $S1 = $this->S1;
689        $S2 = $this->S2;
690        $S3 = $this->S3;
691        $K  = $this->K;
692
693        $in = unpack("V4", $in);
694        $R0 = $K[4] ^ $in[1];
695        $R1 = $K[5] ^ $in[2];
696        $R2 = $K[6] ^ $in[3];
697        $R3 = $K[7] ^ $in[4];
698
699        $ki = 40;
700        while ($ki > 8) {
701            $t0 = $S0[$R0       & 0xff] ^
702                  $S1[$R0 >>  8 & 0xff] ^
703                  $S2[$R0 >> 16 & 0xff] ^
704                  $S3[$R0 >> 24 & 0xff];
705            $t1 = $S0[$R1 >> 24 & 0xff] ^
706                  $S1[$R1       & 0xff] ^
707                  $S2[$R1 >>  8 & 0xff] ^
708                  $S3[$R1 >> 16 & 0xff];
709            $R3^= $t0 + ($t1 << 1) + $K[--$ki];
710            $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
711            $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K[--$ki]);
712
713            $t0 = $S0[$R2       & 0xff] ^
714                  $S1[$R2 >>  8 & 0xff] ^
715                  $S2[$R2 >> 16 & 0xff] ^
716                  $S3[$R2 >> 24 & 0xff];
717            $t1 = $S0[$R3 >> 24 & 0xff] ^
718                  $S1[$R3       & 0xff] ^
719                  $S2[$R3 >>  8 & 0xff] ^
720                  $S3[$R3 >> 16 & 0xff];
721            $R1^= $t0 + ($t1 << 1) + $K[--$ki];
722            $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
723            $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
724        }
725
726        // @codingStandardsIgnoreStart
727        return pack("V4", $K[0] ^ $R2,
728                          $K[1] ^ $R3,
729                          $K[2] ^ $R0,
730                          $K[3] ^ $R1);
731        // @codingStandardsIgnoreEnd
732    }
733
734    /**
735     * Setup the performance-optimized function for de/encrypt()
736     *
737     * @see Crypt_Base::_setupInlineCrypt()
738     * @access private
739     */
740    function _setupInlineCrypt()
741    {
742        $lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
743
744        // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
745        // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
746        $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
747
748        // Generation of a uniqe hash for our generated code
749        $code_hash = "Crypt_Twofish, {$this->mode}";
750        if ($gen_hi_opt_code) {
751            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
752        }
753
754        if (!isset($lambda_functions[$code_hash])) {
755            switch (true) {
756                case $gen_hi_opt_code:
757                    $K = $this->K;
758                    $init_crypt = '
759                        static $S0, $S1, $S2, $S3;
760                        if (!$S0) {
761                            for ($i = 0; $i < 256; ++$i) {
762                                $S0[] = (int)$self->S0[$i];
763                                $S1[] = (int)$self->S1[$i];
764                                $S2[] = (int)$self->S2[$i];
765                                $S3[] = (int)$self->S3[$i];
766                            }
767                        }
768                    ';
769                    break;
770                default:
771                    $K   = array();
772                    for ($i = 0; $i < 40; ++$i) {
773                        $K[] = '$K_' . $i;
774                    }
775                    $init_crypt = '
776                        $S0 = $self->S0;
777                        $S1 = $self->S1;
778                        $S2 = $self->S2;
779                        $S3 = $self->S3;
780                        list(' . implode(',', $K) . ') = $self->K;
781                    ';
782            }
783
784            // Generating encrypt code:
785            $encrypt_block = '
786                $in = unpack("V4", $in);
787                $R0 = '.$K[0].' ^ $in[1];
788                $R1 = '.$K[1].' ^ $in[2];
789                $R2 = '.$K[2].' ^ $in[3];
790                $R3 = '.$K[3].' ^ $in[4];
791            ';
792            for ($ki = 7, $i = 0; $i < 8; ++$i) {
793                $encrypt_block.= '
794                    $t0 = $S0[ $R0        & 0xff] ^
795                          $S1[($R0 >>  8) & 0xff] ^
796                          $S2[($R0 >> 16) & 0xff] ^
797                          $S3[($R0 >> 24) & 0xff];
798                    $t1 = $S0[($R1 >> 24) & 0xff] ^
799                          $S1[ $R1        & 0xff] ^
800                          $S2[($R1 >>  8) & 0xff] ^
801                          $S3[($R1 >> 16) & 0xff];
802                    $R2^= ($t0 + $t1 + '.$K[++$ki].');
803                    $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
804                    $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
805
806                    $t0 = $S0[ $R2        & 0xff] ^
807                          $S1[($R2 >>  8) & 0xff] ^
808                          $S2[($R2 >> 16) & 0xff] ^
809                          $S3[($R2 >> 24) & 0xff];
810                    $t1 = $S0[($R3 >> 24) & 0xff] ^
811                          $S1[ $R3        & 0xff] ^
812                          $S2[($R3 >>  8) & 0xff] ^
813                          $S3[($R3 >> 16) & 0xff];
814                    $R0^= ($t0 + $t1 + '.$K[++$ki].');
815                    $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
816                    $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
817                ';
818            }
819            $encrypt_block.= '
820                $in = pack("V4", '.$K[4].' ^ $R2,
821                                 '.$K[5].' ^ $R3,
822                                 '.$K[6].' ^ $R0,
823                                 '.$K[7].' ^ $R1);
824            ';
825
826            // Generating decrypt code:
827            $decrypt_block = '
828                $in = unpack("V4", $in);
829                $R0 = '.$K[4].' ^ $in[1];
830                $R1 = '.$K[5].' ^ $in[2];
831                $R2 = '.$K[6].' ^ $in[3];
832                $R3 = '.$K[7].' ^ $in[4];
833            ';
834            for ($ki = 40, $i = 0; $i < 8; ++$i) {
835                $decrypt_block.= '
836                    $t0 = $S0[$R0       & 0xff] ^
837                          $S1[$R0 >>  8 & 0xff] ^
838                          $S2[$R0 >> 16 & 0xff] ^
839                          $S3[$R0 >> 24 & 0xff];
840                    $t1 = $S0[$R1 >> 24 & 0xff] ^
841                          $S1[$R1       & 0xff] ^
842                          $S2[$R1 >>  8 & 0xff] ^
843                          $S3[$R1 >> 16 & 0xff];
844                    $R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
845                    $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
846                    $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
847
848                    $t0 = $S0[$R2       & 0xff] ^
849                          $S1[$R2 >>  8 & 0xff] ^
850                          $S2[$R2 >> 16 & 0xff] ^
851                          $S3[$R2 >> 24 & 0xff];
852                    $t1 = $S0[$R3 >> 24 & 0xff] ^
853                          $S1[$R3       & 0xff] ^
854                          $S2[$R3 >>  8 & 0xff] ^
855                          $S3[$R3 >> 16 & 0xff];
856                    $R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
857                    $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
858                    $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
859                ';
860            }
861            $decrypt_block.= '
862                $in = pack("V4", '.$K[0].' ^ $R2,
863                                 '.$K[1].' ^ $R3,
864                                 '.$K[2].' ^ $R0,
865                                 '.$K[3].' ^ $R1);
866            ';
867
868            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
869                array(
870                   'init_crypt'    => $init_crypt,
871                   'init_encrypt'  => '',
872                   'init_decrypt'  => '',
873                   'encrypt_block' => $encrypt_block,
874                   'decrypt_block' => $decrypt_block
875                )
876            );
877        }
878        $this->inline_crypt = $lambda_functions[$code_hash];
879    }
880}