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


Generated: Thu Nov 21 01:00:03 2024 Cross-referenced by PHPXref 0.7.1