includes/rijndael.php
changeset 595 b051eb79b158
parent 518 2b826f2640e9
child 602 ecbc8d202058
equal deleted inserted replaced
594:738c61b498a6 595:b051eb79b158
     1 <?php
     1 <?php
     2 
     2 
     3 /**
     3 /**
     4  * Phijndael - an implementation of the AES encryption standard in PHP
     4  * AES (Rijndael)
     5  * Originally written by Fritz Schneider <fritz AT cd DOT ucsd DOT edu>
     5  * EBC and CBC modes
     6  * Ported to PHP by Dan Fuhry <dan AT enano DOT homelinux DOT org>
     6  * 
     7  * @package phijndael
     7  * Flash port by:
     8  * @author Fritz Schneider
     8  * André S. Barbosa <andre@infolink.com.br>
     9  * @author Dan Fuhry
     9  * http://www.codecta.com.br/rijndael.html
    10  * @license BSD-style license
    10  * This is free code!
       
    11  *
       
    12  * Original code from OpenSSL Library.
       
    13  * Use is very closed to OpenSSL.
    11  */
    14  */
       
    15 
       
    16 
       
    17 /**
       
    18  * rijndael-alg-fst.c
       
    19  *
       
    20  * @version 3.0 (December 2000)
       
    21  *
       
    22  * Optimised ANSI C code for the Rijndael cipher (now AES)
       
    23  *
       
    24  * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
       
    25  * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
       
    26  * @author Paulo Barreto <paulo.barreto@terra.com.br>
       
    27  *
       
    28  * The original C code is released into the public domain. The Enano
       
    29  * Project has relicensed this port under the GNU General Public
       
    30  * License for license compatibility reasons.
       
    31  *
       
    32  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
       
    33  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    34  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
       
    36  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
    37  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
    38  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
       
    39  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
       
    40  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
       
    41  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
       
    42  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    43  */
       
    44 
    12 
    45 
    13 define ('ENC_HEX', 201);
    46 define ('ENC_HEX', 201);
    14 define ('ENC_BASE64', 202);
    47 define ('ENC_BASE64', 202);
    15 define ('ENC_BINARY', 203);
    48 define ('ENC_BINARY', 203);
    16 
    49 
    17 $_aes_objcache = array();
    50 class librijndael2
    18 
    51 {
    19 class AESCrypt {
    52   //////////////////// CONVERSION FUNCTIONS ///////////////////////////
    20   
    53 
    21   var $debug = false;
    54   // Byte to hex
    22   var $mcrypt = false;
    55   static function byte2hex($byte)
    23   var $decrypt_cache = array();
    56   {
    24 
    57     if ( strlen(dechex(ord($byte))) < 2 )
    25   // Rijndael parameters --  Valid values are 128, 192, or 256
    58       return ( "0" . dechex(ord($byte)) );
    26   
    59     else 
    27   var $keySizeInBits = 128;
    60       return ( dechex(ord($byte)) );
    28   var $blockSizeInBits = 128;
    61   }
    29   
    62 
    30   ///////  You shouldn't have to modify anything below this line except for
    63 
    31   ///////  the function getRandomBytes().
    64   /* Convert String to Hex String 
    32   //
    65    * Null byte cannot appear in middle of String.
    33   // Note: in the following code the two dimensional arrays are indexed as
    66    * this function is necessary because toString(16) does not 
    34   //       you would probably expect, as array[row][column]. The state arrays
    67    * produces two hex caracters for 0 to 15.
    35   //       are 2d arrays of the form state[4][Nb].
    68    */
    36   
    69   static function string2hex ($s) {
    37   
    70     $hex = '';
    38   // The number of rounds for the cipher, indexed by [Nk][Nb]
    71     for ($x = 0; $x < strlen($s); $x++) {
    39   var $roundsArray = Array(0,0,0,0,Array(0,0,0,0,10,0, 12,0, 14),0, 
    72       $byte = $s{$x};
    40                                Array(0,0,0,0,12,0, 12,0, 14),0, 
    73       $hex .= librijndael2::byte2hex($byte);
    41                                Array(0,0,0,0,14,0, 14,0, 14) );
    74     }
    42   
    75 
    43   // The number of bytes to shift by in shiftRow, indexed by [Nb][row]
    76     return $hex;
    44   var $shiftOffsets = Array(0,0,0,0,Array(0,1, 2, 3),0,Array(0,1, 2, 3),0,Array(0,1, 3, 4) );
    77   }
    45   
    78            
    46   // The round constants used in subkey expansion
    79   /* Convert Hex String to String  
    47   var $Rcon = Array( 
    80    * 00 (NULL)  is not converted!
    48   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 
    81    * Hex String must be even number of chars (A must be 0A, F must be 0F, etc)
    49   0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 
    82    */
    50   0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 
    83   static function hex2string($hex) {
    51   0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 
    84     $s = '';
    52   0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 );
    85     if (strlen($hex) % 2 == 1) {
    53   
    86       librijndael2::trace("Error: Hex String must be even number of chars");
    54   // Precomputed lookup table for the SBox
    87       return -1;
    55   var $SBox = Array(
    88     }
    56    99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 
    89 
    57   118, 202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 
    90     for ( $i = 0; $i < strlen($hex); $i+=2 )
    58   114, 192, 183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 
    91     {
    59   216,  49,  21,   4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 
    92       $byte = $hex{$i} . $hex{$i+1};
    60   235,  39, 178, 117,   9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 
    93       $s .= chr(hexdec($byte));
    61   179,  41, 227,  47, 132,  83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 
    94     }
    62   190,  57,  74,  76,  88, 207, 208, 239, 170, 251,  67,  77,  51, 133,  69, 
    95           
    63   249,   2, 127,  80,  60, 159, 168,  81, 163,  64, 143, 146, 157,  56, 245, 
    96     return $s;
    64   188, 182, 218,  33,  16, 255, 243, 210, 205,  12,  19, 236,  95, 151,  68,  
    97   }
    65   23,  196, 167, 126,  61, 100,  93,  25, 115,  96, 129,  79, 220,  34,  42, 
    98   
    66   144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 224,  50,  58,  10,  73,
    99   static function trace($error)
    67     6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 231, 200,  55, 109, 
   100   {
    68   141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 186, 120,  37,  
   101     //$bt = debug_backtrace();
    69    46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 112,  62, 
   102     echo("$error\n");
    70   181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 225,
   103     //echo(print_r($bt, true));
    71   248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223,
   104     
    72   140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  
   105     exit();
    73    22 );
   106   }
    74   
   107   
    75   // Precomputed lookup table for the inverse SBox
   108   static function parseInt($str)
    76   var $SBoxInverse = Array(
   109   {
    77    82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243, 215, 
   110     if ( is_int($str) )
    78   251, 124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68, 196, 222, 
   111       return $str;
    79   233, 203,  84, 123, 148,  50, 166, 194,  35,  61, 238,  76, 149,  11,  66, 
   112     if ( !is_string($str) )
    80   250, 195,  78,   8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73, 
   113       librijndael2::trace('Error: non-string (' . gettype($str) . ') passed to librijndael2::parseInt(' . $str . ')');
    81   109, 139, 209,  37, 114, 248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 
   114     if ( substr($str, 0, 2) == '0x' )
    82   204,  93, 101, 182, 146, 108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  
   115     {
    83    70,  87, 167, 141, 157, 132, 144, 216, 171,   0, 140, 188, 211,  10, 247, 
   116       return ( preg_match('/^0x([a-f0-9][a-f0-9])+$/i', $str) ) ? eval("return $str;") : intval($str);
    84   228,  88,   5, 184, 179,  69,   6, 208,  44,  30, 143, 202,  63,  15,   2, 
   117     }
    85   193, 175, 189,   3,   1,  19, 138, 107,  58, 145,  17,  65,  79, 103, 220, 
   118     return intval($str);
    86   234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116,  34, 231, 173,
   119   }
    87    53, 133, 226, 249,  55, 232,  28, 117, 223, 110,  71, 241,  26, 113,  29, 
   120   
    88    41, 197, 137, 111, 183,  98,  14, 170,  24, 190,  27, 252,  86,  62,  75, 
   121   static function ord2hex($byte)
    89   198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244,  31, 221, 168,
   122   {
    90    51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95,  96,  81,
   123     if ( !is_int($byte) )
    91   127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239, 160,
   124       librijndael2::trace('Error: non-integer passed to ord2hex()');
    92   224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97, 
   125     $result = strval(dechex($byte));
    93    23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12,
   126     if ( strlen($result) < 2 )
    94   125 );
   127       $result = "0$result";
    95   
   128     return $result;
    96   function __construct($ks = 128, $bs = 128, $debug = false)
   129   }
    97   {
   130 }
    98     $this->keySizeInBits = $ks;
   131 
    99     $this->blockSizeInBits = $bs;
   132 class Crypt_Rijndael
   100     
   133 {
   101     // Use the Mcrypt library? This speeds things up dramatically.
   134 
   102     if(defined('MCRYPT_RIJNDAEL_' . $ks) && defined('MCRYPT_ACCEL'))
   135  //////////////////// TABLES, STRUCTURES... ////////////////////////
   103     {
   136    
   104       eval('$mcb = MCRYPT_RIJNDAEL_' . $ks.';');
   137   var $Te0 = array(
   105       $bks = mcrypt_module_get_algo_block_size($mcb);
   138     0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
   106       $bks = $bks * 8;
   139     0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
   107       if ( $bks != $bs )
   140     0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
       
   141     0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
       
   142     0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
       
   143     0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
       
   144     0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
       
   145     0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
       
   146     0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
       
   147     0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
       
   148     0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
       
   149     0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
       
   150     0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
       
   151     0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
       
   152     0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
       
   153     0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
       
   154     0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
       
   155     0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
       
   156     0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
       
   157     0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
       
   158     0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
       
   159     0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
       
   160     0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
       
   161     0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
       
   162     0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
       
   163     0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
       
   164     0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
       
   165     0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
       
   166     0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
       
   167     0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
       
   168     0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
       
   169     0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
       
   170     0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
       
   171     0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
       
   172     0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
       
   173     0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
       
   174     0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
       
   175     0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
       
   176     0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
       
   177     0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
       
   178     0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
       
   179     0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
       
   180     0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
       
   181     0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
       
   182     0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
       
   183     0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
       
   184     0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
       
   185     0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
       
   186     0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
       
   187     0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
       
   188     0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
       
   189     0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
       
   190     0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
       
   191     0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
       
   192     0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
       
   193     0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
       
   194     0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
       
   195     0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
       
   196     0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
       
   197     0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
       
   198     0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
       
   199     0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
       
   200     0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
       
   201     0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
       
   202   );
       
   203   
       
   204   var $Te1 = array(
       
   205     0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
       
   206     0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
       
   207     0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
       
   208     0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
       
   209     0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,
       
   210     0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
       
   211     0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,
       
   212     0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
       
   213     0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
       
   214     0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
       
   215     0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1,
       
   216     0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
       
   217     0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,
       
   218     0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
       
   219     0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
       
   220     0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
       
   221     0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,
       
   222     0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
       
   223     0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,
       
   224     0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
       
   225     0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
       
   226     0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
       
   227     0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,
       
   228     0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
       
   229     0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,
       
   230     0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
       
   231     0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
       
   232     0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
       
   233     0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,
       
   234     0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
       
   235     0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,
       
   236     0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
       
   237     0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
       
   238     0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
       
   239     0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,
       
   240     0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
       
   241     0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,
       
   242     0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
       
   243     0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
       
   244     0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
       
   245     0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,
       
   246     0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
       
   247     0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,
       
   248     0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
       
   249     0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
       
   250     0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
       
   251     0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea,
       
   252     0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
       
   253     0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,
       
   254     0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
       
   255     0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
       
   256     0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
       
   257     0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,
       
   258     0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
       
   259     0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,
       
   260     0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
       
   261     0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
       
   262     0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
       
   263     0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,
       
   264     0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
       
   265     0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,
       
   266     0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
       
   267     0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
       
   268     0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616     
       
   269   );
       
   270   
       
   271   var $Te2 = array(
       
   272     0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
       
   273     0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
       
   274     0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
       
   275     0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
       
   276     0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,
       
   277     0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
       
   278     0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,
       
   279     0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
       
   280     0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
       
   281     0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
       
   282     0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,
       
   283     0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
       
   284     0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,
       
   285     0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
       
   286     0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
       
   287     0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
       
   288     0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,
       
   289     0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
       
   290     0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,
       
   291     0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
       
   292     0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
       
   293     0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
       
   294     0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,
       
   295     0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
       
   296     0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,
       
   297     0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
       
   298     0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
       
   299     0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
       
   300     0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,
       
   301     0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
       
   302     0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,
       
   303     0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
       
   304     0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
       
   305     0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
       
   306     0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,
       
   307     0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
       
   308     0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,
       
   309     0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
       
   310     0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
       
   311     0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
       
   312     0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a,
       
   313     0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
       
   314     0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,
       
   315     0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
       
   316     0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
       
   317     0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
       
   318     0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,
       
   319     0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
       
   320     0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,
       
   321     0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
       
   322     0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
       
   323     0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
       
   324     0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,
       
   325     0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
       
   326     0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,
       
   327     0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
       
   328     0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
       
   329     0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
       
   330     0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,
       
   331     0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
       
   332     0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d,
       
   333     0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
       
   334     0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
       
   335     0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16
       
   336   );
       
   337   
       
   338   var $Te3 = array(
       
   339     0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
       
   340     0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
       
   341     0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
       
   342     0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
       
   343     0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,
       
   344     0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
       
   345     0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,
       
   346     0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
       
   347     0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
       
   348     0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
       
   349     0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,
       
   350     0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
       
   351     0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,
       
   352     0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
       
   353     0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
       
   354     0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
       
   355     0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,
       
   356     0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
       
   357     0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,
       
   358     0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
       
   359     0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
       
   360     0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
       
   361     0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,
       
   362     0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
       
   363     0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,
       
   364     0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
       
   365     0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
       
   366     0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
       
   367     0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,
       
   368     0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
       
   369     0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,
       
   370     0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
       
   371     0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
       
   372     0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
       
   373     0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,
       
   374     0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
       
   375     0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,
       
   376     0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
       
   377     0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
       
   378     0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
       
   379     0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14,
       
   380     0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
       
   381     0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,
       
   382     0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
       
   383     0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
       
   384     0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
       
   385     0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,
       
   386     0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
       
   387     0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,
       
   388     0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
       
   389     0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
       
   390     0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
       
   391     0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,
       
   392     0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
       
   393     0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,
       
   394     0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
       
   395     0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
       
   396     0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
       
   397     0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,
       
   398     0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
       
   399     0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a,
       
   400     0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
       
   401     0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
       
   402     0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c
       
   403   );
       
   404   
       
   405   var $Te4 = array(
       
   406     0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,
       
   407     0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5,
       
   408     0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b,
       
   409     0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676,
       
   410     0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d,
       
   411     0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0,
       
   412     0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf,
       
   413     0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
       
   414     0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,
       
   415     0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc,
       
   416     0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1,
       
   417     0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
       
   418     0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3,
       
   419     0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a,
       
   420     0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2,
       
   421     0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
       
   422     0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a,
       
   423     0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,
       
   424     0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3,
       
   425     0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
       
   426     0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed,
       
   427     0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b,
       
   428     0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939,
       
   429     0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
       
   430     0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb,
       
   431     0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585,
       
   432     0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,
       
   433     0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
       
   434     0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f,
       
   435     0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5,
       
   436     0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121,
       
   437     0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
       
   438     0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec,
       
   439     0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717,
       
   440     0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d,
       
   441     0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
       
   442     0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc,
       
   443     0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888,
       
   444     0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414,
       
   445     0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb,
       
   446     0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a,
       
   447     0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c,
       
   448     0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262,
       
   449     0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
       
   450     0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,
       
   451     0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9,
       
   452     0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea,
       
   453     0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
       
   454     0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e,
       
   455     0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6,
       
   456     0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f,
       
   457     0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
       
   458     0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666,
       
   459     0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,
       
   460     0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9,
       
   461     0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
       
   462     0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111,
       
   463     0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494,
       
   464     0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9,
       
   465     0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
       
   466     0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d,
       
   467     0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868,
       
   468     0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
       
   469     0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616
       
   470   );
       
   471   
       
   472   var $Td0 = array(
       
   473     0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
       
   474     0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
       
   475     0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
       
   476     0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
       
   477     0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
       
   478     0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
       
   479     0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
       
   480     0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
       
   481     0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
       
   482     0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
       
   483     0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
       
   484     0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
       
   485     0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
       
   486     0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
       
   487     0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
       
   488     0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
       
   489     0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
       
   490     0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
       
   491     0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
       
   492     0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
       
   493     0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
       
   494     0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
       
   495     0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
       
   496     0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
       
   497     0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
       
   498     0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
       
   499     0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
       
   500     0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
       
   501     0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
       
   502     0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
       
   503     0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
       
   504     0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
       
   505     0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
       
   506     0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
       
   507     0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
       
   508     0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
       
   509     0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
       
   510     0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
       
   511     0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
       
   512     0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
       
   513     0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
       
   514     0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
       
   515     0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
       
   516     0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
       
   517     0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
       
   518     0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
       
   519     0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
       
   520     0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
       
   521     0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
       
   522     0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
       
   523     0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
       
   524     0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
       
   525     0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
       
   526     0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
       
   527     0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
       
   528     0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
       
   529     0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
       
   530     0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
       
   531     0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
       
   532     0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
       
   533     0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
       
   534     0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
       
   535     0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
       
   536     0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
       
   537   );
       
   538   
       
   539   var $Td1 = array(
       
   540     0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,
       
   541     0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
       
   542     0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,
       
   543     0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
       
   544     0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0,
       
   545     0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
       
   546     0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259,
       
   547     0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
       
   548     0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,
       
   549     0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
       
   550     0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f,
       
   551     0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
       
   552     0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8,
       
   553     0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
       
   554     0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708,
       
   555     0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
       
   556     0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2,
       
   557     0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
       
   558     0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb,
       
   559     0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
       
   560     0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,
       
   561     0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
       
   562     0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e,
       
   563     0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
       
   564     0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000,
       
   565     0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
       
   566     0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,
       
   567     0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
       
   568     0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91,
       
   569     0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
       
   570     0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17,
       
   571     0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
       
   572     0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,
       
   573     0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
       
   574     0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1,
       
   575     0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
       
   576     0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1,
       
   577     0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
       
   578     0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,
       
   579     0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
       
   580     0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b,
       
   581     0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
       
   582     0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46,
       
   583     0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
       
   584     0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,
       
   585     0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
       
   586     0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a,
       
   587     0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
       
   588     0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c,
       
   589     0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
       
   590     0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,
       
   591     0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
       
   592     0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604,
       
   593     0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
       
   594     0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41,
       
   595     0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
       
   596     0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,
       
   597     0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
       
   598     0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737,
       
   599     0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
       
   600     0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340,
       
   601     0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
       
   602     0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
       
   603     0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857
       
   604   );
       
   605   
       
   606   var $Td2 = array(
       
   607     0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,
       
   608     0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
       
   609     0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,
       
   610     0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
       
   611     0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe,
       
   612     0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
       
   613     0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552,
       
   614     0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
       
   615     0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,
       
   616     0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
       
   617     0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253,
       
   618     0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
       
   619     0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b,
       
   620     0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
       
   621     0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337,
       
   622     0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
       
   623     0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69,
       
   624     0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
       
   625     0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6,
       
   626     0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
       
   627     0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6,
       
   628     0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
       
   629     0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9,
       
   630     0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
       
   631     0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000,
       
   632     0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
       
   633     0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,
       
   634     0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
       
   635     0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b,
       
   636     0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
       
   637     0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b,
       
   638     0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
       
   639     0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f,
       
   640     0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
       
   641     0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4,
       
   642     0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
       
   643     0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729,
       
   644     0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
       
   645     0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,
       
   646     0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
       
   647     0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4,
       
   648     0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
       
   649     0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e,
       
   650     0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
       
   651     0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,
       
   652     0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
       
   653     0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f,
       
   654     0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
       
   655     0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0,
       
   656     0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
       
   657     0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,
       
   658     0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
       
   659     0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496,
       
   660     0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
       
   661     0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b,
       
   662     0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
       
   663     0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13,
       
   664     0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
       
   665     0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7,
       
   666     0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
       
   667     0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3,
       
   668     0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
       
   669     0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
       
   670     0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8
       
   671   );
       
   672   
       
   673   var $Td3 = array(
       
   674     0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,
       
   675     0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
       
   676     0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5,
       
   677     0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
       
   678     0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d,
       
   679     0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
       
   680     0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95,
       
   681     0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
       
   682     0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,
       
   683     0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
       
   684     0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562,
       
   685     0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
       
   686     0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752,
       
   687     0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
       
   688     0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,
       
   689     0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
       
   690     0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e,
       
   691     0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
       
   692     0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4,
       
   693     0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
       
   694     0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,
       
   695     0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
       
   696     0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767,
       
   697     0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
       
   698     0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000,
       
   699     0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
       
   700     0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,
       
   701     0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
       
   702     0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b,
       
   703     0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
       
   704     0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12,
       
   705     0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
       
   706     0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,
       
   707     0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
       
   708     0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8,
       
   709     0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
       
   710     0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7,
       
   711     0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
       
   712     0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,
       
   713     0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
       
   714     0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698,
       
   715     0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
       
   716     0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254,
       
   717     0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
       
   718     0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,
       
   719     0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
       
   720     0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883,
       
   721     0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
       
   722     0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629,
       
   723     0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
       
   724     0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,
       
   725     0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
       
   726     0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4,
       
   727     0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
       
   728     0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb,
       
   729     0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
       
   730     0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,
       
   731     0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
       
   732     0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73,
       
   733     0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
       
   734     0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2,
       
   735     0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
       
   736     0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064,
       
   737     0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0
       
   738   );
       
   739   
       
   740   var $Td4 = array(
       
   741     0x52525252, 0x09090909, 0x6a6a6a6a, 0xd5d5d5d5,
       
   742     0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838,
       
   743     0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e,
       
   744     0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb,
       
   745     0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282,
       
   746     0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787,
       
   747     0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444,
       
   748     0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb,
       
   749     0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232,
       
   750     0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d,
       
   751     0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0x0b0b0b0b,
       
   752     0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e,
       
   753     0x08080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666,
       
   754     0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2,
       
   755     0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949,
       
   756     0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525,
       
   757     0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464,
       
   758     0x86868686, 0x68686868, 0x98989898, 0x16161616,
       
   759     0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc,
       
   760     0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292,
       
   761     0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050,
       
   762     0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada,
       
   763     0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757,
       
   764     0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484,
       
   765     0x90909090, 0xd8d8d8d8, 0xabababab, 0x00000000,
       
   766     0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0x0a0a0a0a,
       
   767     0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x05050505,
       
   768     0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x06060606,
       
   769     0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f,
       
   770     0xcacacaca, 0x3f3f3f3f, 0x0f0f0f0f, 0x02020202,
       
   771     0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x03030303,
       
   772     0x01010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b,
       
   773     0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141,
       
   774     0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea,
       
   775     0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece,
       
   776     0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373,
       
   777     0x96969696, 0xacacacac, 0x74747474, 0x22222222,
       
   778     0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585,
       
   779     0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8,
       
   780     0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e,
       
   781     0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171,
       
   782     0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989,
       
   783     0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0x0e0e0e0e,
       
   784     0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b,
       
   785     0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b,
       
   786     0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020,
       
   787     0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe,
       
   788     0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4,
       
   789     0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333,
       
   790     0x88888888, 0x07070707, 0xc7c7c7c7, 0x31313131,
       
   791     0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959,
       
   792     0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f,
       
   793     0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9,
       
   794     0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0x0d0d0d0d,
       
   795     0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f,
       
   796     0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef,
       
   797     0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d,
       
   798     0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0,
       
   799     0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c,
       
   800     0x83838383, 0x53535353, 0x99999999, 0x61616161,
       
   801     0x17171717, 0x2b2b2b2b, 0x04040404, 0x7e7e7e7e,
       
   802     0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626,
       
   803     0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363,
       
   804     0x55555555, 0x21212121, 0x0c0c0c0c, 0x7d7d7d7d
       
   805   );
       
   806   
       
   807   var $rcon = array(
       
   808     0x01000000, 0x02000000, 0x04000000, 0x08000000,
       
   809     0x10000000, 0x20000000, 0x40000000, 0x80000000,
       
   810     0x1B000000, 0x36000000
       
   811   );
       
   812 
       
   813   //////////////////// CORE FUNCTIONS ///////////////////////////
       
   814 
       
   815   // Encrypt a single block (bin) and return (bout)
       
   816   function AES_encrypt($bin, $key)
       
   817   {
       
   818     $rk = 0;
       
   819     
       
   820     if ($bin == '' || $key == '') {
       
   821       librijndael2::trace("AES_encrypt: bin/key undefined");
       
   822       return;
       
   823     }
       
   824     
       
   825     // FIXME: BAD: we need rd_key
       
   826   
       
   827     // map byte array block to cipher state
       
   828     // and add initial round key:
       
   829     
       
   830     $s0 = librijndael2::parseInt("0x" . substr($bin, 0 , 8)) ^ $key->rd_key[0];
       
   831     $s1 = librijndael2::parseInt("0x" . substr($bin, 8 , 8)) ^ $key->rd_key[1];
       
   832     $s2 = librijndael2::parseInt("0x" . substr($bin, 16, 8)) ^ $key->rd_key[2];
       
   833     $s3 = librijndael2::parseInt("0x" . substr($bin, 24, 8)) ^ $key->rd_key[3];
       
   834     
       
   835     // Using Full Unroll (Bigger more a bit faster :) )
       
   836     // round 1:
       
   837     $t0 = $this->Te0[($s0 >> 24) & 0xff] ^ $this->Te1[($s1 >> 16) & 0xff] ^ $this->Te2[($s2 >>  8) & 0xff] ^ $this->Te3[$s3 & 0xff] ^ $key->rd_key[4];
       
   838     $t1 = $this->Te0[($s1 >> 24) & 0xff] ^ $this->Te1[($s2 >> 16) & 0xff] ^ $this->Te2[($s3 >>  8) & 0xff] ^ $this->Te3[$s0 & 0xff] ^ $key->rd_key[5];
       
   839     $t2 = $this->Te0[($s2 >> 24) & 0xff] ^ $this->Te1[($s3 >> 16) & 0xff] ^ $this->Te2[($s0 >>  8) & 0xff] ^ $this->Te3[$s1 & 0xff] ^ $key->rd_key[6];
       
   840     $t3 = $this->Te0[($s3 >> 24) & 0xff] ^ $this->Te1[($s0 >> 16) & 0xff] ^ $this->Te2[($s1 >>  8) & 0xff] ^ $this->Te3[$s2 & 0xff] ^ $key->rd_key[7];
       
   841     $s0 = $this->Te0[($t0 >> 24) & 0xff] ^ $this->Te1[($t1 >> 16) & 0xff] ^ $this->Te2[($t2 >>  8) & 0xff] ^ $this->Te3[$t3 & 0xff] ^ $key->rd_key[8];
       
   842     $s1 = $this->Te0[($t1 >> 24) & 0xff] ^ $this->Te1[($t2 >> 16) & 0xff] ^ $this->Te2[($t3 >>  8) & 0xff] ^ $this->Te3[$t0 & 0xff] ^ $key->rd_key[9];
       
   843     $s2 = $this->Te0[($t2 >> 24) & 0xff] ^ $this->Te1[($t3 >> 16) & 0xff] ^ $this->Te2[($t0 >>  8) & 0xff] ^ $this->Te3[$t1 & 0xff] ^ $key->rd_key[10];
       
   844     $s3 = $this->Te0[($t3 >> 24) & 0xff] ^ $this->Te1[($t0 >> 16) & 0xff] ^ $this->Te2[($t1 >>  8) & 0xff] ^ $this->Te3[$t2 & 0xff] ^ $key->rd_key[11];
       
   845     $t0 = $this->Te0[($s0 >> 24) & 0xff] ^ $this->Te1[($s1 >> 16) & 0xff] ^ $this->Te2[($s2 >>  8) & 0xff] ^ $this->Te3[$s3 & 0xff] ^ $key->rd_key[12];
       
   846     $t1 = $this->Te0[($s1 >> 24) & 0xff] ^ $this->Te1[($s2 >> 16) & 0xff] ^ $this->Te2[($s3 >>  8) & 0xff] ^ $this->Te3[$s0 & 0xff] ^ $key->rd_key[13];
       
   847     $t2 = $this->Te0[($s2 >> 24) & 0xff] ^ $this->Te1[($s3 >> 16) & 0xff] ^ $this->Te2[($s0 >>  8) & 0xff] ^ $this->Te3[$s1 & 0xff] ^ $key->rd_key[14];
       
   848     $t3 = $this->Te0[($s3 >> 24) & 0xff] ^ $this->Te1[($s0 >> 16) & 0xff] ^ $this->Te2[($s1 >>  8) & 0xff] ^ $this->Te3[$s2 & 0xff] ^ $key->rd_key[15];
       
   849     $s0 = $this->Te0[($t0 >> 24) & 0xff] ^ $this->Te1[($t1 >> 16) & 0xff] ^ $this->Te2[($t2 >>  8) & 0xff] ^ $this->Te3[$t3 & 0xff] ^ $key->rd_key[16];
       
   850     $s1 = $this->Te0[($t1 >> 24) & 0xff] ^ $this->Te1[($t2 >> 16) & 0xff] ^ $this->Te2[($t3 >>  8) & 0xff] ^ $this->Te3[$t0 & 0xff] ^ $key->rd_key[17];
       
   851     $s2 = $this->Te0[($t2 >> 24) & 0xff] ^ $this->Te1[($t3 >> 16) & 0xff] ^ $this->Te2[($t0 >>  8) & 0xff] ^ $this->Te3[$t1 & 0xff] ^ $key->rd_key[18];
       
   852     $s3 = $this->Te0[($t3 >> 24) & 0xff] ^ $this->Te1[($t0 >> 16) & 0xff] ^ $this->Te2[($t1 >>  8) & 0xff] ^ $this->Te3[$t2 & 0xff] ^ $key->rd_key[19];
       
   853     $t0 = $this->Te0[($s0 >> 24) & 0xff] ^ $this->Te1[($s1 >> 16) & 0xff] ^ $this->Te2[($s2 >>  8) & 0xff] ^ $this->Te3[$s3 & 0xff] ^ $key->rd_key[20];
       
   854     $t1 = $this->Te0[($s1 >> 24) & 0xff] ^ $this->Te1[($s2 >> 16) & 0xff] ^ $this->Te2[($s3 >>  8) & 0xff] ^ $this->Te3[$s0 & 0xff] ^ $key->rd_key[21];
       
   855     $t2 = $this->Te0[($s2 >> 24) & 0xff] ^ $this->Te1[($s3 >> 16) & 0xff] ^ $this->Te2[($s0 >>  8) & 0xff] ^ $this->Te3[$s1 & 0xff] ^ $key->rd_key[22];
       
   856     $t3 = $this->Te0[($s3 >> 24) & 0xff] ^ $this->Te1[($s0 >> 16) & 0xff] ^ $this->Te2[($s1 >>  8) & 0xff] ^ $this->Te3[$s2 & 0xff] ^ $key->rd_key[23];
       
   857     $s0 = $this->Te0[($t0 >> 24) & 0xff] ^ $this->Te1[($t1 >> 16) & 0xff] ^ $this->Te2[($t2 >>  8) & 0xff] ^ $this->Te3[$t3 & 0xff] ^ $key->rd_key[24];
       
   858     $s1 = $this->Te0[($t1 >> 24) & 0xff] ^ $this->Te1[($t2 >> 16) & 0xff] ^ $this->Te2[($t3 >>  8) & 0xff] ^ $this->Te3[$t0 & 0xff] ^ $key->rd_key[25];
       
   859     $s2 = $this->Te0[($t2 >> 24) & 0xff] ^ $this->Te1[($t3 >> 16) & 0xff] ^ $this->Te2[($t0 >>  8) & 0xff] ^ $this->Te3[$t1 & 0xff] ^ $key->rd_key[26];
       
   860     $s3 = $this->Te0[($t3 >> 24) & 0xff] ^ $this->Te1[($t0 >> 16) & 0xff] ^ $this->Te2[($t1 >>  8) & 0xff] ^ $this->Te3[$t2 & 0xff] ^ $key->rd_key[27];
       
   861     $t0 = $this->Te0[($s0 >> 24) & 0xff] ^ $this->Te1[($s1 >> 16) & 0xff] ^ $this->Te2[($s2 >>  8) & 0xff] ^ $this->Te3[$s3 & 0xff] ^ $key->rd_key[28];
       
   862     $t1 = $this->Te0[($s1 >> 24) & 0xff] ^ $this->Te1[($s2 >> 16) & 0xff] ^ $this->Te2[($s3 >>  8) & 0xff] ^ $this->Te3[$s0 & 0xff] ^ $key->rd_key[29];
       
   863     $t2 = $this->Te0[($s2 >> 24) & 0xff] ^ $this->Te1[($s3 >> 16) & 0xff] ^ $this->Te2[($s0 >>  8) & 0xff] ^ $this->Te3[$s1 & 0xff] ^ $key->rd_key[30];
       
   864     $t3 = $this->Te0[($s3 >> 24) & 0xff] ^ $this->Te1[($s0 >> 16) & 0xff] ^ $this->Te2[($s1 >>  8) & 0xff] ^ $this->Te3[$s2 & 0xff] ^ $key->rd_key[31];
       
   865     $s0 = $this->Te0[($t0 >> 24) & 0xff] ^ $this->Te1[($t1 >> 16) & 0xff] ^ $this->Te2[($t2 >>  8) & 0xff] ^ $this->Te3[$t3 & 0xff] ^ $key->rd_key[32];
       
   866     $s1 = $this->Te0[($t1 >> 24) & 0xff] ^ $this->Te1[($t2 >> 16) & 0xff] ^ $this->Te2[($t3 >>  8) & 0xff] ^ $this->Te3[$t0 & 0xff] ^ $key->rd_key[33];
       
   867     $s2 = $this->Te0[($t2 >> 24) & 0xff] ^ $this->Te1[($t3 >> 16) & 0xff] ^ $this->Te2[($t0 >>  8) & 0xff] ^ $this->Te3[$t1 & 0xff] ^ $key->rd_key[34];
       
   868     $s3 = $this->Te0[($t3 >> 24) & 0xff] ^ $this->Te1[($t0 >> 16) & 0xff] ^ $this->Te2[($t1 >>  8) & 0xff] ^ $this->Te3[$t2 & 0xff] ^ $key->rd_key[35];
       
   869     $t0 = $this->Te0[($s0 >> 24) & 0xff] ^ $this->Te1[($s1 >> 16) & 0xff] ^ $this->Te2[($s2 >>  8) & 0xff] ^ $this->Te3[$s3 & 0xff] ^ $key->rd_key[36];
       
   870     $t1 = $this->Te0[($s1 >> 24) & 0xff] ^ $this->Te1[($s2 >> 16) & 0xff] ^ $this->Te2[($s3 >>  8) & 0xff] ^ $this->Te3[$s0 & 0xff] ^ $key->rd_key[37];
       
   871     $t2 = $this->Te0[($s2 >> 24) & 0xff] ^ $this->Te1[($s3 >> 16) & 0xff] ^ $this->Te2[($s0 >>  8) & 0xff] ^ $this->Te3[$s1 & 0xff] ^ $key->rd_key[38];
       
   872     $t3 = $this->Te0[($s3 >> 24) & 0xff] ^ $this->Te1[($s0 >> 16) & 0xff] ^ $this->Te2[($s1 >>  8) & 0xff] ^ $this->Te3[$s2 & 0xff] ^ $key->rd_key[39];
       
   873     
       
   874     // FIXME: BAD: need $key->rounds
       
   875     
       
   876     if ($key->rounds > 10) {
       
   877         // round 10:
       
   878         $s0 = $this->Te0[($t0 >> 24) & 0xff] ^ $this->Te1[($t1 >> 16) & 0xff] ^ $this->Te2[($t2 >>  8) & 0xff] ^ $this->Te3[$t3 & 0xff] ^ $key->rd_key[40];
       
   879         $s1 = $this->Te0[($t1 >> 24) & 0xff] ^ $this->Te1[($t2 >> 16) & 0xff] ^ $this->Te2[($t3 >>  8) & 0xff] ^ $this->Te3[$t0 & 0xff] ^ $key->rd_key[41];
       
   880         $s2 = $this->Te0[($t2 >> 24) & 0xff] ^ $this->Te1[($t3 >> 16) & 0xff] ^ $this->Te2[($t0 >>  8) & 0xff] ^ $this->Te3[$t1 & 0xff] ^ $key->rd_key[42];
       
   881         $s3 = $this->Te0[($t3 >> 24) & 0xff] ^ $this->Te1[($t0 >> 16) & 0xff] ^ $this->Te2[($t1 >>  8) & 0xff] ^ $this->Te3[$t2 & 0xff] ^ $key->rd_key[43];
       
   882         $t0 = $this->Te0[($s0 >> 24) & 0xff] ^ $this->Te1[($s1 >> 16) & 0xff] ^ $this->Te2[($s2 >>  8) & 0xff] ^ $this->Te3[$s3 & 0xff] ^ $key->rd_key[44];
       
   883         $t1 = $this->Te0[($s1 >> 24) & 0xff] ^ $this->Te1[($s2 >> 16) & 0xff] ^ $this->Te2[($s3 >>  8) & 0xff] ^ $this->Te3[$s0 & 0xff] ^ $key->rd_key[45];
       
   884         $t2 = $this->Te0[($s2 >> 24) & 0xff] ^ $this->Te1[($s3 >> 16) & 0xff] ^ $this->Te2[($s0 >>  8) & 0xff] ^ $this->Te3[$s1 & 0xff] ^ $key->rd_key[46];
       
   885         $t3 = $this->Te0[($s3 >> 24) & 0xff] ^ $this->Te1[($s0 >> 16) & 0xff] ^ $this->Te2[($s1 >>  8) & 0xff] ^ $this->Te3[$s2 & 0xff] ^ $key->rd_key[47];
       
   886         
       
   887       if ($key->rounds > 12) {
       
   888             $s0 = $this->Te0[($t0 >> 24) & 0xff] ^ $this->Te1[($t1 >> 16) & 0xff] ^ $this->Te2[($t2 >>  8) & 0xff] ^ $this->Te3[$t3 & 0xff] ^ $key->rd_key[48];
       
   889             $s1 = $this->Te0[($t1 >> 24) & 0xff] ^ $this->Te1[($t2 >> 16) & 0xff] ^ $this->Te2[($t3 >>  8) & 0xff] ^ $this->Te3[$t0 & 0xff] ^ $key->rd_key[49];
       
   890             $s2 = $this->Te0[($t2 >> 24) & 0xff] ^ $this->Te1[($t3 >> 16) & 0xff] ^ $this->Te2[($t0 >>  8) & 0xff] ^ $this->Te3[$t1 & 0xff] ^ $key->rd_key[50];
       
   891             $s3 = $this->Te0[($t3 >> 24) & 0xff] ^ $this->Te1[($t0 >> 16) & 0xff] ^ $this->Te2[($t1 >>  8) & 0xff] ^ $this->Te3[$t2 & 0xff] ^ $key->rd_key[51];
       
   892             $t0 = $this->Te0[($s0 >> 24) & 0xff] ^ $this->Te1[($s1 >> 16) & 0xff] ^ $this->Te2[($s2 >>  8) & 0xff] ^ $this->Te3[$s3 & 0xff] ^ $key->rd_key[52];
       
   893             $t1 = $this->Te0[($s1 >> 24) & 0xff] ^ $this->Te1[($s2 >> 16) & 0xff] ^ $this->Te2[($s3 >>  8) & 0xff] ^ $this->Te3[$s0 & 0xff] ^ $key->rd_key[53];
       
   894             $t2 = $this->Te0[($s2 >> 24) & 0xff] ^ $this->Te1[($s3 >> 16) & 0xff] ^ $this->Te2[($s0 >>  8) & 0xff] ^ $this->Te3[$s1 & 0xff] ^ $key->rd_key[54];
       
   895             $t3 = $this->Te0[($s3 >> 24) & 0xff] ^ $this->Te1[($s0 >> 16) & 0xff] ^ $this->Te2[($s1 >>  8) & 0xff] ^ $this->Te3[$s2 & 0xff] ^ $key->rd_key[55];   
       
   896         }
       
   897     }
       
   898    
       
   899     // This is correct
       
   900     $rk = $key->rounds << 2;
       
   901   
       
   902   
       
   903     /*
       
   904     // No Full Unroll 
       
   905     */
       
   906   
       
   907     // Apply last round and
       
   908     // map cipher state to byte array block:
       
   909      
       
   910     $s0 =  ($this->Te4[($t0 >> 24) & 0xff] & 0xff000000) ^
       
   911            ($this->Te4[($t1 >> 16) & 0xff] & 0x00ff0000) ^
       
   912            ($this->Te4[($t2 >>  8) & 0xff] & 0x0000ff00) ^
       
   913            ($this->Te4[($t3      ) & 0xff] & 0x000000ff) ^
       
   914             $key->rd_key[$rk];
       
   915   
       
   916     $out  = librijndael2::ord2hex(($s0 >> 24) & 0xff);
       
   917     $out .= librijndael2::ord2hex(($s0 >> 16) & 0xff);
       
   918     $out .= librijndael2::ord2hex(($s0 >> 8) & 0xff);
       
   919     $out .= librijndael2::ord2hex($s0 & 0xff);
       
   920 
       
   921     $s1 =  ($this->Te4[($t1 >> 24) & 0xff] & 0xff000000) ^
       
   922            ($this->Te4[($t2 >> 16) & 0xff] & 0x00ff0000) ^
       
   923            ($this->Te4[($t3 >>  8) & 0xff] & 0x0000ff00) ^
       
   924            ($this->Te4[($t0      ) & 0xff] & 0x000000ff) ^
       
   925            $key->rd_key[$rk+1];
       
   926       
       
   927     $out .= librijndael2::ord2hex(($s1 >> 24) & 0xff);
       
   928     $out .= librijndael2::ord2hex(($s1 >> 16) & 0xff);
       
   929     $out .= librijndael2::ord2hex(($s1 >> 8) & 0xff);
       
   930     $out .= librijndael2::ord2hex($s1 & 0xff);
       
   931     
       
   932     $s2 =  ($this->Te4[($t2 >> 24) & 0xff] & 0xff000000) ^
       
   933            ($this->Te4[($t3 >> 16) & 0xff] & 0x00ff0000) ^
       
   934            ($this->Te4[($t0 >>  8) & 0xff] & 0x0000ff00) ^
       
   935            ($this->Te4[($t1      ) & 0xff] & 0x000000ff) ^
       
   936            $key->rd_key[$rk+2];
       
   937 
       
   938     $out .= librijndael2::ord2hex(($s2 >> 24) & 0xff);
       
   939     $out .= librijndael2::ord2hex(($s2 >> 16) & 0xff);
       
   940     $out .= librijndael2::ord2hex(($s2 >> 8) & 0xff); 
       
   941     $out .= librijndael2::ord2hex($s2 & 0xff);
       
   942     
       
   943     $s3 =  ($this->Te4[($t3 >> 24) & 0xff] & 0xff000000) ^
       
   944            ($this->Te4[($t0 >> 16) & 0xff] & 0x00ff0000) ^
       
   945            ($this->Te4[($t1 >>  8) & 0xff] & 0x0000ff00) ^
       
   946            ($this->Te4[($t2      ) & 0xff] & 0x000000ff) ^
       
   947            $key->rd_key[$rk+3];
       
   948     
       
   949     $out .= librijndael2::ord2hex(($s3 >> 24) & 0xff);
       
   950     $out .= librijndael2::ord2hex(($s3 >> 16) & 0xff);
       
   951     $out .= librijndael2::ord2hex(($s3 >> 8) & 0xff);
       
   952     $out .= librijndael2::ord2hex($s3 & 0xff);
       
   953   
       
   954     return $out;
       
   955   }
       
   956 
       
   957 
       
   958   // Decrypt a single block (bin) and return (bout)
       
   959   function AES_decrypt($bin, $key)
       
   960   {
       
   961     $rk = 0;
       
   962     // var r;  // No Full Unroll
       
   963 
       
   964     if ($bin == '' || $key == '')
       
   965     {
       
   966       librijndael2::trace("AES_decrypt: bin/key undefined");
       
   967       return;
       
   968     }
       
   969     
       
   970     // FIXME: BAD: need $key->rd_key
       
   971 
       
   972     // map byte array block to cipher state
       
   973     // and add initial round key:
       
   974     $s0 = librijndael2::parseInt("0x" . substr($bin, 0 , 8)) ^ $key->rd_key[0];
       
   975     $s1 = librijndael2::parseInt("0x" . substr($bin, 8 , 8)) ^ $key->rd_key[1];
       
   976     $s2 = librijndael2::parseInt("0x" . substr($bin, 16, 8)) ^ $key->rd_key[2];
       
   977     $s3 = librijndael2::parseInt("0x" . substr($bin, 24, 8)) ^ $key->rd_key[3];
       
   978    
       
   979     // Using Full Unroll (Bigger more a bit faster :) )
       
   980     $t0 = $this->Td0[($s0 >> 24) & 0xff] ^ $this->Td1[($s3 >> 16) & 0xff] ^ $this->Td2[($s2 >>  8) & 0xff] ^ $this->Td3[$s1 & 0xff] ^ $key->rd_key[4];  // ROUND 1
       
   981     $t1 = $this->Td0[($s1 >> 24) & 0xff] ^ $this->Td1[($s0 >> 16) & 0xff] ^ $this->Td2[($s3 >>  8) & 0xff] ^ $this->Td3[$s2 & 0xff] ^ $key->rd_key[5];
       
   982     $t2 = $this->Td0[($s2 >> 24) & 0xff] ^ $this->Td1[($s1 >> 16) & 0xff] ^ $this->Td2[($s0 >>  8) & 0xff] ^ $this->Td3[$s3 & 0xff] ^ $key->rd_key[6];
       
   983     $t3 = $this->Td0[($s3 >> 24) & 0xff] ^ $this->Td1[($s2 >> 16) & 0xff] ^ $this->Td2[($s1 >>  8) & 0xff] ^ $this->Td3[$s0 & 0xff] ^ $key->rd_key[7];
       
   984     $s0 = $this->Td0[($t0 >> 24) & 0xff] ^ $this->Td1[($t3 >> 16) & 0xff] ^ $this->Td2[($t2 >>  8) & 0xff] ^ $this->Td3[$t1 & 0xff] ^ $key->rd_key[8];  // ROUND 2
       
   985     $s1 = $this->Td0[($t1 >> 24) & 0xff] ^ $this->Td1[($t0 >> 16) & 0xff] ^ $this->Td2[($t3 >>  8) & 0xff] ^ $this->Td3[$t2 & 0xff] ^ $key->rd_key[9];
       
   986     $s2 = $this->Td0[($t2 >> 24) & 0xff] ^ $this->Td1[($t1 >> 16) & 0xff] ^ $this->Td2[($t0 >>  8) & 0xff] ^ $this->Td3[$t3 & 0xff] ^ $key->rd_key[10];
       
   987     $s3 = $this->Td0[($t3 >> 24) & 0xff] ^ $this->Td1[($t2 >> 16) & 0xff] ^ $this->Td2[($t1 >>  8) & 0xff] ^ $this->Td3[$t0 & 0xff] ^ $key->rd_key[11];
       
   988     $t0 = $this->Td0[($s0 >> 24) & 0xff] ^ $this->Td1[($s3 >> 16) & 0xff] ^ $this->Td2[($s2 >>  8) & 0xff] ^ $this->Td3[$s1 & 0xff] ^ $key->rd_key[12]; // ROUND 3
       
   989     $t1 = $this->Td0[($s1 >> 24) & 0xff] ^ $this->Td1[($s0 >> 16) & 0xff] ^ $this->Td2[($s3 >>  8) & 0xff] ^ $this->Td3[$s2 & 0xff] ^ $key->rd_key[13];
       
   990     $t2 = $this->Td0[($s2 >> 24) & 0xff] ^ $this->Td1[($s1 >> 16) & 0xff] ^ $this->Td2[($s0 >>  8) & 0xff] ^ $this->Td3[$s3 & 0xff] ^ $key->rd_key[14];
       
   991     $t3 = $this->Td0[($s3 >> 24) & 0xff] ^ $this->Td1[($s2 >> 16) & 0xff] ^ $this->Td2[($s1 >>  8) & 0xff] ^ $this->Td3[$s0 & 0xff] ^ $key->rd_key[15];
       
   992     $s0 = $this->Td0[($t0 >> 24) & 0xff] ^ $this->Td1[($t3 >> 16) & 0xff] ^ $this->Td2[($t2 >>  8) & 0xff] ^ $this->Td3[$t1 & 0xff] ^ $key->rd_key[16]; // ROUND 4
       
   993     $s1 = $this->Td0[($t1 >> 24) & 0xff] ^ $this->Td1[($t0 >> 16) & 0xff] ^ $this->Td2[($t3 >>  8) & 0xff] ^ $this->Td3[$t2 & 0xff] ^ $key->rd_key[17];
       
   994     $s2 = $this->Td0[($t2 >> 24) & 0xff] ^ $this->Td1[($t1 >> 16) & 0xff] ^ $this->Td2[($t0 >>  8) & 0xff] ^ $this->Td3[$t3 & 0xff] ^ $key->rd_key[18];
       
   995     $s3 = $this->Td0[($t3 >> 24) & 0xff] ^ $this->Td1[($t2 >> 16) & 0xff] ^ $this->Td2[($t1 >>  8) & 0xff] ^ $this->Td3[$t0 & 0xff] ^ $key->rd_key[19];
       
   996     $t0 = $this->Td0[($s0 >> 24) & 0xff] ^ $this->Td1[($s3 >> 16) & 0xff] ^ $this->Td2[($s2 >>  8) & 0xff] ^ $this->Td3[$s1 & 0xff] ^ $key->rd_key[20]; // ROUND 5
       
   997     $t1 = $this->Td0[($s1 >> 24) & 0xff] ^ $this->Td1[($s0 >> 16) & 0xff] ^ $this->Td2[($s3 >>  8) & 0xff] ^ $this->Td3[$s2 & 0xff] ^ $key->rd_key[21];
       
   998     $t2 = $this->Td0[($s2 >> 24) & 0xff] ^ $this->Td1[($s1 >> 16) & 0xff] ^ $this->Td2[($s0 >>  8) & 0xff] ^ $this->Td3[$s3 & 0xff] ^ $key->rd_key[22];
       
   999     $t3 = $this->Td0[($s3 >> 24) & 0xff] ^ $this->Td1[($s2 >> 16) & 0xff] ^ $this->Td2[($s1 >>  8) & 0xff] ^ $this->Td3[$s0 & 0xff] ^ $key->rd_key[23];
       
  1000     $s0 = $this->Td0[($t0 >> 24) & 0xff] ^ $this->Td1[($t3 >> 16) & 0xff] ^ $this->Td2[($t2 >>  8) & 0xff] ^ $this->Td3[$t1 & 0xff] ^ $key->rd_key[24]; // ROUND 6
       
  1001     $s1 = $this->Td0[($t1 >> 24) & 0xff] ^ $this->Td1[($t0 >> 16) & 0xff] ^ $this->Td2[($t3 >>  8) & 0xff] ^ $this->Td3[$t2 & 0xff] ^ $key->rd_key[25];
       
  1002     $s2 = $this->Td0[($t2 >> 24) & 0xff] ^ $this->Td1[($t1 >> 16) & 0xff] ^ $this->Td2[($t0 >>  8) & 0xff] ^ $this->Td3[$t3 & 0xff] ^ $key->rd_key[26];
       
  1003     $s3 = $this->Td0[($t3 >> 24) & 0xff] ^ $this->Td1[($t2 >> 16) & 0xff] ^ $this->Td2[($t1 >>  8) & 0xff] ^ $this->Td3[$t0 & 0xff] ^ $key->rd_key[27];
       
  1004     $t0 = $this->Td0[($s0 >> 24) & 0xff] ^ $this->Td1[($s3 >> 16) & 0xff] ^ $this->Td2[($s2 >>  8) & 0xff] ^ $this->Td3[$s1 & 0xff] ^ $key->rd_key[28]; // ROUND 7
       
  1005     $t1 = $this->Td0[($s1 >> 24) & 0xff] ^ $this->Td1[($s0 >> 16) & 0xff] ^ $this->Td2[($s3 >>  8) & 0xff] ^ $this->Td3[$s2 & 0xff] ^ $key->rd_key[29];
       
  1006     $t2 = $this->Td0[($s2 >> 24) & 0xff] ^ $this->Td1[($s1 >> 16) & 0xff] ^ $this->Td2[($s0 >>  8) & 0xff] ^ $this->Td3[$s3 & 0xff] ^ $key->rd_key[30];
       
  1007     $t3 = $this->Td0[($s3 >> 24) & 0xff] ^ $this->Td1[($s2 >> 16) & 0xff] ^ $this->Td2[($s1 >>  8) & 0xff] ^ $this->Td3[$s0 & 0xff] ^ $key->rd_key[31];
       
  1008     $s0 = $this->Td0[($t0 >> 24) & 0xff] ^ $this->Td1[($t3 >> 16) & 0xff] ^ $this->Td2[($t2 >>  8) & 0xff] ^ $this->Td3[$t1 & 0xff] ^ $key->rd_key[32]; // ROUND 8
       
  1009     $s1 = $this->Td0[($t1 >> 24) & 0xff] ^ $this->Td1[($t0 >> 16) & 0xff] ^ $this->Td2[($t3 >>  8) & 0xff] ^ $this->Td3[$t2 & 0xff] ^ $key->rd_key[33];
       
  1010     $s2 = $this->Td0[($t2 >> 24) & 0xff] ^ $this->Td1[($t1 >> 16) & 0xff] ^ $this->Td2[($t0 >>  8) & 0xff] ^ $this->Td3[$t3 & 0xff] ^ $key->rd_key[34];
       
  1011     $s3 = $this->Td0[($t3 >> 24) & 0xff] ^ $this->Td1[($t2 >> 16) & 0xff] ^ $this->Td2[($t1 >>  8) & 0xff] ^ $this->Td3[$t0 & 0xff] ^ $key->rd_key[35];
       
  1012     $t0 = $this->Td0[($s0 >> 24) & 0xff] ^ $this->Td1[($s3 >> 16) & 0xff] ^ $this->Td2[($s2 >>  8) & 0xff] ^ $this->Td3[$s1 & 0xff] ^ $key->rd_key[36]; // ROUND 9
       
  1013     $t1 = $this->Td0[($s1 >> 24) & 0xff] ^ $this->Td1[($s0 >> 16) & 0xff] ^ $this->Td2[($s3 >>  8) & 0xff] ^ $this->Td3[$s2 & 0xff] ^ $key->rd_key[37];
       
  1014     $t2 = $this->Td0[($s2 >> 24) & 0xff] ^ $this->Td1[($s1 >> 16) & 0xff] ^ $this->Td2[($s0 >>  8) & 0xff] ^ $this->Td3[$s3 & 0xff] ^ $key->rd_key[38];
       
  1015     $t3 = $this->Td0[($s3 >> 24) & 0xff] ^ $this->Td1[($s2 >> 16) & 0xff] ^ $this->Td2[($s1 >>  8) & 0xff] ^ $this->Td3[$s0 & 0xff] ^ $key->rd_key[39];
       
  1016     
       
  1017     // FIXME: BAD: need $key->rounds
       
  1018     
       
  1019     if ($key->rounds > 10)
       
  1020     {
       
  1021       $s0 = $this->Td0[($t0 >> 24) & 0xff] ^ $this->Td1[($t3 >> 16) & 0xff] ^ $this->Td2[($t2 >>  8) & 0xff] ^ $this->Td3[$t1 & 0xff] ^ $key->rd_key[40]; // ROUND 10
       
  1022       $s1 = $this->Td0[($t1 >> 24) & 0xff] ^ $this->Td1[($t0 >> 16) & 0xff] ^ $this->Td2[($t3 >>  8) & 0xff] ^ $this->Td3[$t2 & 0xff] ^ $key->rd_key[41];
       
  1023       $s2 = $this->Td0[($t2 >> 24) & 0xff] ^ $this->Td1[($t1 >> 16) & 0xff] ^ $this->Td2[($t0 >>  8) & 0xff] ^ $this->Td3[$t3 & 0xff] ^ $key->rd_key[42];
       
  1024       $s3 = $this->Td0[($t3 >> 24) & 0xff] ^ $this->Td1[($t2 >> 16) & 0xff] ^ $this->Td2[($t1 >>  8) & 0xff] ^ $this->Td3[$t0 & 0xff] ^ $key->rd_key[43];
       
  1025       $t0 = $this->Td0[($s0 >> 24) & 0xff] ^ $this->Td1[($s3 >> 16) & 0xff] ^ $this->Td2[($s2 >>  8) & 0xff] ^ $this->Td3[$s1 & 0xff] ^ $key->rd_key[44]; // ROUND 11
       
  1026       $t1 = $this->Td0[($s1 >> 24) & 0xff] ^ $this->Td1[($s0 >> 16) & 0xff] ^ $this->Td2[($s3 >>  8) & 0xff] ^ $this->Td3[$s2 & 0xff] ^ $key->rd_key[45];
       
  1027       $t2 = $this->Td0[($s2 >> 24) & 0xff] ^ $this->Td1[($s1 >> 16) & 0xff] ^ $this->Td2[($s0 >>  8) & 0xff] ^ $this->Td3[$s3 & 0xff] ^ $key->rd_key[46];
       
  1028       $t3 = $this->Td0[($s3 >> 24) & 0xff] ^ $this->Td1[($s2 >> 16) & 0xff] ^ $this->Td2[($s1 >>  8) & 0xff] ^ $this->Td3[$s0 & 0xff] ^ $key->rd_key[47];  
       
  1029         
       
  1030       if ($key->rounds > 12)
   108       {
  1031       {
   109         $mcb = false;
  1032         $s0 = $this->Td0[($t0 >> 24) & 0xff] ^ $this->Td1[($t3 >> 16) & 0xff] ^ $this->Td2[($t2 >>  8) & 0xff] ^ $this->Td3[$t1 & 0xff] ^ $key->rd_key[48]; // ROUND 12
   110         echo (string)$bks;
  1033         $s1 = $this->Td0[($t1 >> 24) & 0xff] ^ $this->Td1[($t0 >> 16) & 0xff] ^ $this->Td2[($t3 >>  8) & 0xff] ^ $this->Td3[$t2 & 0xff] ^ $key->rd_key[49];
       
  1034         $s2 = $this->Td0[($t2 >> 24) & 0xff] ^ $this->Td1[($t1 >> 16) & 0xff] ^ $this->Td2[($t0 >>  8) & 0xff] ^ $this->Td3[$t3 & 0xff] ^ $key->rd_key[50];
       
  1035         $s3 = $this->Td0[($t3 >> 24) & 0xff] ^ $this->Td1[($t2 >> 16) & 0xff] ^ $this->Td2[($t1 >>  8) & 0xff] ^ $this->Td3[$t0 & 0xff] ^ $key->rd_key[51];
       
  1036         $t0 = $this->Td0[($s0 >> 24) & 0xff] ^ $this->Td1[($s3 >> 16) & 0xff] ^ $this->Td2[($s2 >>  8) & 0xff] ^ $this->Td3[$s1 & 0xff] ^ $key->rd_key[52]; // ROUND 13
       
  1037         $t1 = $this->Td0[($s1 >> 24) & 0xff] ^ $this->Td1[($s0 >> 16) & 0xff] ^ $this->Td2[($s3 >>  8) & 0xff] ^ $this->Td3[$s2 & 0xff] ^ $key->rd_key[53];
       
  1038         $t2 = $this->Td0[($s2 >> 24) & 0xff] ^ $this->Td1[($s1 >> 16) & 0xff] ^ $this->Td2[($s0 >>  8) & 0xff] ^ $this->Td3[$s3 & 0xff] ^ $key->rd_key[54];
       
  1039         $t3 = $this->Td0[($s3 >> 24) & 0xff] ^ $this->Td1[($s2 >> 16) & 0xff] ^ $this->Td2[($s1 >>  8) & 0xff] ^ $this->Td3[$s0 & 0xff] ^ $key->rd_key[55];
   111       }
  1040       }
   112     }
  1041     }
       
  1042     
       
  1043     // This is correct
       
  1044     $rk = $key->rounds << 2;
       
  1045 
       
  1046     /*
       
  1047     // No Full Unroll 
       
  1048     */
       
  1049   
       
  1050     // Apply last round and
       
  1051     // map cipher state to byte array block:
       
  1052      
       
  1053     $s0 =  ($this->Td4[($t0 >> 24) & 0xff] & 0xff000000) ^
       
  1054            ($this->Td4[($t3 >> 16) & 0xff] & 0x00ff0000) ^
       
  1055            ($this->Td4[($t2 >>  8) & 0xff] & 0x0000ff00) ^
       
  1056            ($this->Td4[($t1      ) & 0xff] & 0x000000ff) ^
       
  1057            $key->rd_key[$rk];
       
  1058   
       
  1059     $out  = librijndael2::ord2hex(($s0 >> 24) & 0xff);
       
  1060     $out .= librijndael2::ord2hex(($s0 >> 16) & 0xff);
       
  1061     $out .= librijndael2::ord2hex(($s0 >> 8) & 0xff);
       
  1062     $out .= librijndael2::ord2hex($s0 & 0xff);
       
  1063 
       
  1064     $s1 =  ($this->Td4[($t1 >> 24) & 0xff] & 0xff000000) ^
       
  1065            ($this->Td4[($t0 >> 16) & 0xff] & 0x00ff0000) ^
       
  1066            ($this->Td4[($t3 >>  8) & 0xff] & 0x0000ff00) ^
       
  1067            ($this->Td4[($t2      ) & 0xff] & 0x000000ff) ^
       
  1068            $key->rd_key[$rk+1];
       
  1069       
       
  1070     $out .= librijndael2::ord2hex(($s1 >> 24) & 0xff);
       
  1071     $out .= librijndael2::ord2hex(($s1 >> 16) & 0xff);
       
  1072     $out .= librijndael2::ord2hex(($s1 >> 8) & 0xff);
       
  1073     $out .= librijndael2::ord2hex($s1 & 0xff);
       
  1074     
       
  1075     $s2 =  ($this->Td4[($t2 >> 24) & 0xff] & 0xff000000) ^
       
  1076            ($this->Td4[($t1 >> 16) & 0xff] & 0x00ff0000) ^
       
  1077            ($this->Td4[($t0 >>  8) & 0xff] & 0x0000ff00) ^
       
  1078            ($this->Td4[($t3      ) & 0xff] & 0x000000ff) ^
       
  1079            $key->rd_key[$rk+2];
       
  1080 
       
  1081     $out .= librijndael2::ord2hex(($s2 >> 24) & 0xff);
       
  1082     $out .= librijndael2::ord2hex(($s2 >> 16) & 0xff);
       
  1083     $out .= librijndael2::ord2hex(($s2 >> 8) & 0xff);
       
  1084     $out .= librijndael2::ord2hex($s2 & 0xff);
       
  1085   
       
  1086     $s3 =  ($this->Td4[($t3 >> 24) & 0xff] & 0xff000000) ^
       
  1087            ($this->Td4[($t2 >> 16) & 0xff] & 0x00ff0000) ^
       
  1088            ($this->Td4[($t1 >>  8) & 0xff] & 0x0000ff00) ^
       
  1089            ($this->Td4[($t0      ) & 0xff] & 0x000000ff) ^
       
  1090            $key->rd_key[$rk+3];
       
  1091     
       
  1092     $out .= librijndael2::ord2hex(($s3 >> 24) & 0xff);
       
  1093     $out .= librijndael2::ord2hex(($s3 >> 16) & 0xff);
       
  1094     $out .= librijndael2::ord2hex(($s3 >> 8) & 0xff);
       
  1095     $out .= librijndael2::ord2hex($s3 & 0xff);
       
  1096   
       
  1097     return $out;
       
  1098   }
       
  1099 
       
  1100 
       
  1101   /////////////////////////////// MODES //////////////////////////////////
       
  1102    
       
  1103   /* ECB MODE (AES_ecb_encrypt) 
       
  1104    * bin:  128 bit block (32 hex digits)
       
  1105    * key:  AES_KEY object (use AES_set_encrypt_key or AES_set_decrypt_key)
       
  1106    * enc:  "AES_ENCRYPT" or "AES_DECRYPT"
       
  1107    * Return value: 128 bit block (32 hex digits) 
       
  1108    */
       
  1109 
       
  1110   function AES_ecb_encrypt($bin, $key, $enc)
       
  1111   {
       
  1112 
       
  1113     if ($bin == '' || $key == '')
       
  1114     {
       
  1115       librijndael2::trace("AES_ecb_encrypt: bin/key undefined");
       
  1116       return;
       
  1117     }
       
  1118     
       
  1119     if ($enc !== "AES_ENCRYPT" && $enc !== "AES_DECRYPT")
       
  1120     {
       
  1121       librijndael2::trace("AES_ecb_encrypt: enc isn't AES_ENCRYPT/AES_DECRYPT");
       
  1122       return;
       
  1123     }
       
  1124     
       
  1125     if ($enc == "AES_ENCRYPT")
       
  1126         $bout = $this->AES_encrypt($bin, $key);
   113     else
  1127     else
   114     {
  1128         $bout = $this->AES_decrypt($bin, $key);
   115       $mcb = false;
  1129   
   116     }
  1130     return $bout;
       
  1131   }
       
  1132 
       
  1133 
       
  1134   /* CBC MODE (AES_cbc_encrypt) 
       
  1135    * bin:  128 bit block (32 hex digits)
       
  1136    * key:  AES_KEY object (use AES_set_encrypt_key or AES_set_decrypt_key)
       
  1137    * ivec: Initialization Vector (32 hex digits)
       
  1138    * enc:  "AES_ENCRYPT" or "AES_DECRYPT"
       
  1139    * Return value: 128 bit block (32 hex digits) 
       
  1140    */
       
  1141 
       
  1142   function AES_cbc_encrypt($bin, $key, $ivec, $enc)
       
  1143   {
       
  1144 
       
  1145     // if ($bin == '' || $key == '' || $ivec == '')
       
  1146     // {
       
  1147     //   librijndael2::trace("AES_cbc_encrypt: bin/key/ivec undefined.");
       
  1148     //   return;
       
  1149     // }
       
  1150         
       
  1151     $len = strlen($bin);
       
  1152     
       
  1153     if ($len % 32 != 0)
       
  1154     {
       
  1155       librijndael2::trace("AES_cbc_encrypt: data isn't multiple of 32 (32 hex = 128bits).");
       
  1156       return;
       
  1157     }
       
  1158         
       
  1159     if ($enc !== "AES_ENCRYPT" && $enc !== "AES_DECRYPT")
       
  1160     {
       
  1161       librijndael2::trace("AES_ecb_encrypt: enc isn't AES_ENCRYPT/AES_DECRYPT");
       
  1162       return;
       
  1163     }
       
  1164 
       
  1165     $tin = $bin;
       
  1166     $tmp = '';
       
  1167     $bout = '';
       
  1168     
       
  1169     if ($enc == "AES_ENCRYPT")
       
  1170       while ($len > 0)
       
  1171       {
       
  1172         $tmp = "";
       
  1173         for($n=0; $n < 32; $n += 2)
       
  1174         {
       
  1175           $aux  = librijndael2::parseInt("0x" . substr($tin, $n , 2)) ^ librijndael2::parseInt("0x" . substr($ivec, $n, 2));
       
  1176           $tmp .= librijndael2::ord2hex($aux);
       
  1177         }
       
  1178         
       
  1179         $tout = $this->AES_encrypt($tmp, $key);
       
  1180         $ivec = $tout; 
       
  1181         $len -= 32;
       
  1182         $tin = substr($tin, 32);
       
  1183         $bout .= $tout;
       
  1184       }
       
  1185     else
       
  1186       while ($len > 0) {
       
  1187         $tmp = $this->AES_decrypt($tin, $key);
       
  1188         $tout = "";
       
  1189         for($n=0; $n < 32; $n+=2)
       
  1190         {
       
  1191           $aux   = librijndael2::parseInt("0x" . substr($tmp, $n , 2)) ^ librijndael2::parseInt("0x" . substr($ivec, $n, 2)); 
       
  1192           $tout .= librijndael2::ord2hex($aux);
       
  1193         }
       
  1194           
       
  1195         $ivec = $tin;
       
  1196         $len -= 32;
       
  1197         $tin = substr($tin, 32);
       
  1198         $bout .= $tout;
       
  1199       }
       
  1200   
       
  1201     return $bout;
       
  1202   }
       
  1203 
       
  1204 }
       
  1205 
       
  1206 class Crypt_Rijndael_Key extends Crypt_Rijndael
       
  1207 {
       
  1208   var $rounds = 12;
       
  1209   var $rd_key = array();
       
  1210   var $key = '';
       
  1211   var $bits = 0;
       
  1212   var $key_state = 'none';
       
  1213   
       
  1214   function __construct($key)
       
  1215   {
       
  1216     $this->key = $key;
       
  1217     $this->bits = ( strlen($key) * 4 );
       
  1218   }
       
  1219   
       
  1220   // Expand the cipher key into the encryption key schedule.
       
  1221   function set_encrypt()
       
  1222   {
       
  1223     $i = 0;
       
  1224     $rk = 0;
       
  1225     
       
  1226     if ( $this->key_state == 'encrypt' )
       
  1227       return 0;
       
  1228     
       
  1229     $this->key_state = 'encrypt';
       
  1230     
       
  1231     $userkey =& $this->key;
       
  1232     $bits =& $this->bits;
       
  1233     
       
  1234     if ($bits != 128 && $bits != 192 && $bits != 256)
       
  1235     {
       
  1236       librijndael2::trace("AES_set_encrypt_key: key size isn't 128/192/256");
       
  1237       return -2;
       
  1238     }
       
  1239 
       
  1240     if ($bits==128)
       
  1241       $this->rounds = 10;
       
  1242     else if ($bits==192)
       
  1243       $this->rounds = 12;
       
  1244     else
       
  1245       $this->rounds = 14;
       
  1246         
       
  1247     
       
  1248     $this->rd_key = array();
       
  1249     $this->rd_key[0] = librijndael2::parseInt("0x" . substr($userkey, 0 , 8));
       
  1250     $this->rd_key[1] = librijndael2::parseInt("0x" . substr($userkey, 8 , 8));
       
  1251     $this->rd_key[2] = librijndael2::parseInt("0x" . substr($userkey, 16, 8));
       
  1252     $this->rd_key[3] = librijndael2::parseInt("0x" . substr($userkey, 24, 8));
       
  1253     
       
  1254     if ($bits == 128) {
       
  1255         for (;;) {
       
  1256             $temp  = $this->rd_key[3+$rk];
       
  1257         // (temp >> 24) & 0xff was difficult bug to tracking...
       
  1258             $this->rd_key[4+$rk] = $this->rd_key[$rk] ^
       
  1259               ($this->Te4[($temp >> 16) & 0xff] & 0xff000000) ^
       
  1260               ($this->Te4[($temp >>  8) & 0xff] & 0x00ff0000) ^
       
  1261               ($this->Te4[ $temp        & 0xff] & 0x0000ff00) ^
       
  1262               ($this->Te4[($temp >> 24) & 0xff] & 0x000000ff) ^
       
  1263               $this->rcon[$i];
       
  1264            
       
  1265       $this->rd_key[5+$rk] = $this->rd_key[1+$rk] ^ $this->rd_key[4+$rk];
       
  1266             $this->rd_key[6+$rk] = $this->rd_key[2+$rk] ^ $this->rd_key[5+$rk];
       
  1267             $this->rd_key[7+$rk] = $this->rd_key[3+$rk] ^ $this->rd_key[6+$rk];
       
  1268             if (++$i == 10) return 0;
       
  1269           $rk += 4;
       
  1270         }
       
  1271     }
       
  1272  
       
  1273     $this->rd_key[4] = librijndael2::parseInt("0x" . @substr($userkey, 32, 8));
       
  1274     $this->rd_key[5] = librijndael2::parseInt("0x" . @substr($userkey, 40, 8));
       
  1275     
       
  1276     if ($bits == 192) {
       
  1277         for (;;) {
       
  1278             $temp  = $this->rd_key[5+$rk];
       
  1279             $this->rd_key[6+$rk] = $this->rd_key[$rk] ^
       
  1280             ($this->Te4[($temp >> 16) & 0xff] & 0xff000000) ^
       
  1281             ($this->Te4[($temp >>  8) & 0xff] & 0x00ff0000) ^
       
  1282             ($this->Te4[($temp      ) & 0xff] & 0x0000ff00) ^
       
  1283             ($this->Te4[($temp >> 24) & 0xff] & 0x000000ff) ^
       
  1284             $this->rcon[$i];
       
  1285     
       
  1286         $this->rd_key[7+$rk] = $this->rd_key[1+$rk] ^ $this->rd_key[6 + $rk];
       
  1287             $this->rd_key[8+$rk] = $this->rd_key[2 + $rk] ^ $this->rd_key[7 + $rk];
       
  1288             $this->rd_key[9+$rk] = $this->rd_key[3 + $rk] ^ $this->rd_key[8 + $rk];
       
  1289             if (++$i == 8) {
       
  1290                 return 0;
       
  1291             }
       
  1292         $this->rd_key[10 + $rk] = $this->rd_key[4 + $rk] ^ $this->rd_key[9 + $rk];
       
  1293             $this->rd_key[11 + $rk] = $this->rd_key[5 + $rk] ^ $this->rd_key[10 + $rk];
       
  1294             $rk += 6;
       
  1295         }
       
  1296     }
       
  1297     
       
  1298     $this->rd_key[6] = librijndael2::parseInt("0x" . @substr($userkey, 48, 8));
       
  1299     $this->rd_key[7] = librijndael2::parseInt("0x" . @substr($userkey, 56, 8));
       
  1300     
       
  1301     if ($bits == 256) {
       
  1302         for (;;) {
       
  1303             $temp  = $this->rd_key[7+$rk];
       
  1304             $this->rd_key[8+$rk] = $this->rd_key[$rk] ^
       
  1305             ($this->Te4[($temp >> 16) & 0xff] & 0xff000000) ^
       
  1306             ($this->Te4[($temp >>  8) & 0xff] & 0x00ff0000) ^
       
  1307             ($this->Te4[($temp      ) & 0xff] & 0x0000ff00) ^
       
  1308             ($this->Te4[($temp >> 24) & 0xff] & 0x000000ff) ^
       
  1309             $this->rcon[$i];
   117       
  1310       
   118     $this->mcrypt = $mcb;
  1311             $this->rd_key[9 + $rk] = $this->rd_key[1 + $rk] ^ $this->rd_key[8 + $rk];
   119     
  1312             $this->rd_key[10 + $rk] = $this->rd_key[2 + $rk] ^ $this->rd_key[9 + $rk];
   120     // Cipher parameters ... do not change these
  1313             $this->rd_key[11 + $rk] = $this->rd_key[3 + $rk] ^ $this->rd_key[10 + $rk];
   121     $this->Nk = $this->keySizeInBits / 32;
  1314             if (++$i == 7) {
   122     $this->Nb = $this->blockSizeInBits / 32;
  1315                 return 0;
   123     $this->Nr = $this->roundsArray[$this->Nk][$this->Nb];
  1316             }
   124     $this->debug = $debug;
  1317             
   125   }
  1318             $temp  = $this->rd_key[11 + $rk];
   126   
  1319             $this->rd_key[12 + $rk] = $this->rd_key[4 + $rk] ^
   127   public static function singleton($key_size, $block_size)
  1320             ($this->Te4[($temp >> 24) & 0xff] & 0xff000000) ^
   128   {
  1321             ($this->Te4[($temp >> 16) & 0xff] & 0x00ff0000) ^
   129     static $_aes_objcache;
  1322             ($this->Te4[($temp >>  8) & 0xff] & 0x0000ff00) ^
   130     if ( isset($_aes_objcache["$key_size,$block_size"]) )
  1323             ($this->Te4[($temp      ) & 0xff] & 0x000000ff);
   131     {
  1324       
   132       return $_aes_objcache["$key_size,$block_size"];
  1325       $this->rd_key[13 + $rk] = $this->rd_key[5 + $rk] ^ $this->rd_key[12 + $rk];
   133     }
  1326             $this->rd_key[14 + $rk] = $this->rd_key[6 + $rk] ^ $this->rd_key[13 + $rk];
   134     
  1327             $this->rd_key[15 + $rk] = $this->rd_key[7 + $rk] ^ $this->rd_key[14 + $rk];
   135     $_aes_objcache["$key_size,$block_size"] = new AESCrypt($key_size, $block_size);
  1328             $rk += 8;
   136     return $_aes_objcache["$key_size,$block_size"];
  1329         }
   137   }
  1330     }
   138   
  1331     return 0;
   139   // Error handler
  1332   }
   140   
  1333 
   141   function trigger_error($text, $level = E_USER_NOTICE)
  1334 
   142   {
  1335   // Expand the cipher key into the decryption key schedule. 
   143     $bt = debug_backtrace();
  1336   function set_decrypt()
   144     $lastfunc =& $bt[1];
  1337   {
   145     switch($level)
  1338     $i = 0;
   146     {
  1339     $j = 0;
   147       case E_USER_NOTICE:
  1340     $rk = 0;
   148       default:
  1341     $bits =& $this->bits;
   149         $desc = 'Notice';
  1342     
   150         break;
  1343     if ( $this->key_state == 'decrypt' )
   151       case E_USER_WARNING:
  1344       return 0;
   152         $desc = 'Warning';
  1345     
   153         break;
  1346     $this->key_state = 'decrypt';
   154       case E_USER_ERROR:
  1347 
   155         $desc = 'Fatal';
  1348     // first, start with an encryption schedule 
   156         break;
  1349     $status = $this->set_encrypt($bits);
   157     }
  1350     
   158     ob_start();
  1351     if ($status < 0) {
   159     if($this->debug || $level == E_USER_ERROR) echo "AES encryption: <b>{$desc}:</b> $text in {$lastfunc['file']} on line {$lastfunc['line']} in function {$lastfunc['function']}<br />";
  1352       librijndael2::trace("AES_set_decrypt_key: AES_set_encrypt_key error");
   160     if($this->debug)
  1353       return;
   161     {
  1354     }
   162       //echo '<pre>'.enano_debug_print_backtrace(true).'</pre>';
  1355   
   163     }
  1356     // invert the order of the round keys: 
   164     ob_end_flush();
  1357     for ($i = 0, $j = 4*($this->rounds); $i < $j; $i += 4, $j -= 4) {
   165     if($level == E_USER_ERROR)
  1358       $temp = $this->rd_key[$i];   $this->rd_key[$i]   = $this->rd_key[$j];   $this->rd_key[$j]   = $temp;
   166     {
  1359       $temp = $this->rd_key[$i+1]; $this->rd_key[$i+1] = $this->rd_key[$j+1]; $this->rd_key[$j+1] = $temp;
   167       echo '<p><b>This can sometimes happen if you are upgrading Enano to a new version and did not log out first.</b> <a href="'.$_SERVER['PHP_SELF'].'?do=diag&amp;sub=cookie_destroy">Click here</a> to force cookies to clear and try again. You will be logged out.</p>';
  1360       $temp = $this->rd_key[$i+2]; $this->rd_key[$i+2] = $this->rd_key[$j+2]; $this->rd_key[$j+2] = $temp;
   168       exit;
  1361       $temp = $this->rd_key[$i+3]; $this->rd_key[$i+3] = $this->rd_key[$j+3]; $this->rd_key[$j+3] = $temp;
   169     }
  1362     }
   170   }
  1363     
   171   
  1364     // apply the inverse MixColumn transform to all round keys but the first and the last: 
   172   function array_slice_js_compat($array, $start, $finish = 0)
  1365     for ($i = 1; $i < ($this->rounds); $i++) {
   173   {
  1366 
   174     $len = $finish - $start;
  1367         $rk += 4;
   175     if($len < 0) $len = 0 - $len;
  1368         $this->rd_key[$rk] =
   176     //if($this->debug) echo (string)$len . ' ';
  1369         $this->Td0[$this->Te4[($this->rd_key[$rk] >> 24) & 0xff] & 0xff] ^
   177     //if(count($array) < $start + $len)
  1370         $this->Td1[$this->Te4[($this->rd_key[$rk] >> 16) & 0xff] & 0xff] ^
   178     //  $this->trigger_error('Index out of range', E_USER_WARNING);
  1371         $this->Td2[$this->Te4[($this->rd_key[$rk] >>  8) & 0xff] & 0xff] ^
   179     return array_slice($array, $start, $len);
  1372         $this->Td3[$this->Te4[($this->rd_key[$rk]      ) & 0xff] & 0xff];
   180   }
  1373        
   181   
  1374         $this->rd_key[1+$rk] =
   182   function concat($s1, $s2)
  1375         $this->Td0[$this->Te4[($this->rd_key[1+$rk] >> 24) & 0xff] & 0xff] ^
   183   {
  1376         $this->Td1[$this->Te4[($this->rd_key[1+$rk] >> 16) & 0xff] & 0xff] ^
   184     if(is_array($s1) && is_array($s2))
  1377         $this->Td2[$this->Te4[($this->rd_key[1+$rk] >>  8) & 0xff] & 0xff] ^
   185       return array_merge($s1, $s2);
  1378         $this->Td3[$this->Te4[($this->rd_key[1+$rk]      ) & 0xff] & 0xff];
   186     elseif( ( is_array($s1) && !is_array($s2) ) || ( !is_array($s1) && is_array($s2) ) )
  1379 
   187     {
  1380         $this->rd_key[2+$rk] =
   188       $this->trigger_error('incompatible types - you can\'t combine a non-array with an array', E_USER_WARNING);
  1381         $this->Td0[$this->Te4[($this->rd_key[2+$rk] >> 24) & 0xff] & 0xff] ^
   189       return false;
  1382         $this->Td1[$this->Te4[($this->rd_key[2+$rk] >> 16) & 0xff] & 0xff] ^
       
  1383         $this->Td2[$this->Te4[($this->rd_key[2+$rk] >>  8) & 0xff] & 0xff] ^
       
  1384         $this->Td3[$this->Te4[($this->rd_key[2+$rk]      ) & 0xff] & 0xff];
       
  1385  
       
  1386         $this->rd_key[3+$rk] =
       
  1387         $this->Td0[$this->Te4[($this->rd_key[3+$rk] >> 24) & 0xff] & 0xff] ^
       
  1388         $this->Td1[$this->Te4[($this->rd_key[3+$rk] >> 16) & 0xff] & 0xff] ^
       
  1389         $this->Td2[$this->Te4[($this->rd_key[3+$rk] >>  8) & 0xff] & 0xff] ^
       
  1390         $this->Td3[$this->Te4[($this->rd_key[3+$rk]      ) & 0xff] & 0xff];
       
  1391     } 
       
  1392     return 0;
       
  1393   }
       
  1394 }
       
  1395 
       
  1396 /**
       
  1397  * Frontend for Crypt_Rijndael, ABI-compatible with the old Rijndael framework.
       
  1398  * @package Enano
       
  1399  * @subpackage Crypto
       
  1400  * @author Dan Fuhry
       
  1401  * @license GNU General Public License
       
  1402  */
       
  1403 
       
  1404 class AESCrypt
       
  1405 {
       
  1406   
       
  1407   /**
       
  1408    * Fetches a Crypt_Rijndael_Key object for the given hex or binary key.
       
  1409    * @param string Key, binary or hex format
       
  1410    * @return object
       
  1411    * @access protected
       
  1412    */
       
  1413    
       
  1414   protected static function fetch_key($key)
       
  1415   {
       
  1416     static $objects = array();
       
  1417     
       
  1418     if ( !preg_match('/^[a-f0-9]+$/i', $key) )
       
  1419       $key = librijndael2::string2hex($key);
       
  1420     
       
  1421     if ( isset($objects[$key]) )
       
  1422     {
       
  1423       return $objects[$key];
   190     }
  1424     }
   191     else
  1425     else
   192       return $s1 . $s2;
  1426     {
   193   }
  1427       $objects[$key] = new Crypt_Rijndael_Key($key);
   194   
  1428       $ret =& $objects[$key];
   195   // This method circularly shifts the array left by the number of elements
  1429       return $ret;
   196   // given in its parameter. It returns the resulting array and is used for 
  1430     }
   197   // the ShiftRow step. Note that shift() and push() could be used for a more 
  1431   }
   198   // elegant solution, but they require IE5.5+, so I chose to do it manually. 
  1432   
   199   
  1433   /**
   200   function cyclicShiftLeft($theArray, $positions) {
  1434    * Fetches a Crypt_Rijndael object.
   201     if(!is_int($positions))
  1435    * @return object
   202     {
  1436    * @access protected
   203       $this->trigger_error('$positions is not an integer! Backtrace:<br /><pre>'.print_r(debug_backtrace(), true).'</pre>', E_USER_WARNING);
  1437    */
   204       return false;
  1438    
   205     }
  1439   protected static function fetch_cr_singleton()
   206     $second = array_slice($theArray, 0, $positions);
  1440   {
   207     $first = array_slice($theArray, $positions);
  1441     static $o = null;
   208     $theArray = array_merge($first, $second);
  1442     
   209     return $theArray;
  1443     if ( is_object($o) )
   210   }
  1444     {
   211   
  1445       return $o;
   212   // Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec.
  1446     }
   213   
       
   214   function xtime($poly) {
       
   215     $poly <<= 1;
       
   216     return (($poly & 0x100) ? ($poly ^ 0x11B) : ($poly));
       
   217   }
       
   218   
       
   219   // Multiplies the two elements of GF(2^8) together and returns the result.
       
   220   // See the Rijndael spec, but should be straightforward: for each power of
       
   221   // the indeterminant that has a 1 coefficient in x, add y times that power
       
   222   // to the result. x and y should be bytes representing elements of GF(2^8)
       
   223   
       
   224   function mult_GF256($x, $y) {
       
   225     $result = 0;
       
   226     
       
   227     for ($bit = 1; $bit < 256; $bit *= 2, $y = $this->xtime($y)) {
       
   228       if ($x & $bit) 
       
   229         $result ^= $y;
       
   230     }
       
   231     return $result;
       
   232   }
       
   233   
       
   234   // Performs the substitution step of the cipher. State is the 2d array of
       
   235   // state information (see spec) and direction is string indicating whether
       
   236   // we are performing the forward substitution ("encrypt") or inverse 
       
   237   // substitution (anything else)
       
   238   
       
   239   function byteSub(&$state, $direction) {
       
   240     //global $this->SBox, $this->SBoxInverse, $this->Nb;
       
   241     if ($direction == "encrypt")           // Point S to the SBox we're using
       
   242       $S =& $this->SBox;
       
   243     else
  1447     else
   244       $S =& $this->SBoxInverse;
  1448     {
   245     for ($i = 0; $i < 4; $i++)           // Substitute for every byte in state
  1449       $o = new Crypt_Rijndael();
   246       for ($j = 0; $j < $this->Nb; $j++)
  1450       $r =& $o;
   247          $state[$i][$j] = $S[$state[$i][$j]];
  1451       return $r;
   248   }
  1452     }
   249   
  1453   }
   250   // Performs the row shifting step of the cipher.
  1454   
   251   
  1455   /**
   252   function shiftRow(&$state, $direction) {
  1456    * Pads a string with nul bytes until it reaches a multiple of 16 bytes.
   253     //global $this->Nb, $this->shiftOffsets;
  1457    * @param string
   254     for ($i=1; $i<4; $i++)               // Row 0 never shifts
  1458    * @return string
   255       if ($direction == "encrypt")
  1459    */
   256          $state[$i] = $this->cyclicShiftLeft($state[$i], $this->shiftOffsets[$this->Nb][$i]);
  1460   
   257       else
  1461   function pad_string($string)
   258          $state[$i] = $this->cyclicShiftLeft($state[$i], $this->Nb - $this->shiftOffsets[$this->Nb][$i]);
  1462   {
   259   
  1463     while ( strlen($string) % 32 > 0 )
   260   }
  1464     {
   261   
  1465       $string .= "\000";
   262   // Performs the column mixing step of the cipher. Most of these steps can
  1466     }
   263   // be combined into table lookups on 32bit values (at least for encryption)
  1467     return $string;
   264   // to greatly increase the speed. 
  1468   }
   265   
  1469   
   266   function mixColumn(&$state, $direction) {
  1470   /**
   267     //global $this->Nb;
  1471    * Constructor. Currently does not take parameters and ignores options from the old API.
   268     $b = Array();                                  // Result of matrix multiplications
  1472    */
   269     for ($j = 0; $j < $this->Nb; $j++) {                 // Go through each column...
  1473   
   270       for ($i = 0; $i < 4; $i++) {                 // and for each row in the column...
  1474   public function __construct($key_size = 192, $block_size = 128, $debug = false)
   271         if ($direction == "encrypt")
  1475   {
   272           $b[$i] = $this->mult_GF256($state[$i][$j], 2) ^ // perform mixing
       
   273                    $this->mult_GF256($state[($i+1)%4][$j], 3) ^ 
       
   274                    $state[($i+2)%4][$j] ^ 
       
   275                    $state[($i+3)%4][$j];
       
   276         else 
       
   277           $b[$i] = $this->mult_GF256($state[$i][$j], 0xE) ^ 
       
   278                    $this->mult_GF256($state[($i+1)%4][$j], 0xB) ^
       
   279                    $this->mult_GF256($state[($i+2)%4][$j], 0xD) ^
       
   280                    $this->mult_GF256($state[($i+3)%4][$j], 9);
       
   281       }
       
   282       for ($i = 0; $i < 4; $i++)          // Place result back into column
       
   283         $state[$i][$j] = $b[$i];
       
   284     }
       
   285   }
       
   286   
       
   287   // Adds the current round key to the state information. Straightforward.
       
   288   
       
   289   function addRoundKey(&$state, $roundKey) {
       
   290     //global $this->Nb;
       
   291     for ($j = 0; $j < $this->Nb; $j++) {                      // Step through columns...
       
   292       $state[0][$j] ^= ( $roundKey[$j] & 0xFF);         // and XOR
       
   293       $state[1][$j] ^= (($roundKey[$j]>>8) & 0xFF);
       
   294       $state[2][$j] ^= (($roundKey[$j]>>16) & 0xFF);
       
   295       $state[3][$j] ^= (($roundKey[$j]>>24) & 0xFF);
       
   296     }
       
   297   }
       
   298   
       
   299   // This function creates the expanded key from the input (128/192/256-bit)
       
   300   // key. The parameter key is an array of bytes holding the value of the key.
       
   301   // The returned value is an array whose elements are the 32-bit words that 
       
   302   // make up the expanded key.
       
   303   
       
   304   function keyExpansion($key) {
       
   305     //global $this->keySizeInBits, $this->blockSizeInBits, $this->roundsArray, $this->Nk, $this->Nb, $this->Nr, $this->Nk, $this->SBox, $this->Rcon;
       
   306     $expandedKey = Array();
       
   307   
       
   308     // in case the key size or parameters were changed...
       
   309     $this->Nk = $this->keySizeInBits / 32;                   
       
   310     $this->Nb = $this->blockSizeInBits / 32;
       
   311     $this->Nr = $this->roundsArray[$this->Nk][$this->Nb];
       
   312   
       
   313     for ($j=0; $j < $this->Nk; $j++)     // Fill in input key first
       
   314       $expandedKey[$j] = 
       
   315         ($key[4*$j]) | ($key[4*$j+1]<<8) | ($key[4*$j+2]<<16) | ($key[4*$j+3]<<24);
       
   316   
       
   317     // Now walk down the rest of the array filling in expanded key bytes as
       
   318     // per Rijndael's spec
       
   319     for ($j = $this->Nk; $j < $this->Nb * ($this->Nr + 1); $j++) {    // For each word of expanded key
       
   320       $temp = $expandedKey[$j - 1];
       
   321       if ($j % $this->Nk == 0) 
       
   322         $temp = ( ($this->SBox[($temp>>8) & 0xFF]) |
       
   323                   ($this->SBox[($temp>>16) & 0xFF]<<8) |
       
   324                   ($this->SBox[($temp>>24) & 0xFF]<<16) |
       
   325                   ($this->SBox[$temp & 0xFF]<<24) ) ^ $this->Rcon[floor($j / $this->Nk) - 1];
       
   326       elseif  ($this->Nk > 6 && $j % $this->Nk == 4)
       
   327         $temp = ($this->SBox[($temp>>24) & 0xFF]<<24) |
       
   328                ($this->SBox[($temp>>16) & 0xFF]<<16) |
       
   329                ($this->SBox[($temp>>8) & 0xFF]<<8) |
       
   330                ($this->SBox[ $temp & 0xFF]);
       
   331       $expandedKey[$j] = $expandedKey[$j-$this->Nk] ^ $temp;
       
   332     }
       
   333     return $expandedKey;
       
   334   }
       
   335   
       
   336   // Rijndael's round functions... 
       
   337   
       
   338   function RijndaelRound(&$state, $roundKey) {
       
   339     $this->byteSub($state, "encrypt");
       
   340     $this->shiftRow($state, "encrypt");
       
   341     $this->mixColumn($state, "encrypt");
       
   342     $this->addRoundKey($state, $roundKey);
       
   343   }
       
   344   
       
   345   function InverseRijndaelRound(&$state, $roundKey) {
       
   346     $this->addRoundKey($state, $roundKey);
       
   347     $this->mixColumn($state, "decrypt");
       
   348     $this->shiftRow($state, "decrypt");
       
   349     $this->byteSub($state, "decrypt");
       
   350   }
       
   351   
       
   352   function FinalRijndaelRound(&$state, $roundKey) {
       
   353     $this->byteSub($state, "encrypt");
       
   354     $this->shiftRow($state, "encrypt");
       
   355     $this->addRoundKey($state, $roundKey);
       
   356   }
       
   357   
       
   358   function InverseFinalRijndaelRound(&$state, $roundKey){
       
   359     $this->addRoundKey($state, $roundKey);
       
   360     $this->shiftRow($state, "decrypt");
       
   361     $this->byteSub($state, "decrypt");  
       
   362   }
       
   363   
       
   364   // encrypt is the basic encryption function. It takes parameters
       
   365   // block, an array of bytes representing a plaintext block, and expandedKey,
       
   366   // an array of words representing the expanded key previously returned by
       
   367   // keyExpansion(). The ciphertext block is returned as an array of bytes.
       
   368   
       
   369   function cryptBlock($block, $expandedKey) {
       
   370     //global $this->blockSizeInBits, $this->Nb, $this->Nr;
       
   371     $t=count($block)*8;
       
   372     if (!is_array($block) || count($block)*8 != $this->blockSizeInBits)
       
   373     {
       
   374       $this->trigger_error('block is bad or block size is wrong<pre>'.print_r($block, true).'</pre><p>Aiming for size '.$this->blockSizeInBits.', got '.$t.'.', E_USER_WARNING); 
       
   375       return false;
       
   376     }
       
   377     if (!$expandedKey)
       
   378       return;
       
   379   
       
   380     $block = $this->packBytes($block);
       
   381     $this->addRoundKey($block, $expandedKey);
       
   382     for ($i=1; $i<$this->Nr; $i++) 
       
   383       $this->RijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$i, $this->Nb*($i+1)));
       
   384     $this->FinalRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$this->Nr));
       
   385     $ret = $this->unpackBytes($block);
       
   386     return $ret;
       
   387   }
       
   388   
       
   389   // decrypt is the basic decryption function. It takes parameters
       
   390   // block, an array of bytes representing a ciphertext block, and expandedKey,
       
   391   // an array of words representing the expanded key previously returned by
       
   392   // keyExpansion(). The decrypted block is returned as an array of bytes.
       
   393   
       
   394   function unCryptBlock($block, $expandedKey) {
       
   395     $t = count($block)*8;
       
   396     if (!is_array($block) || count($block)*8 != $this->blockSizeInBits)
       
   397     {
       
   398       $this->trigger_error('$block is not a valid rijndael-block array: '.$this->byteArrayToHex($block).'<pre>'.print_r($block, true).'</pre><p>Block size is '.$t.', should be '.$this->blockSizeInBits.'</p>', E_USER_WARNING);
       
   399       return false;
       
   400     }
       
   401     if (!$expandedKey)
       
   402     {
       
   403       $this->trigger_error('$expandedKey is invalid', E_USER_WARNING);
       
   404       return false;
       
   405     }
       
   406   
       
   407     $block = $this->packBytes($block);
       
   408     $this->InverseFinalRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$this->Nr)); 
       
   409     for ($i = $this->Nr - 1; $i>0; $i--) 
       
   410     {
       
   411       $this->InverseRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$i, $this->Nb*($i+1)));
       
   412     }
       
   413     $this->addRoundKey($block, $expandedKey);
       
   414     $ret = $this->unpackBytes($block);
       
   415     if(!is_array($ret))
       
   416     {
       
   417       $this->trigger_error('$ret is not an array', E_USER_WARNING);
       
   418     }
       
   419     return $ret;
       
   420   }
       
   421   
       
   422   // This method takes a byte array (byteArray) and converts it to a string by
       
   423   // applying String.fromCharCode() to each value and concatenating the result.
       
   424   // The resulting string is returned. Note that this function SKIPS zero bytes
       
   425   // under the assumption that they are padding added in formatPlaintext().
       
   426   // Obviously, do not invoke this method on raw data that can contain zero
       
   427   // bytes. It is really only appropriate for printable ASCII/Latin-1 
       
   428   // values. Roll your own function for more robust functionality :)
       
   429   
       
   430   function byteArrayToString($byteArray) {
       
   431     $result = "";
       
   432     for($i=0; $i<count($byteArray); $i++)
       
   433       if ($byteArray[$i] != 0) 
       
   434         $result .= chr($byteArray[$i]);
       
   435     return $result;
       
   436   }
       
   437   
       
   438   // This function takes an array of bytes (byteArray) and converts them
       
   439   // to a hexadecimal string. Array element 0 is found at the beginning of 
       
   440   // the resulting string, high nibble first. Consecutive elements follow
       
   441   // similarly, for example [16, 255] --> "10ff". The function returns a 
       
   442   // string.
       
   443   
       
   444   /*
       
   445   function byteArrayToHex($byteArray) {
       
   446     $result = "";
       
   447     if (!$byteArray)
       
   448       return;
       
   449     for ($i=0; $i<count($byteArray); $i++)
       
   450       $result .= (($byteArray[$i]<16) ? "0" : "") + toString($byteArray[$i]); // magic number here is 16, not sure how to handle this...
       
   451   
       
   452     return $result;
       
   453   }
       
   454   */
       
   455   function byteArrayToHex($arr)
       
   456   {
       
   457     $ret = '';
       
   458     foreach($arr as $a)
       
   459     {
       
   460       $nibble = (string)dechex(intval($a));
       
   461       if(strlen($nibble) == 1) $nibble = '0' . $nibble;
       
   462       $ret .= $nibble;
       
   463     }
       
   464     return $ret;
       
   465   }
       
   466   
       
   467   // PHP equivalent of Javascript's toString()
       
   468   function toString($bool)
       
   469   {
       
   470     if(is_bool($bool))
       
   471       return ($bool) ? 'true' : 'false';
       
   472     elseif(is_array($bool))
       
   473       return implode(',', $bool);
       
   474     else
       
   475       return (string)$bool;
       
   476   }
       
   477   
       
   478   // This function converts a string containing hexadecimal digits to an 
       
   479   // array of bytes. The resulting byte array is filled in the order the
       
   480   // values occur in the string, for example "10FF" --> [16, 255]. This
       
   481   // function returns an array. 
       
   482   
       
   483   /*
       
   484   function hexToByteArray($hexString) {
       
   485     $byteArray = Array();
       
   486     if (strlen($hexString) % 2)             // must have even length
       
   487       return;
       
   488     if (strstr($hexString, "0x") == $hexString || strstr($hexString, "0X") == $hexString)
       
   489       $hexString = substr($hexString, 2);
       
   490     for ($i = 0; $i<strlen($hexString); $i++,$i++) 
       
   491       $byteArray[floor($i/2)] = intval(substr($hexString, $i, 2)); // again, that strange magic number: 16
       
   492     return $byteArray;
       
   493   }
       
   494   */
       
   495   function hexToByteArray($str)
       
   496   {
       
   497     if(substr($str, 0, 2) == '0x' || substr($str, 0, 2) == '0X')
       
   498       $str = substr($str, 2);
       
   499     $arr = Array();
       
   500     $str = $this->enano_str_split($str, 2);
       
   501     foreach($str as $s)
       
   502     {
       
   503       $arr[] = intval(hexdec($s));
       
   504     }
       
   505     return $arr;
       
   506   }
       
   507   
       
   508   // This function packs an array of bytes into the four row form defined by
       
   509   // Rijndael. It assumes the length of the array of bytes is divisible by
       
   510   // four. Bytes are filled in according to the Rijndael spec (starting with
       
   511   // column 0, row 0 to 3). This function returns a 2d array.
       
   512   
       
   513   function packBytes($octets) {
       
   514     $state = Array();
       
   515     if (!$octets || count($octets) % 4)
       
   516       return;
       
   517   
       
   518     $state[0] = Array(); $state[1] = Array(); 
       
   519     $state[2] = Array(); $state[3] = Array();
       
   520     for ($j=0; $j<count($octets); $j = $j+4) {
       
   521        $state[0][$j/4] = $octets[$j];
       
   522        $state[1][$j/4] = $octets[$j+1];
       
   523        $state[2][$j/4] = $octets[$j+2];
       
   524        $state[3][$j/4] = $octets[$j+3];
       
   525     }
       
   526     return $state;
       
   527   }
       
   528   
       
   529   // This function unpacks an array of bytes from the four row format preferred
       
   530   // by Rijndael into a single 1d array of bytes. It assumes the input "packed"
       
   531   // is a packed array. Bytes are filled in according to the Rijndael spec. 
       
   532   // This function returns a 1d array of bytes.
       
   533   
       
   534   function unpackBytes($packed) {
       
   535     $result = Array();
       
   536     for ($j=0; $j<count($packed[0]); $j++) {
       
   537       $result[] = $packed[0][$j];
       
   538       $result[] = $packed[1][$j];
       
   539       $result[] = $packed[2][$j];
       
   540       $result[] = $packed[3][$j];
       
   541     }
       
   542     return $result;
       
   543   }
       
   544   
       
   545   function charCodeAt($str, $i)
       
   546   {
       
   547     return ord(substr($str, $i, 1));
       
   548   }
       
   549   
       
   550   function fromCharCode($str)
       
   551   {
       
   552     return chr($str);
       
   553   }
       
   554   
       
   555   // This function takes a prospective plaintext (string or array of bytes)
       
   556   // and pads it with zero bytes if its length is not a multiple of the block 
       
   557   // size. If plaintext is a string, it is converted to an array of bytes
       
   558   // in the process. The type checking can be made much nicer using the 
       
   559   // instanceof operator, but this operator is not available until IE5.0 so I 
       
   560   // chose to use the heuristic below. 
       
   561   
       
   562   function formatPlaintext($plaintext) {
       
   563     //global $this->blockSizeInBits;
       
   564     $bpb = $this->blockSizeInBits / 8;               // bytes per block
       
   565   
       
   566     // if primitive string or String instance
       
   567     if (is_string($plaintext)) {
       
   568       $plaintext = $this->enano_str_split($plaintext);
       
   569       // Unicode issues here (ignoring high byte)
       
   570       for ($i=0; $i<sizeof($plaintext); $i++)
       
   571         $plaintext[$i] = $this->charCodeAt($plaintext[$i], 0) & 0xFF;
       
   572     } 
       
   573   
       
   574     for ($i = $bpb - (sizeof($plaintext) % $bpb); $i > 0 && $i < $bpb; $i--) 
       
   575       $plaintext[] = 0;
       
   576     
       
   577     return $plaintext;
       
   578   }
       
   579   
       
   580   // Returns an array containing "howMany" random bytes. YOU SHOULD CHANGE THIS
       
   581   // TO RETURN HIGHER QUALITY RANDOM BYTES IF YOU ARE USING THIS FOR A "REAL"
       
   582   // APPLICATION. (edit: done, mt_rand() is relatively secure)
       
   583   
       
   584   function getRandomBytes($howMany) {
       
   585     $bytes = Array();
       
   586     for ($i=0; $i<$howMany; $i++)
       
   587       $bytes[$i] = mt_rand(0, 255);
       
   588     return $bytes;
       
   589   }
       
   590   
       
   591   // rijndaelEncrypt(plaintext, key, mode)
       
   592   // Encrypts the plaintext using the given key and in the given mode. 
       
   593   // The parameter "plaintext" can either be a string or an array of bytes. 
       
   594   // The parameter "key" must be an array of key bytes. If you have a hex 
       
   595   // string representing the key, invoke hexToByteArray() on it to convert it 
       
   596   // to an array of bytes. The third parameter "mode" is a string indicating
       
   597   // the encryption mode to use, either "ECB" or "CBC". If the parameter is
       
   598   // omitted, ECB is assumed.
       
   599   // 
       
   600   // An array of bytes representing the cihpertext is returned. To convert 
       
   601   // this array to hex, invoke byteArrayToHex() on it. If you are using this 
       
   602   // "for real" it is a good idea to change the function getRandomBytes() to 
       
   603   // something that returns truly random bits.
       
   604   
       
   605   function rijndaelEncrypt($plaintext, $key, $mode = 'ECB') {
       
   606     //global $this->blockSizeInBits, $this->keySizeInBits;
       
   607     $bpb = $this->blockSizeInBits / 8;          // bytes per block
       
   608     // var ct;                                 // ciphertext
       
   609   
       
   610     if($mode == 'CBC')
       
   611     {
       
   612       if (!is_string($plaintext) || !is_array($key))
       
   613       {
       
   614         $this->trigger_error('In CBC mode the first and second parameters should be strings', E_USER_WARNING);
       
   615         return false;
       
   616       }
       
   617     } else {
       
   618       if (!is_array($plaintext) || !is_array($key))
       
   619       {
       
   620         $this->trigger_error('In ECB mode the first and second parameters should be byte arrays', E_USER_WARNING);
       
   621         return false;
       
   622       }
       
   623     }
       
   624     if (sizeof($key)*8 != $this->keySizeInBits)
       
   625     {
       
   626       $this->trigger_error('The key needs to be '. ( $this->keySizeInBits / 8 ) .' bytes in length', E_USER_WARNING);
       
   627       return false;
       
   628     }
       
   629     if ($mode == "CBC")
       
   630       $ct = $this->getRandomBytes($bpb);             // get IV
       
   631     else {
       
   632       $mode = "ECB";
       
   633       $ct = Array();
       
   634     }
       
   635     
       
   636     // convert plaintext to byte array and pad with zeros if necessary. 
       
   637     $plaintext = $this->formatPlaintext($plaintext);
       
   638     
       
   639     $expandedKey = $this->keyExpansion($key);
       
   640     
       
   641     for ($block=0; $block<sizeof($plaintext) / $bpb; $block++) {
       
   642       $aBlock = $this->array_slice_js_compat($plaintext, $block*$bpb, ($block+1)*$bpb);
       
   643       if ($mode == "CBC")
       
   644       {
       
   645         for ($i=0; $i<$bpb; $i++)
       
   646         {
       
   647           $aBlock[$i] ^= $ct[$block*$bpb + $i];
       
   648         }
       
   649       }
       
   650       $cp = $this->cryptBlock($aBlock, $expandedKey);
       
   651       $ct = $this->concat($ct, $cp);
       
   652     }
       
   653   
       
   654     return $ct;
       
   655   }
       
   656   
       
   657   // rijndaelDecrypt(ciphertext, key, mode)
       
   658   // Decrypts the using the given key and mode. The parameter "ciphertext" 
       
   659   // must be an array of bytes. The parameter "key" must be an array of key 
       
   660   // bytes. If you have a hex string representing the ciphertext or key, 
       
   661   // invoke hexToByteArray() on it to convert it to an array of bytes. The
       
   662   // parameter "mode" is a string, either "CBC" or "ECB".
       
   663   // 
       
   664   // An array of bytes representing the plaintext is returned. To convert 
       
   665   // this array to a hex string, invoke byteArrayToHex() on it. To convert it 
       
   666   // to a string of characters, you can use byteArrayToString().
       
   667   
       
   668   function rijndaelDecrypt($ciphertext, $key, $mode = 'ECB') {
       
   669     //global $this->blockSizeInBits, $this->keySizeInBits;
       
   670     $bpb = $this->blockSizeInBits / 8;          // bytes per block
       
   671     $pt = Array();                   // plaintext array
       
   672     // $aBlock;                             // a decrypted block
       
   673     // $block;                              // current block number
       
   674   
       
   675     if (!$ciphertext)
       
   676     {
       
   677       $this->trigger_error('$ciphertext should be a byte array', E_USER_WARNING);
       
   678       return false;
       
   679     }
       
   680     if(  !is_array($key) )
       
   681     {
       
   682       $this->trigger_error('$key should be a byte array', E_USER_WARNING);
       
   683       return false;
       
   684     }
       
   685     if( is_string($ciphertext) )
       
   686     {
       
   687       $this->trigger_error('$ciphertext should be a byte array', E_USER_WARNING);
       
   688       return false;
       
   689     }
       
   690     if (sizeof($key)*8 != $this->keySizeInBits)
       
   691     {
       
   692       $this->trigger_error('Encryption key is the wrong length', E_USER_WARNING);
       
   693       return false;
       
   694     }
       
   695     if (!$mode)
       
   696       $mode = "ECB";                         // assume ECB if mode omitted
       
   697   
       
   698     $expandedKey = $this->keyExpansion($key);
       
   699    
       
   700     // work backwards to accomodate CBC mode 
       
   701     for ($block=(sizeof($ciphertext) / $bpb)-1; $block>0; $block--)
       
   702     {
       
   703       if( ( $block*$bpb ) + ( ($block+1)*$bpb ) > count($ciphertext) )
       
   704       {
       
   705         //$this->trigger_error('$ciphertext index out of bounds', E_USER_ERROR);
       
   706       }
       
   707       $current_block = $this->array_slice_js_compat($ciphertext, $block*$bpb, ($block+1)*$bpb);
       
   708       if(count($current_block) * 8 != $this->blockSizeInBits)
       
   709       {
       
   710         // $c=count($current_block)*8;
       
   711         // $this->trigger_error('We got a '.$c.'-bit block, instead of '.$this->blockSizeInBits.'', E_USER_ERROR);
       
   712       }
       
   713       $aBlock = $this->uncryptBlock($current_block, $expandedKey);
       
   714       if(!$aBlock)
       
   715       {
       
   716         $this->trigger_error('Shared block decryption routine returned false', E_USER_WARNING);
       
   717         return false;
       
   718       }
       
   719       if ($mode == "CBC")
       
   720         for ($i=0; $i<$bpb; $i++) 
       
   721           $pt[($block-1)*$bpb + $i] = $aBlock[$i] ^ $ciphertext[($block-1)*$bpb + $i];
       
   722       else
       
   723         $pt = $this->concat($aBlock, $pt);
       
   724     }
       
   725   
       
   726     // do last block if ECB (skips the IV in CBC)
       
   727     if ($mode == "ECB")
       
   728     {
       
   729       $x = $this->uncryptBlock($this->array_slice_js_compat($ciphertext, 0, $bpb), $expandedKey);
       
   730       if(!$x)
       
   731       {
       
   732         $this->trigger_error('ECB block decryption routine returned false', E_USER_WARNING);
       
   733         return false;
       
   734       }
       
   735       $pt = $this->concat($x, $pt);
       
   736       if(!$pt)
       
   737       {
       
   738         $this->trigger_error('ECB concatenation routine returned false', E_USER_WARNING);
       
   739         return false;
       
   740       }
       
   741     }
       
   742   
       
   743     return $pt;
       
   744   }
  1476   }
   745   
  1477   
   746   /**
  1478   /**
   747    * Wrapper for encryption.
  1479    * Wrapper for encryption.
   748    * @param string $text the text to encrypt
  1480    * @param string Plain text to encrypt
   749    * @param string $key the raw binary key to encrypt with
  1481    * @param string Binary or hex key
   750    * @param int $return_encoding optional - can be ENC_BINARY, ENC_HEX or ENC_BASE64
  1482    * @param int Format to return result in - ENC_BINARY, ENC_HEX, or ENC_BASE64
       
  1483    * @return string
   751    */
  1484    */
   752    
  1485   
   753   function encrypt($text, $key, $return_encoding = ENC_HEX)
  1486   public function encrypt($plaintext, $key, $return_format = ENC_HEX)
   754   {
  1487   {
   755     if ( $text == '' )
  1488     return $this->encrypt_cbc($plaintext, $key, '00000000000000000000000000000000', ENC_HEX);
   756       return '';
       
   757     if ( $this->mcrypt && $this->blockSizeInBits == mcrypt_module_get_algo_block_size(eval('return MCRYPT_RIJNDAEL_'.$this->keySizeInBits.';')) )
       
   758     {
       
   759       $iv_size = mcrypt_get_iv_size($this->mcrypt, MCRYPT_MODE_ECB);
       
   760       $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
       
   761       $cryptext = mcrypt_encrypt($this->mcrypt, $key, $text, MCRYPT_MODE_ECB, $iv);
       
   762       switch($return_encoding)
       
   763       {
       
   764         case ENC_HEX:
       
   765         default:
       
   766           $cryptext = $this->strtohex($cryptext);
       
   767           break;
       
   768         case ENC_BINARY:
       
   769           $cryptext = $cryptext;
       
   770           break;
       
   771         case ENC_BASE64:
       
   772           $cryptext = base64_encode($cryptext);
       
   773           break;
       
   774       }
       
   775     }
       
   776     else
       
   777     {
       
   778       $key = $this->prepare_string($key);
       
   779       $text = $this->prepare_string($text);
       
   780       profiler_log('AES: Started encryption of a string');
       
   781       $cryptext = $this->rijndaelEncrypt($text, $key, 'ECB');
       
   782       profiler_log('AES: Finished encryption of a string');
       
   783       if(!is_array($cryptext))
       
   784       {
       
   785         echo 'Warning: encryption failed for string: '.print_r($text,true).'<br />';
       
   786         return false;
       
   787       }
       
   788       switch($return_encoding)
       
   789       {
       
   790         case ENC_HEX:
       
   791         default:
       
   792           $cryptext = $this->byteArrayToHex($cryptext);
       
   793           break;
       
   794         case ENC_BINARY:
       
   795           $cryptext = $this->byteArrayToString($cryptext);
       
   796           break;
       
   797         case ENC_BASE64:
       
   798           $cryptext = base64_encode($this->byteArrayToString($cryptext));
       
   799           break;
       
   800       }
       
   801     }
       
   802     return $cryptext;
       
   803   }
  1489   }
   804   
  1490   
   805   /**
  1491   /**
   806    * Wrapper for decryption.
  1492    * Wrapper for decryption.
   807    * @param string $text the encrypted text
  1493    * @param string Encrypted text
   808    * @param string $key the raw binary key used to encrypt the text
  1494    * @param string Binary or hex key
   809    * @param int $input_encoding the encoding used for the encrypted string. Can be ENC_BINARY, ENC_HEX, or ENC_BASE64.
  1495    * @param int Format that the encrypted text is in - ENC_BINARY, ENC_HEX, or ENC_BASE64
   810    * @param bool $no_cache If true, will not cache the decrypted string on disk.
  1496    * @param bool If true, avoids caching the decryption result.
   811    * @return string
  1497    * @return string
   812    */
  1498    */
   813    
  1499   
   814   function decrypt($text, $key, $input_encoding = ENC_HEX, $no_cache = false)
  1500   public function decrypt($cryptext, $key, $input_format = ENC_HEX, $no_cache = false)
   815   {
  1501   {
   816     if ( $text == '' )
  1502     return $this->decrypt_cbc($cryptext, $key, '00000000000000000000000000000000', ENC_HEX, $no_cache);
   817       return '';
  1503   }
   818     
  1504   
   819     switch($input_encoding)
  1505   /**
       
  1506    * Wrapper for CBC encryption.
       
  1507    * @param string Plain text to encrypt
       
  1508    * @param string Binary or hex key
       
  1509    * @param string 128-bit initialization vector, either hex or binary will do
       
  1510    * @param int Format to return result in - ENC_BINARY, ENC_HEX, or ENC_BASE64
       
  1511    */
       
  1512   
       
  1513   public function encrypt_cbc($plaintext, $key, $ivec, $return_format = ENC_HEX)
       
  1514   {
       
  1515     $okey = self::fetch_key($key);
       
  1516     $okey->set_encrypt();
       
  1517     $aes = self::fetch_cr_singleton();
       
  1518     $plaintext = librijndael2::string2hex($plaintext);
       
  1519     
       
  1520     // init ivec
       
  1521     if ( strlen($ivec) == '16' )
       
  1522     {
       
  1523       $ivec = librijndael2::string2hex($ivec);
       
  1524     }
       
  1525     else if ( preg_match('/^[a-f0-9]+$/i', $ivec) && strlen($ivec) == 32 )
       
  1526     {
       
  1527       // ivec is good
       
  1528     }
       
  1529     else
       
  1530     {
       
  1531       // invalid ivec
       
  1532       return false;
       
  1533     }
       
  1534     
       
  1535     $result = '';
       
  1536     $plaintext = str_split($this->pad_string($plaintext), 32);
       
  1537     foreach ( $plaintext as $block )
       
  1538     {
       
  1539       $result .= $aes->AES_cbc_encrypt($block, $okey, $ivec, 'AES_ENCRYPT');
       
  1540     }
       
  1541     
       
  1542     switch ( $return_format )
   820     {
  1543     {
   821       case ENC_BINARY:
  1544       case ENC_BINARY:
       
  1545         return librijndael2::hex2string($result);
       
  1546       case ENC_HEX:
   822       default:
  1547       default:
   823         break;
  1548         return $result;
   824       case ENC_HEX:
  1549       case ENC_BASE64:
   825         $text = $this->hextostring($text);
  1550         return base64_encode(librijndael2::hex2string($result));
       
  1551     }
       
  1552   }
       
  1553   
       
  1554   /**
       
  1555    * Wrapper for CBC decryption.
       
  1556    * @param string Encrypted text
       
  1557    * @param string Binary or hex key
       
  1558    * @param string 128-bit initialization vector, either hex or binary will do
       
  1559    * @param int Format that the encrypted text is in - ENC_BINARY, ENC_HEX, or ENC_BASE64
       
  1560    * @param bool If true, avoids caching the decryption result.
       
  1561    * @return string
       
  1562    */
       
  1563   
       
  1564   public function decrypt_cbc($cryptext, $key, $ivec, $input_format = ENC_HEX, $no_cache = false)
       
  1565   {
       
  1566     // AES_cbc_encrypt() expects hex
       
  1567     switch ( $input_format )
       
  1568     {
       
  1569       case ENC_BINARY:
       
  1570         $cryptext = librijndael2::string2hex($cryptext);
   826         break;
  1571         break;
   827       case ENC_BASE64:
  1572       case ENC_BASE64:
   828         $text = base64_decode($text);
  1573         $cryptext = librijndael2::string2hex(base64_decode($cryptext));
   829         break;
  1574         break;
   830     }
  1575     }
   831     
  1576     
   832     // Run memory-cache check
  1577     $hash = sha1("{$cryptext}::{$key}");
   833     if ( isset($this->decrypt_cache[$key]) && is_array($this->decrypt_cache[$key]) )
  1578     if ( $cache_result = aes_decrypt_cache_fetch($hash) )
   834     {
  1579       return $cache_result;
   835       if ( isset($this->decrypt_cache[$key][$text]) )
  1580     
   836       {
  1581     // load objects
   837         return $this->decrypt_cache[$key][$text];
  1582     profiler_log("AES: Started decryption of string $hash");
   838       }
  1583     $okey = self::fetch_key($key);
   839     }
  1584     $okey->set_decrypt();
   840     
  1585     $aes = self::fetch_cr_singleton();
   841     // Run disk-cache check
  1586     
   842     $hash = sha1($text . '::' . $key);
  1587     // init ivec
   843     if ( $dypt = aes_decrypt_cache_fetch($hash) )
  1588     if ( strlen($ivec) == '16' )
   844       return $dypt;
  1589     {
   845     
  1590       $ivec = librijndael2::string2hex($ivec);
   846     $text_bin = $text;
  1591     }
   847     $key_bin = $key;
  1592     else if ( preg_match('/^[a-f0-9]+$/i', $ivec) && strlen($ivec) == 32 )
   848     
  1593     {
   849     if ( $this->mcrypt )
  1594       // ivec is good
   850     {
       
   851       $iv_size = mcrypt_get_iv_size($this->mcrypt, MCRYPT_MODE_ECB);
       
   852       $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
       
   853       $dypt = mcrypt_decrypt($this->mcrypt, $key, $text, MCRYPT_MODE_ECB, $iv);
       
   854     }
  1595     }
   855     else
  1596     else
   856     {
  1597     {
   857       $etext = $this->prepare_string($text);
  1598       // invalid ivec
   858       $ekey  = $this->prepare_string($key);
  1599       return false;
   859       $mod = count($etext) % $this->blockSizeInBits;
  1600     }
   860       profiler_log('AES: Started decryption of a string');
  1601     
   861       $dypt = $this->rijndaelDecrypt($etext, $ekey, 'ECB');
  1602     // perform decryption
   862       profiler_log('AES: Finished decryption of a string');
  1603     $result = '';
   863       if(!$dypt)
  1604     $cryptext_orig = $cryptext;
   864       {
  1605     $cryptext = str_split($cryptext, 32);
   865         echo '<pre>'.print_r($dypt, true).'</pre>';
  1606     foreach ( $cryptext as $block )
   866         $this->trigger_error('Rijndael main decryption routine failed', E_USER_ERROR);
  1607     {
   867       }
  1608       $result .= $aes->AES_cbc_encrypt($block, $okey, $ivec, 'AES_DECRYPT');
   868       $dypt = $this->byteArrayToString($dypt);
  1609     }
   869     }
  1610     
   870     if ( !isset($this->decrypt_cache[$key_bin]) )
  1611     // decode result and trim nul bytes
   871       $this->decrypt_cache[$key_bin] = array();
  1612     $result = librijndael2::hex2string($result);
   872     
  1613     $result = rtrim($result, "\000");
   873     $this->decrypt_cache[$key_bin][$text_bin] = $dypt;
       
   874     
  1614     
   875     if ( !$no_cache )
  1615     if ( !$no_cache )
   876       aes_decrypt_cache_store($text_bin, $dypt, $key_bin);
  1616       aes_decrypt_cache_store($cryptext_orig, $result, $key);
   877     
  1617     
   878     return $dypt;
  1618     profiler_log("AES: Finished decryption of string $hash");
       
  1619     
       
  1620     // done! :)
       
  1621     return $result;
   879   }
  1622   }
   880   
  1623   
   881   /**
  1624   /**
   882    * Enano-ese equivalent of str_split() which is only found in PHP5
  1625    * Factory.
   883    * @param $text string the text to split
  1626    * @param int Key size in bits
   884    * @param $inc int size of each block
  1627    * @param int Block size in bits - ONLY 128-bit supported.
   885    * @return array
  1628    * @return object Instance of AESCrypt
   886    */
  1629    */
   887    
  1630   
   888   function enano_str_split($text, $inc = 1)
  1631   public static function singleton($key_size = AES_BITS, $block_size = 128)
   889   {
  1632   {
   890     if($inc < 1) return false;
  1633     static $instance = false;
   891     if($inc >= strlen($text)) return Array($text);
  1634     if ( !$instance )
   892     $len = ceil(strlen($text) / $inc);
  1635     {
   893     $ret = Array();
  1636       $class = __CLASS__;
   894     for($i=0;$i<strlen($text);$i=$i+$inc)
  1637       $instance = new $class();
   895     {
  1638     }
   896       $ret[] = substr($text, $i, $inc);
  1639     return $instance;
   897     }
  1640   }
   898     return $ret;
  1641   
   899   }
       
   900   
       
   901   /**
       
   902    * Generates a random key suitable for encryption
       
   903    * @param int $len the length of the key, in bytes
       
   904    * @return string a BINARY key
       
   905    */
       
   906   
       
   907   function randkey($len = 32)
       
   908   {
       
   909     $key = '';
       
   910     for($i=0;$i<$len;$i++)
       
   911     {
       
   912       $key .= chr(mt_rand(0, 255));
       
   913     }
       
   914     if ( @file_exists('/dev/urandom') && @is_readable('/dev/urandom') )
       
   915     {
       
   916       // Let's use something a little more secure
       
   917       $ur = @fopen('/dev/urandom', 'r');
       
   918       if ( !$ur )
       
   919         return $key;
       
   920       $ukey = @fread($ur, $len);
       
   921       fclose($ur);
       
   922       if ( strlen($ukey) != $len )
       
   923         return $key;
       
   924       return $ukey;
       
   925     }
       
   926     return $key;
       
   927   }
       
   928   
       
   929   /*
       
   930   function byteArrayToString($arr)
       
   931   {
       
   932     if(!is_array($arr))
       
   933     {
       
   934       $this->trigger_error('First parameter should be an array', E_USER_WARNING);
       
   935       return false;
       
   936     }
       
   937     $ret = '';
       
   938     foreach($arr as $a)
       
   939     {
       
   940       if($a != 0) $ret .= chr($a);
       
   941     }
       
   942     return $ret;
       
   943   }
       
   944   */
       
   945   
       
   946   function strtohex($str)
       
   947   {
       
   948     $str = $this->enano_str_split($str);
       
   949     $ret = '';
       
   950     foreach($str as $s)
       
   951     {
       
   952       $chr = dechex(ord($s));
       
   953       if(strlen($chr) < 2) $chr = '0' . $chr;
       
   954       $ret .= $chr;
       
   955     }
       
   956     return $ret;
       
   957   }
       
   958   
       
   959   function gen_readymade_key()
       
   960   {
       
   961     $key = $this->strtohex($this->randkey($this->keySizeInBits / 8));
       
   962     return $key;
       
   963   }
       
   964   
       
   965   function prepare_string($text)
       
   966   {
       
   967     $ret = $this->hexToByteArray($this->strtohex($text));
       
   968     if(count($ret) != strlen($text))
       
   969     {
       
   970       die('Could not convert string "' . $text . '" to hex byte array for encryption');
       
   971     }
       
   972     return $ret;
       
   973   }
       
   974   
       
   975   /**
       
   976    * Decodes a hex string.
       
   977    * @param string $hex The hex code to decode
       
   978    * @return string
       
   979    */
       
   980   
       
   981   function hextostring($hex)
       
   982   {
       
   983     $hex = $this->enano_str_split($hex, 2);
       
   984     $bin_key = '';
       
   985     foreach($hex as $nibble)
       
   986     {
       
   987       $byte = chr(hexdec($nibble));
       
   988       $bin_key .= $byte;
       
   989     }
       
   990     return $bin_key;
       
   991   }
       
   992 }
  1642 }
   993 
  1643 
   994 function aes_decrypt_cache_store($encrypted, $decrypted, $key)
  1644 function aes_decrypt_cache_store($encrypted, $decrypted, $key)
   995 {
  1645 {
   996   $cache_file = ENANO_ROOT . '/cache/aes_decrypt.php';
  1646   $cache_file = ENANO_ROOT . '/cache/aes_decrypt.php';