[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

   1  <?php
   2  
   3  if (class_exists('ParagonIE_Sodium_Core_Salsa20', false)) {
   4      return;
   5  }
   6  
   7  /**
   8   * Class ParagonIE_Sodium_Core_Salsa20
   9   */
  10  abstract class ParagonIE_Sodium_Core_Salsa20 extends ParagonIE_Sodium_Core_Util
  11  {
  12      const ROUNDS = 20;
  13  
  14      /**
  15       * Calculate an salsa20 hash of a single block
  16       *
  17       * @internal You should not use this directly from another application
  18       *
  19       * @param string $in
  20       * @param string $k
  21       * @param string|null $c
  22       * @return string
  23       * @throws TypeError
  24       */
  25      public static function core_salsa20($in, $k, $c = null)
  26      {
  27          if (self::strlen($k) < 32) {
  28              throw new RangeException('Key must be 32 bytes long');
  29          }
  30          if ($c === null) {
  31              $j0  = $x0  = 0x61707865;
  32              $j5  = $x5  = 0x3320646e;
  33              $j10 = $x10 = 0x79622d32;
  34              $j15 = $x15 = 0x6b206574;
  35          } else {
  36              $j0  = $x0  = self::load_4(self::substr($c, 0, 4));
  37              $j5  = $x5  = self::load_4(self::substr($c, 4, 4));
  38              $j10 = $x10 = self::load_4(self::substr($c, 8, 4));
  39              $j15 = $x15 = self::load_4(self::substr($c, 12, 4));
  40          }
  41          $j1  = $x1  = self::load_4(self::substr($k, 0, 4));
  42          $j2  = $x2  = self::load_4(self::substr($k, 4, 4));
  43          $j3  = $x3  = self::load_4(self::substr($k, 8, 4));
  44          $j4  = $x4  = self::load_4(self::substr($k, 12, 4));
  45          $j6  = $x6  = self::load_4(self::substr($in, 0, 4));
  46          $j7  = $x7  = self::load_4(self::substr($in, 4, 4));
  47          $j8  = $x8  = self::load_4(self::substr($in, 8, 4));
  48          $j9  = $x9  = self::load_4(self::substr($in, 12, 4));
  49          $j11 = $x11 = self::load_4(self::substr($k, 16, 4));
  50          $j12 = $x12 = self::load_4(self::substr($k, 20, 4));
  51          $j13 = $x13 = self::load_4(self::substr($k, 24, 4));
  52          $j14 = $x14 = self::load_4(self::substr($k, 28, 4));
  53  
  54          for ($i = self::ROUNDS; $i > 0; $i -= 2) {
  55              $x4 ^= self::rotate($x0 + $x12, 7);
  56              $x8 ^= self::rotate($x4 + $x0, 9);
  57              $x12 ^= self::rotate($x8 + $x4, 13);
  58              $x0 ^= self::rotate($x12 + $x8, 18);
  59  
  60              $x9 ^= self::rotate($x5 + $x1, 7);
  61              $x13 ^= self::rotate($x9 + $x5, 9);
  62              $x1 ^= self::rotate($x13 + $x9, 13);
  63              $x5 ^= self::rotate($x1 + $x13, 18);
  64  
  65              $x14 ^= self::rotate($x10 + $x6, 7);
  66              $x2 ^= self::rotate($x14 + $x10, 9);
  67              $x6 ^= self::rotate($x2 + $x14, 13);
  68              $x10 ^= self::rotate($x6 + $x2, 18);
  69  
  70              $x3 ^= self::rotate($x15 + $x11, 7);
  71              $x7 ^= self::rotate($x3 + $x15, 9);
  72              $x11 ^= self::rotate($x7 + $x3, 13);
  73              $x15 ^= self::rotate($x11 + $x7, 18);
  74  
  75              $x1 ^= self::rotate($x0 + $x3, 7);
  76              $x2 ^= self::rotate($x1 + $x0, 9);
  77              $x3 ^= self::rotate($x2 + $x1, 13);
  78              $x0 ^= self::rotate($x3 + $x2, 18);
  79  
  80              $x6 ^= self::rotate($x5 + $x4, 7);
  81              $x7 ^= self::rotate($x6 + $x5, 9);
  82              $x4 ^= self::rotate($x7 + $x6, 13);
  83              $x5 ^= self::rotate($x4 + $x7, 18);
  84  
  85              $x11 ^= self::rotate($x10 + $x9, 7);
  86              $x8 ^= self::rotate($x11 + $x10, 9);
  87              $x9 ^= self::rotate($x8 + $x11, 13);
  88              $x10 ^= self::rotate($x9 + $x8, 18);
  89  
  90              $x12 ^= self::rotate($x15 + $x14, 7);
  91              $x13 ^= self::rotate($x12 + $x15, 9);
  92              $x14 ^= self::rotate($x13 + $x12, 13);
  93              $x15 ^= self::rotate($x14 + $x13, 18);
  94          }
  95  
  96          $x0  += $j0;
  97          $x1  += $j1;
  98          $x2  += $j2;
  99          $x3  += $j3;
 100          $x4  += $j4;
 101          $x5  += $j5;
 102          $x6  += $j6;
 103          $x7  += $j7;
 104          $x8  += $j8;
 105          $x9  += $j9;
 106          $x10 += $j10;
 107          $x11 += $j11;
 108          $x12 += $j12;
 109          $x13 += $j13;
 110          $x14 += $j14;
 111          $x15 += $j15;
 112  
 113          return self::store32_le($x0) .
 114              self::store32_le($x1) .
 115              self::store32_le($x2) .
 116              self::store32_le($x3) .
 117              self::store32_le($x4) .
 118              self::store32_le($x5) .
 119              self::store32_le($x6) .
 120              self::store32_le($x7) .
 121              self::store32_le($x8) .
 122              self::store32_le($x9) .
 123              self::store32_le($x10) .
 124              self::store32_le($x11) .
 125              self::store32_le($x12) .
 126              self::store32_le($x13) .
 127              self::store32_le($x14) .
 128              self::store32_le($x15);
 129      }
 130  
 131      /**
 132       * @internal You should not use this directly from another application
 133       *
 134       * @param int $len
 135       * @param string $nonce
 136       * @param string $key
 137       * @return string
 138       * @throws SodiumException
 139       * @throws TypeError
 140       */
 141      public static function salsa20($len, $nonce, $key)
 142      {
 143          if (self::strlen($key) !== 32) {
 144              throw new RangeException('Key must be 32 bytes long');
 145          }
 146          $kcopy = '' . $key;
 147          $in = self::substr($nonce, 0, 8) . str_repeat("\0", 8);
 148          $c = '';
 149          while ($len >= 64) {
 150              $c .= self::core_salsa20($in, $kcopy, null);
 151              $u = 1;
 152              // Internal counter.
 153              for ($i = 8; $i < 16; ++$i) {
 154                  $u += self::chrToInt($in[$i]);
 155                  $in[$i] = self::intToChr($u & 0xff);
 156                  $u >>= 8;
 157              }
 158              $len -= 64;
 159          }
 160          if ($len > 0) {
 161              $c .= self::substr(
 162                  self::core_salsa20($in, $kcopy, null),
 163                  0,
 164                  $len
 165              );
 166          }
 167          try {
 168              ParagonIE_Sodium_Compat::memzero($kcopy);
 169          } catch (SodiumException $ex) {
 170              $kcopy = null;
 171          }
 172          return $c;
 173      }
 174  
 175      /**
 176       * @internal You should not use this directly from another application
 177       *
 178       * @param string $m
 179       * @param string $n
 180       * @param int $ic
 181       * @param string $k
 182       * @return string
 183       * @throws SodiumException
 184       * @throws TypeError
 185       */
 186      public static function salsa20_xor_ic($m, $n, $ic, $k)
 187      {
 188          $mlen = self::strlen($m);
 189          if ($mlen < 1) {
 190              return '';
 191          }
 192          $kcopy = self::substr($k, 0, 32);
 193          $in = self::substr($n, 0, 8);
 194          // Initialize the counter
 195          $in .= ParagonIE_Sodium_Core_Util::store64_le($ic);
 196  
 197          $c = '';
 198          while ($mlen >= 64) {
 199              $block = self::core_salsa20($in, $kcopy, null);
 200              $c .= self::xorStrings(
 201                  self::substr($m, 0, 64),
 202                  self::substr($block, 0, 64)
 203              );
 204              $u = 1;
 205              for ($i = 8; $i < 16; ++$i) {
 206                  $u += self::chrToInt($in[$i]);
 207                  $in[$i] = self::intToChr($u & 0xff);
 208                  $u >>= 8;
 209              }
 210  
 211              $mlen -= 64;
 212              $m = self::substr($m, 64);
 213          }
 214  
 215          if ($mlen) {
 216              $block = self::core_salsa20($in, $kcopy, null);
 217              $c .= self::xorStrings(
 218                  self::substr($m, 0, $mlen),
 219                  self::substr($block, 0, $mlen)
 220              );
 221          }
 222          try {
 223              ParagonIE_Sodium_Compat::memzero($block);
 224              ParagonIE_Sodium_Compat::memzero($kcopy);
 225          } catch (SodiumException $ex) {
 226              $block = null;
 227              $kcopy = null;
 228          }
 229  
 230          return $c;
 231      }
 232  
 233      /**
 234       * @internal You should not use this directly from another application
 235       *
 236       * @param string $message
 237       * @param string $nonce
 238       * @param string $key
 239       * @return string
 240       * @throws SodiumException
 241       * @throws TypeError
 242       */
 243      public static function salsa20_xor($message, $nonce, $key)
 244      {
 245          return self::xorStrings(
 246              $message,
 247              self::salsa20(
 248                  self::strlen($message),
 249                  $nonce,
 250                  $key
 251              )
 252          );
 253      }
 254  
 255      /**
 256       * @internal You should not use this directly from another application
 257       *
 258       * @param int $u
 259       * @param int $c
 260       * @return int
 261       */
 262      public static function rotate($u, $c)
 263      {
 264          $u &= 0xffffffff;
 265          $c %= 32;
 266          return (int) (0xffffffff & (
 267                  ($u << $c)
 268                      |
 269                  ($u >> (32 - $c))
 270              )
 271          );
 272      }
 273  }


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