[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/ -> PublicKey.php (source)

   1  <?php
   2  
   3  /**
   4   * EC Public Key
   5   *
   6   * @category  Crypt
   7   * @package   EC
   8   * @author    Jim Wigginton <[email protected]>
   9   * @copyright 2015 Jim Wigginton
  10   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  11   * @link      http://phpseclib.sourceforge.net
  12   */
  13  
  14  namespace phpseclib3\Crypt\EC;
  15  
  16  use phpseclib3\Common\Functions\Strings;
  17  use phpseclib3\Crypt\Common;
  18  use phpseclib3\Crypt\EC;
  19  use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
  20  use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
  21  use phpseclib3\Crypt\EC\Curves\Ed25519;
  22  use phpseclib3\Crypt\EC\Formats\Keys\PKCS1;
  23  use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature;
  24  use phpseclib3\Crypt\Hash;
  25  use phpseclib3\Exception\UnsupportedOperationException;
  26  use phpseclib3\Math\BigInteger;
  27  
  28  /**
  29   * EC Public Key
  30   *
  31   * @package EC
  32   * @author  Jim Wigginton <[email protected]>
  33   * @access  public
  34   */
  35  class PublicKey extends EC implements Common\PublicKey
  36  {
  37      use Common\Traits\Fingerprint;
  38  
  39      /**
  40       * Verify a signature
  41       *
  42       * @see self::verify()
  43       * @access public
  44       * @param string $message
  45       * @param string $signature
  46       * @return mixed
  47       */
  48      public function verify($message, $signature)
  49      {
  50          if ($this->curve instanceof MontgomeryCurve) {
  51              throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures');
  52          }
  53  
  54          $shortFormat = $this->shortFormat;
  55          $format = $this->sigFormat;
  56          if ($format === false) {
  57              return false;
  58          }
  59  
  60          $order = $this->curve->getOrder();
  61  
  62          if ($this->curve instanceof TwistedEdwardsCurve) {
  63              if ($shortFormat == 'SSH2') {
  64                  list(, $signature) = Strings::unpackSSH2('ss', $signature);
  65              }
  66  
  67              if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) {
  68                  return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium'));
  69              }
  70  
  71              $curve = $this->curve;
  72              if (strlen($signature) != 2 * $curve::SIZE) {
  73                  return false;
  74              }
  75  
  76              $R = substr($signature, 0, $curve::SIZE);
  77              $S = substr($signature, $curve::SIZE);
  78  
  79              try {
  80                  $R = PKCS1::extractPoint($R, $curve);
  81                  $R = $this->curve->convertToInternal($R);
  82              } catch (\Exception $e) {
  83                  return false;
  84              }
  85  
  86              $S = strrev($S);
  87              $S = new BigInteger($S, 256);
  88  
  89              if ($S->compare($order) >= 0) {
  90                  return false;
  91              }
  92  
  93              $A = $curve->encodePoint($this->QA);
  94  
  95              if ($curve instanceof Ed25519) {
  96                  $dom2 = !isset($this->context) ? '' :
  97                      'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context;
  98              } else {
  99                  $context = isset($this->context) ? $this->context : '';
 100                  $dom2 = 'SigEd448' . "\0" . chr(strlen($context)) . $context;
 101              }
 102  
 103              $hash = new Hash($curve::HASH);
 104              $k = $hash->hash($dom2 . substr($signature, 0, $curve::SIZE) . $A . $message);
 105              $k = strrev($k);
 106              $k = new BigInteger($k, 256);
 107              list(, $k) = $k->divide($order);
 108  
 109              $qa = $curve->convertToInternal($this->QA);
 110  
 111              $lhs = $curve->multiplyPoint($curve->getBasePoint(), $S);
 112              $rhs = $curve->multiplyPoint($qa, $k);
 113              $rhs = $curve->addPoint($rhs, $R);
 114              $rhs = $curve->convertToAffine($rhs);
 115  
 116              return $lhs[0]->equals($rhs[0]) && $lhs[1]->equals($rhs[1]);
 117          }
 118  
 119          $params = $format::load($signature);
 120          if ($params === false || count($params) != 2) {
 121              return false;
 122          }
 123          extract($params);
 124  
 125          if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
 126              $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature;
 127  
 128              $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash());
 129  
 130              if ($result != -1) {
 131                  return (bool) $result;
 132              }
 133          }
 134  
 135          $n_1 = $order->subtract(self::$one);
 136          if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) {
 137              return false;
 138          }
 139  
 140          $e = $this->hash->hash($message);
 141          $e = new BigInteger($e, 256);
 142  
 143          $Ln = $this->hash->getLength() - $order->getLength();
 144          $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e;
 145  
 146          $w = $s->modInverse($order);
 147          list(, $u1) = $z->multiply($w)->divide($order);
 148          list(, $u2) = $r->multiply($w)->divide($order);
 149  
 150          $u1 = $this->curve->convertInteger($u1);
 151          $u2 = $this->curve->convertInteger($u2);
 152  
 153          list($x1, $y1) = $this->curve->multiplyAddPoints(
 154              [$this->curve->getBasePoint(), $this->QA],
 155              [$u1, $u2]
 156          );
 157  
 158          $x1 = $x1->toBigInteger();
 159          list(, $x1) = $x1->divide($order);
 160  
 161          return $x1->equals($r);
 162      }
 163  
 164      /**
 165       * Returns the public key
 166       *
 167       * @param string $type
 168       * @param array $options optional
 169       * @return string
 170       */
 171      public function toString($type, array $options = [])
 172      {
 173          $type = self::validatePlugin('Keys', $type, 'savePublicKey');
 174  
 175          return $type::savePublicKey($this->curve, $this->QA, $options);
 176      }
 177  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer