[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

   1  <?php
   2  
   3  if (class_exists('ParagonIE_Sodium_Core_BLAKE2b', false)) {
   4      return;
   5  }
   6  
   7  /**
   8   * Class ParagonIE_Sodium_Core_BLAKE2b
   9   *
  10   * Based on the work of Devi Mandiri in devi/salt.
  11   */
  12  abstract class ParagonIE_Sodium_Core_BLAKE2b extends ParagonIE_Sodium_Core_Util
  13  {
  14      /**
  15       * @var SplFixedArray
  16       */
  17      protected static $iv;
  18  
  19      /**
  20       * @var array<int, array<int, int>>
  21       */
  22      protected static $sigma = array(
  23          array(  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15),
  24          array( 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3),
  25          array( 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4),
  26          array(  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8),
  27          array(  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13),
  28          array(  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9),
  29          array( 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11),
  30          array( 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10),
  31          array(  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5),
  32          array( 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0),
  33          array(  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15),
  34          array( 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3)
  35      );
  36  
  37      const BLOCKBYTES = 128;
  38      const OUTBYTES   = 64;
  39      const KEYBYTES   = 64;
  40  
  41      /**
  42       * Turn two 32-bit integers into a fixed array representing a 64-bit integer.
  43       *
  44       * @internal You should not use this directly from another application
  45       *
  46       * @param int $high
  47       * @param int $low
  48       * @return SplFixedArray
  49       * @psalm-suppress MixedAssignment
  50       */
  51      public static function new64($high, $low)
  52      {
  53          $i64 = new SplFixedArray(2);
  54          $i64[0] = $high & 0xffffffff;
  55          $i64[1] = $low & 0xffffffff;
  56          return $i64;
  57      }
  58  
  59      /**
  60       * Convert an arbitrary number into an SplFixedArray of two 32-bit integers
  61       * that represents a 64-bit integer.
  62       *
  63       * @internal You should not use this directly from another application
  64       *
  65       * @param int $num
  66       * @return SplFixedArray
  67       */
  68      protected static function to64($num)
  69      {
  70          list($hi, $lo) = self::numericTo64BitInteger($num);
  71          return self::new64($hi, $lo);
  72      }
  73  
  74      /**
  75       * Adds two 64-bit integers together, returning their sum as a SplFixedArray
  76       * containing two 32-bit integers (representing a 64-bit integer).
  77       *
  78       * @internal You should not use this directly from another application
  79       *
  80       * @param SplFixedArray $x
  81       * @param SplFixedArray $y
  82       * @return SplFixedArray
  83       * @psalm-suppress MixedArgument
  84       * @psalm-suppress MixedAssignment
  85       * @psalm-suppress MixedOperand
  86       */
  87      protected static function add64($x, $y)
  88      {
  89          $l = ($x[1] + $y[1]) & 0xffffffff;
  90          return self::new64(
  91              (int) ($x[0] + $y[0] + (
  92                  ($l < $x[1]) ? 1 : 0
  93              )),
  94              (int) $l
  95          );
  96      }
  97  
  98      /**
  99       * @internal You should not use this directly from another application
 100       *
 101       * @param SplFixedArray $x
 102       * @param SplFixedArray $y
 103       * @param SplFixedArray $z
 104       * @return SplFixedArray
 105       */
 106      protected static function add364($x, $y, $z)
 107      {
 108          return self::add64($x, self::add64($y, $z));
 109      }
 110  
 111      /**
 112       * @internal You should not use this directly from another application
 113       *
 114       * @param SplFixedArray $x
 115       * @param SplFixedArray $y
 116       * @return SplFixedArray
 117       * @throws SodiumException
 118       * @throws TypeError
 119       */
 120      protected static function xor64(SplFixedArray $x, SplFixedArray $y)
 121      {
 122          if (!is_numeric($x[0])) {
 123              throw new SodiumException('x[0] is not an integer');
 124          }
 125          if (!is_numeric($x[1])) {
 126              throw new SodiumException('x[1] is not an integer');
 127          }
 128          if (!is_numeric($y[0])) {
 129              throw new SodiumException('y[0] is not an integer');
 130          }
 131          if (!is_numeric($y[1])) {
 132              throw new SodiumException('y[1] is not an integer');
 133          }
 134          return self::new64(
 135              (int) (($x[0] ^ $y[0]) & 0xffffffff),
 136              (int) (($x[1] ^ $y[1]) & 0xffffffff)
 137          );
 138      }
 139  
 140      /**
 141       * @internal You should not use this directly from another application
 142       *
 143       * @param SplFixedArray $x
 144       * @param int $c
 145       * @return SplFixedArray
 146       * @psalm-suppress MixedAssignment
 147       */
 148      public static function rotr64($x, $c)
 149      {
 150          if ($c >= 64) {
 151              $c %= 64;
 152          }
 153          if ($c >= 32) {
 154              /** @var int $tmp */
 155              $tmp = $x[0];
 156              $x[0] = $x[1];
 157              $x[1] = $tmp;
 158              $c -= 32;
 159          }
 160          if ($c === 0) {
 161              return $x;
 162          }
 163  
 164          $l0 = 0;
 165          $c = 64 - $c;
 166  
 167          if ($c < 32) {
 168              /** @var int $h0 */
 169              $h0 = ((int) ($x[0]) << $c) | (
 170                  (
 171                      (int) ($x[1]) & ((1 << $c) - 1)
 172                          <<
 173                      (32 - $c)
 174                  ) >> (32 - $c)
 175              );
 176              /** @var int $l0 */
 177              $l0 = (int) ($x[1]) << $c;
 178          } else {
 179              /** @var int $h0 */
 180              $h0 = (int) ($x[1]) << ($c - 32);
 181          }
 182  
 183          $h1 = 0;
 184          $c1 = 64 - $c;
 185  
 186          if ($c1 < 32) {
 187              /** @var int $h1 */
 188              $h1 = (int) ($x[0]) >> $c1;
 189              /** @var int $l1 */
 190              $l1 = ((int) ($x[1]) >> $c1) | ((int) ($x[0]) & ((1 << $c1) - 1)) << (32 - $c1);
 191          } else {
 192              /** @var int $l1 */
 193              $l1 = (int) ($x[0]) >> ($c1 - 32);
 194          }
 195  
 196          return self::new64($h0 | $h1, $l0 | $l1);
 197      }
 198  
 199      /**
 200       * @internal You should not use this directly from another application
 201       *
 202       * @param SplFixedArray $x
 203       * @return int
 204       * @psalm-suppress MixedOperand
 205       */
 206      protected static function flatten64($x)
 207      {
 208          return (int) ($x[0] * 4294967296 + $x[1]);
 209      }
 210  
 211      /**
 212       * @internal You should not use this directly from another application
 213       *
 214       * @param SplFixedArray $x
 215       * @param int $i
 216       * @return SplFixedArray
 217       * @psalm-suppress MixedArgument
 218       * @psalm-suppress MixedArrayOffset
 219       */
 220      protected static function load64(SplFixedArray $x, $i)
 221      {
 222          /** @var int $l */
 223          $l = (int) ($x[$i])
 224               | ((int) ($x[$i+1]) << 8)
 225               | ((int) ($x[$i+2]) << 16)
 226               | ((int) ($x[$i+3]) << 24);
 227          /** @var int $h */
 228          $h = (int) ($x[$i+4])
 229               | ((int) ($x[$i+5]) << 8)
 230               | ((int) ($x[$i+6]) << 16)
 231               | ((int) ($x[$i+7]) << 24);
 232          return self::new64($h, $l);
 233      }
 234  
 235      /**
 236       * @internal You should not use this directly from another application
 237       *
 238       * @param SplFixedArray $x
 239       * @param int $i
 240       * @param SplFixedArray $u
 241       * @return void
 242       * @psalm-suppress MixedAssignment
 243       */
 244      protected static function store64(SplFixedArray $x, $i, SplFixedArray $u)
 245      {
 246          $maxLength = $x->getSize() - 1;
 247          for ($j = 0; $j < 8; ++$j) {
 248              /*
 249                 [0, 1, 2, 3, 4, 5, 6, 7]
 250                      ... becomes ...
 251                 [0, 0, 0, 0, 1, 1, 1, 1]
 252              */
 253              /** @var int $uIdx */
 254              $uIdx = ((7 - $j) & 4) >> 2;
 255              $x[$i]   = ((int) ($u[$uIdx]) & 0xff);
 256              if (++$i > $maxLength) {
 257                  return;
 258              }
 259              /** @psalm-suppress MixedOperand */
 260              $u[$uIdx] >>= 8;
 261          }
 262      }
 263  
 264      /**
 265       * This just sets the $iv static variable.
 266       *
 267       * @internal You should not use this directly from another application
 268       *
 269       * @return void
 270       */
 271      public static function pseudoConstructor()
 272      {
 273          static $called = false;
 274          if ($called) {
 275              return;
 276          }
 277          self::$iv = new SplFixedArray(8);
 278          self::$iv[0] = self::new64(0x6a09e667, 0xf3bcc908);
 279          self::$iv[1] = self::new64(0xbb67ae85, 0x84caa73b);
 280          self::$iv[2] = self::new64(0x3c6ef372, 0xfe94f82b);
 281          self::$iv[3] = self::new64(0xa54ff53a, 0x5f1d36f1);
 282          self::$iv[4] = self::new64(0x510e527f, 0xade682d1);
 283          self::$iv[5] = self::new64(0x9b05688c, 0x2b3e6c1f);
 284          self::$iv[6] = self::new64(0x1f83d9ab, 0xfb41bd6b);
 285          self::$iv[7] = self::new64(0x5be0cd19, 0x137e2179);
 286  
 287          $called = true;
 288      }
 289  
 290      /**
 291       * Returns a fresh BLAKE2 context.
 292       *
 293       * @internal You should not use this directly from another application
 294       *
 295       * @return SplFixedArray
 296       * @psalm-suppress MixedAssignment
 297       * @psalm-suppress MixedArrayAccess
 298       * @psalm-suppress MixedArrayAssignment
 299       */
 300      protected static function context()
 301      {
 302          $ctx    = new SplFixedArray(6);
 303          $ctx[0] = new SplFixedArray(8);   // h
 304          $ctx[1] = new SplFixedArray(2);   // t
 305          $ctx[2] = new SplFixedArray(2);   // f
 306          $ctx[3] = new SplFixedArray(256); // buf
 307          $ctx[4] = 0;                      // buflen
 308          $ctx[5] = 0;                      // last_node (uint8_t)
 309  
 310          for ($i = 8; $i--;) {
 311              $ctx[0][$i] = self::$iv[$i];
 312          }
 313          for ($i = 256; $i--;) {
 314              $ctx[3][$i] = 0;
 315          }
 316  
 317          $zero = self::new64(0, 0);
 318          $ctx[1][0] = $zero;
 319          $ctx[1][1] = $zero;
 320          $ctx[2][0] = $zero;
 321          $ctx[2][1] = $zero;
 322  
 323          return $ctx;
 324      }
 325  
 326      /**
 327       * @internal You should not use this directly from another application
 328       *
 329       * @param SplFixedArray $ctx
 330       * @param SplFixedArray $buf
 331       * @return void
 332       * @throws SodiumException
 333       * @throws TypeError
 334       * @psalm-suppress MixedArgument
 335       * @psalm-suppress MixedAssignment
 336       * @psalm-suppress MixedArrayAccess
 337       * @psalm-suppress MixedArrayAssignment
 338       * @psalm-suppress MixedArrayOffset
 339       */
 340      protected static function compress(SplFixedArray $ctx, SplFixedArray $buf)
 341      {
 342          $m = new SplFixedArray(16);
 343          $v = new SplFixedArray(16);
 344  
 345          for ($i = 16; $i--;) {
 346              $m[$i] = self::load64($buf, $i << 3);
 347          }
 348  
 349          for ($i = 8; $i--;) {
 350              $v[$i] = $ctx[0][$i];
 351          }
 352  
 353          $v[ 8] = self::$iv[0];
 354          $v[ 9] = self::$iv[1];
 355          $v[10] = self::$iv[2];
 356          $v[11] = self::$iv[3];
 357  
 358          $v[12] = self::xor64($ctx[1][0], self::$iv[4]);
 359          $v[13] = self::xor64($ctx[1][1], self::$iv[5]);
 360          $v[14] = self::xor64($ctx[2][0], self::$iv[6]);
 361          $v[15] = self::xor64($ctx[2][1], self::$iv[7]);
 362  
 363          for ($r = 0; $r < 12; ++$r) {
 364              $v = self::G($r, 0, 0, 4, 8, 12, $v, $m);
 365              $v = self::G($r, 1, 1, 5, 9, 13, $v, $m);
 366              $v = self::G($r, 2, 2, 6, 10, 14, $v, $m);
 367              $v = self::G($r, 3, 3, 7, 11, 15, $v, $m);
 368              $v = self::G($r, 4, 0, 5, 10, 15, $v, $m);
 369              $v = self::G($r, 5, 1, 6, 11, 12, $v, $m);
 370              $v = self::G($r, 6, 2, 7, 8, 13, $v, $m);
 371              $v = self::G($r, 7, 3, 4, 9, 14, $v, $m);
 372          }
 373  
 374          for ($i = 8; $i--;) {
 375              $ctx[0][$i] = self::xor64(
 376                  $ctx[0][$i], self::xor64($v[$i], $v[$i+8])
 377              );
 378          }
 379      }
 380  
 381      /**
 382       * @internal You should not use this directly from another application
 383       *
 384       * @param int $r
 385       * @param int $i
 386       * @param int $a
 387       * @param int $b
 388       * @param int $c
 389       * @param int $d
 390       * @param SplFixedArray $v
 391       * @param SplFixedArray $m
 392       * @return SplFixedArray
 393       * @throws SodiumException
 394       * @throws TypeError
 395       * @psalm-suppress MixedArgument
 396       * @psalm-suppress MixedArrayOffset
 397       */
 398      public static function G($r, $i, $a, $b, $c, $d, SplFixedArray $v, SplFixedArray $m)
 399      {
 400          $v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][$i << 1]]);
 401          $v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 32);
 402          $v[$c] = self::add64($v[$c], $v[$d]);
 403          $v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 24);
 404          $v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][($i << 1) + 1]]);
 405          $v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 16);
 406          $v[$c] = self::add64($v[$c], $v[$d]);
 407          $v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 63);
 408          return $v;
 409      }
 410  
 411      /**
 412       * @internal You should not use this directly from another application
 413       *
 414       * @param SplFixedArray $ctx
 415       * @param int $inc
 416       * @return void
 417       * @throws SodiumException
 418       * @psalm-suppress MixedArgument
 419       * @psalm-suppress MixedArrayAccess
 420       * @psalm-suppress MixedArrayAssignment
 421       */
 422      public static function increment_counter($ctx, $inc)
 423      {
 424          if ($inc < 0) {
 425              throw new SodiumException('Increasing by a negative number makes no sense.');
 426          }
 427          $t = self::to64($inc);
 428          # S->t is $ctx[1] in our implementation
 429  
 430          # S->t[0] = ( uint64_t )( t >> 0 );
 431          $ctx[1][0] = self::add64($ctx[1][0], $t);
 432  
 433          # S->t[1] += ( S->t[0] < inc );
 434          if (self::flatten64($ctx[1][0]) < $inc) {
 435              $ctx[1][1] = self::add64($ctx[1][1], self::to64(1));
 436          }
 437      }
 438  
 439      /**
 440       * @internal You should not use this directly from another application
 441       *
 442       * @param SplFixedArray $ctx
 443       * @param SplFixedArray $p
 444       * @param int $plen
 445       * @return void
 446       * @throws SodiumException
 447       * @throws TypeError
 448       * @psalm-suppress MixedArgument
 449       * @psalm-suppress MixedAssignment
 450       * @psalm-suppress MixedArrayAccess
 451       * @psalm-suppress MixedArrayAssignment
 452       * @psalm-suppress MixedArrayOffset
 453       * @psalm-suppress MixedOperand
 454       */
 455      public static function update(SplFixedArray $ctx, SplFixedArray $p, $plen)
 456      {
 457          self::pseudoConstructor();
 458  
 459          $offset = 0;
 460          while ($plen > 0) {
 461              $left = $ctx[4];
 462              $fill = 256 - $left;
 463  
 464              if ($plen > $fill) {
 465                  # memcpy( S->buf + left, in, fill ); /* Fill buffer */
 466                  for ($i = $fill; $i--;) {
 467                      $ctx[3][$i + $left] = $p[$i + $offset];
 468                  }
 469  
 470                  # S->buflen += fill;
 471                  $ctx[4] += $fill;
 472  
 473                  # blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
 474                  self::increment_counter($ctx, 128);
 475  
 476                  # blake2b_compress( S, S->buf ); /* Compress */
 477                  self::compress($ctx, $ctx[3]);
 478  
 479                  # memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */
 480                  for ($i = 128; $i--;) {
 481                      $ctx[3][$i] = $ctx[3][$i + 128];
 482                  }
 483  
 484                  # S->buflen -= BLAKE2B_BLOCKBYTES;
 485                  $ctx[4] -= 128;
 486  
 487                  # in += fill;
 488                  $offset += $fill;
 489  
 490                  # inlen -= fill;
 491                  $plen -= $fill;
 492              } else {
 493                  for ($i = $plen; $i--;) {
 494                      $ctx[3][$i + $left] = $p[$i + $offset];
 495                  }
 496                  $ctx[4] += $plen;
 497                  $offset += $plen;
 498                  $plen -= $plen;
 499              }
 500          }
 501      }
 502  
 503      /**
 504       * @internal You should not use this directly from another application
 505       *
 506       * @param SplFixedArray $ctx
 507       * @param SplFixedArray $out
 508       * @return SplFixedArray
 509       * @throws SodiumException
 510       * @throws TypeError
 511       * @psalm-suppress MixedArgument
 512       * @psalm-suppress MixedAssignment
 513       * @psalm-suppress MixedArrayAccess
 514       * @psalm-suppress MixedArrayAssignment
 515       * @psalm-suppress MixedArrayOffset
 516       * @psalm-suppress MixedOperand
 517       */
 518      public static function finish(SplFixedArray $ctx, SplFixedArray $out)
 519      {
 520          self::pseudoConstructor();
 521          if ($ctx[4] > 128) {
 522              self::increment_counter($ctx, 128);
 523              self::compress($ctx, $ctx[3]);
 524              $ctx[4] -= 128;
 525              if ($ctx[4] > 128) {
 526                  throw new SodiumException('Failed to assert that buflen <= 128 bytes');
 527              }
 528              for ($i = $ctx[4]; $i--;) {
 529                  $ctx[3][$i] = $ctx[3][$i + 128];
 530              }
 531          }
 532  
 533          self::increment_counter($ctx, $ctx[4]);
 534          $ctx[2][0] = self::new64(0xffffffff, 0xffffffff);
 535  
 536          for ($i = 256 - $ctx[4]; $i--;) {
 537              $ctx[3][$i+$ctx[4]] = 0;
 538          }
 539  
 540          self::compress($ctx, $ctx[3]);
 541  
 542          $i = (int) (($out->getSize() - 1) / 8);
 543          for (; $i >= 0; --$i) {
 544              self::store64($out, $i << 3, $ctx[0][$i]);
 545          }
 546          return $out;
 547      }
 548  
 549      /**
 550       * @internal You should not use this directly from another application
 551       *
 552       * @param SplFixedArray|null $key
 553       * @param int $outlen
 554       * @param SplFixedArray|null $salt
 555       * @param SplFixedArray|null $personal
 556       * @return SplFixedArray
 557       * @throws SodiumException
 558       * @throws TypeError
 559       * @psalm-suppress MixedArgument
 560       * @psalm-suppress MixedAssignment
 561       * @psalm-suppress MixedArrayAccess
 562       * @psalm-suppress MixedArrayAssignment
 563       * @psalm-suppress MixedArrayOffset
 564       */
 565      public static function init(
 566          $key = null,
 567          $outlen = 64,
 568          $salt = null,
 569          $personal = null
 570      ) {
 571          self::pseudoConstructor();
 572          $klen = 0;
 573  
 574          if ($key !== null) {
 575              if (count($key) > 64) {
 576                  throw new SodiumException('Invalid key size');
 577              }
 578              $klen = count($key);
 579          }
 580  
 581          if ($outlen > 64) {
 582              throw new SodiumException('Invalid output size');
 583          }
 584  
 585          $ctx = self::context();
 586  
 587          $p = new SplFixedArray(64);
 588          // Zero our param buffer...
 589          for ($i = 64; --$i;) {
 590              $p[$i] = 0;
 591          }
 592  
 593          $p[0] = $outlen; // digest_length
 594          $p[1] = $klen;   // key_length
 595          $p[2] = 1;       // fanout
 596          $p[3] = 1;       // depth
 597  
 598          if ($salt instanceof SplFixedArray) {
 599              // salt: [32] through [47]
 600              for ($i = 0; $i < 16; ++$i) {
 601                  $p[32 + $i] = (int) $salt[$i];
 602              }
 603          }
 604          if ($personal instanceof SplFixedArray) {
 605              // personal: [48] through [63]
 606              for ($i = 0; $i < 16; ++$i) {
 607                  $p[48 + $i] = (int) $personal[$i];
 608              }
 609          }
 610  
 611          $ctx[0][0] = self::xor64(
 612              $ctx[0][0],
 613              self::load64($p, 0)
 614          );
 615          if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) {
 616              // We need to do what blake2b_init_param() does:
 617              for ($i = 1; $i < 8; ++$i) {
 618                  $ctx[0][$i] = self::xor64(
 619                      $ctx[0][$i],
 620                      self::load64($p, $i << 3)
 621                  );
 622              }
 623          }
 624  
 625          if ($klen > 0 && $key instanceof SplFixedArray) {
 626              $block = new SplFixedArray(128);
 627              for ($i = 128; $i--;) {
 628                  $block[$i] = 0;
 629              }
 630              for ($i = $klen; $i--;) {
 631                  $block[$i] = $key[$i];
 632              }
 633              self::update($ctx, $block, 128);
 634              $ctx[4] = 128;
 635          }
 636  
 637          return $ctx;
 638      }
 639  
 640      /**
 641       * Convert a string into an SplFixedArray of integers
 642       *
 643       * @internal You should not use this directly from another application
 644       *
 645       * @param string $str
 646       * @return SplFixedArray
 647       */
 648      public static function stringToSplFixedArray($str = '')
 649      {
 650          $values = unpack('C*', $str);
 651          return SplFixedArray::fromArray(array_values($values));
 652      }
 653  
 654      /**
 655       * Convert an SplFixedArray of integers into a string
 656       *
 657       * @internal You should not use this directly from another application
 658       *
 659       * @param SplFixedArray $a
 660       * @return string
 661       * @throws TypeError
 662       */
 663      public static function SplFixedArrayToString(SplFixedArray $a)
 664      {
 665          /**
 666           * @var array<int, int|string> $arr
 667           */
 668          $arr = $a->toArray();
 669          $c = $a->count();
 670          array_unshift($arr, str_repeat('C', $c));
 671          return (string) (call_user_func_array('pack', $arr));
 672      }
 673  
 674      /**
 675       * @internal You should not use this directly from another application
 676       *
 677       * @param SplFixedArray $ctx
 678       * @return string
 679       * @throws TypeError
 680       * @psalm-suppress MixedArgument
 681       * @psalm-suppress MixedAssignment
 682       * @psalm-suppress MixedArrayAccess
 683       * @psalm-suppress MixedArrayAssignment
 684       * @psalm-suppress MixedArrayOffset
 685       * @psalm-suppress MixedMethodCall
 686       */
 687      public static function contextToString(SplFixedArray $ctx)
 688      {
 689          $str = '';
 690          /** @var array<int, array<int, int>> $ctxA */
 691          $ctxA = $ctx[0]->toArray();
 692  
 693          # uint64_t h[8];
 694          for ($i = 0; $i < 8; ++$i) {
 695              $str .= self::store32_le($ctxA[$i][1]);
 696              $str .= self::store32_le($ctxA[$i][0]);
 697          }
 698  
 699          # uint64_t t[2];
 700          # uint64_t f[2];
 701          for ($i = 1; $i < 3; ++$i) {
 702              $ctxA = $ctx[$i]->toArray();
 703              $str .= self::store32_le($ctxA[0][1]);
 704              $str .= self::store32_le($ctxA[0][0]);
 705              $str .= self::store32_le($ctxA[1][1]);
 706              $str .= self::store32_le($ctxA[1][0]);
 707          }
 708  
 709          # uint8_t buf[2 * 128];
 710          $str .= self::SplFixedArrayToString($ctx[3]);
 711  
 712          /** @var int $ctx4 */
 713          $ctx4 = (int) $ctx[4];
 714  
 715          # size_t buflen;
 716          $str .= implode('', array(
 717              self::intToChr($ctx4 & 0xff),
 718              self::intToChr(($ctx4 >> 8) & 0xff),
 719              self::intToChr(($ctx4 >> 16) & 0xff),
 720              self::intToChr(($ctx4 >> 24) & 0xff),
 721              self::intToChr(($ctx4 >> 32) & 0xff),
 722              self::intToChr(($ctx4 >> 40) & 0xff),
 723              self::intToChr(($ctx4 >> 48) & 0xff),
 724              self::intToChr(($ctx4 >> 56) & 0xff)
 725          ));
 726          # uint8_t last_node;
 727          return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23);
 728      }
 729  
 730      /**
 731       * Creates an SplFixedArray containing other SplFixedArray elements, from
 732       * a string (compatible with \Sodium\crypto_generichash_{init, update, final})
 733       *
 734       * @internal You should not use this directly from another application
 735       *
 736       * @param string $string
 737       * @return SplFixedArray
 738       * @throws SodiumException
 739       * @throws TypeError
 740       * @psalm-suppress MixedArrayAssignment
 741       */
 742      public static function stringToContext($string)
 743      {
 744          $ctx = self::context();
 745  
 746          # uint64_t h[8];
 747          for ($i = 0; $i < 8; ++$i) {
 748              $ctx[0][$i] = SplFixedArray::fromArray(
 749                  array(
 750                      self::load_4(
 751                          self::substr($string, (($i << 3) + 4), 4)
 752                      ),
 753                      self::load_4(
 754                          self::substr($string, (($i << 3) + 0), 4)
 755                      )
 756                  )
 757              );
 758          }
 759  
 760          # uint64_t t[2];
 761          # uint64_t f[2];
 762          for ($i = 1; $i < 3; ++$i) {
 763              $ctx[$i][1] = SplFixedArray::fromArray(
 764                  array(
 765                      self::load_4(self::substr($string, 76 + (($i - 1) << 4), 4)),
 766                      self::load_4(self::substr($string, 72 + (($i - 1) << 4), 4))
 767                  )
 768              );
 769              $ctx[$i][0] = SplFixedArray::fromArray(
 770                  array(
 771                      self::load_4(self::substr($string, 68 + (($i - 1) << 4), 4)),
 772                      self::load_4(self::substr($string, 64 + (($i - 1) << 4), 4))
 773                  )
 774              );
 775          }
 776  
 777          # uint8_t buf[2 * 128];
 778          $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256));
 779  
 780          # uint8_t buf[2 * 128];
 781          $int = 0;
 782          for ($i = 0; $i < 8; ++$i) {
 783              $int |= self::chrToInt($string[352 + $i]) << ($i << 3);
 784          }
 785          $ctx[4] = $int;
 786  
 787          return $ctx;
 788      }
 789  }


Generated: Sun Jan 19 01:00:03 2020 Cross-referenced by PHPXref 0.7.1