Issues (365)

src/Library/libraries/phpseclib/Crypt/Twofish.php (1 issue)

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

676
        $lambda_functions =& self::/** @scrutinizer ignore-call */ _getLambdaFunctions();
Loading history...
677
678
        // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
679
        // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
680
        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
681
682
        // Generation of a unique hash for our generated code
683
        $code_hash = "Crypt_Twofish, {$this->mode}";
684
        if ($gen_hi_opt_code) {
685
            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
686
        }
687
688
        if (!isset($lambda_functions[$code_hash])) {
689
            switch (true) {
690
                case $gen_hi_opt_code:
691
                    $K = $this->K;
692
                    $init_crypt = '
693
                        static $S0, $S1, $S2, $S3;
694
                        if (!$S0) {
695
                            for ($i = 0; $i < 256; ++$i) {
696
                                $S0[] = (int)$self->S0[$i];
697
                                $S1[] = (int)$self->S1[$i];
698
                                $S2[] = (int)$self->S2[$i];
699
                                $S3[] = (int)$self->S3[$i];
700
                            }
701
                        }
702
                    ';
703
                    break;
704
                default:
705
                    $K   = array();
706
                    for ($i = 0; $i < 40; ++$i) {
707
                        $K[] = '$K_' . $i;
708
                    }
709
                    $init_crypt = '
710
                        $S0 = $self->S0;
711
                        $S1 = $self->S1;
712
                        $S2 = $self->S2;
713
                        $S3 = $self->S3;
714
                        list(' . implode(',', $K) . ') = $self->K;
715
                    ';
716
            }
717
718
            // Generating encrypt code:
719
            $encrypt_block = '
720
                $in = unpack("V4", $in);
721
                $R0 = ' . $K[0] . ' ^ $in[1];
722
                $R1 = ' . $K[1] . ' ^ $in[2];
723
                $R2 = ' . $K[2] . ' ^ $in[3];
724
                $R3 = ' . $K[3] . ' ^ $in[4];
725
            ';
726
            for ($ki = 7, $i = 0; $i < 8; ++$i) {
727
                $encrypt_block.= '
728
                    $t0 = $S0[ $R0        & 0xff] ^
729
                          $S1[($R0 >>  8) & 0xff] ^
730
                          $S2[($R0 >> 16) & 0xff] ^
731
                          $S3[($R0 >> 24) & 0xff];
732
                    $t1 = $S0[($R1 >> 24) & 0xff] ^
733
                          $S1[ $R1        & 0xff] ^
734
                          $S2[($R1 >>  8) & 0xff] ^
735
                          $S3[($R1 >> 16) & 0xff];
736
                    $R2^= ($t0 + $t1 + ' . $K[++$ki] . ');
737
                    $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
738
                    $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + ' . $K[++$ki] . ');
739
740
                    $t0 = $S0[ $R2        & 0xff] ^
741
                          $S1[($R2 >>  8) & 0xff] ^
742
                          $S2[($R2 >> 16) & 0xff] ^
743
                          $S3[($R2 >> 24) & 0xff];
744
                    $t1 = $S0[($R3 >> 24) & 0xff] ^
745
                          $S1[ $R3        & 0xff] ^
746
                          $S2[($R3 >>  8) & 0xff] ^
747
                          $S3[($R3 >> 16) & 0xff];
748
                    $R0^= ($t0 + $t1 + ' . $K[++$ki] . ');
749
                    $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
750
                    $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + ' . $K[++$ki] . ');
751
                ';
752
            }
753
            $encrypt_block.= '
754
                $in = pack("V4", ' . $K[4] . ' ^ $R2,
755
                                 ' . $K[5] . ' ^ $R3,
756
                                 ' . $K[6] . ' ^ $R0,
757
                                 ' . $K[7] . ' ^ $R1);
758
            ';
759
760
            // Generating decrypt code:
761
            $decrypt_block = '
762
                $in = unpack("V4", $in);
763
                $R0 = ' . $K[4] . ' ^ $in[1];
764
                $R1 = ' . $K[5] . ' ^ $in[2];
765
                $R2 = ' . $K[6] . ' ^ $in[3];
766
                $R3 = ' . $K[7] . ' ^ $in[4];
767
            ';
768
            for ($ki = 40, $i = 0; $i < 8; ++$i) {
769
                $decrypt_block.= '
770
                    $t0 = $S0[$R0       & 0xff] ^
771
                          $S1[$R0 >>  8 & 0xff] ^
772
                          $S2[$R0 >> 16 & 0xff] ^
773
                          $S3[$R0 >> 24 & 0xff];
774
                    $t1 = $S0[$R1 >> 24 & 0xff] ^
775
                          $S1[$R1       & 0xff] ^
776
                          $S2[$R1 >>  8 & 0xff] ^
777
                          $S3[$R1 >> 16 & 0xff];
778
                    $R3^= $t0 + ($t1 << 1) + ' . $K[--$ki] . ';
779
                    $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
780
                    $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + ' . $K[--$ki] . ');
781
782
                    $t0 = $S0[$R2       & 0xff] ^
783
                          $S1[$R2 >>  8 & 0xff] ^
784
                          $S2[$R2 >> 16 & 0xff] ^
785
                          $S3[$R2 >> 24 & 0xff];
786
                    $t1 = $S0[$R3 >> 24 & 0xff] ^
787
                          $S1[$R3       & 0xff] ^
788
                          $S2[$R3 >>  8 & 0xff] ^
789
                          $S3[$R3 >> 16 & 0xff];
790
                    $R1^= $t0 + ($t1 << 1) + ' . $K[--$ki] . ';
791
                    $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
792
                    $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + ' . $K[--$ki] . ');
793
                ';
794
            }
795
            $decrypt_block.= '
796
                $in = pack("V4", ' . $K[0] . ' ^ $R2,
797
                                 ' . $K[1] . ' ^ $R3,
798
                                 ' . $K[2] . ' ^ $R0,
799
                                 ' . $K[3] . ' ^ $R1);
800
            ';
801
802
            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
803
                array(
804
                   'init_crypt'    => $init_crypt,
805
                   'init_encrypt'  => '',
806
                   'init_decrypt'  => '',
807
                   'encrypt_block' => $encrypt_block,
808
                   'decrypt_block' => $decrypt_block
809
                )
810
            );
811
        }
812
        $this->inline_crypt = $lambda_functions[$code_hash];
813
    }
814
}
815