Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 138
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Crypt_Blowfish
0.00% covered (danger)
0.00%
0 / 131
0.00% covered (danger)
0.00%
0 / 6
756
0.00% covered (danger)
0.00%
0 / 1
 setKey
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 isValidEngine
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 _setupKey
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
90
 _encryptBlock
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
6
 _decryptBlock
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
6
 _setupInlineCrypt
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3/**
4 * Pure-PHP implementation of Blowfish.
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/Blowfish_(cipher) Wikipedia description of Blowfish}
13 *
14 * Here's a short example of how to use this library:
15 * <code>
16 * <?php
17 *    include 'Crypt/Blowfish.php';
18 *
19 *    $blowfish = new Crypt_Blowfish();
20 *
21 *    $blowfish->setKey('12345678901234567890123456789012');
22 *
23 *    $plaintext = str_repeat('a', 1024);
24 *
25 *    echo $blowfish->decrypt($blowfish->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_Blowfish
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_Blowfish::encrypt()
68 * @see Crypt_Blowfish::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_BLOWFISH_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_BLOWFISH_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_BLOWFISH_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_BLOWFISH_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_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
102/**#@-*/
103
104/**
105 * Pure-PHP implementation of Blowfish.
106 *
107 * @package Crypt_Blowfish
108 * @author  Jim Wigginton <terrafrost@php.net>
109 * @author  Hans-Juergen Petrich <petrich@tronic-media.com>
110 * @access  public
111 */
112class Crypt_Blowfish extends Crypt_Base
113{
114    /**
115     * Block Length of the cipher
116     *
117     * @see Crypt_Base::block_size
118     * @var Integer
119     * @access private
120     */
121    var $block_size = 8;
122
123    /**
124     * The default password key_size used by setPassword()
125     *
126     * @see Crypt_Base::password_key_size
127     * @see Crypt_Base::setPassword()
128     * @var Integer
129     * @access private
130     */
131    var $password_key_size = 56;
132
133    /**
134     * The namespace used by the cipher for its constants.
135     *
136     * @see Crypt_Base::const_namespace
137     * @var String
138     * @access private
139     */
140    var $const_namespace = 'BLOWFISH';
141
142    /**
143     * The mcrypt specific name of the cipher
144     *
145     * @see Crypt_Base::cipher_name_mcrypt
146     * @var String
147     * @access private
148     */
149    var $cipher_name_mcrypt = 'blowfish';
150
151    /**
152     * Optimizing value while CFB-encrypting
153     *
154     * @see Crypt_Base::cfb_init_len
155     * @var Integer
156     * @access private
157     */
158    var $cfb_init_len = 500;
159
160    /**
161     * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
162     *
163     * S-Box 0
164     *
165     * @access private
166     * @var    array
167     */
168    var $sbox0 = array (
169        0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
170        0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
171        0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
172        0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
173        0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
174        0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
175        0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
176        0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
177        0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
178        0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
179        0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
180        0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
181        0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
182        0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
183        0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
184        0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
185        0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
186        0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
187        0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
188        0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
189        0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
190        0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
191        0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
192        0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
193        0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
194        0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
195        0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
196        0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
197        0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
198        0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
199        0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
200        0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
201    );
202
203    /**
204     * S-Box 1
205     *
206     * @access private
207     * @var    array
208     */
209    var $sbox1 = array(
210        0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
211        0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
212        0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
213        0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
214        0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
215        0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
216        0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
217        0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
218        0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
219        0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
220        0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
221        0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
222        0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
223        0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
224        0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
225        0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
226        0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
227        0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
228        0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
229        0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
230        0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
231        0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
232        0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
233        0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
234        0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
235        0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
236        0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
237        0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
238        0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
239        0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
240        0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
241        0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
242    );
243
244    /**
245     * S-Box 2
246     *
247     * @access private
248     * @var    array
249     */
250    var $sbox2 = array(
251        0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
252        0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
253        0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
254        0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
255        0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
256        0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
257        0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
258        0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
259        0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
260        0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
261        0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
262        0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
263        0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
264        0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
265        0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
266        0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
267        0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
268        0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
269        0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
270        0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
271        0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
272        0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
273        0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
274        0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
275        0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
276        0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
277        0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
278        0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
279        0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
280        0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
281        0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
282        0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
283    );
284
285    /**
286     * S-Box 3
287     *
288     * @access private
289     * @var    array
290     */
291    var $sbox3 = array(
292        0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
293        0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
294        0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
295        0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
296        0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
297        0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
298        0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
299        0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
300        0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
301        0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
302        0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
303        0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
304        0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
305        0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
306        0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
307        0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
308        0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
309        0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
310        0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
311        0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
312        0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
313        0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
314        0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
315        0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
316        0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
317        0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
318        0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
319        0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
320        0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
321        0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
322        0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
323        0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
324    );
325
326    /**
327     * P-Array consists of 18 32-bit subkeys
328     *
329     * @var array
330     * @access private
331     */
332    var $parray = array(
333        0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
334        0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
335        0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
336    );
337
338    /**
339     * The BCTX-working Array
340     *
341     * Holds the expanded key [p] and the key-depended s-boxes [sb]
342     *
343     * @var array
344     * @access private
345     */
346    var $bctx;
347
348    /**
349     * Holds the last used key
350     *
351     * @var Array
352     * @access private
353     */
354    var $kl;
355
356    /**
357     * Sets the key.
358     *
359     * Keys can be of any length.  Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
360     * If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
361     * with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
362     *
363     * If the key is more than 448-bits, we trim the excess bits.
364     *
365     * If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
366     *
367     * @access public
368     * @see Crypt_Base::setKey()
369     * @param String $key
370     */
371    function setKey($key)
372    {
373        $keylength = strlen($key);
374
375        if (!$keylength) {
376            $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
377        } elseif ($keylength > 56) {
378            $key = substr($key, 0, 56);
379        }
380
381        parent::setKey($key);
382    }
383
384    /**
385     * Test for engine validity
386     *
387     * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
388     *
389     * @see Crypt_Base::isValidEngine()
390     * @param Integer $engine
391     * @access public
392     * @return Boolean
393     */
394    function isValidEngine($engine)
395    {
396        if ($engine == CRYPT_ENGINE_OPENSSL) {
397            if (strlen($this->key) != 16) {
398                return false;
399            }
400            $this->cipher_name_openssl_ecb = 'bf-ecb';
401            $this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
402        }
403
404        return parent::isValidEngine($engine);
405    }
406
407    /**
408     * Setup the key (expansion)
409     *
410     * @see Crypt_Base::_setupKey()
411     * @access private
412     */
413    function _setupKey()
414    {
415        if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
416            // already expanded
417            return;
418        }
419        $this->kl = array('key' => $this->key);
420
421        /* key-expanding p[] and S-Box building sb[] */
422        $this->bctx = array(
423            'p'  => array(),
424            'sb' => array(
425                $this->sbox0,
426                $this->sbox1,
427                $this->sbox2,
428                $this->sbox3
429            )
430        );
431
432        // unpack binary string in unsigned chars
433        $key  = array_values(unpack('C*', $this->key));
434        $keyl = count($key);
435        for ($j = 0, $i = 0; $i < 18; ++$i) {
436            // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
437            for ($data = 0, $k = 0; $k < 4; ++$k) {
438                $data = ($data << 8) | $key[$j];
439                if (++$j >= $keyl) {
440                    $j = 0;
441                }
442            }
443            $this->bctx['p'][] = $this->parray[$i] ^ $data;
444        }
445
446        // encrypt the zero-string, replace P1 and P2 with the encrypted data,
447        // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
448        $data = "\0\0\0\0\0\0\0\0";
449        for ($i = 0; $i < 18; $i += 2) {
450            list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
451            $this->bctx['p'][$i    ] = $l;
452            $this->bctx['p'][$i + 1] = $r;
453        }
454        for ($i = 0; $i < 4; ++$i) {
455            for ($j = 0; $j < 256; $j += 2) {
456                list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
457                $this->bctx['sb'][$i][$j    ] = $l;
458                $this->bctx['sb'][$i][$j + 1] = $r;
459            }
460        }
461    }
462
463    /**
464     * Encrypts a block
465     *
466     * @access private
467     * @param String $in
468     * @return String
469     */
470    function _encryptBlock($in)
471    {
472        $p = $this->bctx["p"];
473        // extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower
474        $sb_0 = $this->bctx["sb"][0];
475        $sb_1 = $this->bctx["sb"][1];
476        $sb_2 = $this->bctx["sb"][2];
477        $sb_3 = $this->bctx["sb"][3];
478
479        $in = unpack("N*", $in);
480        $l = $in[1];
481        $r = $in[2];
482
483        for ($i = 0; $i < 16; $i+= 2) {
484            $l^= $p[$i];
485            $r^= ($sb_0[$l >> 24 & 0xff]  +
486                  $sb_1[$l >> 16 & 0xff]  ^
487                  $sb_2[$l >>  8 & 0xff]) +
488                  $sb_3[$l       & 0xff];
489
490            $r^= $p[$i + 1];
491            $l^= ($sb_0[$r >> 24 & 0xff]  +
492                  $sb_1[$r >> 16 & 0xff]  ^
493                  $sb_2[$r >>  8 & 0xff]) +
494                  $sb_3[$r       & 0xff];
495        }
496        return pack("N*", $r ^ $p[17], $l ^ $p[16]);
497    }
498
499    /**
500     * Decrypts a block
501     *
502     * @access private
503     * @param String $in
504     * @return String
505     */
506    function _decryptBlock($in)
507    {
508        $p = $this->bctx["p"];
509        $sb_0 = $this->bctx["sb"][0];
510        $sb_1 = $this->bctx["sb"][1];
511        $sb_2 = $this->bctx["sb"][2];
512        $sb_3 = $this->bctx["sb"][3];
513
514        $in = unpack("N*", $in);
515        $l = $in[1];
516        $r = $in[2];
517
518        for ($i = 17; $i > 2; $i-= 2) {
519            $l^= $p[$i];
520            $r^= ($sb_0[$l >> 24 & 0xff]  +
521                  $sb_1[$l >> 16 & 0xff]  ^
522                  $sb_2[$l >>  8 & 0xff]) +
523                  $sb_3[$l       & 0xff];
524
525            $r^= $p[$i - 1];
526            $l^= ($sb_0[$r >> 24 & 0xff]  +
527                  $sb_1[$r >> 16 & 0xff]  ^
528                  $sb_2[$r >>  8 & 0xff]) +
529                  $sb_3[$r       & 0xff];
530        }
531        return pack("N*", $r ^ $p[0], $l ^ $p[1]);
532    }
533
534    /**
535     * Setup the performance-optimized function for de/encrypt()
536     *
537     * @see Crypt_Base::_setupInlineCrypt()
538     * @access private
539     */
540    function _setupInlineCrypt()
541    {
542        $lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
543
544        // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
545        // (Currently, for Crypt_Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
546        // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
547        $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
548
549        // Generation of a unique hash for our generated code
550        $code_hash = "Crypt_Blowfish, {$this->mode}";
551        if ($gen_hi_opt_code) {
552            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
553        }
554
555        if (!isset($lambda_functions[$code_hash])) {
556            switch (true) {
557                case $gen_hi_opt_code:
558                    $p = $this->bctx['p'];
559                    $init_crypt = '
560                        static $sb_0, $sb_1, $sb_2, $sb_3;
561                        if (!$sb_0) {
562                            $sb_0 = $self->bctx["sb"][0];
563                            $sb_1 = $self->bctx["sb"][1];
564                            $sb_2 = $self->bctx["sb"][2];
565                            $sb_3 = $self->bctx["sb"][3];
566                        }
567                    ';
568                    break;
569                default:
570                    $p   = array();
571                    for ($i = 0; $i < 18; ++$i) {
572                        $p[] = '$p_' . $i;
573                    }
574                    $init_crypt = '
575                        list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"];
576                        list(' . implode(',', $p) . ') = $self->bctx["p"];
577
578                    ';
579            }
580
581            // Generating encrypt code:
582            $encrypt_block = '
583                $in = unpack("N*", $in);
584                $l = $in[1];
585                $r = $in[2];
586            ';
587            for ($i = 0; $i < 16; $i+= 2) {
588                $encrypt_block.= '
589                    $l^= ' . $p[$i] . ';
590                    $r^= ($sb_0[$l >> 24 & 0xff]  +
591                          $sb_1[$l >> 16 & 0xff]  ^
592                          $sb_2[$l >>  8 & 0xff]) +
593                          $sb_3[$l       & 0xff];
594
595                    $r^= ' . $p[$i + 1] . ';
596                    $l^= ($sb_0[$r >> 24 & 0xff]  +
597                          $sb_1[$r >> 16 & 0xff]  ^
598                          $sb_2[$r >>  8 & 0xff]) +
599                          $sb_3[$r       & 0xff];
600                ';
601            }
602            $encrypt_block.= '
603                $in = pack("N*",
604                    $r ^ ' . $p[17] . ',
605                    $l ^ ' . $p[16] . '
606                );
607            ';
608
609            // Generating decrypt code:
610            $decrypt_block = '
611                $in = unpack("N*", $in);
612                $l = $in[1];
613                $r = $in[2];
614            ';
615
616            for ($i = 17; $i > 2; $i-= 2) {
617                $decrypt_block.= '
618                    $l^= ' . $p[$i] . ';
619                    $r^= ($sb_0[$l >> 24 & 0xff]  +
620                          $sb_1[$l >> 16 & 0xff]  ^
621                          $sb_2[$l >>  8 & 0xff]) +
622                          $sb_3[$l       & 0xff];
623
624                    $r^= ' . $p[$i - 1] . ';
625                    $l^= ($sb_0[$r >> 24 & 0xff]  +
626                          $sb_1[$r >> 16 & 0xff]  ^
627                          $sb_2[$r >>  8 & 0xff]) +
628                          $sb_3[$r       & 0xff];
629                ';
630            }
631
632            $decrypt_block.= '
633                $in = pack("N*",
634                    $r ^ ' . $p[0] . ',
635                    $l ^ ' . $p[1] . '
636                );
637            ';
638
639            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
640                array(
641                   'init_crypt'    => $init_crypt,
642                   'init_encrypt'  => '',
643                   'init_decrypt'  => '',
644                   'encrypt_block' => $encrypt_block,
645                   'decrypt_block' => $decrypt_block
646                )
647            );
648        }
649        $this->inline_crypt = $lambda_functions[$code_hash];
650    }
651}