Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
827 daniel-mar 1
<?php
2
 
3
/**
4
 * OpenSSL Modular Exponentiation Engine
5
 *
6
 * PHP version 5 and 7
7
 *
874 daniel-mar 8
 * @category  Math
9
 * @package   BigInteger
827 daniel-mar 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
 *
874 daniel-mar 24
 * @package Engines
827 daniel-mar 25
 * @author  Jim Wigginton <terrafrost@php.net>
874 daniel-mar 26
 * @access  public
827 daniel-mar 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
}