You are here

public static function ParagonIE_Sodium_Core_Util::mul in Automatic Updates 8

Same name and namespace in other branches
  1. 7 vendor/paragonie/sodium_compat/src/Core/Util.php \ParagonIE_Sodium_Core_Util::mul()

Multiply two integers in constant-time

Micro-architecture timing side-channels caused by how your CPU implements multiplication are best prevented by never using the multiplication operators and ensuring that our code always takes the same number of operations to complete, regardless of the values of $a and $b.

@internal You should not use this directly from another application

Parameters

int $a:

int $b:

int $size Limits the number of operations (useful for small,: constant operands)

Return value

int

10 calls to ParagonIE_Sodium_Core_Util::mul()
ParagonIE_Sodium_Core_Curve25519::fe_frombytes in vendor/paragonie/sodium_compat/src/Core/Curve25519.php
Give: 32-byte string. Receive: A field element object to use for internal calculations.
ParagonIE_Sodium_Core_Curve25519::fe_mul in vendor/paragonie/sodium_compat/src/Core/Curve25519.php
Multiply two field elements
ParagonIE_Sodium_Core_Curve25519::fe_sq in vendor/paragonie/sodium_compat/src/Core/Curve25519.php
Square a field element
ParagonIE_Sodium_Core_Curve25519::fe_sq2 in vendor/paragonie/sodium_compat/src/Core/Curve25519.php
Square and double a field element
ParagonIE_Sodium_Core_Curve25519::fe_tobytes in vendor/paragonie/sodium_compat/src/Core/Curve25519.php
Convert a field element to a byte string.

... See full list

File

vendor/paragonie/sodium_compat/src/Core/Util.php, line 524

Class

ParagonIE_Sodium_Core_Util
Class ParagonIE_Sodium_Core_Util

Code

public static function mul($a, $b, $size = 0) {
  if (ParagonIE_Sodium_Compat::$fastMult) {
    return (int) ($a * $b);
  }
  static $defaultSize = null;

  /** @var int $defaultSize */
  if (!$defaultSize) {

    /** @var int $defaultSize */
    $defaultSize = (PHP_INT_SIZE << 3) - 1;
  }
  if ($size < 1) {

    /** @var int $size */
    $size = $defaultSize;
  }

  /** @var int $size */
  $c = 0;

  /**
   * Mask is either -1 or 0.
   *
   * -1 in binary looks like 0x1111 ... 1111
   *  0 in binary looks like 0x0000 ... 0000
   *
   * @var int
   */
  $mask = -($b >> (int) $defaultSize & 1);

  /**
   * Ensure $b is a positive integer, without creating
   * a branching side-channel
   *
   * @var int $b
   */
  $b = $b & ~$mask | $mask & -$b;

  /**
   * Unless $size is provided:
   *
   * This loop always runs 32 times when PHP_INT_SIZE is 4.
   * This loop always runs 64 times when PHP_INT_SIZE is 8.
   */
  for ($i = $size; $i >= 0; --$i) {
    $c += (int) ($a & -($b & 1));
    $a <<= 1;
    $b >>= 1;
  }

  /**
   * If $b was negative, we then apply the same value to $c here.
   * It doesn't matter much if $a was negative; the $c += above would
   * have produced a negative integer to begin with. But a negative $b
   * makes $b >>= 1 never return 0, so we would end up with incorrect
   * results.
   *
   * The end result is what we'd expect from integer multiplication.
   */
  return (int) ($c & ~$mask | $mask & -$c);
}