[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

   1  <?php
   2  
   3  if (class_exists('ParagonIE_Sodium_Core_ChaCha20', false)) {
   4      return;
   5  }
   6  
   7  /**
   8   * Class ParagonIE_Sodium_Core_ChaCha20
   9   */
  10  class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util
  11  {
  12      /**
  13       * Bitwise left rotation
  14       *
  15       * @internal You should not use this directly from another application
  16       *
  17       * @param int $v
  18       * @param int $n
  19       * @return int
  20       */
  21      public static function rotate($v, $n)
  22      {
  23          $v &= 0xffffffff;
  24          $n &= 31;
  25          return (int) (
  26              0xffffffff & (
  27                  ($v << $n)
  28                      |
  29                  ($v >> (32 - $n))
  30              )
  31          );
  32      }
  33  
  34      /**
  35       * The ChaCha20 quarter round function. Works on four 32-bit integers.
  36       *
  37       * @internal You should not use this directly from another application
  38       *
  39       * @param int $a
  40       * @param int $b
  41       * @param int $c
  42       * @param int $d
  43       * @return array<int, int>
  44       */
  45      protected static function quarterRound($a, $b, $c, $d)
  46      {
  47          # a = PLUS(a,b); d = ROTATE(XOR(d,a),16);
  48          /** @var int $a */
  49          $a = ($a + $b) & 0xffffffff;
  50          $d = self::rotate($d ^ $a, 16);
  51  
  52          # c = PLUS(c,d); b = ROTATE(XOR(b,c),12);
  53          /** @var int $c */
  54          $c = ($c + $d) & 0xffffffff;
  55          $b = self::rotate($b ^ $c, 12);
  56  
  57          # a = PLUS(a,b); d = ROTATE(XOR(d,a), 8);
  58          /** @var int $a */
  59          $a = ($a + $b) & 0xffffffff;
  60          $d = self::rotate($d ^ $a, 8);
  61  
  62          # c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
  63          /** @var int $c */
  64          $c = ($c + $d) & 0xffffffff;
  65          $b = self::rotate($b ^ $c, 7);
  66          return array((int) $a, (int) $b, (int) $c, (int) $d);
  67      }
  68  
  69      /**
  70       * @internal You should not use this directly from another application
  71       *
  72       * @param ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx
  73       * @param string $message
  74       *
  75       * @return string
  76       * @throws TypeError
  77       * @throws SodiumException
  78       */
  79      public static function encryptBytes(
  80          ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx,
  81          $message = ''
  82      ) {
  83          $bytes = self::strlen($message);
  84  
  85          /*
  86          j0 = ctx->input[0];
  87          j1 = ctx->input[1];
  88          j2 = ctx->input[2];
  89          j3 = ctx->input[3];
  90          j4 = ctx->input[4];
  91          j5 = ctx->input[5];
  92          j6 = ctx->input[6];
  93          j7 = ctx->input[7];
  94          j8 = ctx->input[8];
  95          j9 = ctx->input[9];
  96          j10 = ctx->input[10];
  97          j11 = ctx->input[11];
  98          j12 = ctx->input[12];
  99          j13 = ctx->input[13];
 100          j14 = ctx->input[14];
 101          j15 = ctx->input[15];
 102          */
 103          $j0  = (int) $ctx[0];
 104          $j1  = (int) $ctx[1];
 105          $j2  = (int) $ctx[2];
 106          $j3  = (int) $ctx[3];
 107          $j4  = (int) $ctx[4];
 108          $j5  = (int) $ctx[5];
 109          $j6  = (int) $ctx[6];
 110          $j7  = (int) $ctx[7];
 111          $j8  = (int) $ctx[8];
 112          $j9  = (int) $ctx[9];
 113          $j10 = (int) $ctx[10];
 114          $j11 = (int) $ctx[11];
 115          $j12 = (int) $ctx[12];
 116          $j13 = (int) $ctx[13];
 117          $j14 = (int) $ctx[14];
 118          $j15 = (int) $ctx[15];
 119  
 120          $c = '';
 121          for (;;) {
 122              if ($bytes < 64) {
 123                  $message .= str_repeat("\x00", 64 - $bytes);
 124              }
 125  
 126              $x0 =  (int) $j0;
 127              $x1 =  (int) $j1;
 128              $x2 =  (int) $j2;
 129              $x3 =  (int) $j3;
 130              $x4 =  (int) $j4;
 131              $x5 =  (int) $j5;
 132              $x6 =  (int) $j6;
 133              $x7 =  (int) $j7;
 134              $x8 =  (int) $j8;
 135              $x9 =  (int) $j9;
 136              $x10 = (int) $j10;
 137              $x11 = (int) $j11;
 138              $x12 = (int) $j12;
 139              $x13 = (int) $j13;
 140              $x14 = (int) $j14;
 141              $x15 = (int) $j15;
 142  
 143              # for (i = 20; i > 0; i -= 2) {
 144              for ($i = 20; $i > 0; $i -= 2) {
 145                  # QUARTERROUND( x0,  x4,  x8,  x12)
 146                  list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
 147  
 148                  # QUARTERROUND( x1,  x5,  x9,  x13)
 149                  list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
 150  
 151                  # QUARTERROUND( x2,  x6,  x10,  x14)
 152                  list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
 153  
 154                  # QUARTERROUND( x3,  x7,  x11,  x15)
 155                  list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
 156  
 157                  # QUARTERROUND( x0,  x5,  x10,  x15)
 158                  list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
 159  
 160                  # QUARTERROUND( x1,  x6,  x11,  x12)
 161                  list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
 162  
 163                  # QUARTERROUND( x2,  x7,  x8,  x13)
 164                  list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
 165  
 166                  # QUARTERROUND( x3,  x4,  x9,  x14)
 167                  list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
 168              }
 169              /*
 170              x0 = PLUS(x0, j0);
 171              x1 = PLUS(x1, j1);
 172              x2 = PLUS(x2, j2);
 173              x3 = PLUS(x3, j3);
 174              x4 = PLUS(x4, j4);
 175              x5 = PLUS(x5, j5);
 176              x6 = PLUS(x6, j6);
 177              x7 = PLUS(x7, j7);
 178              x8 = PLUS(x8, j8);
 179              x9 = PLUS(x9, j9);
 180              x10 = PLUS(x10, j10);
 181              x11 = PLUS(x11, j11);
 182              x12 = PLUS(x12, j12);
 183              x13 = PLUS(x13, j13);
 184              x14 = PLUS(x14, j14);
 185              x15 = PLUS(x15, j15);
 186              */
 187              /** @var int $x0 */
 188              $x0  = ($x0 & 0xffffffff) + $j0;
 189              /** @var int $x1 */
 190              $x1  = ($x1 & 0xffffffff) + $j1;
 191              /** @var int $x2 */
 192              $x2  = ($x2 & 0xffffffff) + $j2;
 193              /** @var int $x3 */
 194              $x3  = ($x3 & 0xffffffff) + $j3;
 195              /** @var int $x4 */
 196              $x4  = ($x4 & 0xffffffff) + $j4;
 197              /** @var int $x5 */
 198              $x5  = ($x5 & 0xffffffff) + $j5;
 199              /** @var int $x6 */
 200              $x6  = ($x6 & 0xffffffff) + $j6;
 201              /** @var int $x7 */
 202              $x7  = ($x7 & 0xffffffff) + $j7;
 203              /** @var int $x8 */
 204              $x8  = ($x8 & 0xffffffff) + $j8;
 205              /** @var int $x9 */
 206              $x9  = ($x9 & 0xffffffff) + $j9;
 207              /** @var int $x10 */
 208              $x10 = ($x10 & 0xffffffff) + $j10;
 209              /** @var int $x11 */
 210              $x11 = ($x11 & 0xffffffff) + $j11;
 211              /** @var int $x12 */
 212              $x12 = ($x12 & 0xffffffff) + $j12;
 213              /** @var int $x13 */
 214              $x13 = ($x13 & 0xffffffff) + $j13;
 215              /** @var int $x14 */
 216              $x14 = ($x14 & 0xffffffff) + $j14;
 217              /** @var int $x15 */
 218              $x15 = ($x15 & 0xffffffff) + $j15;
 219  
 220              /*
 221              x0 = XOR(x0, LOAD32_LE(m + 0));
 222              x1 = XOR(x1, LOAD32_LE(m + 4));
 223              x2 = XOR(x2, LOAD32_LE(m + 8));
 224              x3 = XOR(x3, LOAD32_LE(m + 12));
 225              x4 = XOR(x4, LOAD32_LE(m + 16));
 226              x5 = XOR(x5, LOAD32_LE(m + 20));
 227              x6 = XOR(x6, LOAD32_LE(m + 24));
 228              x7 = XOR(x7, LOAD32_LE(m + 28));
 229              x8 = XOR(x8, LOAD32_LE(m + 32));
 230              x9 = XOR(x9, LOAD32_LE(m + 36));
 231              x10 = XOR(x10, LOAD32_LE(m + 40));
 232              x11 = XOR(x11, LOAD32_LE(m + 44));
 233              x12 = XOR(x12, LOAD32_LE(m + 48));
 234              x13 = XOR(x13, LOAD32_LE(m + 52));
 235              x14 = XOR(x14, LOAD32_LE(m + 56));
 236              x15 = XOR(x15, LOAD32_LE(m + 60));
 237              */
 238              $x0  ^= self::load_4(self::substr($message, 0, 4));
 239              $x1  ^= self::load_4(self::substr($message, 4, 4));
 240              $x2  ^= self::load_4(self::substr($message, 8, 4));
 241              $x3  ^= self::load_4(self::substr($message, 12, 4));
 242              $x4  ^= self::load_4(self::substr($message, 16, 4));
 243              $x5  ^= self::load_4(self::substr($message, 20, 4));
 244              $x6  ^= self::load_4(self::substr($message, 24, 4));
 245              $x7  ^= self::load_4(self::substr($message, 28, 4));
 246              $x8  ^= self::load_4(self::substr($message, 32, 4));
 247              $x9  ^= self::load_4(self::substr($message, 36, 4));
 248              $x10 ^= self::load_4(self::substr($message, 40, 4));
 249              $x11 ^= self::load_4(self::substr($message, 44, 4));
 250              $x12 ^= self::load_4(self::substr($message, 48, 4));
 251              $x13 ^= self::load_4(self::substr($message, 52, 4));
 252              $x14 ^= self::load_4(self::substr($message, 56, 4));
 253              $x15 ^= self::load_4(self::substr($message, 60, 4));
 254  
 255              /*
 256                  j12 = PLUSONE(j12);
 257                  if (!j12) {
 258                      j13 = PLUSONE(j13);
 259                  }
 260               */
 261              ++$j12;
 262              if ($j12 & 0xf0000000) {
 263                  throw new SodiumException('Overflow');
 264              }
 265  
 266              /*
 267              STORE32_LE(c + 0, x0);
 268              STORE32_LE(c + 4, x1);
 269              STORE32_LE(c + 8, x2);
 270              STORE32_LE(c + 12, x3);
 271              STORE32_LE(c + 16, x4);
 272              STORE32_LE(c + 20, x5);
 273              STORE32_LE(c + 24, x6);
 274              STORE32_LE(c + 28, x7);
 275              STORE32_LE(c + 32, x8);
 276              STORE32_LE(c + 36, x9);
 277              STORE32_LE(c + 40, x10);
 278              STORE32_LE(c + 44, x11);
 279              STORE32_LE(c + 48, x12);
 280              STORE32_LE(c + 52, x13);
 281              STORE32_LE(c + 56, x14);
 282              STORE32_LE(c + 60, x15);
 283              */
 284              $block = self::store32_le((int) ($x0  & 0xffffffff)) .
 285                   self::store32_le((int) ($x1  & 0xffffffff)) .
 286                   self::store32_le((int) ($x2  & 0xffffffff)) .
 287                   self::store32_le((int) ($x3  & 0xffffffff)) .
 288                   self::store32_le((int) ($x4  & 0xffffffff)) .
 289                   self::store32_le((int) ($x5  & 0xffffffff)) .
 290                   self::store32_le((int) ($x6  & 0xffffffff)) .
 291                   self::store32_le((int) ($x7  & 0xffffffff)) .
 292                   self::store32_le((int) ($x8  & 0xffffffff)) .
 293                   self::store32_le((int) ($x9  & 0xffffffff)) .
 294                   self::store32_le((int) ($x10 & 0xffffffff)) .
 295                   self::store32_le((int) ($x11 & 0xffffffff)) .
 296                   self::store32_le((int) ($x12 & 0xffffffff)) .
 297                   self::store32_le((int) ($x13 & 0xffffffff)) .
 298                   self::store32_le((int) ($x14 & 0xffffffff)) .
 299                   self::store32_le((int) ($x15 & 0xffffffff));
 300  
 301              /* Partial block */
 302              if ($bytes < 64) {
 303                  $c .= self::substr($block, 0, $bytes);
 304                  break;
 305              }
 306  
 307              /* Full block */
 308              $c .= $block;
 309              $bytes -= 64;
 310              if ($bytes <= 0) {
 311                  break;
 312              }
 313              $message = self::substr($message, 64);
 314          }
 315          /* end for(;;) loop */
 316  
 317          $ctx[12] = $j12;
 318          $ctx[13] = $j13;
 319          return $c;
 320      }
 321  
 322      /**
 323       * @internal You should not use this directly from another application
 324       *
 325       * @param int $len
 326       * @param string $nonce
 327       * @param string $key
 328       * @return string
 329       * @throws SodiumException
 330       * @throws TypeError
 331       */
 332      public static function stream($len = 64, $nonce = '', $key = '')
 333      {
 334          return self::encryptBytes(
 335              new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce),
 336              str_repeat("\x00", $len)
 337          );
 338      }
 339  
 340      /**
 341       * @internal You should not use this directly from another application
 342       *
 343       * @param int $len
 344       * @param string $nonce
 345       * @param string $key
 346       * @return string
 347       * @throws SodiumException
 348       * @throws TypeError
 349       */
 350      public static function ietfStream($len, $nonce = '', $key = '')
 351      {
 352          return self::encryptBytes(
 353              new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce),
 354              str_repeat("\x00", $len)
 355          );
 356      }
 357  
 358      /**
 359       * @internal You should not use this directly from another application
 360       *
 361       * @param string $message
 362       * @param string $nonce
 363       * @param string $key
 364       * @param string $ic
 365       * @return string
 366       * @throws SodiumException
 367       * @throws TypeError
 368       */
 369      public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
 370      {
 371          return self::encryptBytes(
 372              new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce, $ic),
 373              $message
 374          );
 375      }
 376  
 377      /**
 378       * @internal You should not use this directly from another application
 379       *
 380       * @param string $message
 381       * @param string $nonce
 382       * @param string $key
 383       * @param string $ic
 384       * @return string
 385       * @throws SodiumException
 386       * @throws TypeError
 387       */
 388      public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
 389      {
 390          return self::encryptBytes(
 391              new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce, $ic),
 392              $message
 393          );
 394      }
 395  }


Generated: Tue Mar 19 01:00:02 2024 Cross-referenced by PHPXref 0.7.1