[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-includes/sodium_compat/src/Core/ -> SipHash.php (source)

   1  <?php
   2  
   3  if (class_exists('ParagonIE_Sodium_Core_SipHash', false)) {
   4      return;
   5  }
   6  
   7  /**
   8   * Class ParagonIE_SodiumCompat_Core_SipHash
   9   *
  10   * Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
  11   */
  12  class ParagonIE_Sodium_Core_SipHash extends ParagonIE_Sodium_Core_Util
  13  {
  14      /**
  15       * @internal You should not use this directly from another application
  16       *
  17       * @param int[] $v
  18       * @return int[]
  19       */
  20      public static function sipRound(array $v)
  21      {
  22          # v0 += v1;
  23          list($v[0], $v[1]) = self::add(
  24              array($v[0], $v[1]),
  25              array($v[2], $v[3])
  26          );
  27  
  28          #  v1=ROTL(v1,13);
  29          list($v[2], $v[3]) = self::rotl_64($v[2], $v[3], 13);
  30  
  31          #  v1 ^= v0;
  32          $v[2] ^= $v[0];
  33          $v[3] ^= $v[1];
  34  
  35          #  v0=ROTL(v0,32);
  36          list($v[0], $v[1]) = self::rotl_64((int) $v[0], (int) $v[1], 32);
  37  
  38          # v2 += v3;
  39          list($v[4], $v[5]) = self::add(
  40              array($v[4], $v[5]),
  41              array($v[6], $v[7])
  42          );
  43  
  44          # v3=ROTL(v3,16);
  45          list($v[6], $v[7]) = self::rotl_64($v[6], $v[7], 16);
  46  
  47          #  v3 ^= v2;
  48          $v[6] ^= $v[4];
  49          $v[7] ^= $v[5];
  50  
  51          # v0 += v3;
  52          list($v[0], $v[1]) = self::add(
  53              array((int) $v[0], (int) $v[1]),
  54              array((int) $v[6], (int) $v[7])
  55          );
  56  
  57          # v3=ROTL(v3,21);
  58          list($v[6], $v[7]) = self::rotl_64((int) $v[6], (int) $v[7], 21);
  59  
  60          # v3 ^= v0;
  61          $v[6] ^= $v[0];
  62          $v[7] ^= $v[1];
  63  
  64          # v2 += v1;
  65          list($v[4], $v[5]) = self::add(
  66              array((int) $v[4], (int) $v[5]),
  67              array((int) $v[2], (int) $v[3])
  68          );
  69  
  70          # v1=ROTL(v1,17);
  71          list($v[2], $v[3]) = self::rotl_64((int) $v[2], (int) $v[3], 17);
  72  
  73          #  v1 ^= v2;;
  74          $v[2] ^= $v[4];
  75          $v[3] ^= $v[5];
  76  
  77          # v2=ROTL(v2,32)
  78          list($v[4], $v[5]) = self::rotl_64((int) $v[4], (int) $v[5], 32);
  79  
  80          return $v;
  81      }
  82  
  83      /**
  84       * Add two 32 bit integers representing a 64-bit integer.
  85       *
  86       * @internal You should not use this directly from another application
  87       *
  88       * @param int[] $a
  89       * @param int[] $b
  90       * @return array<int, mixed>
  91       */
  92      public static function add(array $a, array $b)
  93      {
  94          /** @var int $x1 */
  95          $x1 = $a[1] + $b[1];
  96          /** @var int $c */
  97          $c = $x1 >> 32; // Carry if ($a + $b) > 0xffffffff
  98          /** @var int $x0 */
  99          $x0 = $a[0] + $b[0] + $c;
 100          return array(
 101              $x0 & 0xffffffff,
 102              $x1 & 0xffffffff
 103          );
 104      }
 105  
 106      /**
 107       * @internal You should not use this directly from another application
 108       *
 109       * @param int $int0
 110       * @param int $int1
 111       * @param int $c
 112       * @return array<int, mixed>
 113       */
 114      public static function rotl_64($int0, $int1, $c)
 115      {
 116          $int0 &= 0xffffffff;
 117          $int1 &= 0xffffffff;
 118          $c &= 63;
 119          if ($c === 32) {
 120              return array($int1, $int0);
 121          }
 122          if ($c > 31) {
 123              $tmp = $int1;
 124              $int1 = $int0;
 125              $int0 = $tmp;
 126              $c &= 31;
 127          }
 128          if ($c === 0) {
 129              return array($int0, $int1);
 130          }
 131          return array(
 132              0xffffffff & (
 133                  ($int0 << $c)
 134                      |
 135                  ($int1 >> (32 - $c))
 136              ),
 137              0xffffffff & (
 138                  ($int1 << $c)
 139                      |
 140                  ($int0 >> (32 - $c))
 141              ),
 142          );
 143      }
 144  
 145      /**
 146       * Implements Siphash-2-4 using only 32-bit numbers.
 147       *
 148       * When we split an int into two, the higher bits go to the lower index.
 149       * e.g. 0xDEADBEEFAB10C92D becomes [
 150       *     0 => 0xDEADBEEF,
 151       *     1 => 0xAB10C92D
 152       * ].
 153       *
 154       * @internal You should not use this directly from another application
 155       *
 156       * @param string $in
 157       * @param string $key
 158       * @return string
 159       * @throws SodiumException
 160       * @throws TypeError
 161       */
 162      public static function sipHash24($in, $key)
 163      {
 164          $inlen = self::strlen($in);
 165  
 166          # /* "somepseudorandomlygeneratedbytes" */
 167          # u64 v0 = 0x736f6d6570736575ULL;
 168          # u64 v1 = 0x646f72616e646f6dULL;
 169          # u64 v2 = 0x6c7967656e657261ULL;
 170          # u64 v3 = 0x7465646279746573ULL;
 171          $v = array(
 172              0x736f6d65, // 0
 173              0x70736575, // 1
 174              0x646f7261, // 2
 175              0x6e646f6d, // 3
 176              0x6c796765, // 4
 177              0x6e657261, // 5
 178              0x74656462, // 6
 179              0x79746573  // 7
 180          );
 181          // v0 => $v[0], $v[1]
 182          // v1 => $v[2], $v[3]
 183          // v2 => $v[4], $v[5]
 184          // v3 => $v[6], $v[7]
 185  
 186          # u64 k0 = LOAD64_LE( k );
 187          # u64 k1 = LOAD64_LE( k + 8 );
 188          $k = array(
 189              self::load_4(self::substr($key, 4, 4)),
 190              self::load_4(self::substr($key, 0, 4)),
 191              self::load_4(self::substr($key, 12, 4)),
 192              self::load_4(self::substr($key, 8, 4))
 193          );
 194          // k0 => $k[0], $k[1]
 195          // k1 => $k[2], $k[3]
 196  
 197          # b = ( ( u64 )inlen ) << 56;
 198          $b = array(
 199              $inlen << 24,
 200              0
 201          );
 202          // See docblock for why the 0th index gets the higher bits.
 203  
 204          # v3 ^= k1;
 205          $v[6] ^= $k[2];
 206          $v[7] ^= $k[3];
 207          # v2 ^= k0;
 208          $v[4] ^= $k[0];
 209          $v[5] ^= $k[1];
 210          # v1 ^= k1;
 211          $v[2] ^= $k[2];
 212          $v[3] ^= $k[3];
 213          # v0 ^= k0;
 214          $v[0] ^= $k[0];
 215          $v[1] ^= $k[1];
 216  
 217          $left = $inlen;
 218          # for ( ; in != end; in += 8 )
 219          while ($left >= 8) {
 220              # m = LOAD64_LE( in );
 221              $m = array(
 222                  self::load_4(self::substr($in, 4, 4)),
 223                  self::load_4(self::substr($in, 0, 4))
 224              );
 225  
 226              # v3 ^= m;
 227              $v[6] ^= $m[0];
 228              $v[7] ^= $m[1];
 229  
 230              # SIPROUND;
 231              # SIPROUND;
 232              $v = self::sipRound($v);
 233              $v = self::sipRound($v);
 234  
 235              # v0 ^= m;
 236              $v[0] ^= $m[0];
 237              $v[1] ^= $m[1];
 238  
 239              $in = self::substr($in, 8);
 240              $left -= 8;
 241          }
 242  
 243          # switch( left )
 244          #  {
 245          #     case 7: b |= ( ( u64 )in[ 6] )  << 48;
 246          #     case 6: b |= ( ( u64 )in[ 5] )  << 40;
 247          #     case 5: b |= ( ( u64 )in[ 4] )  << 32;
 248          #     case 4: b |= ( ( u64 )in[ 3] )  << 24;
 249          #     case 3: b |= ( ( u64 )in[ 2] )  << 16;
 250          #     case 2: b |= ( ( u64 )in[ 1] )  <<  8;
 251          #     case 1: b |= ( ( u64 )in[ 0] ); break;
 252          #     case 0: break;
 253          # }
 254          switch ($left) {
 255              case 7:
 256                  $b[0] |= self::chrToInt($in[6]) << 16;
 257              case 6:
 258                  $b[0] |= self::chrToInt($in[5]) << 8;
 259              case 5:
 260                  $b[0] |= self::chrToInt($in[4]);
 261              case 4:
 262                  $b[1] |= self::chrToInt($in[3]) << 24;
 263              case 3:
 264                  $b[1] |= self::chrToInt($in[2]) << 16;
 265              case 2:
 266                  $b[1] |= self::chrToInt($in[1]) << 8;
 267              case 1:
 268                  $b[1] |= self::chrToInt($in[0]);
 269              case 0:
 270                  break;
 271          }
 272          // See docblock for why the 0th index gets the higher bits.
 273  
 274          # v3 ^= b;
 275          $v[6] ^= $b[0];
 276          $v[7] ^= $b[1];
 277  
 278          # SIPROUND;
 279          # SIPROUND;
 280          $v = self::sipRound($v);
 281          $v = self::sipRound($v);
 282  
 283          # v0 ^= b;
 284          $v[0] ^= $b[0];
 285          $v[1] ^= $b[1];
 286  
 287          // Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
 288          # v2 ^= 0xff;
 289          $v[5] ^= 0xff;
 290  
 291          # SIPROUND;
 292          # SIPROUND;
 293          # SIPROUND;
 294          # SIPROUND;
 295          $v = self::sipRound($v);
 296          $v = self::sipRound($v);
 297          $v = self::sipRound($v);
 298          $v = self::sipRound($v);
 299  
 300          # b = v0 ^ v1 ^ v2 ^ v3;
 301          # STORE64_LE( out, b );
 302          return  self::store32_le($v[1] ^ $v[3] ^ $v[5] ^ $v[7]) .
 303              self::store32_le($v[0] ^ $v[2] ^ $v[4] ^ $v[6]);
 304      }
 305  }


Generated: Fri Oct 25 08:20:01 2019 Cross-referenced by PHPXref 0.7