[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/ -> Base.php (source)

   1  <?php
   2  
   3  /**
   4   * Curve methods common to all curves
   5   *
   6   * PHP version 5 and 7
   7   *
   8   * @author    Jim Wigginton <terrafrost@php.net>
   9   * @copyright 2017 Jim Wigginton
  10   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  11   * @link      http://pear.php.net/package/Math_BigInteger
  12   */
  13  
  14  namespace phpseclib3\Crypt\EC\BaseCurves;
  15  
  16  use phpseclib3\Math\BigInteger;
  17  
  18  /**
  19   * Base
  20   *
  21   * @author  Jim Wigginton <terrafrost@php.net>
  22   */
  23  abstract class Base
  24  {
  25      /**
  26       * The Order
  27       *
  28       * @var BigInteger
  29       */
  30      protected $order;
  31  
  32      /**
  33       * Finite Field Integer factory
  34       *
  35       * @var \phpseclib3\Math\FiniteField\Integer
  36       */
  37      protected $factory;
  38  
  39      /**
  40       * Returns a random integer
  41       *
  42       * @return object
  43       */
  44      public function randomInteger()
  45      {
  46          return $this->factory->randomInteger();
  47      }
  48  
  49      /**
  50       * Converts a BigInteger to a \phpseclib3\Math\FiniteField\Integer integer
  51       *
  52       * @return object
  53       */
  54      public function convertInteger(BigInteger $x)
  55      {
  56          return $this->factory->newInteger($x);
  57      }
  58  
  59      /**
  60       * Returns the length, in bytes, of the modulo
  61       *
  62       * @return integer
  63       */
  64      public function getLengthInBytes()
  65      {
  66          return $this->factory->getLengthInBytes();
  67      }
  68  
  69      /**
  70       * Returns the length, in bits, of the modulo
  71       *
  72       * @return integer
  73       */
  74      public function getLength()
  75      {
  76          return $this->factory->getLength();
  77      }
  78  
  79      /**
  80       * Multiply a point on the curve by a scalar
  81       *
  82       * Uses the montgomery ladder technique as described here:
  83       *
  84       * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder
  85       * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772
  86       *
  87       * @return array
  88       */
  89      public function multiplyPoint(array $p, BigInteger $d)
  90      {
  91          $alreadyInternal = isset($p[2]);
  92          $r = $alreadyInternal ?
  93              [[], $p] :
  94              [[], $this->convertToInternal($p)];
  95  
  96          $d = $d->toBits();
  97          for ($i = 0; $i < strlen($d); $i++) {
  98              $d_i = (int) $d[$i];
  99              $r[1 - $d_i] = $this->addPoint($r[0], $r[1]);
 100              $r[$d_i] = $this->doublePoint($r[$d_i]);
 101          }
 102  
 103          return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]);
 104      }
 105  
 106      /**
 107       * Creates a random scalar multiplier
 108       *
 109       * @return BigInteger
 110       */
 111      public function createRandomMultiplier()
 112      {
 113          static $one;
 114          if (!isset($one)) {
 115              $one = new BigInteger(1);
 116          }
 117  
 118          return BigInteger::randomRange($one, $this->order->subtract($one));
 119      }
 120  
 121      /**
 122       * Performs range check
 123       */
 124      public function rangeCheck(BigInteger $x)
 125      {
 126          static $zero;
 127          if (!isset($zero)) {
 128              $zero = new BigInteger();
 129          }
 130  
 131          if (!isset($this->order)) {
 132              throw new \RuntimeException('setOrder needs to be called before this method');
 133          }
 134          if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) {
 135              throw new \RangeException('x must be between 1 and the order of the curve');
 136          }
 137      }
 138  
 139      /**
 140       * Sets the Order
 141       */
 142      public function setOrder(BigInteger $order)
 143      {
 144          $this->order = $order;
 145      }
 146  
 147      /**
 148       * Returns the Order
 149       *
 150       * @return \phpseclib3\Math\BigInteger
 151       */
 152      public function getOrder()
 153      {
 154          return $this->order;
 155      }
 156  
 157      /**
 158       * Use a custom defined modular reduction function
 159       *
 160       * @return object
 161       */
 162      public function setReduction(callable $func)
 163      {
 164          $this->factory->setReduction($func);
 165      }
 166  
 167      /**
 168       * Returns the affine point
 169       *
 170       * @return object[]
 171       */
 172      public function convertToAffine(array $p)
 173      {
 174          return $p;
 175      }
 176  
 177      /**
 178       * Converts an affine point to a jacobian coordinate
 179       *
 180       * @return object[]
 181       */
 182      public function convertToInternal(array $p)
 183      {
 184          return $p;
 185      }
 186  
 187      /**
 188       * Negates a point
 189       *
 190       * @return object[]
 191       */
 192      public function negatePoint(array $p)
 193      {
 194          $temp = [
 195              $p[0],
 196              $p[1]->negate()
 197          ];
 198          if (isset($p[2])) {
 199              $temp[] = $p[2];
 200          }
 201          return $temp;
 202      }
 203  
 204      /**
 205       * Multiply and Add Points
 206       *
 207       * @return int[]
 208       */
 209      public function multiplyAddPoints(array $points, array $scalars)
 210      {
 211          $p1 = $this->convertToInternal($points[0]);
 212          $p2 = $this->convertToInternal($points[1]);
 213          $p1 = $this->multiplyPoint($p1, $scalars[0]);
 214          $p2 = $this->multiplyPoint($p2, $scalars[1]);
 215          $r = $this->addPoint($p1, $p2);
 216          return $this->convertToAffine($r);
 217      }
 218  }