You are here

class ParagonIE_Sodium_Core32_Poly1305_State in Automatic Updates 8

Same name and namespace in other branches
  1. 7 vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php \ParagonIE_Sodium_Core32_Poly1305_State

Class ParagonIE_Sodium_Core32_Poly1305_State

Hierarchy

Expanded class hierarchy of ParagonIE_Sodium_Core32_Poly1305_State

1 string reference to 'ParagonIE_Sodium_Core32_Poly1305_State'
State.php in vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php

File

vendor/paragonie/sodium_compat/src/Core32/Poly1305/State.php, line 10

View source
class ParagonIE_Sodium_Core32_Poly1305_State extends ParagonIE_Sodium_Core32_Util {

  /**
   * @var array<int, int>
   */
  protected $buffer = array();

  /**
   * @var bool
   */
  protected $final = false;

  /**
   * @var array<int, ParagonIE_Sodium_Core32_Int32>
   */
  public $h;

  /**
   * @var int
   */
  protected $leftover = 0;

  /**
   * @var array<int, ParagonIE_Sodium_Core32_Int32>
   */
  public $r;

  /**
   * @var array<int, ParagonIE_Sodium_Core32_Int64>
   */
  public $pad;

  /**
   * ParagonIE_Sodium_Core32_Poly1305_State constructor.
   *
   * @internal You should not use this directly from another application
   *
   * @param string $key
   * @throws InvalidArgumentException
   * @throws SodiumException
   * @throws TypeError
   */
  public function __construct($key = '') {
    if (self::strlen($key) < 32) {
      throw new InvalidArgumentException('Poly1305 requires a 32-byte key');
    }

    /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
    $this->r = array(
      // st->r[0] = ...
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4))
        ->setUnsignedInt(true)
        ->mask(0x3ffffff),
      // st->r[1] = ...
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 3, 4))
        ->setUnsignedInt(true)
        ->shiftRight(2)
        ->mask(0x3ffff03),
      // st->r[2] = ...
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 6, 4))
        ->setUnsignedInt(true)
        ->shiftRight(4)
        ->mask(0x3ffc0ff),
      // st->r[3] = ...
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 9, 4))
        ->setUnsignedInt(true)
        ->shiftRight(6)
        ->mask(0x3f03fff),
      // st->r[4] = ...
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4))
        ->setUnsignedInt(true)
        ->shiftRight(8)
        ->mask(0xfffff),
    );

    /* h = 0 */
    $this->h = array(
      new ParagonIE_Sodium_Core32_Int32(array(
        0,
        0,
      ), true),
      new ParagonIE_Sodium_Core32_Int32(array(
        0,
        0,
      ), true),
      new ParagonIE_Sodium_Core32_Int32(array(
        0,
        0,
      ), true),
      new ParagonIE_Sodium_Core32_Int32(array(
        0,
        0,
      ), true),
      new ParagonIE_Sodium_Core32_Int32(array(
        0,
        0,
      ), true),
    );

    /* save pad for later */
    $this->pad = array(
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4))
        ->setUnsignedInt(true)
        ->toInt64(),
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4))
        ->setUnsignedInt(true)
        ->toInt64(),
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4))
        ->setUnsignedInt(true)
        ->toInt64(),
      ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4))
        ->setUnsignedInt(true)
        ->toInt64(),
    );
    $this->leftover = 0;
    $this->final = false;
  }

  /**
   * @internal You should not use this directly from another application
   *
   * @param string $message
   * @return self
   * @throws SodiumException
   * @throws TypeError
   */
  public function update($message = '') {
    $bytes = self::strlen($message);

    /* handle leftover */
    if ($this->leftover) {

      /** @var int $want */
      $want = ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - $this->leftover;
      if ($want > $bytes) {
        $want = $bytes;
      }
      for ($i = 0; $i < $want; ++$i) {
        $mi = self::chrToInt($message[$i]);
        $this->buffer[$this->leftover + $i] = $mi;
      }

      // We snip off the leftmost bytes.
      $message = self::substr($message, $want);
      $bytes = self::strlen($message);
      $this->leftover += $want;
      if ($this->leftover < ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {

        // We still don't have enough to run $this->blocks()
        return $this;
      }
      $this
        ->blocks(self::intArrayToString($this->buffer), ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE);
      $this->leftover = 0;
    }

    /* process full blocks */
    if ($bytes >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {

      /** @var int $want */
      $want = $bytes & ~(ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - 1);
      if ($want >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {

        /** @var string $block */
        $block = self::substr($message, 0, $want);
        if (self::strlen($block) >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
          $this
            ->blocks($block, $want);
          $message = self::substr($message, $want);
          $bytes = self::strlen($message);
        }
      }
    }

    /* store leftover */
    if ($bytes) {
      for ($i = 0; $i < $bytes; ++$i) {
        $mi = self::chrToInt($message[$i]);
        $this->buffer[$this->leftover + $i] = $mi;
      }
      $this->leftover = (int) $this->leftover + $bytes;
    }
    return $this;
  }

  /**
   * @internal You should not use this directly from another application
   *
   * @param string $message
   * @param int $bytes
   * @return self
   * @throws SodiumException
   * @throws TypeError
   */
  public function blocks($message, $bytes) {
    if (self::strlen($message) < 16) {
      $message = str_pad($message, 16, "\0", STR_PAD_RIGHT);
    }
    $hibit = ParagonIE_Sodium_Core32_Int32::fromInt((int) ($this->final ? 0 : 1 << 24));

    /* 1 << 128 */
    $hibit
      ->setUnsignedInt(true);
    $zero = new ParagonIE_Sodium_Core32_Int64(array(
      0,
      0,
      0,
      0,
    ), true);

    /**
     * @var ParagonIE_Sodium_Core32_Int64 $d0
     * @var ParagonIE_Sodium_Core32_Int64 $d1
     * @var ParagonIE_Sodium_Core32_Int64 $d2
     * @var ParagonIE_Sodium_Core32_Int64 $d3
     * @var ParagonIE_Sodium_Core32_Int64 $d4
     * @var ParagonIE_Sodium_Core32_Int64 $r0
     * @var ParagonIE_Sodium_Core32_Int64 $r1
     * @var ParagonIE_Sodium_Core32_Int64 $r2
     * @var ParagonIE_Sodium_Core32_Int64 $r3
     * @var ParagonIE_Sodium_Core32_Int64 $r4
     *
     * @var ParagonIE_Sodium_Core32_Int32 $h0
     * @var ParagonIE_Sodium_Core32_Int32 $h1
     * @var ParagonIE_Sodium_Core32_Int32 $h2
     * @var ParagonIE_Sodium_Core32_Int32 $h3
     * @var ParagonIE_Sodium_Core32_Int32 $h4
     */
    $r0 = $this->r[0]
      ->toInt64();
    $r1 = $this->r[1]
      ->toInt64();
    $r2 = $this->r[2]
      ->toInt64();
    $r3 = $this->r[3]
      ->toInt64();
    $r4 = $this->r[4]
      ->toInt64();
    $s1 = $r1
      ->toInt64()
      ->mulInt(5, 3);
    $s2 = $r2
      ->toInt64()
      ->mulInt(5, 3);
    $s3 = $r3
      ->toInt64()
      ->mulInt(5, 3);
    $s4 = $r4
      ->toInt64()
      ->mulInt(5, 3);
    $h0 = $this->h[0];
    $h1 = $this->h[1];
    $h2 = $this->h[2];
    $h3 = $this->h[3];
    $h4 = $this->h[4];
    while ($bytes >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {

      /* h += m[i] */
      $h0 = $h0
        ->addInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 0, 4))
        ->mask(0x3ffffff))
        ->toInt64();
      $h1 = $h1
        ->addInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 3, 4))
        ->shiftRight(2)
        ->mask(0x3ffffff))
        ->toInt64();
      $h2 = $h2
        ->addInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 6, 4))
        ->shiftRight(4)
        ->mask(0x3ffffff))
        ->toInt64();
      $h3 = $h3
        ->addInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 9, 4))
        ->shiftRight(6)
        ->mask(0x3ffffff))
        ->toInt64();
      $h4 = $h4
        ->addInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 12, 4))
        ->shiftRight(8)
        ->orInt32($hibit))
        ->toInt64();

      /* h *= r */
      $d0 = $zero
        ->addInt64($h0
        ->mulInt64($r0, 25))
        ->addInt64($s4
        ->mulInt64($h1, 26))
        ->addInt64($s3
        ->mulInt64($h2, 26))
        ->addInt64($s2
        ->mulInt64($h3, 26))
        ->addInt64($s1
        ->mulInt64($h4, 26));
      $d1 = $zero
        ->addInt64($h0
        ->mulInt64($r1, 25))
        ->addInt64($h1
        ->mulInt64($r0, 25))
        ->addInt64($s4
        ->mulInt64($h2, 26))
        ->addInt64($s3
        ->mulInt64($h3, 26))
        ->addInt64($s2
        ->mulInt64($h4, 26));
      $d2 = $zero
        ->addInt64($h0
        ->mulInt64($r2, 25))
        ->addInt64($h1
        ->mulInt64($r1, 25))
        ->addInt64($h2
        ->mulInt64($r0, 25))
        ->addInt64($s4
        ->mulInt64($h3, 26))
        ->addInt64($s3
        ->mulInt64($h4, 26));
      $d3 = $zero
        ->addInt64($h0
        ->mulInt64($r3, 25))
        ->addInt64($h1
        ->mulInt64($r2, 25))
        ->addInt64($h2
        ->mulInt64($r1, 25))
        ->addInt64($h3
        ->mulInt64($r0, 25))
        ->addInt64($s4
        ->mulInt64($h4, 26));
      $d4 = $zero
        ->addInt64($h0
        ->mulInt64($r4, 25))
        ->addInt64($h1
        ->mulInt64($r3, 25))
        ->addInt64($h2
        ->mulInt64($r2, 25))
        ->addInt64($h3
        ->mulInt64($r1, 25))
        ->addInt64($h4
        ->mulInt64($r0, 25));

      /* (partial) h %= p */
      $c = $d0
        ->shiftRight(26);
      $h0 = $d0
        ->toInt32()
        ->mask(0x3ffffff);
      $d1 = $d1
        ->addInt64($c);
      $c = $d1
        ->shiftRight(26);
      $h1 = $d1
        ->toInt32()
        ->mask(0x3ffffff);
      $d2 = $d2
        ->addInt64($c);
      $c = $d2
        ->shiftRight(26);
      $h2 = $d2
        ->toInt32()
        ->mask(0x3ffffff);
      $d3 = $d3
        ->addInt64($c);
      $c = $d3
        ->shiftRight(26);
      $h3 = $d3
        ->toInt32()
        ->mask(0x3ffffff);
      $d4 = $d4
        ->addInt64($c);
      $c = $d4
        ->shiftRight(26);
      $h4 = $d4
        ->toInt32()
        ->mask(0x3ffffff);
      $h0 = $h0
        ->addInt32($c
        ->toInt32()
        ->mulInt(5, 3));
      $c = $h0
        ->shiftRight(26);
      $h0 = $h0
        ->mask(0x3ffffff);
      $h1 = $h1
        ->addInt32($c);

      // Chop off the left 32 bytes.
      $message = self::substr($message, ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE);
      $bytes -= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE;
    }

    /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
    $this->h = array(
      $h0,
      $h1,
      $h2,
      $h3,
      $h4,
    );
    return $this;
  }

  /**
   * @internal You should not use this directly from another application
   *
   * @return string
   * @throws SodiumException
   * @throws TypeError
   */
  public function finish() {

    /* process the remaining block */
    if ($this->leftover) {
      $i = $this->leftover;
      $this->buffer[$i++] = 1;
      for (; $i < ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE; ++$i) {
        $this->buffer[$i] = 0;
      }
      $this->final = true;
      $this
        ->blocks(self::substr(self::intArrayToString($this->buffer), 0, ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE), $b = ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE);
    }

    /**
     * @var ParagonIE_Sodium_Core32_Int32 $f
     * @var ParagonIE_Sodium_Core32_Int32 $g0
     * @var ParagonIE_Sodium_Core32_Int32 $g1
     * @var ParagonIE_Sodium_Core32_Int32 $g2
     * @var ParagonIE_Sodium_Core32_Int32 $g3
     * @var ParagonIE_Sodium_Core32_Int32 $g4
     * @var ParagonIE_Sodium_Core32_Int32 $h0
     * @var ParagonIE_Sodium_Core32_Int32 $h1
     * @var ParagonIE_Sodium_Core32_Int32 $h2
     * @var ParagonIE_Sodium_Core32_Int32 $h3
     * @var ParagonIE_Sodium_Core32_Int32 $h4
     */
    $h0 = $this->h[0];
    $h1 = $this->h[1];
    $h2 = $this->h[2];
    $h3 = $this->h[3];
    $h4 = $this->h[4];
    $c = $h1
      ->shiftRight(26);

    # $c = $h1 >> 26;
    $h1 = $h1
      ->mask(0x3ffffff);

    # $h1 &= 0x3ffffff;
    $h2 = $h2
      ->addInt32($c);

    # $h2 += $c;
    $c = $h2
      ->shiftRight(26);

    # $c = $h2 >> 26;
    $h2 = $h2
      ->mask(0x3ffffff);

    # $h2 &= 0x3ffffff;
    $h3 = $h3
      ->addInt32($c);

    # $h3 += $c;
    $c = $h3
      ->shiftRight(26);

    # $c = $h3 >> 26;
    $h3 = $h3
      ->mask(0x3ffffff);

    # $h3 &= 0x3ffffff;
    $h4 = $h4
      ->addInt32($c);

    # $h4 += $c;
    $c = $h4
      ->shiftRight(26);

    # $c = $h4 >> 26;
    $h4 = $h4
      ->mask(0x3ffffff);

    # $h4 &= 0x3ffffff;
    $h0 = $h0
      ->addInt32($c
      ->mulInt(5, 3));

    # $h0 += self::mul($c, 5);
    $c = $h0
      ->shiftRight(26);

    # $c = $h0 >> 26;
    $h0 = $h0
      ->mask(0x3ffffff);

    # $h0 &= 0x3ffffff;
    $h1 = $h1
      ->addInt32($c);

    # $h1 += $c;

    /* compute h + -p */
    $g0 = $h0
      ->addInt(5);
    $c = $g0
      ->shiftRight(26);
    $g0 = $g0
      ->mask(0x3ffffff);
    $g1 = $h1
      ->addInt32($c);
    $c = $g1
      ->shiftRight(26);
    $g1 = $g1
      ->mask(0x3ffffff);
    $g2 = $h2
      ->addInt32($c);
    $c = $g2
      ->shiftRight(26);
    $g2 = $g2
      ->mask(0x3ffffff);
    $g3 = $h3
      ->addInt32($c);
    $c = $g3
      ->shiftRight(26);
    $g3 = $g3
      ->mask(0x3ffffff);
    $g4 = $h4
      ->addInt32($c)
      ->subInt(1 << 26);

    # $mask = ($g4 >> 31) - 1;

    /* select h if h < p, or h + -p if h >= p */
    $mask = (int) (($g4
      ->toInt() >> 31) + 1);
    $g0 = $g0
      ->mask($mask);
    $g1 = $g1
      ->mask($mask);
    $g2 = $g2
      ->mask($mask);
    $g3 = $g3
      ->mask($mask);
    $g4 = $g4
      ->mask($mask);

    /** @var int $mask */
    $mask = ~$mask & 0xffffffff;
    $h0 = $h0
      ->mask($mask)
      ->orInt32($g0);
    $h1 = $h1
      ->mask($mask)
      ->orInt32($g1);
    $h2 = $h2
      ->mask($mask)
      ->orInt32($g2);
    $h3 = $h3
      ->mask($mask)
      ->orInt32($g3);
    $h4 = $h4
      ->mask($mask)
      ->orInt32($g4);

    /* h = h % (2^128) */
    $h0 = $h0
      ->orInt32($h1
      ->shiftLeft(26));
    $h1 = $h1
      ->shiftRight(6)
      ->orInt32($h2
      ->shiftLeft(20));
    $h2 = $h2
      ->shiftRight(12)
      ->orInt32($h3
      ->shiftLeft(14));
    $h3 = $h3
      ->shiftRight(18)
      ->orInt32($h4
      ->shiftLeft(8));

    /* mac = (h + pad) % (2^128) */
    $f = $h0
      ->toInt64()
      ->addInt64($this->pad[0]);
    $h0 = $f
      ->toInt32();
    $f = $h1
      ->toInt64()
      ->addInt64($this->pad[1])
      ->addInt($h0->overflow);
    $h1 = $f
      ->toInt32();
    $f = $h2
      ->toInt64()
      ->addInt64($this->pad[2])
      ->addInt($h1->overflow);
    $h2 = $f
      ->toInt32();
    $f = $h3
      ->toInt64()
      ->addInt64($this->pad[3])
      ->addInt($h2->overflow);
    $h3 = $f
      ->toInt32();
    return $h0
      ->toReverseString() . $h1
      ->toReverseString() . $h2
      ->toReverseString() . $h3
      ->toReverseString();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ParagonIE_Sodium_Core32_Poly1305_State::$buffer protected property
ParagonIE_Sodium_Core32_Poly1305_State::$final protected property
ParagonIE_Sodium_Core32_Poly1305_State::$h public property
ParagonIE_Sodium_Core32_Poly1305_State::$leftover protected property
ParagonIE_Sodium_Core32_Poly1305_State::$pad public property
ParagonIE_Sodium_Core32_Poly1305_State::$r public property
ParagonIE_Sodium_Core32_Poly1305_State::blocks public function @internal You should not use this directly from another application
ParagonIE_Sodium_Core32_Poly1305_State::finish public function @internal You should not use this directly from another application
ParagonIE_Sodium_Core32_Poly1305_State::update public function @internal You should not use this directly from another application
ParagonIE_Sodium_Core32_Poly1305_State::__construct public function ParagonIE_Sodium_Core32_Poly1305_State constructor.
ParagonIE_Sodium_Core_Util::abs public static function
ParagonIE_Sodium_Core_Util::bin2hex public static function Convert a binary string into a hexadecimal string without cache-timing leaks
ParagonIE_Sodium_Core_Util::bin2hexUpper public static function Convert a binary string into a hexadecimal string without cache-timing leaks, returning uppercase letters (as per RFC 4648)
ParagonIE_Sodium_Core_Util::chrToInt public static function Cache-timing-safe variant of ord()
ParagonIE_Sodium_Core_Util::compare public static function Compares two strings.
ParagonIE_Sodium_Core_Util::declareScalarType public static function If a variable does not match a given type, throw a TypeError.
ParagonIE_Sodium_Core_Util::hashEquals public static function Evaluate whether or not two strings are equal (in constant-time)
ParagonIE_Sodium_Core_Util::hex2bin public static function Convert a hexadecimal string into a binary string without cache-timing leaks
ParagonIE_Sodium_Core_Util::intArrayToString public static function Turn an array of integers into a string
ParagonIE_Sodium_Core_Util::intToChr public static function Cache-timing-safe variant of ord()
ParagonIE_Sodium_Core_Util::isMbStringOverride protected static function Returns whether or not mbstring.func_overload is in effect.
ParagonIE_Sodium_Core_Util::load64_le public static function Load a 8 character substring into an integer
ParagonIE_Sodium_Core_Util::load_3 public static function Load a 3 character substring into an integer
ParagonIE_Sodium_Core_Util::load_4 public static function Load a 4 character substring into an integer
ParagonIE_Sodium_Core_Util::memcmp public static function @internal You should not use this directly from another application
ParagonIE_Sodium_Core_Util::mul public static function Multiply two integers in constant-time
ParagonIE_Sodium_Core_Util::numericTo64BitInteger public static function Convert any arbitrary numbers into two 32-bit integers that represent a 64-bit integer.
ParagonIE_Sodium_Core_Util::store32_le public static function Store a 32-bit integer into a string, treating it as little-endian.
ParagonIE_Sodium_Core_Util::store64_le public static function Stores a 64-bit integer as an string, treating it as little-endian.
ParagonIE_Sodium_Core_Util::store_3 public static function Store a 24-bit integer into a string, treating it as big-endian.
ParagonIE_Sodium_Core_Util::store_4 public static function Store a 32-bit integer into a string, treating it as big-endian.
ParagonIE_Sodium_Core_Util::stringToIntArray public static function Turn a string into an array of integers
ParagonIE_Sodium_Core_Util::strlen public static function Safe string length
ParagonIE_Sodium_Core_Util::substr public static function Safe substring
ParagonIE_Sodium_Core_Util::verify_16 public static function Compare a 16-character byte string in constant time.
ParagonIE_Sodium_Core_Util::verify_32 public static function Compare a 32-character byte string in constant time.
ParagonIE_Sodium_Core_Util::xorStrings public static function Calculate $a ^ $b for two strings.