[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

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

   1  <?php
   2  
   3  /**
   4   * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2
   5   *
   6   * http://www.secg.org/SEC2-Ver-1.0.pdf provides for curves with custom parameters.
   7   * ie. the coefficients can be arbitrary set through specially formatted keys, etc.
   8   * As such, Prime.php is built very generically and it's not able to take full
   9   * advantage of curves with 0 coefficients to produce simplified point doubling,
  10   * point addition. Twisted Edwards curves, in contrast, do not have a way, currently,
  11   * to customize them. As such, we can omit the super generic stuff from this class
  12   * and let the named curves (Ed25519 and Ed448) define their own custom tailored
  13   * point addition and point doubling methods.
  14   *
  15   * More info:
  16   *
  17   * https://en.wikipedia.org/wiki/Twisted_Edwards_curve
  18   *
  19   * PHP version 5 and 7
  20   *
  21   * @author    Jim Wigginton <terrafrost@php.net>
  22   * @copyright 2017 Jim Wigginton
  23   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  24   * @link      http://pear.php.net/package/Math_BigInteger
  25   */
  26  
  27  namespace phpseclib3\Crypt\EC\BaseCurves;
  28  
  29  use phpseclib3\Math\BigInteger;
  30  use phpseclib3\Math\PrimeField;
  31  use phpseclib3\Math\PrimeField\Integer as PrimeInteger;
  32  
  33  /**
  34   * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2
  35   *
  36   * @author  Jim Wigginton <terrafrost@php.net>
  37   */
  38  class TwistedEdwards extends Base
  39  {
  40      /**
  41       * The modulo
  42       *
  43       * @var BigInteger
  44       */
  45      protected $modulo;
  46  
  47      /**
  48       * Cofficient for x^2
  49       *
  50       * @var object
  51       */
  52      protected $a;
  53  
  54      /**
  55       * Cofficient for x^2*y^2
  56       *
  57       * @var object
  58       */
  59      protected $d;
  60  
  61      /**
  62       * Base Point
  63       *
  64       * @var object[]
  65       */
  66      protected $p;
  67  
  68      /**
  69       * The number zero over the specified finite field
  70       *
  71       * @var object
  72       */
  73      protected $zero;
  74  
  75      /**
  76       * The number one over the specified finite field
  77       *
  78       * @var object
  79       */
  80      protected $one;
  81  
  82      /**
  83       * The number two over the specified finite field
  84       *
  85       * @var object
  86       */
  87      protected $two;
  88  
  89      /**
  90       * Sets the modulo
  91       */
  92      public function setModulo(BigInteger $modulo)
  93      {
  94          $this->modulo = $modulo;
  95          $this->factory = new PrimeField($modulo);
  96          $this->zero = $this->factory->newInteger(new BigInteger(0));
  97          $this->one = $this->factory->newInteger(new BigInteger(1));
  98          $this->two = $this->factory->newInteger(new BigInteger(2));
  99      }
 100  
 101      /**
 102       * Set coefficients a and b
 103       */
 104      public function setCoefficients(BigInteger $a, BigInteger $d)
 105      {
 106          if (!isset($this->factory)) {
 107              throw new \RuntimeException('setModulo needs to be called before this method');
 108          }
 109          $this->a = $this->factory->newInteger($a);
 110          $this->d = $this->factory->newInteger($d);
 111      }
 112  
 113      /**
 114       * Set x and y coordinates for the base point
 115       */
 116      public function setBasePoint($x, $y)
 117      {
 118          switch (true) {
 119              case !$x instanceof BigInteger && !$x instanceof PrimeInteger:
 120                  throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer');
 121              case !$y instanceof BigInteger && !$y instanceof PrimeInteger:
 122                  throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer');
 123          }
 124          if (!isset($this->factory)) {
 125              throw new \RuntimeException('setModulo needs to be called before this method');
 126          }
 127          $this->p = [
 128              $x instanceof BigInteger ? $this->factory->newInteger($x) : $x,
 129              $y instanceof BigInteger ? $this->factory->newInteger($y) : $y
 130          ];
 131      }
 132  
 133      /**
 134       * Returns the a coefficient
 135       *
 136       * @return \phpseclib3\Math\PrimeField\Integer
 137       */
 138      public function getA()
 139      {
 140          return $this->a;
 141      }
 142  
 143      /**
 144       * Returns the a coefficient
 145       *
 146       * @return \phpseclib3\Math\PrimeField\Integer
 147       */
 148      public function getD()
 149      {
 150          return $this->d;
 151      }
 152  
 153      /**
 154       * Retrieve the base point as an array
 155       *
 156       * @return array
 157       */
 158      public function getBasePoint()
 159      {
 160          if (!isset($this->factory)) {
 161              throw new \RuntimeException('setModulo needs to be called before this method');
 162          }
 163          /*
 164          if (!isset($this->p)) {
 165              throw new \RuntimeException('setBasePoint needs to be called before this method');
 166          }
 167          */
 168          return $this->p;
 169      }
 170  
 171      /**
 172       * Returns the affine point
 173       *
 174       * @return \phpseclib3\Math\PrimeField\Integer[]
 175       */
 176      public function convertToAffine(array $p)
 177      {
 178          if (!isset($p[2])) {
 179              return $p;
 180          }
 181          list($x, $y, $z) = $p;
 182          $z = $this->one->divide($z);
 183          return [
 184              $x->multiply($z),
 185              $y->multiply($z)
 186          ];
 187      }
 188  
 189      /**
 190       * Returns the modulo
 191       *
 192       * @return \phpseclib3\Math\BigInteger
 193       */
 194      public function getModulo()
 195      {
 196          return $this->modulo;
 197      }
 198  
 199      /**
 200       * Tests whether or not the x / y values satisfy the equation
 201       *
 202       * @return boolean
 203       */
 204      public function verifyPoint(array $p)
 205      {
 206          list($x, $y) = $p;
 207          $x2 = $x->multiply($x);
 208          $y2 = $y->multiply($y);
 209  
 210          $lhs = $this->a->multiply($x2)->add($y2);
 211          $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one);
 212  
 213          return $lhs->equals($rhs);
 214      }
 215  }