[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/phpseclib/phpseclib/phpseclib/Crypt/ -> Twofish.php (source)

   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 <terrafrost@php.net>
  32   * @author    Hans-Juergen Petrich <petrich@tronic-media.com>
  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 <terrafrost@php.net>
  45   * @author  Hans-Juergen Petrich <petrich@tronic-media.com>
  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      var $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      var $cfb_init_len = 800;
  67  
  68      /**
  69       * Q-Table
  70       *
  71       * @var array
  72       * @access private
  73       */
  74      var $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      var $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      var $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      var $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      var $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      var $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      var $K = array();
 321  
 322      /**
 323       * The Key depended S-Table 0
 324       *
 325       * @var array
 326       * @access private
 327       */
 328      var $S0 = array();
 329  
 330      /**
 331       * The Key depended S-Table 1
 332       *
 333       * @var array
 334       * @access private
 335       */
 336      var $S1 = array();
 337  
 338      /**
 339       * The Key depended S-Table 2
 340       *
 341       * @var array
 342       * @access private
 343       */
 344      var $S2 = array();
 345  
 346      /**
 347       * The Key depended S-Table 3
 348       *
 349       * @var array
 350       * @access private
 351       */
 352      var $S3 = array();
 353  
 354      /**
 355       * Holds the last used key
 356       *
 357       * @var array
 358       * @access private
 359       */
 360      var $kl;
 361  
 362      /**
 363       * The Key Length (in bytes)
 364       *
 365       * @see Crypt_Twofish::setKeyLength()
 366       * @var int
 367       * @access private
 368       */
 369      var $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      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      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                      $A = $this->safe_intval($A + $B);
 436                      $K[] = $A;
 437                      $A = $this->safe_intval($A + $B);
 438                      $K[] = ($A << 9 | $A >> 23 & 0x1ff);
 439                  }
 440                  for ($i = 0; $i < 256; ++$i) {
 441                      $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
 442                      $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
 443                      $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
 444                      $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
 445                  }
 446                  break;
 447              case 24:
 448                  list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
 449                  list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
 450                  list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
 451                  for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
 452                      $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
 453                           $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
 454                           $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
 455                           $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
 456                      $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
 457                           $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
 458                           $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
 459                           $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
 460                      $B = ($B << 8) | ($B >> 24 & 0xff);
 461                      $A = $this->safe_intval($A + $B);
 462                      $K[] = $A;
 463                      $A = $this->safe_intval($A + $B);
 464                      $K[] = ($A << 9 | $A >> 23 & 0x1ff);
 465                  }
 466                  for ($i = 0; $i < 256; ++$i) {
 467                      $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
 468                      $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
 469                      $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
 470                      $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
 471                  }
 472                  break;
 473              default: // 32
 474                  list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
 475                  list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
 476                  list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
 477                  list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
 478                  for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
 479                      $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
 480                           $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
 481                           $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
 482                           $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
 483                      $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
 484                           $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
 485                           $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
 486                           $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
 487                      $B = ($B << 8) | ($B >> 24 & 0xff);
 488                      $A = $this->safe_intval($A + $B);
 489                      $K[] = $A;
 490                      $A = $this->safe_intval($A + $B);
 491                      $K[] = ($A << 9 | $A >> 23 & 0x1ff);
 492                  }
 493                  for ($i = 0; $i < 256; ++$i) {
 494                      $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
 495                      $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
 496                      $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
 497                      $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
 498                  }
 499          }
 500  
 501          $this->K  = $K;
 502          $this->S0 = $S0;
 503          $this->S1 = $S1;
 504          $this->S2 = $S2;
 505          $this->S3 = $S3;
 506      }
 507  
 508      /**
 509       * _mdsrem function using by the twofish cipher algorithm
 510       *
 511       * @access private
 512       * @param string $A
 513       * @param string $B
 514       * @return array
 515       */
 516      function _mdsrem($A, $B)
 517      {
 518          // No gain by unrolling this loop.
 519          for ($i = 0; $i < 8; ++$i) {
 520              // Get most significant coefficient.
 521              $t = 0xff & ($B >> 24);
 522  
 523              // Shift the others up.
 524              $B = ($B << 8) | (0xff & ($A >> 24));
 525              $A<<= 8;
 526  
 527              $u = $t << 1;
 528  
 529              // Subtract the modular polynomial on overflow.
 530              if ($t & 0x80) {
 531                  $u^= 0x14d;
 532              }
 533  
 534              // Remove t * (a * x^2 + 1).
 535              $B ^= $t ^ ($u << 16);
 536  
 537              // Form u = a*t + t/a = t*(a + 1/a).
 538              $u^= 0x7fffffff & ($t >> 1);
 539  
 540              // Add the modular polynomial on underflow.
 541              if ($t & 0x01) {
 542                  $u^= 0xa6 ;
 543              }
 544  
 545              // Remove t * (a + 1/a) * (x^3 + x).
 546              $B^= ($u << 24) | ($u << 8);
 547          }
 548  
 549          return array(
 550              0xff & $B >> 24,
 551              0xff & $B >> 16,
 552              0xff & $B >>  8,
 553              0xff & $B);
 554      }
 555  
 556      /**
 557       * Encrypts a block
 558       *
 559       * @access private
 560       * @param string $in
 561       * @return string
 562       */
 563      function _encryptBlock($in)
 564      {
 565          $S0 = $this->S0;
 566          $S1 = $this->S1;
 567          $S2 = $this->S2;
 568          $S3 = $this->S3;
 569          $K  = $this->K;
 570  
 571          $in = unpack("V4", $in);
 572          $R0 = $K[0] ^ $in[1];
 573          $R1 = $K[1] ^ $in[2];
 574          $R2 = $K[2] ^ $in[3];
 575          $R3 = $K[3] ^ $in[4];
 576  
 577          $ki = 7;
 578          while ($ki < 39) {
 579              $t0 = $S0[ $R0        & 0xff] ^
 580                    $S1[($R0 >>  8) & 0xff] ^
 581                    $S2[($R0 >> 16) & 0xff] ^
 582                    $S3[($R0 >> 24) & 0xff];
 583              $t1 = $S0[($R1 >> 24) & 0xff] ^
 584                    $S1[ $R1        & 0xff] ^
 585                    $S2[($R1 >>  8) & 0xff] ^
 586                    $S3[($R1 >> 16) & 0xff];
 587              $R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
 588              $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
 589              $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
 590  
 591              $t0 = $S0[ $R2        & 0xff] ^
 592                    $S1[($R2 >>  8) & 0xff] ^
 593                    $S2[($R2 >> 16) & 0xff] ^
 594                    $S3[($R2 >> 24) & 0xff];
 595              $t1 = $S0[($R3 >> 24) & 0xff] ^
 596                    $S1[ $R3        & 0xff] ^
 597                    $S2[($R3 >>  8) & 0xff] ^
 598                    $S3[($R3 >> 16) & 0xff];
 599              $R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
 600              $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
 601              $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
 602          }
 603  
 604          // @codingStandardsIgnoreStart
 605          return pack("V4", $K[4] ^ $R2,
 606                            $K[5] ^ $R3,
 607                            $K[6] ^ $R0,
 608                            $K[7] ^ $R1);
 609          // @codingStandardsIgnoreEnd
 610      }
 611  
 612      /**
 613       * Decrypts a block
 614       *
 615       * @access private
 616       * @param string $in
 617       * @return string
 618       */
 619      function _decryptBlock($in)
 620      {
 621          $S0 = $this->S0;
 622          $S1 = $this->S1;
 623          $S2 = $this->S2;
 624          $S3 = $this->S3;
 625          $K  = $this->K;
 626  
 627          $in = unpack("V4", $in);
 628          $R0 = $K[4] ^ $in[1];
 629          $R1 = $K[5] ^ $in[2];
 630          $R2 = $K[6] ^ $in[3];
 631          $R3 = $K[7] ^ $in[4];
 632  
 633          $ki = 40;
 634          while ($ki > 8) {
 635              $t0 = $S0[$R0       & 0xff] ^
 636                    $S1[$R0 >>  8 & 0xff] ^
 637                    $S2[$R0 >> 16 & 0xff] ^
 638                    $S3[$R0 >> 24 & 0xff];
 639              $t1 = $S0[$R1 >> 24 & 0xff] ^
 640                    $S1[$R1       & 0xff] ^
 641                    $S2[$R1 >>  8 & 0xff] ^
 642                    $S3[$R1 >> 16 & 0xff];
 643              $R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
 644              $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
 645              $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
 646  
 647              $t0 = $S0[$R2       & 0xff] ^
 648                    $S1[$R2 >>  8 & 0xff] ^
 649                    $S2[$R2 >> 16 & 0xff] ^
 650                    $S3[$R2 >> 24 & 0xff];
 651              $t1 = $S0[$R3 >> 24 & 0xff] ^
 652                    $S1[$R3       & 0xff] ^
 653                    $S2[$R3 >>  8 & 0xff] ^
 654                    $S3[$R3 >> 16 & 0xff];
 655              $R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
 656              $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
 657              $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
 658          }
 659  
 660          // @codingStandardsIgnoreStart
 661          return pack("V4", $K[0] ^ $R2,
 662                            $K[1] ^ $R3,
 663                            $K[2] ^ $R0,
 664                            $K[3] ^ $R1);
 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      function _setupInlineCrypt()
 675      {
 676          $lambda_functions =& self::_getLambdaFunctions();
 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          $safeint = $this->safe_intval_inline();
 689  
 690          if (!isset($lambda_functions[$code_hash])) {
 691              switch (true) {
 692                  case $gen_hi_opt_code:
 693                      $K = $this->K;
 694                      $init_crypt = '
 695                          static $S0, $S1, $S2, $S3;
 696                          if (!$S0) {
 697                              for ($i = 0; $i < 256; ++$i) {
 698                                  $S0[] = (int)$self->S0[$i];
 699                                  $S1[] = (int)$self->S1[$i];
 700                                  $S2[] = (int)$self->S2[$i];
 701                                  $S3[] = (int)$self->S3[$i];
 702                              }
 703                          }
 704                      ';
 705                      break;
 706                  default:
 707                      $K   = array();
 708                      for ($i = 0; $i < 40; ++$i) {
 709                          $K[] = '$K_' . $i;
 710                      }
 711                      $init_crypt = '
 712                          $S0 = $self->S0;
 713                          $S1 = $self->S1;
 714                          $S2 = $self->S2;
 715                          $S3 = $self->S3;
 716                          list(' . implode(',', $K) . ') = $self->K;
 717                      ';
 718              }
 719  
 720              // Generating encrypt code:
 721              $encrypt_block = '
 722                  $in = unpack("V4", $in);
 723                  $R0 = '.$K[0].' ^ $in[1];
 724                  $R1 = '.$K[1].' ^ $in[2];
 725                  $R2 = '.$K[2].' ^ $in[3];
 726                  $R3 = '.$K[3].' ^ $in[4];
 727              ';
 728              for ($ki = 7, $i = 0; $i < 8; ++$i) {
 729                  $encrypt_block.= '
 730                      $t0 = $S0[ $R0        & 0xff] ^
 731                            $S1[($R0 >>  8) & 0xff] ^
 732                            $S2[($R0 >> 16) & 0xff] ^
 733                            $S3[($R0 >> 24) & 0xff];
 734                      $t1 = $S0[($R1 >> 24) & 0xff] ^
 735                            $S1[ $R1        & 0xff] ^
 736                            $S2[($R1 >>  8) & 0xff] ^
 737                            $S3[($R1 >> 16) & 0xff];
 738                      $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . ';
 739                      $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
 740                      $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
 741  
 742                      $t0 = $S0[ $R2        & 0xff] ^
 743                            $S1[($R2 >>  8) & 0xff] ^
 744                            $S2[($R2 >> 16) & 0xff] ^
 745                            $S3[($R2 >> 24) & 0xff];
 746                      $t1 = $S0[($R3 >> 24) & 0xff] ^
 747                            $S1[ $R3        & 0xff] ^
 748                            $S2[($R3 >>  8) & 0xff] ^
 749                            $S3[($R3 >> 16) & 0xff];
 750                      $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . ';
 751                      $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
 752                      $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
 753                  ';
 754              }
 755              $encrypt_block.= '
 756                  $in = pack("V4", ' . $K[4] . ' ^ $R2,
 757                                   ' . $K[5] . ' ^ $R3,
 758                                   ' . $K[6] . ' ^ $R0,
 759                                   ' . $K[7] . ' ^ $R1);
 760              ';
 761  
 762              // Generating decrypt code:
 763              $decrypt_block = '
 764                  $in = unpack("V4", $in);
 765                  $R0 = '.$K[4].' ^ $in[1];
 766                  $R1 = '.$K[5].' ^ $in[2];
 767                  $R2 = '.$K[6].' ^ $in[3];
 768                  $R3 = '.$K[7].' ^ $in[4];
 769              ';
 770              for ($ki = 40, $i = 0; $i < 8; ++$i) {
 771                  $decrypt_block.= '
 772                      $t0 = $S0[$R0       & 0xff] ^
 773                            $S1[$R0 >>  8 & 0xff] ^
 774                            $S2[$R0 >> 16 & 0xff] ^
 775                            $S3[$R0 >> 24 & 0xff];
 776                      $t1 = $S0[$R1 >> 24 & 0xff] ^
 777                            $S1[$R1       & 0xff] ^
 778                            $S2[$R1 >>  8 & 0xff] ^
 779                            $S3[$R1 >> 16 & 0xff];
 780                      $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
 781                      $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
 782                      $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
 783  
 784                      $t0 = $S0[$R2       & 0xff] ^
 785                            $S1[$R2 >>  8 & 0xff] ^
 786                            $S2[$R2 >> 16 & 0xff] ^
 787                            $S3[$R2 >> 24 & 0xff];
 788                      $t1 = $S0[$R3 >> 24 & 0xff] ^
 789                            $S1[$R3       & 0xff] ^
 790                            $S2[$R3 >>  8 & 0xff] ^
 791                            $S3[$R3 >> 16 & 0xff];
 792                      $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
 793                      $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
 794                      $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
 795                  ';
 796              }
 797              $decrypt_block.= '
 798                  $in = pack("V4", ' . $K[0] . ' ^ $R2,
 799                                   ' . $K[1] . ' ^ $R3,
 800                                   ' . $K[2] . ' ^ $R0,
 801                                   ' . $K[3] . ' ^ $R1);
 802              ';
 803  
 804              $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
 805                  array(
 806                     'init_crypt'    => $init_crypt,
 807                     'init_encrypt'  => '',
 808                     'init_decrypt'  => '',
 809                     'encrypt_block' => $encrypt_block,
 810                     'decrypt_block' => $decrypt_block
 811                  )
 812              );
 813          }
 814          $this->inline_crypt = $lambda_functions[$code_hash];
 815      }
 816  }