wp/wp-includes/sodium_compat/src/Core32/SipHash.php
changeset 9 177826044cd9
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
       
     1 <?php
       
     2 
       
     3 if (class_exists('ParagonIE_Sodium_Core32_SipHash', false)) {
       
     4     return;
       
     5 }
       
     6 
       
     7 /**
       
     8  * Class ParagonIE_SodiumCompat_Core32_SipHash
       
     9  *
       
    10  * Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
       
    11  */
       
    12 class ParagonIE_Sodium_Core32_SipHash extends ParagonIE_Sodium_Core32_Util
       
    13 {
       
    14     /**
       
    15      * @internal You should not use this directly from another application
       
    16      *
       
    17      * @param array<int, ParagonIE_Sodium_Core32_Int64> $v
       
    18      * @return array<int, ParagonIE_Sodium_Core32_Int64>
       
    19      */
       
    20     public static function sipRound(array $v)
       
    21     {
       
    22         # v0 += v1;
       
    23         $v[0] = $v[0]->addInt64($v[1]);
       
    24 
       
    25         # v1 = ROTL(v1, 13);
       
    26         $v[1] = $v[1]->rotateLeft(13);
       
    27 
       
    28         #  v1 ^= v0;
       
    29         $v[1] = $v[1]->xorInt64($v[0]);
       
    30 
       
    31         #  v0=ROTL(v0,32);
       
    32         $v[0] = $v[0]->rotateLeft(32);
       
    33 
       
    34         # v2 += v3;
       
    35         $v[2] = $v[2]->addInt64($v[3]);
       
    36 
       
    37         # v3=ROTL(v3,16);
       
    38         $v[3] = $v[3]->rotateLeft(16);
       
    39 
       
    40         #  v3 ^= v2;
       
    41         $v[3] = $v[3]->xorInt64($v[2]);
       
    42 
       
    43         # v0 += v3;
       
    44         $v[0] = $v[0]->addInt64($v[3]);
       
    45 
       
    46         # v3=ROTL(v3,21);
       
    47         $v[3] = $v[3]->rotateLeft(21);
       
    48 
       
    49         # v3 ^= v0;
       
    50         $v[3] = $v[3]->xorInt64($v[0]);
       
    51 
       
    52         # v2 += v1;
       
    53         $v[2] = $v[2]->addInt64($v[1]);
       
    54 
       
    55         # v1=ROTL(v1,17);
       
    56         $v[1] = $v[1]->rotateLeft(17);
       
    57 
       
    58         #  v1 ^= v2;
       
    59         $v[1] = $v[1]->xorInt64($v[2]);
       
    60 
       
    61         # v2=ROTL(v2,32)
       
    62         $v[2] = $v[2]->rotateLeft(32);
       
    63 
       
    64         return $v;
       
    65     }
       
    66 
       
    67     /**
       
    68      * @internal You should not use this directly from another application
       
    69      *
       
    70      * @param string $in
       
    71      * @param string $key
       
    72      * @return string
       
    73      * @throws SodiumException
       
    74      * @throws TypeError
       
    75      */
       
    76     public static function sipHash24($in, $key)
       
    77     {
       
    78         $inlen = self::strlen($in);
       
    79 
       
    80         # /* "somepseudorandomlygeneratedbytes" */
       
    81         # u64 v0 = 0x736f6d6570736575ULL;
       
    82         # u64 v1 = 0x646f72616e646f6dULL;
       
    83         # u64 v2 = 0x6c7967656e657261ULL;
       
    84         # u64 v3 = 0x7465646279746573ULL;
       
    85         $v = array(
       
    86             new ParagonIE_Sodium_Core32_Int64(
       
    87                 array(0x736f, 0x6d65, 0x7073, 0x6575)
       
    88             ),
       
    89             new ParagonIE_Sodium_Core32_Int64(
       
    90                 array(0x646f, 0x7261, 0x6e64, 0x6f6d)
       
    91             ),
       
    92             new ParagonIE_Sodium_Core32_Int64(
       
    93                 array(0x6c79, 0x6765, 0x6e65, 0x7261)
       
    94             ),
       
    95             new ParagonIE_Sodium_Core32_Int64(
       
    96                 array(0x7465, 0x6462, 0x7974, 0x6573)
       
    97             )
       
    98         );
       
    99 
       
   100         # u64 k0 = LOAD64_LE( k );
       
   101         # u64 k1 = LOAD64_LE( k + 8 );
       
   102         $k = array(
       
   103             ParagonIE_Sodium_Core32_Int64::fromReverseString(
       
   104                 self::substr($key, 0, 8)
       
   105             ),
       
   106             ParagonIE_Sodium_Core32_Int64::fromReverseString(
       
   107                 self::substr($key, 8, 8)
       
   108             )
       
   109         );
       
   110 
       
   111         # b = ( ( u64 )inlen ) << 56;
       
   112         $b = new ParagonIE_Sodium_Core32_Int64(
       
   113             array(($inlen << 8) & 0xffff, 0, 0, 0)
       
   114         );
       
   115 
       
   116         # v3 ^= k1;
       
   117         $v[3] = $v[3]->xorInt64($k[1]);
       
   118         # v2 ^= k0;
       
   119         $v[2] = $v[2]->xorInt64($k[0]);
       
   120         # v1 ^= k1;
       
   121         $v[1] = $v[1]->xorInt64($k[1]);
       
   122         # v0 ^= k0;
       
   123         $v[0] = $v[0]->xorInt64($k[0]);
       
   124 
       
   125         $left = $inlen;
       
   126         # for ( ; in != end; in += 8 )
       
   127         while ($left >= 8) {
       
   128             # m = LOAD64_LE( in );
       
   129             $m = ParagonIE_Sodium_Core32_Int64::fromReverseString(
       
   130                 self::substr($in, 0, 8)
       
   131             );
       
   132 
       
   133             # v3 ^= m;
       
   134             $v[3] = $v[3]->xorInt64($m);
       
   135 
       
   136             # SIPROUND;
       
   137             # SIPROUND;
       
   138             $v = self::sipRound($v);
       
   139             $v = self::sipRound($v);
       
   140 
       
   141             # v0 ^= m;
       
   142             $v[0] = $v[0]->xorInt64($m);
       
   143 
       
   144             $in = self::substr($in, 8);
       
   145             $left -= 8;
       
   146         }
       
   147 
       
   148         # switch( left )
       
   149         #  {
       
   150         #     case 7: b |= ( ( u64 )in[ 6] )  << 48;
       
   151         #     case 6: b |= ( ( u64 )in[ 5] )  << 40;
       
   152         #     case 5: b |= ( ( u64 )in[ 4] )  << 32;
       
   153         #     case 4: b |= ( ( u64 )in[ 3] )  << 24;
       
   154         #     case 3: b |= ( ( u64 )in[ 2] )  << 16;
       
   155         #     case 2: b |= ( ( u64 )in[ 1] )  <<  8;
       
   156         #     case 1: b |= ( ( u64 )in[ 0] ); break;
       
   157         #     case 0: break;
       
   158         # }
       
   159         switch ($left) {
       
   160             case 7:
       
   161                 $b = $b->orInt64(
       
   162                     ParagonIE_Sodium_Core32_Int64::fromInts(
       
   163                         0, self::chrToInt($in[6]) << 16
       
   164                     )
       
   165                 );
       
   166             case 6:
       
   167                 $b = $b->orInt64(
       
   168                     ParagonIE_Sodium_Core32_Int64::fromInts(
       
   169                         0, self::chrToInt($in[5]) << 8
       
   170                     )
       
   171                 );
       
   172             case 5:
       
   173                 $b = $b->orInt64(
       
   174                     ParagonIE_Sodium_Core32_Int64::fromInts(
       
   175                         0, self::chrToInt($in[4])
       
   176                     )
       
   177                 );
       
   178             case 4:
       
   179                 $b = $b->orInt64(
       
   180                     ParagonIE_Sodium_Core32_Int64::fromInts(
       
   181                         self::chrToInt($in[3]) << 24, 0
       
   182                     )
       
   183                 );
       
   184             case 3:
       
   185                 $b = $b->orInt64(
       
   186                     ParagonIE_Sodium_Core32_Int64::fromInts(
       
   187                         self::chrToInt($in[2]) << 16, 0
       
   188                     )
       
   189                 );
       
   190             case 2:
       
   191                 $b = $b->orInt64(
       
   192                     ParagonIE_Sodium_Core32_Int64::fromInts(
       
   193                         self::chrToInt($in[1]) << 8, 0
       
   194                     )
       
   195                 );
       
   196             case 1:
       
   197                 $b = $b->orInt64(
       
   198                     ParagonIE_Sodium_Core32_Int64::fromInts(
       
   199                         self::chrToInt($in[0]), 0
       
   200                     )
       
   201                 );
       
   202             case 0:
       
   203                 break;
       
   204         }
       
   205 
       
   206         # v3 ^= b;
       
   207         $v[3] = $v[3]->xorInt64($b);
       
   208 
       
   209         # SIPROUND;
       
   210         # SIPROUND;
       
   211         $v = self::sipRound($v);
       
   212         $v = self::sipRound($v);
       
   213 
       
   214         # v0 ^= b;
       
   215         $v[0] = $v[0]->xorInt64($b);
       
   216 
       
   217         // Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
       
   218         # v2 ^= 0xff;
       
   219         $v[2]->limbs[3] ^= 0xff;
       
   220 
       
   221         # SIPROUND;
       
   222         # SIPROUND;
       
   223         # SIPROUND;
       
   224         # SIPROUND;
       
   225         $v = self::sipRound($v);
       
   226         $v = self::sipRound($v);
       
   227         $v = self::sipRound($v);
       
   228         $v = self::sipRound($v);
       
   229 
       
   230         # b = v0 ^ v1 ^ v2 ^ v3;
       
   231         # STORE64_LE( out, b );
       
   232         return $v[0]
       
   233             ->xorInt64($v[1])
       
   234             ->xorInt64($v[2])
       
   235             ->xorInt64($v[3])
       
   236             ->toReverseString();
       
   237     }
       
   238 }