Subversion Repositories oidplus

Rev

Rev 846 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /**
  4.  * OpenSSL Modular Exponentiation Engine
  5.  *
  6.  * PHP version 5 and 7
  7.  *
  8.  * @category  Math
  9.  * @package   BigInteger
  10.  * @author    Jim Wigginton <terrafrost@php.net>
  11.  * @copyright 2017 Jim Wigginton
  12.  * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  13.  * @link      http://pear.php.net/package/Math_BigInteger
  14.  */
  15.  
  16. namespace phpseclib3\Math\BigInteger\Engines;
  17.  
  18. use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8;
  19. use phpseclib3\Math\BigInteger;
  20.  
  21. /**
  22.  * OpenSSL Modular Exponentiation Engine
  23.  *
  24.  * @package Engines
  25.  * @author  Jim Wigginton <terrafrost@php.net>
  26.  * @access  public
  27.  */
  28. abstract class OpenSSL
  29. {
  30.     /**
  31.      * Test for engine validity
  32.      *
  33.      * @return bool
  34.      */
  35.     public static function isValidEngine()
  36.     {
  37.         return extension_loaded('openssl') && static::class != __CLASS__;
  38.     }
  39.  
  40.     /**
  41.      * Performs modular exponentiation.
  42.      *
  43.      * @param Engine $x
  44.      * @param Engine $e
  45.      * @param Engine $n
  46.      * @return Engine
  47.      */
  48.     public static function powModHelper(Engine $x, Engine $e, Engine $n)
  49.     {
  50.         if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) {
  51.             throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted');
  52.         }
  53.  
  54.         $key = PKCS8::savePublicKey(
  55.             new BigInteger($n),
  56.             new BigInteger($e)
  57.         );
  58.  
  59.         $plaintext = str_pad($x->toBytes(), $n->getLengthInBytes(), "\0", STR_PAD_LEFT);
  60.  
  61.         // this is easily prone to failure. if the modulo is a multiple of 2 or 3 or whatever it
  62.         // won't work and you'll get a "failure: error:0906D06C:PEM routines:PEM_read_bio:no start line"
  63.         // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what
  64.         // about odd numbers divisible by 3, by 5, etc?
  65.         if (!openssl_public_encrypt($plaintext, $result, $key, OPENSSL_NO_PADDING)) {
  66.             throw new \UnexpectedValueException(openssl_error_string());
  67.         }
  68.  
  69.         $class = get_class($x);
  70.         return new $class($result, 256);
  71.     }
  72. }
  73.