[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

   1  <?php
   2  
   3  if (class_exists('ParagonIE_Sodium_Core_Poly1305_State', false)) {
   4      return;
   5  }
   6  
   7  /**
   8   * Class ParagonIE_Sodium_Core_Poly1305_State
   9   */
  10  class ParagonIE_Sodium_Core_Poly1305_State extends ParagonIE_Sodium_Core_Util
  11  {
  12      /**
  13       * @var array<int, int>
  14       */
  15      protected $buffer = array();
  16  
  17      /**
  18       * @var bool
  19       */
  20      protected $final = false;
  21  
  22      /**
  23       * @var array<int, int>
  24       */
  25      public $h;
  26  
  27      /**
  28       * @var int
  29       */
  30      protected $leftover = 0;
  31  
  32      /**
  33       * @var int[]
  34       */
  35      public $r;
  36  
  37      /**
  38       * @var int[]
  39       */
  40      public $pad;
  41  
  42      /**
  43       * ParagonIE_Sodium_Core_Poly1305_State constructor.
  44       *
  45       * @internal You should not use this directly from another application
  46       *
  47       * @param string $key
  48       * @throws InvalidArgumentException
  49       * @throws TypeError
  50       */
  51      public function __construct($key = '')
  52      {
  53          if (self::strlen($key) < 32) {
  54              throw new InvalidArgumentException(
  55                  'Poly1305 requires a 32-byte key'
  56              );
  57          }
  58          /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
  59          $this->r = array(
  60              (int) ((self::load_4(self::substr($key, 0, 4))) & 0x3ffffff),
  61              (int) ((self::load_4(self::substr($key, 3, 4)) >> 2) & 0x3ffff03),
  62              (int) ((self::load_4(self::substr($key, 6, 4)) >> 4) & 0x3ffc0ff),
  63              (int) ((self::load_4(self::substr($key, 9, 4)) >> 6) & 0x3f03fff),
  64              (int) ((self::load_4(self::substr($key, 12, 4)) >> 8) & 0x00fffff)
  65          );
  66  
  67          /* h = 0 */
  68          $this->h = array(0, 0, 0, 0, 0);
  69  
  70          /* save pad for later */
  71          $this->pad = array(
  72              self::load_4(self::substr($key, 16, 4)),
  73              self::load_4(self::substr($key, 20, 4)),
  74              self::load_4(self::substr($key, 24, 4)),
  75              self::load_4(self::substr($key, 28, 4)),
  76          );
  77  
  78          $this->leftover = 0;
  79          $this->final = false;
  80      }
  81  
  82      /**
  83       * Zero internal buffer upon destruction
  84       */
  85      public function __destruct()
  86      {
  87          $this->r[0] ^= $this->r[0];
  88          $this->r[1] ^= $this->r[1];
  89          $this->r[2] ^= $this->r[2];
  90          $this->r[3] ^= $this->r[3];
  91          $this->r[4] ^= $this->r[4];
  92          $this->h[0] ^= $this->h[0];
  93          $this->h[1] ^= $this->h[1];
  94          $this->h[2] ^= $this->h[2];
  95          $this->h[3] ^= $this->h[3];
  96          $this->h[4] ^= $this->h[4];
  97          $this->pad[0] ^= $this->pad[0];
  98          $this->pad[1] ^= $this->pad[1];
  99          $this->pad[2] ^= $this->pad[2];
 100          $this->pad[3] ^= $this->pad[3];
 101          $this->leftover = 0;
 102          $this->final = true;
 103      }
 104  
 105      /**
 106       * @internal You should not use this directly from another application
 107       *
 108       * @param string $message
 109       * @return self
 110       * @throws SodiumException
 111       * @throws TypeError
 112       */
 113      public function update($message = '')
 114      {
 115          $bytes = self::strlen($message);
 116          if ($bytes < 1) {
 117              return $this;
 118          }
 119  
 120          /* handle leftover */
 121          if ($this->leftover) {
 122              $want = ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - $this->leftover;
 123              if ($want > $bytes) {
 124                  $want = $bytes;
 125              }
 126              for ($i = 0; $i < $want; ++$i) {
 127                  $mi = self::chrToInt($message[$i]);
 128                  $this->buffer[$this->leftover + $i] = $mi;
 129              }
 130              // We snip off the leftmost bytes.
 131              $message = self::substr($message, $want);
 132              $bytes = self::strlen($message);
 133              $this->leftover += $want;
 134              if ($this->leftover < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
 135                  // We still don't have enough to run $this->blocks()
 136                  return $this;
 137              }
 138  
 139              $this->blocks(
 140                  self::intArrayToString($this->buffer),
 141                  ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
 142              );
 143              $this->leftover = 0;
 144          }
 145  
 146          /* process full blocks */
 147          if ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
 148              /** @var int $want */
 149              $want = $bytes & ~(ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - 1);
 150              if ($want >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
 151                  $block = self::substr($message, 0, $want);
 152                  if (self::strlen($block) >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
 153                      $this->blocks($block, $want);
 154                      $message = self::substr($message, $want);
 155                      $bytes = self::strlen($message);
 156                  }
 157              }
 158          }
 159  
 160          /* store leftover */
 161          if ($bytes) {
 162              for ($i = 0; $i < $bytes; ++$i) {
 163                  $mi = self::chrToInt($message[$i]);
 164                  $this->buffer[$this->leftover + $i] = $mi;
 165              }
 166              $this->leftover = (int) $this->leftover + $bytes;
 167          }
 168          return $this;
 169      }
 170  
 171      /**
 172       * @internal You should not use this directly from another application
 173       *
 174       * @param string $message
 175       * @param int $bytes
 176       * @return self
 177       * @throws TypeError
 178       */
 179      public function blocks($message, $bytes)
 180      {
 181          if (self::strlen($message) < 16) {
 182              $message = str_pad($message, 16, "\x00", STR_PAD_RIGHT);
 183          }
 184          /** @var int $hibit */
 185          $hibit = $this->final ? 0 : 1 << 24; /* 1 << 128 */
 186          $r0 = (int) $this->r[0];
 187          $r1 = (int) $this->r[1];
 188          $r2 = (int) $this->r[2];
 189          $r3 = (int) $this->r[3];
 190          $r4 = (int) $this->r[4];
 191  
 192          $s1 = self::mul($r1, 5, 3);
 193          $s2 = self::mul($r2, 5, 3);
 194          $s3 = self::mul($r3, 5, 3);
 195          $s4 = self::mul($r4, 5, 3);
 196  
 197          $h0 = $this->h[0];
 198          $h1 = $this->h[1];
 199          $h2 = $this->h[2];
 200          $h3 = $this->h[3];
 201          $h4 = $this->h[4];
 202  
 203          while ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
 204              /* h += m[i] */
 205              $h0 +=  self::load_4(self::substr($message, 0, 4))       & 0x3ffffff;
 206              $h1 += (self::load_4(self::substr($message, 3, 4)) >> 2) & 0x3ffffff;
 207              $h2 += (self::load_4(self::substr($message, 6, 4)) >> 4) & 0x3ffffff;
 208              $h3 += (self::load_4(self::substr($message, 9, 4)) >> 6) & 0x3ffffff;
 209              $h4 += (self::load_4(self::substr($message, 12, 4)) >> 8) | $hibit;
 210  
 211              /* h *= r */
 212              $d0 = (
 213                  self::mul($h0, $r0, 27) +
 214                  self::mul($s4, $h1, 27) +
 215                  self::mul($s3, $h2, 27) +
 216                  self::mul($s2, $h3, 27) +
 217                  self::mul($s1, $h4, 27)
 218              );
 219  
 220              $d1 = (
 221                  self::mul($h0, $r1, 27) +
 222                  self::mul($h1, $r0, 27) +
 223                  self::mul($s4, $h2, 27) +
 224                  self::mul($s3, $h3, 27) +
 225                  self::mul($s2, $h4, 27)
 226              );
 227  
 228              $d2 = (
 229                  self::mul($h0, $r2, 27) +
 230                  self::mul($h1, $r1, 27) +
 231                  self::mul($h2, $r0, 27) +
 232                  self::mul($s4, $h3, 27) +
 233                  self::mul($s3, $h4, 27)
 234              );
 235  
 236              $d3 = (
 237                  self::mul($h0, $r3, 27) +
 238                  self::mul($h1, $r2, 27) +
 239                  self::mul($h2, $r1, 27) +
 240                  self::mul($h3, $r0, 27) +
 241                  self::mul($s4, $h4, 27)
 242              );
 243  
 244              $d4 = (
 245                  self::mul($h0, $r4, 27) +
 246                  self::mul($h1, $r3, 27) +
 247                  self::mul($h2, $r2, 27) +
 248                  self::mul($h3, $r1, 27) +
 249                  self::mul($h4, $r0, 27)
 250              );
 251  
 252              /* (partial) h %= p */
 253              /** @var int $c */
 254              $c = $d0 >> 26;
 255              /** @var int $h0 */
 256              $h0 = $d0 & 0x3ffffff;
 257              $d1 += $c;
 258  
 259              /** @var int $c */
 260              $c = $d1 >> 26;
 261              /** @var int $h1 */
 262              $h1 = $d1 & 0x3ffffff;
 263              $d2 += $c;
 264  
 265              /** @var int $c */
 266              $c = $d2 >> 26;
 267              /** @var int $h2  */
 268              $h2 = $d2 & 0x3ffffff;
 269              $d3 += $c;
 270  
 271              /** @var int $c */
 272              $c = $d3 >> 26;
 273              /** @var int $h3 */
 274              $h3 = $d3 & 0x3ffffff;
 275              $d4 += $c;
 276  
 277              /** @var int $c */
 278              $c = $d4 >> 26;
 279              /** @var int $h4 */
 280              $h4 = $d4 & 0x3ffffff;
 281              $h0 += (int) self::mul($c, 5, 3);
 282  
 283              /** @var int $c */
 284              $c = $h0 >> 26;
 285              /** @var int $h0 */
 286              $h0 &= 0x3ffffff;
 287              $h1 += $c;
 288  
 289              // Chop off the left 32 bytes.
 290              $message = self::substr(
 291                  $message,
 292                  ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
 293              );
 294              $bytes -= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE;
 295          }
 296  
 297          $this->h = array(
 298              (int) ($h0 & 0xffffffff),
 299              (int) ($h1 & 0xffffffff),
 300              (int) ($h2 & 0xffffffff),
 301              (int) ($h3 & 0xffffffff),
 302              (int) ($h4 & 0xffffffff)
 303          );
 304          return $this;
 305      }
 306  
 307      /**
 308       * @internal You should not use this directly from another application
 309       *
 310       * @return string
 311       * @throws TypeError
 312       */
 313      public function finish()
 314      {
 315          /* process the remaining block */
 316          if ($this->leftover) {
 317              $i = $this->leftover;
 318              $this->buffer[$i++] = 1;
 319              for (; $i < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; ++$i) {
 320                  $this->buffer[$i] = 0;
 321              }
 322              $this->final = true;
 323              $this->blocks(
 324                  self::substr(
 325                      self::intArrayToString($this->buffer),
 326                      0,
 327                      ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
 328                  ),
 329                  ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
 330              );
 331          }
 332  
 333          $h0 = (int) $this->h[0];
 334          $h1 = (int) $this->h[1];
 335          $h2 = (int) $this->h[2];
 336          $h3 = (int) $this->h[3];
 337          $h4 = (int) $this->h[4];
 338  
 339          /** @var int $c */
 340          $c = $h1 >> 26;
 341          /** @var int $h1 */
 342          $h1 &= 0x3ffffff;
 343          /** @var int $h2 */
 344          $h2 += $c;
 345          /** @var int $c */
 346          $c = $h2 >> 26;
 347          /** @var int $h2 */
 348          $h2 &= 0x3ffffff;
 349          $h3 += $c;
 350          /** @var int $c */
 351          $c = $h3 >> 26;
 352          $h3 &= 0x3ffffff;
 353          $h4 += $c;
 354          /** @var int $c */
 355          $c = $h4 >> 26;
 356          $h4 &= 0x3ffffff;
 357          /** @var int $h0 */
 358          $h0 += self::mul($c, 5, 3);
 359          /** @var int $c */
 360          $c = $h0 >> 26;
 361          /** @var int $h0 */
 362          $h0 &= 0x3ffffff;
 363          /** @var int $h1 */
 364          $h1 += $c;
 365  
 366          /* compute h + -p */
 367          /** @var int $g0 */
 368          $g0 = $h0 + 5;
 369          /** @var int $c */
 370          $c = $g0 >> 26;
 371          /** @var int $g0 */
 372          $g0 &= 0x3ffffff;
 373  
 374          /** @var int $g1 */
 375          $g1 = $h1 + $c;
 376          /** @var int $c */
 377          $c = $g1 >> 26;
 378          $g1 &= 0x3ffffff;
 379  
 380          /** @var int $g2 */
 381          $g2 = $h2 + $c;
 382          /** @var int $c */
 383          $c = $g2 >> 26;
 384          /** @var int $g2 */
 385          $g2 &= 0x3ffffff;
 386  
 387          /** @var int $g3 */
 388          $g3 = $h3 + $c;
 389          /** @var int $c */
 390          $c = $g3 >> 26;
 391          /** @var int $g3 */
 392          $g3 &= 0x3ffffff;
 393  
 394          /** @var int $g4 */
 395          $g4 = ($h4 + $c - (1 << 26)) & 0xffffffff;
 396  
 397          /* select h if h < p, or h + -p if h >= p */
 398          /** @var int $mask */
 399          $mask = ($g4 >> 31) - 1;
 400  
 401          $g0 &= $mask;
 402          $g1 &= $mask;
 403          $g2 &= $mask;
 404          $g3 &= $mask;
 405          $g4 &= $mask;
 406  
 407          /** @var int $mask */
 408          $mask = ~$mask & 0xffffffff;
 409          /** @var int $h0 */
 410          $h0 = ($h0 & $mask) | $g0;
 411          /** @var int $h1 */
 412          $h1 = ($h1 & $mask) | $g1;
 413          /** @var int $h2 */
 414          $h2 = ($h2 & $mask) | $g2;
 415          /** @var int $h3 */
 416          $h3 = ($h3 & $mask) | $g3;
 417          /** @var int $h4 */
 418          $h4 = ($h4 & $mask) | $g4;
 419  
 420          /* h = h % (2^128) */
 421          /** @var int $h0 */
 422          $h0 = (($h0) | ($h1 << 26)) & 0xffffffff;
 423          /** @var int $h1 */
 424          $h1 = (($h1 >>  6) | ($h2 << 20)) & 0xffffffff;
 425          /** @var int $h2 */
 426          $h2 = (($h2 >> 12) | ($h3 << 14)) & 0xffffffff;
 427          /** @var int $h3 */
 428          $h3 = (($h3 >> 18) | ($h4 <<  8)) & 0xffffffff;
 429  
 430          /* mac = (h + pad) % (2^128) */
 431          $f = (int) ($h0 + $this->pad[0]);
 432          $h0 = (int) $f;
 433          $f = (int) ($h1 + $this->pad[1] + ($f >> 32));
 434          $h1 = (int) $f;
 435          $f = (int) ($h2 + $this->pad[2] + ($f >> 32));
 436          $h2 = (int) $f;
 437          $f = (int) ($h3 + $this->pad[3] + ($f >> 32));
 438          $h3 = (int) $f;
 439  
 440          return self::store32_le($h0 & 0xffffffff) .
 441              self::store32_le($h1 & 0xffffffff) .
 442              self::store32_le($h2 & 0xffffffff) .
 443              self::store32_le($h3 & 0xffffffff);
 444      }
 445  }


Generated : Wed Nov 13 08:20:01 2024 Cross-referenced by PHPXref