Subversion Repositories cheapmusic

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
103 - 1
<?php
2
 
3
/**
4
 * Pure-PHP arbitrary precision integer arithmetic library.
5
 *
6
 * Supports base-2, base-10, base-16, and base-256 numbers.  Uses the GMP or BCMath extensions, if available,
7
 * and an internal implementation, otherwise.
8
 *
9
 * PHP version 5
10
 *
11
 * {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the
12
 * {@link self::MODE_INTERNAL self::MODE_INTERNAL} mode)
13
 *
14
 * BigInteger uses base-2**26 to perform operations such as multiplication and division and
15
 * base-2**52 (ie. two base 2**26 digits) to perform addition and subtraction.  Because the largest possible
16
 * value when multiplying two base-2**26 numbers together is a base-2**52 number, double precision floating
17
 * point numbers - numbers that should be supported on most hardware and whose significand is 53 bits - are
18
 * used.  As a consequence, bitwise operators such as >> and << cannot be used, nor can the modulo operator %,
19
 * which only supports integers.  Although this fact will slow this library down, the fact that such a high
20
 * base is being used should more than compensate.
21
 *
22
 * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format.  ie.
23
 * (new \phpseclib\Math\BigInteger(pow(2, 26)))->value = array(0, 1)
24
 *
25
 * Useful resources are as follows:
26
 *
27
 *  - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)}
28
 *  - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)}
29
 *  - Java's BigInteger classes.  See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip
30
 *
31
 * Here's an example of how to use this library:
32
 * <code>
33
 * <?php
34
 *    $a = new \phpseclib\Math\BigInteger(2);
35
 *    $b = new \phpseclib\Math\BigInteger(3);
36
 *
37
 *    $c = $a->add($b);
38
 *
39
 *    echo $c->toString(); // outputs 5
40
 * ?>
41
 * </code>
42
 *
43
 * @category  Math
44
 * @package   BigInteger
45
 * @author    Jim Wigginton <terrafrost@php.net>
46
 * @copyright 2006 Jim Wigginton
47
 * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
48
 * @link      http://pear.php.net/package/Math_BigInteger
49
 */
50
 
51
namespace phpseclib\Math;
52
 
53
use phpseclib\Crypt\Random;
54
 
55
/**
56
 * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256
57
 * numbers.
58
 *
59
 * @package BigInteger
60
 * @author  Jim Wigginton <terrafrost@php.net>
61
 * @access  public
62
 */
63
class BigInteger
64
{
65
    /**#@+
66
     * Reduction constants
67
     *
68
     * @access private
69
     * @see BigInteger::_reduce()
70
     */
71
    /**
72
     * @see BigInteger::_montgomery()
73
     * @see BigInteger::_prepMontgomery()
74
     */
75
    const MONTGOMERY = 0;
76
    /**
77
     * @see BigInteger::_barrett()
78
     */
79
    const BARRETT = 1;
80
    /**
81
     * @see BigInteger::_mod2()
82
     */
83
    const POWEROF2 = 2;
84
    /**
85
     * @see BigInteger::_remainder()
86
     */
87
    const CLASSIC = 3;
88
    /**
89
     * @see BigInteger::__clone()
90
     */
91
    const NONE = 4;
92
    /**#@-*/
93
 
94
    /**#@+
95
     * Array constants
96
     *
97
     * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and
98
     * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them.
99
     *
100
     * @access private
101
    */
102
    /**
103
     * $result[self::VALUE] contains the value.
104
     */
105
    const VALUE = 0;
106
    /**
107
     * $result[self::SIGN] contains the sign.
108
     */
109
    const SIGN = 1;
110
    /**#@-*/
111
 
112
    /**#@+
113
     * @access private
114
     * @see BigInteger::_montgomery()
115
     * @see BigInteger::_barrett()
116
    */
117
    /**
118
     * Cache constants
119
     *
120
     * $cache[self::VARIABLE] tells us whether or not the cached data is still valid.
121
     */
122
    const VARIABLE = 0;
123
    /**
124
     * $cache[self::DATA] contains the cached data.
125
     */
126
    const DATA = 1;
127
    /**#@-*/
128
 
129
    /**#@+
130
     * Mode constants.
131
     *
132
     * @access private
133
     * @see BigInteger::__construct()
134
    */
135
    /**
136
     * To use the pure-PHP implementation
137
     */
138
    const MODE_INTERNAL = 1;
139
    /**
140
     * To use the BCMath library
141
     *
142
     * (if enabled; otherwise, the internal implementation will be used)
143
     */
144
    const MODE_BCMATH = 2;
145
    /**
146
     * To use the GMP library
147
     *
148
     * (if present; otherwise, either the BCMath or the internal implementation will be used)
149
     */
150
    const MODE_GMP = 3;
151
    /**#@-*/
152
 
153
    /**
154
     * Karatsuba Cutoff
155
     *
156
     * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication?
157
     *
158
     * @access private
159
     */
160
    const KARATSUBA_CUTOFF = 25;
161
 
162
    /**#@+
163
     * Static properties used by the pure-PHP implementation.
164
     *
165
     * @see __construct()
166
     */
167
    protected static $base;
168
    protected static $baseFull;
169
    protected static $maxDigit;
170
    protected static $msb;
171
 
172
    /**
173
     * $max10 in greatest $max10Len satisfying
174
     * $max10 = 10**$max10Len <= 2**$base.
175
     */
176
    protected static $max10;
177
 
178
    /**
179
     * $max10Len in greatest $max10Len satisfying
180
     * $max10 = 10**$max10Len <= 2**$base.
181
     */
182
    protected static $max10Len;
183
    protected static $maxDigit2;
184
    /**#@-*/
185
 
186
    /**
187
     * Holds the BigInteger's value.
188
     *
189
     * @var array
190
     * @access private
191
     */
192
    var $value;
193
 
194
    /**
195
     * Holds the BigInteger's magnitude.
196
     *
197
     * @var bool
198
     * @access private
199
     */
200
    var $is_negative = false;
201
 
202
    /**
203
     * Precision
204
     *
205
     * @see self::setPrecision()
206
     * @access private
207
     */
208
    var $precision = -1;
209
 
210
    /**
211
     * Precision Bitmask
212
     *
213
     * @see self::setPrecision()
214
     * @access private
215
     */
216
    var $bitmask = false;
217
 
218
    /**
219
     * Mode independent value used for serialization.
220
     *
221
     * If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for
222
     * a variable that'll be serializable regardless of whether or not extensions are being used.  Unlike $this->value,
223
     * however, $this->hex is only calculated when $this->__sleep() is called.
224
     *
225
     * @see self::__sleep()
226
     * @see self::__wakeup()
227
     * @var string
228
     * @access private
229
     */
230
    var $hex;
231
 
232
    /**
233
     * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers.
234
     *
235
     * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
236
     * two's compliment.  The sole exception to this is -10, which is treated the same as 10 is.
237
     *
238
     * Here's an example:
239
     * <code>
240
     * <?php
241
     *    $a = new \phpseclib\Math\BigInteger('0x32', 16); // 50 in base-16
242
     *
243
     *    echo $a->toString(); // outputs 50
244
     * ?>
245
     * </code>
246
     *
247
     * @param $x base-10 number or base-$base number if $base set.
248
     * @param int $base
249
     * @return \phpseclib\Math\BigInteger
250
     * @access public
251
     */
252
    function __construct($x = 0, $base = 10)
253
    {
254
        if (!defined('MATH_BIGINTEGER_MODE')) {
255
            switch (true) {
256
                case extension_loaded('gmp'):
257
                    define('MATH_BIGINTEGER_MODE', self::MODE_GMP);
258
                    break;
259
                case extension_loaded('bcmath'):
260
                    define('MATH_BIGINTEGER_MODE', self::MODE_BCMATH);
261
                    break;
262
                default:
263
                    define('MATH_BIGINTEGER_MODE', self::MODE_INTERNAL);
264
            }
265
        }
266
 
267
        if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
268
            // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
269
            ob_start();
270
            @phpinfo();
271
            $content = ob_get_contents();
272
            ob_end_clean();
273
 
274
            preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
275
 
276
            $versions = array();
277
            if (!empty($matches[1])) {
278
                for ($i = 0; $i < count($matches[1]); $i++) {
279
                    $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
280
 
281
                    // Remove letter part in OpenSSL version
282
                    if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
283
                        $versions[$matches[1][$i]] = $fullVersion;
284
                    } else {
285
                        $versions[$matches[1][$i]] = $m[0];
286
                    }
287
                }
288
            }
289
 
290
            // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
291
            switch (true) {
292
                case !isset($versions['Header']):
293
                case !isset($versions['Library']):
294
                case $versions['Header'] == $versions['Library']:
295
                case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0:
296
                    define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
297
                    break;
298
                default:
299
                    define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
300
            }
301
        }
302
 
303
        if (!defined('PHP_INT_SIZE')) {
304
            define('PHP_INT_SIZE', 4);
305
        }
306
 
307
        if (empty(self::$base) && MATH_BIGINTEGER_MODE == self::MODE_INTERNAL) {
308
            switch (PHP_INT_SIZE) {
309
                case 8: // use 64-bit integers if int size is 8 bytes
310
                    self::$base      = 31;
311
                    self::$baseFull  = 0x80000000;
312
                    self::$maxDigit  = 0x7FFFFFFF;
313
                    self::$msb       = 0x40000000;
314
                    self::$max10     = 1000000000;
315
                    self::$max10Len  = 9;
316
                    self::$maxDigit2 = pow(2, 62);
317
                    break;
318
                //case 4: // use 64-bit floats if int size is 4 bytes
319
                default:
320
                    self::$base      = 26;
321
                    self::$baseFull  = 0x4000000;
322
                    self::$maxDigit  = 0x3FFFFFF;
323
                    self::$msb       = 0x2000000;
324
                    self::$max10     = 10000000;
325
                    self::$max10Len  = 7;
326
                    self::$maxDigit2 = pow(2, 52); // pow() prevents truncation
327
            }
328
        }
329
 
330
        switch (MATH_BIGINTEGER_MODE) {
331
            case self::MODE_GMP:
332
                switch (true) {
333
                    case is_resource($x) && get_resource_type($x) == 'GMP integer':
334
                    // PHP 5.6 switched GMP from using resources to objects
335
                    case $x instanceof \GMP:
336
                        $this->value = $x;
337
                        return;
338
                }
339
                $this->value = gmp_init(0);
340
                break;
341
            case self::MODE_BCMATH:
342
                $this->value = '0';
343
                break;
344
            default:
345
                $this->value = array();
346
        }
347
 
348
        // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48
349
        // '0' is the only value like this per http://php.net/empty
350
        if (empty($x) && (abs($base) != 256 || $x !== '0')) {
351
            return;
352
        }
353
 
354
        switch ($base) {
355
            case -256:
356
                if (ord($x[0]) & 0x80) {
357
                    $x = ~$x;
358
                    $this->is_negative = true;
359
                }
360
            case 256:
361
                switch (MATH_BIGINTEGER_MODE) {
362
                    case self::MODE_GMP:
363
                        $sign = $this->is_negative ? '-' : '';
364
                        $this->value = gmp_init($sign . '0x' . bin2hex($x));
365
                        break;
366
                    case self::MODE_BCMATH:
367
                        // round $len to the nearest 4 (thanks, DavidMJ!)
368
                        $len = (strlen($x) + 3) & 0xFFFFFFFC;
369
 
370
                        $x = str_pad($x, $len, chr(0), STR_PAD_LEFT);
371
 
372
                        for ($i = 0; $i < $len; $i+= 4) {
373
                            $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32
374
                            $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0);
375
                        }
376
 
377
                        if ($this->is_negative) {
378
                            $this->value = '-' . $this->value;
379
                        }
380
 
381
                        break;
382
                    // converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb)
383
                    default:
384
                        while (strlen($x)) {
385
                            $this->value[] = $this->_bytes2int($this->_base256_rshift($x, self::$base));
386
                        }
387
                }
388
 
389
                if ($this->is_negative) {
390
                    if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
391
                        $this->is_negative = false;
392
                    }
393
                    $temp = $this->add(new static('-1'));
394
                    $this->value = $temp->value;
395
                }
396
                break;
397
            case 16:
398
            case -16:
399
                if ($base > 0 && $x[0] == '-') {
400
                    $this->is_negative = true;
401
                    $x = substr($x, 1);
402
                }
403
 
404
                $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x);
405
 
406
                $is_negative = false;
407
                if ($base < 0 && hexdec($x[0]) >= 8) {
408
                    $this->is_negative = $is_negative = true;
409
                    $x = bin2hex(~pack('H*', $x));
410
                }
411
 
412
                switch (MATH_BIGINTEGER_MODE) {
413
                    case self::MODE_GMP:
414
                        $temp = $this->is_negative ? '-0x' . $x : '0x' . $x;
415
                        $this->value = gmp_init($temp);
416
                        $this->is_negative = false;
417
                        break;
418
                    case self::MODE_BCMATH:
419
                        $x = (strlen($x) & 1) ? '0' . $x : $x;
420
                        $temp = new static(pack('H*', $x), 256);
421
                        $this->value = $this->is_negative ? '-' . $temp->value : $temp->value;
422
                        $this->is_negative = false;
423
                        break;
424
                    default:
425
                        $x = (strlen($x) & 1) ? '0' . $x : $x;
426
                        $temp = new static(pack('H*', $x), 256);
427
                        $this->value = $temp->value;
428
                }
429
 
430
                if ($is_negative) {
431
                    $temp = $this->add(new static('-1'));
432
                    $this->value = $temp->value;
433
                }
434
                break;
435
            case 10:
436
            case -10:
437
                // (?<!^)(?:-).*: find any -'s that aren't at the beginning and then any characters that follow that
438
                // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
439
                // [^-0-9].*: find any non-numeric characters and then any characters that follow that
440
                $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
441
 
442
                switch (MATH_BIGINTEGER_MODE) {
443
                    case self::MODE_GMP:
444
                        $this->value = gmp_init($x);
445
                        break;
446
                    case self::MODE_BCMATH:
447
                        // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different
448
                        // results then doing it on '-1' does (modInverse does $x[0])
449
                        $this->value = $x === '-' ? '0' : (string) $x;
450
                        break;
451
                    default:
452
                        $temp = new static();
453
 
454
                        $multiplier = new static();
455
                        $multiplier->value = array(self::$max10);
456
 
457
                        if ($x[0] == '-') {
458
                            $this->is_negative = true;
459
                            $x = substr($x, 1);
460
                        }
461
 
462
                        $x = str_pad($x, strlen($x) + ((self::$max10Len - 1) * strlen($x)) % self::$max10Len, 0, STR_PAD_LEFT);
463
                        while (strlen($x)) {
464
                            $temp = $temp->multiply($multiplier);
465
                            $temp = $temp->add(new static($this->_int2bytes(substr($x, 0, self::$max10Len)), 256));
466
                            $x = substr($x, self::$max10Len);
467
                        }
468
 
469
                        $this->value = $temp->value;
470
                }
471
                break;
472
            case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
473
            case -2:
474
                if ($base > 0 && $x[0] == '-') {
475
                    $this->is_negative = true;
476
                    $x = substr($x, 1);
477
                }
478
 
479
                $x = preg_replace('#^([01]*).*#', '$1', $x);
480
                $x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT);
481
 
482
                $str = '0x';
483
                while (strlen($x)) {
484
                    $part = substr($x, 0, 4);
485
                    $str.= dechex(bindec($part));
486
                    $x = substr($x, 4);
487
                }
488
 
489
                if ($this->is_negative) {
490
                    $str = '-' . $str;
491
                }
492
 
493
                $temp = new static($str, 8 * $base); // ie. either -16 or +16
494
                $this->value = $temp->value;
495
                $this->is_negative = $temp->is_negative;
496
 
497
                break;
498
            default:
499
                // base not supported, so we'll let $this == 0
500
        }
501
    }
502
 
503
    /**
504
     * Converts a BigInteger to a byte string (eg. base-256).
505
     *
506
     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
507
     * saved as two's compliment.
508
     *
509
     * Here's an example:
510
     * <code>
511
     * <?php
512
     *    $a = new \phpseclib\Math\BigInteger('65');
513
     *
514
     *    echo $a->toBytes(); // outputs chr(65)
515
     * ?>
516
     * </code>
517
     *
518
     * @param bool $twos_compliment
519
     * @return string
520
     * @access public
521
     * @internal Converts a base-2**26 number to base-2**8
522
     */
523
    function toBytes($twos_compliment = false)
524
    {
525
        if ($twos_compliment) {
526
            $comparison = $this->compare(new static());
527
            if ($comparison == 0) {
528
                return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
529
            }
530
 
531
            $temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy();
532
            $bytes = $temp->toBytes();
533
 
534
            if (empty($bytes)) { // eg. if the number we're trying to convert is -1
535
                $bytes = chr(0);
536
            }
537
 
538
            if (ord($bytes[0]) & 0x80) {
539
                $bytes = chr(0) . $bytes;
540
            }
541
 
542
            return $comparison < 0 ? ~$bytes : $bytes;
543
        }
544
 
545
        switch (MATH_BIGINTEGER_MODE) {
546
            case self::MODE_GMP:
547
                if (gmp_cmp($this->value, gmp_init(0)) == 0) {
548
                    return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
549
                }
550
 
551
                $temp = gmp_strval(gmp_abs($this->value), 16);
552
                $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
553
                $temp = pack('H*', $temp);
554
 
555
                return $this->precision > 0 ?
556
                    substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
557
                    ltrim($temp, chr(0));
558
            case self::MODE_BCMATH:
559
                if ($this->value === '0') {
560
                    return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
561
                }
562
 
563
                $value = '';
564
                $current = $this->value;
565
 
566
                if ($current[0] == '-') {
567
                    $current = substr($current, 1);
568
                }
569
 
570
                while (bccomp($current, '0', 0) > 0) {
571
                    $temp = bcmod($current, '16777216');
572
                    $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value;
573
                    $current = bcdiv($current, '16777216', 0);
574
                }
575
 
576
                return $this->precision > 0 ?
577
                    substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
578
                    ltrim($value, chr(0));
579
        }
580
 
581
        if (!count($this->value)) {
582
            return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
583
        }
584
        $result = $this->_int2bytes($this->value[count($this->value) - 1]);
585
 
586
        $temp = $this->copy();
587
 
588
        for ($i = count($temp->value) - 2; $i >= 0; --$i) {
589
            $temp->_base256_lshift($result, self::$base);
590
            $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT);
591
        }
592
 
593
        return $this->precision > 0 ?
594
            str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) :
595
            $result;
596
    }
597
 
598
    /**
599
     * Converts a BigInteger to a hex string (eg. base-16)).
600
     *
601
     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
602
     * saved as two's compliment.
603
     *
604
     * Here's an example:
605
     * <code>
606
     * <?php
607
     *    $a = new \phpseclib\Math\BigInteger('65');
608
     *
609
     *    echo $a->toHex(); // outputs '41'
610
     * ?>
611
     * </code>
612
     *
613
     * @param bool $twos_compliment
614
     * @return string
615
     * @access public
616
     * @internal Converts a base-2**26 number to base-2**8
617
     */
618
    function toHex($twos_compliment = false)
619
    {
620
        return bin2hex($this->toBytes($twos_compliment));
621
    }
622
 
623
    /**
624
     * Converts a BigInteger to a bit string (eg. base-2).
625
     *
626
     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
627
     * saved as two's compliment.
628
     *
629
     * Here's an example:
630
     * <code>
631
     * <?php
632
     *    $a = new \phpseclib\Math\BigInteger('65');
633
     *
634
     *    echo $a->toBits(); // outputs '1000001'
635
     * ?>
636
     * </code>
637
     *
638
     * @param bool $twos_compliment
639
     * @return string
640
     * @access public
641
     * @internal Converts a base-2**26 number to base-2**2
642
     */
643
    function toBits($twos_compliment = false)
644
    {
645
        $hex = $this->toHex($twos_compliment);
646
        $bits = '';
647
        for ($i = strlen($hex) - 8, $start = strlen($hex) & 7; $i >= $start; $i-=8) {
648
            $bits = str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT) . $bits;
649
        }
650
        if ($start) { // hexdec('') == 0
651
            $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8, '0', STR_PAD_LEFT) . $bits;
652
        }
653
        $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0');
654
 
655
        if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) {
656
            return '0' . $result;
657
        }
658
 
659
        return $result;
660
    }
661
 
662
    /**
663
     * Converts a BigInteger to a base-10 number.
664
     *
665
     * Here's an example:
666
     * <code>
667
     * <?php
668
     *    $a = new \phpseclib\Math\BigInteger('50');
669
     *
670
     *    echo $a->toString(); // outputs 50
671
     * ?>
672
     * </code>
673
     *
674
     * @return string
675
     * @access public
676
     * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10)
677
     */
678
    function toString()
679
    {
680
        switch (MATH_BIGINTEGER_MODE) {
681
            case self::MODE_GMP:
682
                return gmp_strval($this->value);
683
            case self::MODE_BCMATH:
684
                if ($this->value === '0') {
685
                    return '0';
686
                }
687
 
688
                return ltrim($this->value, '0');
689
        }
690
 
691
        if (!count($this->value)) {
692
            return '0';
693
        }
694
 
695
        $temp = $this->copy();
696
        $temp->is_negative = false;
697
 
698
        $divisor = new static();
699
        $divisor->value = array(self::$max10);
700
        $result = '';
701
        while (count($temp->value)) {
702
            list($temp, $mod) = $temp->divide($divisor);
703
            $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', self::$max10Len, '0', STR_PAD_LEFT) . $result;
704
        }
705
        $result = ltrim($result, '0');
706
        if (empty($result)) {
707
            $result = '0';
708
        }
709
 
710
        if ($this->is_negative) {
711
            $result = '-' . $result;
712
        }
713
 
714
        return $result;
715
    }
716
 
717
    /**
718
     * Copy an object
719
     *
720
     * PHP5 passes objects by reference while PHP4 passes by value.  As such, we need a function to guarantee
721
     * that all objects are passed by value, when appropriate.  More information can be found here:
722
     *
723
     * {@link http://php.net/language.oop5.basic#51624}
724
     *
725
     * @access public
726
     * @see self::__clone()
727
     * @return \phpseclib\Math\BigInteger
728
     */
729
    function copy()
730
    {
731
        $temp = new static();
732
        $temp->value = $this->value;
733
        $temp->is_negative = $this->is_negative;
734
        $temp->precision = $this->precision;
735
        $temp->bitmask = $this->bitmask;
736
        return $temp;
737
    }
738
 
739
    /**
740
     *  __toString() magic method
741
     *
742
     * Will be called, automatically, if you're supporting just PHP5.  If you're supporting PHP4, you'll need to call
743
     * toString().
744
     *
745
     * @access public
746
     * @internal Implemented per a suggestion by Techie-Michael - thanks!
747
     */
748
    function __toString()
749
    {
750
        return $this->toString();
751
    }
752
 
753
    /**
754
     * __clone() magic method
755
     *
756
     * Although you can call BigInteger::__toString() directly in PHP5, you cannot call BigInteger::__clone() directly
757
     * in PHP5.  You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5
758
     * only syntax of $y = clone $x.  As such, if you're trying to write an application that works on both PHP4 and
759
     * PHP5, call BigInteger::copy(), instead.
760
     *
761
     * @access public
762
     * @see self::copy()
763
     * @return \phpseclib\Math\BigInteger
764
     */
765
    function __clone()
766
    {
767
        return $this->copy();
768
    }
769
 
770
    /**
771
     *  __sleep() magic method
772
     *
773
     * Will be called, automatically, when serialize() is called on a BigInteger object.
774
     *
775
     * @see self::__wakeup()
776
     * @access public
777
     */
778
    function __sleep()
779
    {
780
        $this->hex = $this->toHex(true);
781
        $vars = array('hex');
782
        if ($this->precision > 0) {
783
            $vars[] = 'precision';
784
        }
785
        return $vars;
786
    }
787
 
788
    /**
789
     *  __wakeup() magic method
790
     *
791
     * Will be called, automatically, when unserialize() is called on a BigInteger object.
792
     *
793
     * @see self::__sleep()
794
     * @access public
795
     */
796
    function __wakeup()
797
    {
798
        $temp = new static($this->hex, -16);
799
        $this->value = $temp->value;
800
        $this->is_negative = $temp->is_negative;
801
        if ($this->precision > 0) {
802
            // recalculate $this->bitmask
803
            $this->setPrecision($this->precision);
804
        }
805
    }
806
 
807
    /**
808
     *  __debugInfo() magic method
809
     *
810
     * Will be called, automatically, when print_r() or var_dump() are called
811
     *
812
     * @access public
813
     */
814
    function __debugInfo()
815
    {
816
        $opts = array();
817
        switch (MATH_BIGINTEGER_MODE) {
818
            case self::MODE_GMP:
819
                $engine = 'gmp';
820
                break;
821
            case self::MODE_BCMATH:
822
                $engine = 'bcmath';
823
                break;
824
            case self::MODE_INTERNAL:
825
                $engine = 'internal';
826
                $opts[] = PHP_INT_SIZE == 8 ? '64-bit' : '32-bit';
827
        }
828
        if (MATH_BIGINTEGER_MODE != self::MODE_GMP && defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
829
            $opts[] = 'OpenSSL';
830
        }
831
        if (!empty($opts)) {
832
            $engine.= ' (' . implode($opts, ', ') . ')';
833
        }
834
        return array(
835
            'value' => '0x' . $this->toHex(true),
836
            'engine' => $engine
837
        );
838
    }
839
 
840
    /**
841
     * Adds two BigIntegers.
842
     *
843
     * Here's an example:
844
     * <code>
845
     * <?php
846
     *    $a = new \phpseclib\Math\BigInteger('10');
847
     *    $b = new \phpseclib\Math\BigInteger('20');
848
     *
849
     *    $c = $a->add($b);
850
     *
851
     *    echo $c->toString(); // outputs 30
852
     * ?>
853
     * </code>
854
     *
855
     * @param \phpseclib\Math\BigInteger $y
856
     * @return \phpseclib\Math\BigInteger
857
     * @access public
858
     * @internal Performs base-2**52 addition
859
     */
860
    function add($y)
861
    {
862
        switch (MATH_BIGINTEGER_MODE) {
863
            case self::MODE_GMP:
864
                $temp = new static();
865
                $temp->value = gmp_add($this->value, $y->value);
866
 
867
                return $this->_normalize($temp);
868
            case self::MODE_BCMATH:
869
                $temp = new static();
870
                $temp->value = bcadd($this->value, $y->value, 0);
871
 
872
                return $this->_normalize($temp);
873
        }
874
 
875
        $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative);
876
 
877
        $result = new static();
878
        $result->value = $temp[self::VALUE];
879
        $result->is_negative = $temp[self::SIGN];
880
 
881
        return $this->_normalize($result);
882
    }
883
 
884
    /**
885
     * Performs addition.
886
     *
887
     * @param array $x_value
888
     * @param bool $x_negative
889
     * @param array $y_value
890
     * @param bool $y_negative
891
     * @return array
892
     * @access private
893
     */
894
    function _add($x_value, $x_negative, $y_value, $y_negative)
895
    {
896
        $x_size = count($x_value);
897
        $y_size = count($y_value);
898
 
899
        if ($x_size == 0) {
900
            return array(
901
                self::VALUE => $y_value,
902
                self::SIGN => $y_negative
903
            );
904
        } elseif ($y_size == 0) {
905
            return array(
906
                self::VALUE => $x_value,
907
                self::SIGN => $x_negative
908
            );
909
        }
910
 
911
        // subtract, if appropriate
912
        if ($x_negative != $y_negative) {
913
            if ($x_value == $y_value) {
914
                return array(
915
                    self::VALUE => array(),
916
                    self::SIGN => false
917
                );
918
            }
919
 
920
            $temp = $this->_subtract($x_value, false, $y_value, false);
921
            $temp[self::SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ?
922
                                          $x_negative : $y_negative;
923
 
924
            return $temp;
925
        }
926
 
927
        if ($x_size < $y_size) {
928
            $size = $x_size;
929
            $value = $y_value;
930
        } else {
931
            $size = $y_size;
932
            $value = $x_value;
933
        }
934
 
935
        $value[count($value)] = 0; // just in case the carry adds an extra digit
936
 
937
        $carry = 0;
938
        for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
939
            $sum = $x_value[$j] * self::$baseFull + $x_value[$i] + $y_value[$j] * self::$baseFull + $y_value[$i] + $carry;
940
            $carry = $sum >= self::$maxDigit2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
941
            $sum = $carry ? $sum - self::$maxDigit2 : $sum;
942
 
943
            $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
944
 
945
            $value[$i] = (int) ($sum - self::$baseFull * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)
946
            $value[$j] = $temp;
947
        }
948
 
949
        if ($j == $size) { // ie. if $y_size is odd
950
            $sum = $x_value[$i] + $y_value[$i] + $carry;
951
            $carry = $sum >= self::$baseFull;
952
            $value[$i] = $carry ? $sum - self::$baseFull : $sum;
953
            ++$i; // ie. let $i = $j since we've just done $value[$i]
954
        }
955
 
956
        if ($carry) {
957
            for (; $value[$i] == self::$maxDigit; ++$i) {
958
                $value[$i] = 0;
959
            }
960
            ++$value[$i];
961
        }
962
 
963
        return array(
964
            self::VALUE => $this->_trim($value),
965
            self::SIGN => $x_negative
966
        );
967
    }
968
 
969
    /**
970
     * Subtracts two BigIntegers.
971
     *
972
     * Here's an example:
973
     * <code>
974
     * <?php
975
     *    $a = new \phpseclib\Math\BigInteger('10');
976
     *    $b = new \phpseclib\Math\BigInteger('20');
977
     *
978
     *    $c = $a->subtract($b);
979
     *
980
     *    echo $c->toString(); // outputs -10
981
     * ?>
982
     * </code>
983
     *
984
     * @param \phpseclib\Math\BigInteger $y
985
     * @return \phpseclib\Math\BigInteger
986
     * @access public
987
     * @internal Performs base-2**52 subtraction
988
     */
989
    function subtract($y)
990
    {
991
        switch (MATH_BIGINTEGER_MODE) {
992
            case self::MODE_GMP:
993
                $temp = new static();
994
                $temp->value = gmp_sub($this->value, $y->value);
995
 
996
                return $this->_normalize($temp);
997
            case self::MODE_BCMATH:
998
                $temp = new static();
999
                $temp->value = bcsub($this->value, $y->value, 0);
1000
 
1001
                return $this->_normalize($temp);
1002
        }
1003
 
1004
        $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative);
1005
 
1006
        $result = new static();
1007
        $result->value = $temp[self::VALUE];
1008
        $result->is_negative = $temp[self::SIGN];
1009
 
1010
        return $this->_normalize($result);
1011
    }
1012
 
1013
    /**
1014
     * Performs subtraction.
1015
     *
1016
     * @param array $x_value
1017
     * @param bool $x_negative
1018
     * @param array $y_value
1019
     * @param bool $y_negative
1020
     * @return array
1021
     * @access private
1022
     */
1023
    function _subtract($x_value, $x_negative, $y_value, $y_negative)
1024
    {
1025
        $x_size = count($x_value);
1026
        $y_size = count($y_value);
1027
 
1028
        if ($x_size == 0) {
1029
            return array(
1030
                self::VALUE => $y_value,
1031
                self::SIGN => !$y_negative
1032
            );
1033
        } elseif ($y_size == 0) {
1034
            return array(
1035
                self::VALUE => $x_value,
1036
                self::SIGN => $x_negative
1037
            );
1038
        }
1039
 
1040
        // add, if appropriate (ie. -$x - +$y or +$x - -$y)
1041
        if ($x_negative != $y_negative) {
1042
            $temp = $this->_add($x_value, false, $y_value, false);
1043
            $temp[self::SIGN] = $x_negative;
1044
 
1045
            return $temp;
1046
        }
1047
 
1048
        $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);
1049
 
1050
        if (!$diff) {
1051
            return array(
1052
                self::VALUE => array(),
1053
                self::SIGN => false
1054
            );
1055
        }
1056
 
1057
        // switch $x and $y around, if appropriate.
1058
        if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) {
1059
            $temp = $x_value;
1060
            $x_value = $y_value;
1061
            $y_value = $temp;
1062
 
1063
            $x_negative = !$x_negative;
1064
 
1065
            $x_size = count($x_value);
1066
            $y_size = count($y_value);
1067
        }
1068
 
1069
        // at this point, $x_value should be at least as big as - if not bigger than - $y_value
1070
 
1071
        $carry = 0;
1072
        for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) {
1073
            $sum = $x_value[$j] * self::$baseFull + $x_value[$i] - $y_value[$j] * self::$baseFull - $y_value[$i] - $carry;
1074
            $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
1075
            $sum = $carry ? $sum + self::$maxDigit2 : $sum;
1076
 
1077
            $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
1078
 
1079
            $x_value[$i] = (int) ($sum - self::$baseFull * $temp);
1080
            $x_value[$j] = $temp;
1081
        }
1082
 
1083
        if ($j == $y_size) { // ie. if $y_size is odd
1084
            $sum = $x_value[$i] - $y_value[$i] - $carry;
1085
            $carry = $sum < 0;
1086
            $x_value[$i] = $carry ? $sum + self::$baseFull : $sum;
1087
            ++$i;
1088
        }
1089
 
1090
        if ($carry) {
1091
            for (; !$x_value[$i]; ++$i) {
1092
                $x_value[$i] = self::$maxDigit;
1093
            }
1094
            --$x_value[$i];
1095
        }
1096
 
1097
        return array(
1098
            self::VALUE => $this->_trim($x_value),
1099
            self::SIGN => $x_negative
1100
        );
1101
    }
1102
 
1103
    /**
1104
     * Multiplies two BigIntegers
1105
     *
1106
     * Here's an example:
1107
     * <code>
1108
     * <?php
1109
     *    $a = new \phpseclib\Math\BigInteger('10');
1110
     *    $b = new \phpseclib\Math\BigInteger('20');
1111
     *
1112
     *    $c = $a->multiply($b);
1113
     *
1114
     *    echo $c->toString(); // outputs 200
1115
     * ?>
1116
     * </code>
1117
     *
1118
     * @param \phpseclib\Math\BigInteger $x
1119
     * @return \phpseclib\Math\BigInteger
1120
     * @access public
1121
     */
1122
    function multiply($x)
1123
    {
1124
        switch (MATH_BIGINTEGER_MODE) {
1125
            case self::MODE_GMP:
1126
                $temp = new static();
1127
                $temp->value = gmp_mul($this->value, $x->value);
1128
 
1129
                return $this->_normalize($temp);
1130
            case self::MODE_BCMATH:
1131
                $temp = new static();
1132
                $temp->value = bcmul($this->value, $x->value, 0);
1133
 
1134
                return $this->_normalize($temp);
1135
        }
1136
 
1137
        $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative);
1138
 
1139
        $product = new static();
1140
        $product->value = $temp[self::VALUE];
1141
        $product->is_negative = $temp[self::SIGN];
1142
 
1143
        return $this->_normalize($product);
1144
    }
1145
 
1146
    /**
1147
     * Performs multiplication.
1148
     *
1149
     * @param array $x_value
1150
     * @param bool $x_negative
1151
     * @param array $y_value
1152
     * @param bool $y_negative
1153
     * @return array
1154
     * @access private
1155
     */
1156
    function _multiply($x_value, $x_negative, $y_value, $y_negative)
1157
    {
1158
        //if ( $x_value == $y_value ) {
1159
        //    return array(
1160
        //        self::VALUE => $this->_square($x_value),
1161
        //        self::SIGN => $x_sign != $y_value
1162
        //    );
1163
        //}
1164
 
1165
        $x_length = count($x_value);
1166
        $y_length = count($y_value);
1167
 
1168
        if (!$x_length || !$y_length) { // a 0 is being multiplied
1169
            return array(
1170
                self::VALUE => array(),
1171
                self::SIGN => false
1172
            );
1173
        }
1174
 
1175
        return array(
1176
            self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ?
1177
                $this->_trim($this->_regularMultiply($x_value, $y_value)) :
1178
                $this->_trim($this->_karatsuba($x_value, $y_value)),
1179
            self::SIGN => $x_negative != $y_negative
1180
        );
1181
    }
1182
 
1183
    /**
1184
     * Performs long multiplication on two BigIntegers
1185
     *
1186
     * Modeled after 'multiply' in MutableBigInteger.java.
1187
     *
1188
     * @param array $x_value
1189
     * @param array $y_value
1190
     * @return array
1191
     * @access private
1192
     */
1193
    function _regularMultiply($x_value, $y_value)
1194
    {
1195
        $x_length = count($x_value);
1196
        $y_length = count($y_value);
1197
 
1198
        if (!$x_length || !$y_length) { // a 0 is being multiplied
1199
            return array();
1200
        }
1201
 
1202
        if ($x_length < $y_length) {
1203
            $temp = $x_value;
1204
            $x_value = $y_value;
1205
            $y_value = $temp;
1206
 
1207
            $x_length = count($x_value);
1208
            $y_length = count($y_value);
1209
        }
1210
 
1211
        $product_value = $this->_array_repeat(0, $x_length + $y_length);
1212
 
1213
        // the following for loop could be removed if the for loop following it
1214
        // (the one with nested for loops) initially set $i to 0, but
1215
        // doing so would also make the result in one set of unnecessary adds,
1216
        // since on the outermost loops first pass, $product->value[$k] is going
1217
        // to always be 0
1218
 
1219
        $carry = 0;
1220
 
1221
        for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0
1222
            $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
1223
            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
1224
            $product_value[$j] = (int) ($temp - self::$baseFull * $carry);
1225
        }
1226
 
1227
        $product_value[$j] = $carry;
1228
 
1229
        // the above for loop is what the previous comment was talking about.  the
1230
        // following for loop is the "one with nested for loops"
1231
        for ($i = 1; $i < $y_length; ++$i) {
1232
            $carry = 0;
1233
 
1234
            for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {
1235
                $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
1236
                $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
1237
                $product_value[$k] = (int) ($temp - self::$baseFull * $carry);
1238
            }
1239
 
1240
            $product_value[$k] = $carry;
1241
        }
1242
 
1243
        return $product_value;
1244
    }
1245
 
1246
    /**
1247
     * Performs Karatsuba multiplication on two BigIntegers
1248
     *
1249
     * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
1250
     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}.
1251
     *
1252
     * @param array $x_value
1253
     * @param array $y_value
1254
     * @return array
1255
     * @access private
1256
     */
1257
    function _karatsuba($x_value, $y_value)
1258
    {
1259
        $m = min(count($x_value) >> 1, count($y_value) >> 1);
1260
 
1261
        if ($m < self::KARATSUBA_CUTOFF) {
1262
            return $this->_regularMultiply($x_value, $y_value);
1263
        }
1264
 
1265
        $x1 = array_slice($x_value, $m);
1266
        $x0 = array_slice($x_value, 0, $m);
1267
        $y1 = array_slice($y_value, $m);
1268
        $y0 = array_slice($y_value, 0, $m);
1269
 
1270
        $z2 = $this->_karatsuba($x1, $y1);
1271
        $z0 = $this->_karatsuba($x0, $y0);
1272
 
1273
        $z1 = $this->_add($x1, false, $x0, false);
1274
        $temp = $this->_add($y1, false, $y0, false);
1275
        $z1 = $this->_karatsuba($z1[self::VALUE], $temp[self::VALUE]);
1276
        $temp = $this->_add($z2, false, $z0, false);
1277
        $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false);
1278
 
1279
        $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
1280
        $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]);
1281
 
1282
        $xy = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]);
1283
        $xy = $this->_add($xy[self::VALUE], $xy[self::SIGN], $z0, false);
1284
 
1285
        return $xy[self::VALUE];
1286
    }
1287
 
1288
    /**
1289
     * Performs squaring
1290
     *
1291
     * @param array $x
1292
     * @return array
1293
     * @access private
1294
     */
1295
    function _square($x = false)
1296
    {
1297
        return count($x) < 2 * self::KARATSUBA_CUTOFF ?
1298
            $this->_trim($this->_baseSquare($x)) :
1299
            $this->_trim($this->_karatsubaSquare($x));
1300
    }
1301
 
1302
    /**
1303
     * Performs traditional squaring on two BigIntegers
1304
     *
1305
     * Squaring can be done faster than multiplying a number by itself can be.  See
1306
     * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} /
1307
     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information.
1308
     *
1309
     * @param array $value
1310
     * @return array
1311
     * @access private
1312
     */
1313
    function _baseSquare($value)
1314
    {
1315
        if (empty($value)) {
1316
            return array();
1317
        }
1318
        $square_value = $this->_array_repeat(0, 2 * count($value));
1319
 
1320
        for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) {
1321
            $i2 = $i << 1;
1322
 
1323
            $temp = $square_value[$i2] + $value[$i] * $value[$i];
1324
            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
1325
            $square_value[$i2] = (int) ($temp - self::$baseFull * $carry);
1326
 
1327
            // note how we start from $i+1 instead of 0 as we do in multiplication.
1328
            for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {
1329
                $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;
1330
                $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
1331
                $square_value[$k] = (int) ($temp - self::$baseFull * $carry);
1332
            }
1333
 
1334
            // the following line can yield values larger 2**15.  at this point, PHP should switch
1335
            // over to floats.
1336
            $square_value[$i + $max_index + 1] = $carry;
1337
        }
1338
 
1339
        return $square_value;
1340
    }
1341
 
1342
    /**
1343
     * Performs Karatsuba "squaring" on two BigIntegers
1344
     *
1345
     * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
1346
     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}.
1347
     *
1348
     * @param array $value
1349
     * @return array
1350
     * @access private
1351
     */
1352
    function _karatsubaSquare($value)
1353
    {
1354
        $m = count($value) >> 1;
1355
 
1356
        if ($m < self::KARATSUBA_CUTOFF) {
1357
            return $this->_baseSquare($value);
1358
        }
1359
 
1360
        $x1 = array_slice($value, $m);
1361
        $x0 = array_slice($value, 0, $m);
1362
 
1363
        $z2 = $this->_karatsubaSquare($x1);
1364
        $z0 = $this->_karatsubaSquare($x0);
1365
 
1366
        $z1 = $this->_add($x1, false, $x0, false);
1367
        $z1 = $this->_karatsubaSquare($z1[self::VALUE]);
1368
        $temp = $this->_add($z2, false, $z0, false);
1369
        $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false);
1370
 
1371
        $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
1372
        $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]);
1373
 
1374
        $xx = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]);
1375
        $xx = $this->_add($xx[self::VALUE], $xx[self::SIGN], $z0, false);
1376
 
1377
        return $xx[self::VALUE];
1378
    }
1379
 
1380
    /**
1381
     * Divides two BigIntegers.
1382
     *
1383
     * Returns an array whose first element contains the quotient and whose second element contains the
1384
     * "common residue".  If the remainder would be positive, the "common residue" and the remainder are the
1385
     * same.  If the remainder would be negative, the "common residue" is equal to the sum of the remainder
1386
     * and the divisor (basically, the "common residue" is the first positive modulo).
1387
     *
1388
     * Here's an example:
1389
     * <code>
1390
     * <?php
1391
     *    $a = new \phpseclib\Math\BigInteger('10');
1392
     *    $b = new \phpseclib\Math\BigInteger('20');
1393
     *
1394
     *    list($quotient, $remainder) = $a->divide($b);
1395
     *
1396
     *    echo $quotient->toString(); // outputs 0
1397
     *    echo "\r\n";
1398
     *    echo $remainder->toString(); // outputs 10
1399
     * ?>
1400
     * </code>
1401
     *
1402
     * @param \phpseclib\Math\BigInteger $y
1403
     * @return array
1404
     * @access public
1405
     * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.
1406
     */
1407
    function divide($y)
1408
    {
1409
        switch (MATH_BIGINTEGER_MODE) {
1410
            case self::MODE_GMP:
1411
                $quotient = new static();
1412
                $remainder = new static();
1413
 
1414
                list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
1415
 
1416
                if (gmp_sign($remainder->value) < 0) {
1417
                    $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
1418
                }
1419
 
1420
                return array($this->_normalize($quotient), $this->_normalize($remainder));
1421
            case self::MODE_BCMATH:
1422
                $quotient = new static();
1423
                $remainder = new static();
1424
 
1425
                $quotient->value = bcdiv($this->value, $y->value, 0);
1426
                $remainder->value = bcmod($this->value, $y->value);
1427
 
1428
                if ($remainder->value[0] == '-') {
1429
                    $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);
1430
                }
1431
 
1432
                return array($this->_normalize($quotient), $this->_normalize($remainder));
1433
        }
1434
 
1435
        if (count($y->value) == 1) {
1436
            list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);
1437
            $quotient = new static();
1438
            $remainder = new static();
1439
            $quotient->value = $q;
1440
            $remainder->value = array($r);
1441
            $quotient->is_negative = $this->is_negative != $y->is_negative;
1442
            return array($this->_normalize($quotient), $this->_normalize($remainder));
1443
        }
1444
 
1445
        static $zero;
1446
        if (!isset($zero)) {
1447
            $zero = new static();
1448
        }
1449
 
1450
        $x = $this->copy();
1451
        $y = $y->copy();
1452
 
1453
        $x_sign = $x->is_negative;
1454
        $y_sign = $y->is_negative;
1455
 
1456
        $x->is_negative = $y->is_negative = false;
1457
 
1458
        $diff = $x->compare($y);
1459
 
1460
        if (!$diff) {
1461
            $temp = new static();
1462
            $temp->value = array(1);
1463
            $temp->is_negative = $x_sign != $y_sign;
1464
            return array($this->_normalize($temp), $this->_normalize(new static()));
1465
        }
1466
 
1467
        if ($diff < 0) {
1468
            // if $x is negative, "add" $y.
1469
            if ($x_sign) {
1470
                $x = $y->subtract($x);
1471
            }
1472
            return array($this->_normalize(new static()), $this->_normalize($x));
1473
        }
1474
 
1475
        // normalize $x and $y as described in HAC 14.23 / 14.24
1476
        $msb = $y->value[count($y->value) - 1];
1477
        for ($shift = 0; !($msb & self::$msb); ++$shift) {
1478
            $msb <<= 1;
1479
        }
1480
        $x->_lshift($shift);
1481
        $y->_lshift($shift);
1482
        $y_value = &$y->value;
1483
 
1484
        $x_max = count($x->value) - 1;
1485
        $y_max = count($y->value) - 1;
1486
 
1487
        $quotient = new static();
1488
        $quotient_value = &$quotient->value;
1489
        $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);
1490
 
1491
        static $temp, $lhs, $rhs;
1492
        if (!isset($temp)) {
1493
            $temp = new static();
1494
            $lhs =  new static();
1495
            $rhs =  new static();
1496
        }
1497
        $temp_value = &$temp->value;
1498
        $rhs_value =  &$rhs->value;
1499
 
1500
        // $temp = $y << ($x_max - $y_max-1) in base 2**26
1501
        $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
1502
 
1503
        while ($x->compare($temp) >= 0) {
1504
            // calculate the "common residue"
1505
            ++$quotient_value[$x_max - $y_max];
1506
            $x = $x->subtract($temp);
1507
            $x_max = count($x->value) - 1;
1508
        }
1509
 
1510
        for ($i = $x_max; $i >= $y_max + 1; --$i) {
1511
            $x_value = &$x->value;
1512
            $x_window = array(
1513
                isset($x_value[$i]) ? $x_value[$i] : 0,
1514
                isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0,
1515
                isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0
1516
            );
1517
            $y_window = array(
1518
                $y_value[$y_max],
1519
                ($y_max > 0) ? $y_value[$y_max - 1] : 0
1520
            );
1521
 
1522
            $q_index = $i - $y_max - 1;
1523
            if ($x_window[0] == $y_window[0]) {
1524
                $quotient_value[$q_index] = self::$maxDigit;
1525
            } else {
1526
                $quotient_value[$q_index] = $this->_safe_divide(
1527
                    $x_window[0] * self::$baseFull + $x_window[1],
1528
                    $y_window[0]
1529
                );
1530
            }
1531
 
1532
            $temp_value = array($y_window[1], $y_window[0]);
1533
 
1534
            $lhs->value = array($quotient_value[$q_index]);
1535
            $lhs = $lhs->multiply($temp);
1536
 
1537
            $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
1538
 
1539
            while ($lhs->compare($rhs) > 0) {
1540
                --$quotient_value[$q_index];
1541
 
1542
                $lhs->value = array($quotient_value[$q_index]);
1543
                $lhs = $lhs->multiply($temp);
1544
            }
1545
 
1546
            $adjust = $this->_array_repeat(0, $q_index);
1547
            $temp_value = array($quotient_value[$q_index]);
1548
            $temp = $temp->multiply($y);
1549
            $temp_value = &$temp->value;
1550
            $temp_value = array_merge($adjust, $temp_value);
1551
 
1552
            $x = $x->subtract($temp);
1553
 
1554
            if ($x->compare($zero) < 0) {
1555
                $temp_value = array_merge($adjust, $y_value);
1556
                $x = $x->add($temp);
1557
 
1558
                --$quotient_value[$q_index];
1559
            }
1560
 
1561
            $x_max = count($x_value) - 1;
1562
        }
1563
 
1564
        // unnormalize the remainder
1565
        $x->_rshift($shift);
1566
 
1567
        $quotient->is_negative = $x_sign != $y_sign;
1568
 
1569
        // calculate the "common residue", if appropriate
1570
        if ($x_sign) {
1571
            $y->_rshift($shift);
1572
            $x = $y->subtract($x);
1573
        }
1574
 
1575
        return array($this->_normalize($quotient), $this->_normalize($x));
1576
    }
1577
 
1578
    /**
1579
     * Divides a BigInteger by a regular integer
1580
     *
1581
     * abc / x = a00 / x + b0 / x + c / x
1582
     *
1583
     * @param array $dividend
1584
     * @param array $divisor
1585
     * @return array
1586
     * @access private
1587
     */
1588
    function _divide_digit($dividend, $divisor)
1589
    {
1590
        $carry = 0;
1591
        $result = array();
1592
 
1593
        for ($i = count($dividend) - 1; $i >= 0; --$i) {
1594
            $temp = self::$baseFull * $carry + $dividend[$i];
1595
            $result[$i] = $this->_safe_divide($temp, $divisor);
1596
            $carry = (int) ($temp - $divisor * $result[$i]);
1597
        }
1598
 
1599
        return array($result, $carry);
1600
    }
1601
 
1602
    /**
1603
     * Performs modular exponentiation.
1604
     *
1605
     * Here's an example:
1606
     * <code>
1607
     * <?php
1608
     *    $a = new \phpseclib\Math\BigInteger('10');
1609
     *    $b = new \phpseclib\Math\BigInteger('20');
1610
     *    $c = new \phpseclib\Math\BigInteger('30');
1611
     *
1612
     *    $c = $a->modPow($b, $c);
1613
     *
1614
     *    echo $c->toString(); // outputs 10
1615
     * ?>
1616
     * </code>
1617
     *
1618
     * @param \phpseclib\Math\BigInteger $e
1619
     * @param \phpseclib\Math\BigInteger $n
1620
     * @return \phpseclib\Math\BigInteger
1621
     * @access public
1622
     * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
1623
     *    and although the approach involving repeated squaring does vastly better, it, too, is impractical
1624
     *    for our purposes.  The reason being that division - by far the most complicated and time-consuming
1625
     *    of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
1626
     *
1627
     *    Modular reductions resolve this issue.  Although an individual modular reduction takes more time
1628
     *    then an individual division, when performed in succession (with the same modulo), they're a lot faster.
1629
     *
1630
     *    The two most commonly used modular reductions are Barrett and Montgomery reduction.  Montgomery reduction,
1631
     *    although faster, only works when the gcd of the modulo and of the base being used is 1.  In RSA, when the
1632
     *    base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
1633
     *    the product of two odd numbers is odd), but what about when RSA isn't used?
1634
     *
1635
     *    In contrast, Barrett reduction has no such constraint.  As such, some bigint implementations perform a
1636
     *    Barrett reduction after every operation in the modpow function.  Others perform Barrett reductions when the
1637
     *    modulo is even and Montgomery reductions when the modulo is odd.  BigInteger.java's modPow method, however,
1638
     *    uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
1639
     *    the other, a power of two - and recombine them, later.  This is the method that this modPow function uses.
1640
     *    {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
1641
     */
1642
    function modPow($e, $n)
1643
    {
1644
        $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();
1645
 
1646
        if ($e->compare(new static()) < 0) {
1647
            $e = $e->abs();
1648
 
1649
            $temp = $this->modInverse($n);
1650
            if ($temp === false) {
1651
                return false;
1652
            }
1653
 
1654
            return $this->_normalize($temp->modPow($e, $n));
1655
        }
1656
 
1657
        if (MATH_BIGINTEGER_MODE == self::MODE_GMP) {
1658
            $temp = new static();
1659
            $temp->value = gmp_powm($this->value, $e->value, $n->value);
1660
 
1661
            return $this->_normalize($temp);
1662
        }
1663
 
1664
        if ($this->compare(new static()) < 0 || $this->compare($n) > 0) {
1665
            list(, $temp) = $this->divide($n);
1666
            return $temp->modPow($e, $n);
1667
        }
1668
 
1669
        if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
1670
            $components = array(
1671
                'modulus' => $n->toBytes(true),
1672
                'publicExponent' => $e->toBytes(true)
1673
            );
1674
 
1675
            $components = array(
1676
                'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']),
1677
                'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent'])
1678
            );
1679
 
1680
            $RSAPublicKey = pack(
1681
                'Ca*a*a*',
1682
                48,
1683
                $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
1684
                $components['modulus'],
1685
                $components['publicExponent']
1686
            );
1687
 
1688
            $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
1689
            $RSAPublicKey = chr(0) . $RSAPublicKey;
1690
            $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
1691
 
1692
            $encapsulated = pack(
1693
                'Ca*a*',
1694
                48,
1695
                $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)),
1696
                $rsaOID . $RSAPublicKey
1697
            );
1698
 
1699
            $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
1700
                             chunk_split(base64_encode($encapsulated)) .
1701
                             '-----END PUBLIC KEY-----';
1702
 
1703
            $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT);
1704
 
1705
            if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) {
1706
                return new static($result, 256);
1707
            }
1708
        }
1709
 
1710
        if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
1711
            $temp = new static();
1712
            $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
1713
 
1714
            return $this->_normalize($temp);
1715
        }
1716
 
1717
        if (empty($e->value)) {
1718
            $temp = new static();
1719
            $temp->value = array(1);
1720
            return $this->_normalize($temp);
1721
        }
1722
 
1723
        if ($e->value == array(1)) {
1724
            list(, $temp) = $this->divide($n);
1725
            return $this->_normalize($temp);
1726
        }
1727
 
1728
        if ($e->value == array(2)) {
1729
            $temp = new static();
1730
            $temp->value = $this->_square($this->value);
1731
            list(, $temp) = $temp->divide($n);
1732
            return $this->_normalize($temp);
1733
        }
1734
 
1735
        return $this->_normalize($this->_slidingWindow($e, $n, self::BARRETT));
1736
 
1737
        // the following code, although not callable, can be run independently of the above code
1738
        // although the above code performed better in my benchmarks the following could might
1739
        // perform better under different circumstances. in lieu of deleting it it's just been
1740
        // made uncallable
1741
 
1742
        // is the modulo odd?
1743
        if ($n->value[0] & 1) {
1744
            return $this->_normalize($this->_slidingWindow($e, $n, self::MONTGOMERY));
1745
        }
1746
        // if it's not, it's even
1747
 
1748
        // find the lowest set bit (eg. the max pow of 2 that divides $n)
1749
        for ($i = 0; $i < count($n->value); ++$i) {
1750
            if ($n->value[$i]) {
1751
                $temp = decbin($n->value[$i]);
1752
                $j = strlen($temp) - strrpos($temp, '1') - 1;
1753
                $j+= 26 * $i;
1754
                break;
1755
            }
1756
        }
1757
        // at this point, 2^$j * $n/(2^$j) == $n
1758
 
1759
        $mod1 = $n->copy();
1760
        $mod1->_rshift($j);
1761
        $mod2 = new static();
1762
        $mod2->value = array(1);
1763
        $mod2->_lshift($j);
1764
 
1765
        $part1 = ($mod1->value != array(1)) ? $this->_slidingWindow($e, $mod1, self::MONTGOMERY) : new static();
1766
        $part2 = $this->_slidingWindow($e, $mod2, self::POWEROF2);
1767
 
1768
        $y1 = $mod2->modInverse($mod1);
1769
        $y2 = $mod1->modInverse($mod2);
1770
 
1771
        $result = $part1->multiply($mod2);
1772
        $result = $result->multiply($y1);
1773
 
1774
        $temp = $part2->multiply($mod1);
1775
        $temp = $temp->multiply($y2);
1776
 
1777
        $result = $result->add($temp);
1778
        list(, $result) = $result->divide($n);
1779
 
1780
        return $this->_normalize($result);
1781
    }
1782
 
1783
    /**
1784
     * Performs modular exponentiation.
1785
     *
1786
     * Alias for modPow().
1787
     *
1788
     * @param \phpseclib\Math\BigInteger $e
1789
     * @param \phpseclib\Math\BigInteger $n
1790
     * @return \phpseclib\Math\BigInteger
1791
     * @access public
1792
     */
1793
    function powMod($e, $n)
1794
    {
1795
        return $this->modPow($e, $n);
1796
    }
1797
 
1798
    /**
1799
     * Sliding Window k-ary Modular Exponentiation
1800
     *
1801
     * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} /
1802
     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}.  In a departure from those algorithims,
1803
     * however, this function performs a modular reduction after every multiplication and squaring operation.
1804
     * As such, this function has the same preconditions that the reductions being used do.
1805
     *
1806
     * @param \phpseclib\Math\BigInteger $e
1807
     * @param \phpseclib\Math\BigInteger $n
1808
     * @param int $mode
1809
     * @return \phpseclib\Math\BigInteger
1810
     * @access private
1811
     */
1812
    function _slidingWindow($e, $n, $mode)
1813
    {
1814
        static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function
1815
        //static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1
1816
 
1817
        $e_value = $e->value;
1818
        $e_length = count($e_value) - 1;
1819
        $e_bits = decbin($e_value[$e_length]);
1820
        for ($i = $e_length - 1; $i >= 0; --$i) {
1821
            $e_bits.= str_pad(decbin($e_value[$i]), self::$base, '0', STR_PAD_LEFT);
1822
        }
1823
 
1824
        $e_length = strlen($e_bits);
1825
 
1826
        // calculate the appropriate window size.
1827
        // $window_size == 3 if $window_ranges is between 25 and 81, for example.
1828
        for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) {
1829
        }
1830
 
1831
        $n_value = $n->value;
1832
 
1833
        // precompute $this^0 through $this^$window_size
1834
        $powers = array();
1835
        $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode);
1836
        $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode);
1837
 
1838
        // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end
1839
        // in a 1.  ie. it's supposed to be odd.
1840
        $temp = 1 << ($window_size - 1);
1841
        for ($i = 1; $i < $temp; ++$i) {
1842
            $i2 = $i << 1;
1843
            $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode);
1844
        }
1845
 
1846
        $result = array(1);
1847
        $result = $this->_prepareReduce($result, $n_value, $mode);
1848
 
1849
        for ($i = 0; $i < $e_length;) {
1850
            if (!$e_bits[$i]) {
1851
                $result = $this->_squareReduce($result, $n_value, $mode);
1852
                ++$i;
1853
            } else {
1854
                for ($j = $window_size - 1; $j > 0; --$j) {
1855
                    if (!empty($e_bits[$i + $j])) {
1856
                        break;
1857
                    }
1858
                }
1859
 
1860
                // eg. the length of substr($e_bits, $i, $j + 1)
1861
                for ($k = 0; $k <= $j; ++$k) {
1862
                    $result = $this->_squareReduce($result, $n_value, $mode);
1863
                }
1864
 
1865
                $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode);
1866
 
1867
                $i += $j + 1;
1868
            }
1869
        }
1870
 
1871
        $temp = new static();
1872
        $temp->value = $this->_reduce($result, $n_value, $mode);
1873
 
1874
        return $temp;
1875
    }
1876
 
1877
    /**
1878
     * Modular reduction
1879
     *
1880
     * For most $modes this will return the remainder.
1881
     *
1882
     * @see self::_slidingWindow()
1883
     * @access private
1884
     * @param array $x
1885
     * @param array $n
1886
     * @param int $mode
1887
     * @return array
1888
     */
1889
    function _reduce($x, $n, $mode)
1890
    {
1891
        switch ($mode) {
1892
            case self::MONTGOMERY:
1893
                return $this->_montgomery($x, $n);
1894
            case self::BARRETT:
1895
                return $this->_barrett($x, $n);
1896
            case self::POWEROF2:
1897
                $lhs = new static();
1898
                $lhs->value = $x;
1899
                $rhs = new static();
1900
                $rhs->value = $n;
1901
                return $x->_mod2($n);
1902
            case self::CLASSIC:
1903
                $lhs = new static();
1904
                $lhs->value = $x;
1905
                $rhs = new static();
1906
                $rhs->value = $n;
1907
                list(, $temp) = $lhs->divide($rhs);
1908
                return $temp->value;
1909
            case self::NONE:
1910
                return $x;
1911
            default:
1912
                // an invalid $mode was provided
1913
        }
1914
    }
1915
 
1916
    /**
1917
     * Modular reduction preperation
1918
     *
1919
     * @see self::_slidingWindow()
1920
     * @access private
1921
     * @param array $x
1922
     * @param array $n
1923
     * @param int $mode
1924
     * @return array
1925
     */
1926
    function _prepareReduce($x, $n, $mode)
1927
    {
1928
        if ($mode == self::MONTGOMERY) {
1929
            return $this->_prepMontgomery($x, $n);
1930
        }
1931
        return $this->_reduce($x, $n, $mode);
1932
    }
1933
 
1934
    /**
1935
     * Modular multiply
1936
     *
1937
     * @see self::_slidingWindow()
1938
     * @access private
1939
     * @param array $x
1940
     * @param array $y
1941
     * @param array $n
1942
     * @param int $mode
1943
     * @return array
1944
     */
1945
    function _multiplyReduce($x, $y, $n, $mode)
1946
    {
1947
        if ($mode == self::MONTGOMERY) {
1948
            return $this->_montgomeryMultiply($x, $y, $n);
1949
        }
1950
        $temp = $this->_multiply($x, false, $y, false);
1951
        return $this->_reduce($temp[self::VALUE], $n, $mode);
1952
    }
1953
 
1954
    /**
1955
     * Modular square
1956
     *
1957
     * @see self::_slidingWindow()
1958
     * @access private
1959
     * @param array $x
1960
     * @param array $n
1961
     * @param int $mode
1962
     * @return array
1963
     */
1964
    function _squareReduce($x, $n, $mode)
1965
    {
1966
        if ($mode == self::MONTGOMERY) {
1967
            return $this->_montgomeryMultiply($x, $x, $n);
1968
        }
1969
        return $this->_reduce($this->_square($x), $n, $mode);
1970
    }
1971
 
1972
    /**
1973
     * Modulos for Powers of Two
1974
     *
1975
     * Calculates $x%$n, where $n = 2**$e, for some $e.  Since this is basically the same as doing $x & ($n-1),
1976
     * we'll just use this function as a wrapper for doing that.
1977
     *
1978
     * @see self::_slidingWindow()
1979
     * @access private
1980
     * @param \phpseclib\Math\BigInteger
1981
     * @return \phpseclib\Math\BigInteger
1982
     */
1983
    function _mod2($n)
1984
    {
1985
        $temp = new static();
1986
        $temp->value = array(1);
1987
        return $this->bitwise_and($n->subtract($temp));
1988
    }
1989
 
1990
    /**
1991
     * Barrett Modular Reduction
1992
     *
1993
     * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} /
1994
     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information.  Modified slightly,
1995
     * so as not to require negative numbers (initially, this script didn't support negative numbers).
1996
     *
1997
     * Employs "folding", as described at
1998
     * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}.  To quote from
1999
     * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x."
2000
     *
2001
     * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that
2002
     * usable on account of (1) its not using reasonable radix points as discussed in
2003
     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable
2004
     * radix points, it only works when there are an even number of digits in the denominator.  The reason for (2) is that
2005
     * (x >> 1) + (x >> 1) != x / 2 + x / 2.  If x is even, they're the same, but if x is odd, they're not.  See the in-line
2006
     * comments for details.
2007
     *
2008
     * @see self::_slidingWindow()
2009
     * @access private
2010
     * @param array $n
2011
     * @param array $m
2012
     * @return array
2013
     */
2014
    function _barrett($n, $m)
2015
    {
2016
        static $cache = array(
2017
            self::VARIABLE => array(),
2018
            self::DATA => array()
2019
        );
2020
 
2021
        $m_length = count($m);
2022
 
2023
        // if ($this->_compare($n, $this->_square($m)) >= 0) {
2024
        if (count($n) > 2 * $m_length) {
2025
            $lhs = new static();
2026
            $rhs = new static();
2027
            $lhs->value = $n;
2028
            $rhs->value = $m;
2029
            list(, $temp) = $lhs->divide($rhs);
2030
            return $temp->value;
2031
        }
2032
 
2033
        // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced
2034
        if ($m_length < 5) {
2035
            return $this->_regularBarrett($n, $m);
2036
        }
2037
 
2038
        // n = 2 * m.length
2039
 
2040
        if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
2041
            $key = count($cache[self::VARIABLE]);
2042
            $cache[self::VARIABLE][] = $m;
2043
 
2044
            $lhs = new static();
2045
            $lhs_value = &$lhs->value;
2046
            $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1));
2047
            $lhs_value[] = 1;
2048
            $rhs = new static();
2049
            $rhs->value = $m;
2050
 
2051
            list($u, $m1) = $lhs->divide($rhs);
2052
            $u = $u->value;
2053
            $m1 = $m1->value;
2054
 
2055
            $cache[self::DATA][] = array(
2056
                'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1)
2057
                'm1'=> $m1 // m.length
2058
            );
2059
        } else {
2060
            extract($cache[self::DATA][$key]);
2061
        }
2062
 
2063
        $cutoff = $m_length + ($m_length >> 1);
2064
        $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1)
2065
        $msd = array_slice($n, $cutoff);    // m.length >> 1
2066
        $lsd = $this->_trim($lsd);
2067
        $temp = $this->_multiply($msd, false, $m1, false);
2068
        $n = $this->_add($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1
2069
 
2070
        if ($m_length & 1) {
2071
            return $this->_regularBarrett($n[self::VALUE], $m);
2072
        }
2073
 
2074
        // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2
2075
        $temp = array_slice($n[self::VALUE], $m_length - 1);
2076
        // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2
2077
        // if odd:  ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1
2078
        $temp = $this->_multiply($temp, false, $u, false);
2079
        // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1
2080
        // if odd:  (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1)
2081
        $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1);
2082
        // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1
2083
        // if odd:  (m.length - (m.length >> 1)) + m.length     = 2 * m.length - (m.length >> 1)
2084
        $temp = $this->_multiply($temp, false, $m, false);
2085
 
2086
        // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit
2087
        // number from a m.length + (m.length >> 1) + 1 digit number.  ie. there'd be an extra digit and the while loop
2088
        // following this comment would loop a lot (hence our calling _regularBarrett() in that situation).
2089
 
2090
        $result = $this->_subtract($n[self::VALUE], false, $temp[self::VALUE], false);
2091
 
2092
        while ($this->_compare($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) {
2093
            $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $m, false);
2094
        }
2095
 
2096
        return $result[self::VALUE];
2097
    }
2098
 
2099
    /**
2100
     * (Regular) Barrett Modular Reduction
2101
     *
2102
     * For numbers with more than four digits BigInteger::_barrett() is faster.  The difference between that and this
2103
     * is that this function does not fold the denominator into a smaller form.
2104
     *
2105
     * @see self::_slidingWindow()
2106
     * @access private
2107
     * @param array $x
2108
     * @param array $n
2109
     * @return array
2110
     */
2111
    function _regularBarrett($x, $n)
2112
    {
2113
        static $cache = array(
2114
            self::VARIABLE => array(),
2115
            self::DATA => array()
2116
        );
2117
 
2118
        $n_length = count($n);
2119
 
2120
        if (count($x) > 2 * $n_length) {
2121
            $lhs = new static();
2122
            $rhs = new static();
2123
            $lhs->value = $x;
2124
            $rhs->value = $n;
2125
            list(, $temp) = $lhs->divide($rhs);
2126
            return $temp->value;
2127
        }
2128
 
2129
        if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
2130
            $key = count($cache[self::VARIABLE]);
2131
            $cache[self::VARIABLE][] = $n;
2132
            $lhs = new static();
2133
            $lhs_value = &$lhs->value;
2134
            $lhs_value = $this->_array_repeat(0, 2 * $n_length);
2135
            $lhs_value[] = 1;
2136
            $rhs = new static();
2137
            $rhs->value = $n;
2138
            list($temp, ) = $lhs->divide($rhs); // m.length
2139
            $cache[self::DATA][] = $temp->value;
2140
        }
2141
 
2142
        // 2 * m.length - (m.length - 1) = m.length + 1
2143
        $temp = array_slice($x, $n_length - 1);
2144
        // (m.length + 1) + m.length = 2 * m.length + 1
2145
        $temp = $this->_multiply($temp, false, $cache[self::DATA][$key], false);
2146
        // (2 * m.length + 1) - (m.length - 1) = m.length + 2
2147
        $temp = array_slice($temp[self::VALUE], $n_length + 1);
2148
 
2149
        // m.length + 1
2150
        $result = array_slice($x, 0, $n_length + 1);
2151
        // m.length + 1
2152
        $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1);
2153
        // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1)
2154
 
2155
        if ($this->_compare($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) {
2156
            $corrector_value = $this->_array_repeat(0, $n_length + 1);
2157
            $corrector_value[count($corrector_value)] = 1;
2158
            $result = $this->_add($result, false, $corrector_value, false);
2159
            $result = $result[self::VALUE];
2160
        }
2161
 
2162
        // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits
2163
        $result = $this->_subtract($result, false, $temp[self::VALUE], $temp[self::SIGN]);
2164
        while ($this->_compare($result[self::VALUE], $result[self::SIGN], $n, false) > 0) {
2165
            $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $n, false);
2166
        }
2167
 
2168
        return $result[self::VALUE];
2169
    }
2170
 
2171
    /**
2172
     * Performs long multiplication up to $stop digits
2173
     *
2174
     * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved.
2175
     *
2176
     * @see self::_regularBarrett()
2177
     * @param array $x_value
2178
     * @param bool $x_negative
2179
     * @param array $y_value
2180
     * @param bool $y_negative
2181
     * @param int $stop
2182
     * @return array
2183
     * @access private
2184
     */
2185
    function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop)
2186
    {
2187
        $x_length = count($x_value);
2188
        $y_length = count($y_value);
2189
 
2190
        if (!$x_length || !$y_length) { // a 0 is being multiplied
2191
            return array(
2192
                self::VALUE => array(),
2193
                self::SIGN => false
2194
            );
2195
        }
2196
 
2197
        if ($x_length < $y_length) {
2198
            $temp = $x_value;
2199
            $x_value = $y_value;
2200
            $y_value = $temp;
2201
 
2202
            $x_length = count($x_value);
2203
            $y_length = count($y_value);
2204
        }
2205
 
2206
        $product_value = $this->_array_repeat(0, $x_length + $y_length);
2207
 
2208
        // the following for loop could be removed if the for loop following it
2209
        // (the one with nested for loops) initially set $i to 0, but
2210
        // doing so would also make the result in one set of unnecessary adds,
2211
        // since on the outermost loops first pass, $product->value[$k] is going
2212
        // to always be 0
2213
 
2214
        $carry = 0;
2215
 
2216
        for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i
2217
            $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
2218
            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
2219
            $product_value[$j] = (int) ($temp - self::$baseFull * $carry);
2220
        }
2221
 
2222
        if ($j < $stop) {
2223
            $product_value[$j] = $carry;
2224
        }
2225
 
2226
        // the above for loop is what the previous comment was talking about.  the
2227
        // following for loop is the "one with nested for loops"
2228
 
2229
        for ($i = 1; $i < $y_length; ++$i) {
2230
            $carry = 0;
2231
 
2232
            for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {
2233
                $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
2234
                $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
2235
                $product_value[$k] = (int) ($temp - self::$baseFull * $carry);
2236
            }
2237
 
2238
            if ($k < $stop) {
2239
                $product_value[$k] = $carry;
2240
            }
2241
        }
2242
 
2243
        return array(
2244
            self::VALUE => $this->_trim($product_value),
2245
            self::SIGN => $x_negative != $y_negative
2246
        );
2247
    }
2248
 
2249
    /**
2250
     * Montgomery Modular Reduction
2251
     *
2252
     * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n.
2253
     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be
2254
     * improved upon (basically, by using the comba method).  gcd($n, 2) must be equal to one for this function
2255
     * to work correctly.
2256
     *
2257
     * @see self::_prepMontgomery()
2258
     * @see self::_slidingWindow()
2259
     * @access private
2260
     * @param array $x
2261
     * @param array $n
2262
     * @return array
2263
     */
2264
    function _montgomery($x, $n)
2265
    {
2266
        static $cache = array(
2267
            self::VARIABLE => array(),
2268
            self::DATA => array()
2269
        );
2270
 
2271
        if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
2272
            $key = count($cache[self::VARIABLE]);
2273
            $cache[self::VARIABLE][] = $x;
2274
            $cache[self::DATA][] = $this->_modInverse67108864($n);
2275
        }
2276
 
2277
        $k = count($n);
2278
 
2279
        $result = array(self::VALUE => $x);
2280
 
2281
        for ($i = 0; $i < $k; ++$i) {
2282
            $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key];
2283
            $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
2284
            $temp = $this->_regularMultiply(array($temp), $n);
2285
            $temp = array_merge($this->_array_repeat(0, $i), $temp);
2286
            $result = $this->_add($result[self::VALUE], false, $temp, false);
2287
        }
2288
 
2289
        $result[self::VALUE] = array_slice($result[self::VALUE], $k);
2290
 
2291
        if ($this->_compare($result, false, $n, false) >= 0) {
2292
            $result = $this->_subtract($result[self::VALUE], false, $n, false);
2293
        }
2294
 
2295
        return $result[self::VALUE];
2296
    }
2297
 
2298
    /**
2299
     * Montgomery Multiply
2300
     *
2301
     * Interleaves the montgomery reduction and long multiplication algorithms together as described in
2302
     * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36}
2303
     *
2304
     * @see self::_prepMontgomery()
2305
     * @see self::_montgomery()
2306
     * @access private
2307
     * @param array $x
2308
     * @param array $y
2309
     * @param array $m
2310
     * @return array
2311
     */
2312
    function _montgomeryMultiply($x, $y, $m)
2313
    {
2314
        $temp = $this->_multiply($x, false, $y, false);
2315
        return $this->_montgomery($temp[self::VALUE], $m);
2316
 
2317
        // the following code, although not callable, can be run independently of the above code
2318
        // although the above code performed better in my benchmarks the following could might
2319
        // perform better under different circumstances. in lieu of deleting it it's just been
2320
        // made uncallable
2321
 
2322
        static $cache = array(
2323
            self::VARIABLE => array(),
2324
            self::DATA => array()
2325
        );
2326
 
2327
        if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
2328
            $key = count($cache[self::VARIABLE]);
2329
            $cache[self::VARIABLE][] = $m;
2330
            $cache[self::DATA][] = $this->_modInverse67108864($m);
2331
        }
2332
 
2333
        $n = max(count($x), count($y), count($m));
2334
        $x = array_pad($x, $n, 0);
2335
        $y = array_pad($y, $n, 0);
2336
        $m = array_pad($m, $n, 0);
2337
        $a = array(self::VALUE => $this->_array_repeat(0, $n + 1));
2338
        for ($i = 0; $i < $n; ++$i) {
2339
            $temp = $a[self::VALUE][0] + $x[$i] * $y[0];
2340
            $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
2341
            $temp = $temp * $cache[self::DATA][$key];
2342
            $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
2343
            $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false);
2344
            $a = $this->_add($a[self::VALUE], false, $temp[self::VALUE], false);
2345
            $a[self::VALUE] = array_slice($a[self::VALUE], 1);
2346
        }
2347
        if ($this->_compare($a[self::VALUE], false, $m, false) >= 0) {
2348
            $a = $this->_subtract($a[self::VALUE], false, $m, false);
2349
        }
2350
        return $a[self::VALUE];
2351
    }
2352
 
2353
    /**
2354
     * Prepare a number for use in Montgomery Modular Reductions
2355
     *
2356
     * @see self::_montgomery()
2357
     * @see self::_slidingWindow()
2358
     * @access private
2359
     * @param array $x
2360
     * @param array $n
2361
     * @return array
2362
     */
2363
    function _prepMontgomery($x, $n)
2364
    {
2365
        $lhs = new static();
2366
        $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x);
2367
        $rhs = new static();
2368
        $rhs->value = $n;
2369
 
2370
        list(, $temp) = $lhs->divide($rhs);
2371
        return $temp->value;
2372
    }
2373
 
2374
    /**
2375
     * Modular Inverse of a number mod 2**26 (eg. 67108864)
2376
     *
2377
     * Based off of the bnpInvDigit function implemented and justified in the following URL:
2378
     *
2379
     * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js}
2380
     *
2381
     * The following URL provides more info:
2382
     *
2383
     * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85}
2384
     *
2385
     * As for why we do all the bitmasking...  strange things can happen when converting from floats to ints. For
2386
     * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields
2387
     * int(-2147483648).  To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't
2388
     * auto-converted to floats.  The outermost bitmask is present because without it, there's no guarantee that
2389
     * the "residue" returned would be the so-called "common residue".  We use fmod, in the last step, because the
2390
     * maximum possible $x is 26 bits and the maximum $result is 16 bits.  Thus, we have to be able to handle up to
2391
     * 40 bits, which only 64-bit floating points will support.
2392
     *
2393
     * Thanks to Pedro Gimeno Fortea for input!
2394
     *
2395
     * @see self::_montgomery()
2396
     * @access private
2397
     * @param array $x
2398
     * @return int
2399
     */
2400
    function _modInverse67108864($x) // 2**26 == 67,108,864
2401
    {
2402
        $x = -$x[0];
2403
        $result = $x & 0x3; // x**-1 mod 2**2
2404
        $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4
2405
        $result = ($result * (2 - ($x & 0xFF) * $result))  & 0xFF; // x**-1 mod 2**8
2406
        $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16
2407
        $result = fmod($result * (2 - fmod($x * $result, self::$baseFull)), self::$baseFull); // x**-1 mod 2**26
2408
        return $result & self::$maxDigit;
2409
    }
2410
 
2411
    /**
2412
     * Calculates modular inverses.
2413
     *
2414
     * Say you have (30 mod 17 * x mod 17) mod 17 == 1.  x can be found using modular inverses.
2415
     *
2416
     * Here's an example:
2417
     * <code>
2418
     * <?php
2419
     *    $a = new \phpseclib\Math\BigInteger(30);
2420
     *    $b = new \phpseclib\Math\BigInteger(17);
2421
     *
2422
     *    $c = $a->modInverse($b);
2423
     *    echo $c->toString(); // outputs 4
2424
     *
2425
     *    echo "\r\n";
2426
     *
2427
     *    $d = $a->multiply($c);
2428
     *    list(, $d) = $d->divide($b);
2429
     *    echo $d; // outputs 1 (as per the definition of modular inverse)
2430
     * ?>
2431
     * </code>
2432
     *
2433
     * @param \phpseclib\Math\BigInteger $n
2434
     * @return \phpseclib\Math\BigInteger|false
2435
     * @access public
2436
     * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.
2437
     */
2438
    function modInverse($n)
2439
    {
2440
        switch (MATH_BIGINTEGER_MODE) {
2441
            case self::MODE_GMP:
2442
                $temp = new static();
2443
                $temp->value = gmp_invert($this->value, $n->value);
2444
 
2445
                return ($temp->value === false) ? false : $this->_normalize($temp);
2446
        }
2447
 
2448
        static $zero, $one;
2449
        if (!isset($zero)) {
2450
            $zero = new static();
2451
            $one = new static(1);
2452
        }
2453
 
2454
        // $x mod -$n == $x mod $n.
2455
        $n = $n->abs();
2456
 
2457
        if ($this->compare($zero) < 0) {
2458
            $temp = $this->abs();
2459
            $temp = $temp->modInverse($n);
2460
            return $this->_normalize($n->subtract($temp));
2461
        }
2462
 
2463
        extract($this->extendedGCD($n));
2464
 
2465
        if (!$gcd->equals($one)) {
2466
            return false;
2467
        }
2468
 
2469
        $x = $x->compare($zero) < 0 ? $x->add($n) : $x;
2470
 
2471
        return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x);
2472
    }
2473
 
2474
    /**
2475
     * Calculates the greatest common divisor and Bezout's identity.
2476
     *
2477
     * Say you have 693 and 609.  The GCD is 21.  Bezout's identity states that there exist integers x and y such that
2478
     * 693*x + 609*y == 21.  In point of fact, there are actually an infinite number of x and y combinations and which
2479
     * combination is returned is dependent upon which mode is in use.  See
2480
     * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information.
2481
     *
2482
     * Here's an example:
2483
     * <code>
2484
     * <?php
2485
     *    $a = new \phpseclib\Math\BigInteger(693);
2486
     *    $b = new \phpseclib\Math\BigInteger(609);
2487
     *
2488
     *    extract($a->extendedGCD($b));
2489
     *
2490
     *    echo $gcd->toString() . "\r\n"; // outputs 21
2491
     *    echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21
2492
     * ?>
2493
     * </code>
2494
     *
2495
     * @param \phpseclib\Math\BigInteger $n
2496
     * @return \phpseclib\Math\BigInteger
2497
     * @access public
2498
     * @internal Calculates the GCD using the binary xGCD algorithim described in
2499
     *    {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}.  As the text above 14.61 notes,
2500
     *    the more traditional algorithim requires "relatively costly multiple-precision divisions".
2501
     */
2502
    function extendedGCD($n)
2503
    {
2504
        switch (MATH_BIGINTEGER_MODE) {
2505
            case self::MODE_GMP:
2506
                extract(gmp_gcdext($this->value, $n->value));
2507
 
2508
                return array(
2509
                    'gcd' => $this->_normalize(new static($g)),
2510
                    'x'   => $this->_normalize(new static($s)),
2511
                    'y'   => $this->_normalize(new static($t))
2512
                );
2513
            case self::MODE_BCMATH:
2514
                // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works
2515
                // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway.  as is,
2516
                // the basic extended euclidean algorithim is what we're using.
2517
 
2518
                $u = $this->value;
2519
                $v = $n->value;
2520
 
2521
                $a = '1';
2522
                $b = '0';
2523
                $c = '0';
2524
                $d = '1';
2525
 
2526
                while (bccomp($v, '0', 0) != 0) {
2527
                    $q = bcdiv($u, $v, 0);
2528
 
2529
                    $temp = $u;
2530
                    $u = $v;
2531
                    $v = bcsub($temp, bcmul($v, $q, 0), 0);
2532
 
2533
                    $temp = $a;
2534
                    $a = $c;
2535
                    $c = bcsub($temp, bcmul($a, $q, 0), 0);
2536
 
2537
                    $temp = $b;
2538
                    $b = $d;
2539
                    $d = bcsub($temp, bcmul($b, $q, 0), 0);
2540
                }
2541
 
2542
                return array(
2543
                    'gcd' => $this->_normalize(new static($u)),
2544
                    'x'   => $this->_normalize(new static($a)),
2545
                    'y'   => $this->_normalize(new static($b))
2546
                );
2547
        }
2548
 
2549
        $y = $n->copy();
2550
        $x = $this->copy();
2551
        $g = new static();
2552
        $g->value = array(1);
2553
 
2554
        while (!(($x->value[0] & 1)|| ($y->value[0] & 1))) {
2555
            $x->_rshift(1);
2556
            $y->_rshift(1);
2557
            $g->_lshift(1);
2558
        }
2559
 
2560
        $u = $x->copy();
2561
        $v = $y->copy();
2562
 
2563
        $a = new static();
2564
        $b = new static();
2565
        $c = new static();
2566
        $d = new static();
2567
 
2568
        $a->value = $d->value = $g->value = array(1);
2569
        $b->value = $c->value = array();
2570
 
2571
        while (!empty($u->value)) {
2572
            while (!($u->value[0] & 1)) {
2573
                $u->_rshift(1);
2574
                if ((!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1))) {
2575
                    $a = $a->add($y);
2576
                    $b = $b->subtract($x);
2577
                }
2578
                $a->_rshift(1);
2579
                $b->_rshift(1);
2580
            }
2581
 
2582
            while (!($v->value[0] & 1)) {
2583
                $v->_rshift(1);
2584
                if ((!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1))) {
2585
                    $c = $c->add($y);
2586
                    $d = $d->subtract($x);
2587
                }
2588
                $c->_rshift(1);
2589
                $d->_rshift(1);
2590
            }
2591
 
2592
            if ($u->compare($v) >= 0) {
2593
                $u = $u->subtract($v);
2594
                $a = $a->subtract($c);
2595
                $b = $b->subtract($d);
2596
            } else {
2597
                $v = $v->subtract($u);
2598
                $c = $c->subtract($a);
2599
                $d = $d->subtract($b);
2600
            }
2601
        }
2602
 
2603
        return array(
2604
            'gcd' => $this->_normalize($g->multiply($v)),
2605
            'x'   => $this->_normalize($c),
2606
            'y'   => $this->_normalize($d)
2607
        );
2608
    }
2609
 
2610
    /**
2611
     * Calculates the greatest common divisor
2612
     *
2613
     * Say you have 693 and 609.  The GCD is 21.
2614
     *
2615
     * Here's an example:
2616
     * <code>
2617
     * <?php
2618
     *    $a = new \phpseclib\Math\BigInteger(693);
2619
     *    $b = new \phpseclib\Math\BigInteger(609);
2620
     *
2621
     *    $gcd = a->extendedGCD($b);
2622
     *
2623
     *    echo $gcd->toString() . "\r\n"; // outputs 21
2624
     * ?>
2625
     * </code>
2626
     *
2627
     * @param \phpseclib\Math\BigInteger $n
2628
     * @return \phpseclib\Math\BigInteger
2629
     * @access public
2630
     */
2631
    function gcd($n)
2632
    {
2633
        extract($this->extendedGCD($n));
2634
        return $gcd;
2635
    }
2636
 
2637
    /**
2638
     * Absolute value.
2639
     *
2640
     * @return \phpseclib\Math\BigInteger
2641
     * @access public
2642
     */
2643
    function abs()
2644
    {
2645
        $temp = new static();
2646
 
2647
        switch (MATH_BIGINTEGER_MODE) {
2648
            case self::MODE_GMP:
2649
                $temp->value = gmp_abs($this->value);
2650
                break;
2651
            case self::MODE_BCMATH:
2652
                $temp->value = (bccomp($this->value, '0', 0) < 0) ? substr($this->value, 1) : $this->value;
2653
                break;
2654
            default:
2655
                $temp->value = $this->value;
2656
        }
2657
 
2658
        return $temp;
2659
    }
2660
 
2661
    /**
2662
     * Compares two numbers.
2663
     *
2664
     * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite.  The reason for this is
2665
     * demonstrated thusly:
2666
     *
2667
     * $x  > $y: $x->compare($y)  > 0
2668
     * $x  < $y: $x->compare($y)  < 0
2669
     * $x == $y: $x->compare($y) == 0
2670
     *
2671
     * Note how the same comparison operator is used.  If you want to test for equality, use $x->equals($y).
2672
     *
2673
     * @param \phpseclib\Math\BigInteger $y
2674
     * @return int < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
2675
     * @access public
2676
     * @see self::equals()
2677
     * @internal Could return $this->subtract($x), but that's not as fast as what we do do.
2678
     */
2679
    function compare($y)
2680
    {
2681
        switch (MATH_BIGINTEGER_MODE) {
2682
            case self::MODE_GMP:
2683
                return gmp_cmp($this->value, $y->value);
2684
            case self::MODE_BCMATH:
2685
                return bccomp($this->value, $y->value, 0);
2686
        }
2687
 
2688
        return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative);
2689
    }
2690
 
2691
    /**
2692
     * Compares two numbers.
2693
     *
2694
     * @param array $x_value
2695
     * @param bool $x_negative
2696
     * @param array $y_value
2697
     * @param bool $y_negative
2698
     * @return int
2699
     * @see self::compare()
2700
     * @access private
2701
     */
2702
    function _compare($x_value, $x_negative, $y_value, $y_negative)
2703
    {
2704
        if ($x_negative != $y_negative) {
2705
            return (!$x_negative && $y_negative) ? 1 : -1;
2706
        }
2707
 
2708
        $result = $x_negative ? -1 : 1;
2709
 
2710
        if (count($x_value) != count($y_value)) {
2711
            return (count($x_value) > count($y_value)) ? $result : -$result;
2712
        }
2713
        $size = max(count($x_value), count($y_value));
2714
 
2715
        $x_value = array_pad($x_value, $size, 0);
2716
        $y_value = array_pad($y_value, $size, 0);
2717
 
2718
        for ($i = count($x_value) - 1; $i >= 0; --$i) {
2719
            if ($x_value[$i] != $y_value[$i]) {
2720
                return ($x_value[$i] > $y_value[$i]) ? $result : -$result;
2721
            }
2722
        }
2723
 
2724
        return 0;
2725
    }
2726
 
2727
    /**
2728
     * Tests the equality of two numbers.
2729
     *
2730
     * If you need to see if one number is greater than or less than another number, use BigInteger::compare()
2731
     *
2732
     * @param \phpseclib\Math\BigInteger $x
2733
     * @return bool
2734
     * @access public
2735
     * @see self::compare()
2736
     */
2737
    function equals($x)
2738
    {
2739
        switch (MATH_BIGINTEGER_MODE) {
2740
            case self::MODE_GMP:
2741
                return gmp_cmp($this->value, $x->value) == 0;
2742
            default:
2743
                return $this->value === $x->value && $this->is_negative == $x->is_negative;
2744
        }
2745
    }
2746
 
2747
    /**
2748
     * Set Precision
2749
     *
2750
     * Some bitwise operations give different results depending on the precision being used.  Examples include left
2751
     * shift, not, and rotates.
2752
     *
2753
     * @param int $bits
2754
     * @access public
2755
     */
2756
    function setPrecision($bits)
2757
    {
2758
        $this->precision = $bits;
2759
        if (MATH_BIGINTEGER_MODE != self::MODE_BCMATH) {
2760
            $this->bitmask = new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256);
2761
        } else {
2762
            $this->bitmask = new static(bcpow('2', $bits, 0));
2763
        }
2764
 
2765
        $temp = $this->_normalize($this);
2766
        $this->value = $temp->value;
2767
    }
2768
 
2769
    /**
2770
     * Logical And
2771
     *
2772
     * @param \phpseclib\Math\BigInteger $x
2773
     * @access public
2774
     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
2775
     * @return \phpseclib\Math\BigInteger
2776
     */
2777
    function bitwise_and($x)
2778
    {
2779
        switch (MATH_BIGINTEGER_MODE) {
2780
            case self::MODE_GMP:
2781
                $temp = new static();
2782
                $temp->value = gmp_and($this->value, $x->value);
2783
 
2784
                return $this->_normalize($temp);
2785
            case self::MODE_BCMATH:
2786
                $left = $this->toBytes();
2787
                $right = $x->toBytes();
2788
 
2789
                $length = max(strlen($left), strlen($right));
2790
 
2791
                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
2792
                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
2793
 
2794
                return $this->_normalize(new static($left & $right, 256));
2795
        }
2796
 
2797
        $result = $this->copy();
2798
 
2799
        $length = min(count($x->value), count($this->value));
2800
 
2801
        $result->value = array_slice($result->value, 0, $length);
2802
 
2803
        for ($i = 0; $i < $length; ++$i) {
2804
            $result->value[$i]&= $x->value[$i];
2805
        }
2806
 
2807
        return $this->_normalize($result);
2808
    }
2809
 
2810
    /**
2811
     * Logical Or
2812
     *
2813
     * @param \phpseclib\Math\BigInteger $x
2814
     * @access public
2815
     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
2816
     * @return \phpseclib\Math\BigInteger
2817
     */
2818
    function bitwise_or($x)
2819
    {
2820
        switch (MATH_BIGINTEGER_MODE) {
2821
            case self::MODE_GMP:
2822
                $temp = new static();
2823
                $temp->value = gmp_or($this->value, $x->value);
2824
 
2825
                return $this->_normalize($temp);
2826
            case self::MODE_BCMATH:
2827
                $left = $this->toBytes();
2828
                $right = $x->toBytes();
2829
 
2830
                $length = max(strlen($left), strlen($right));
2831
 
2832
                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
2833
                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
2834
 
2835
                return $this->_normalize(new static($left | $right, 256));
2836
        }
2837
 
2838
        $length = max(count($this->value), count($x->value));
2839
        $result = $this->copy();
2840
        $result->value = array_pad($result->value, $length, 0);
2841
        $x->value = array_pad($x->value, $length, 0);
2842
 
2843
        for ($i = 0; $i < $length; ++$i) {
2844
            $result->value[$i]|= $x->value[$i];
2845
        }
2846
 
2847
        return $this->_normalize($result);
2848
    }
2849
 
2850
    /**
2851
     * Logical Exclusive-Or
2852
     *
2853
     * @param \phpseclib\Math\BigInteger $x
2854
     * @access public
2855
     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
2856
     * @return \phpseclib\Math\BigInteger
2857
     */
2858
    function bitwise_xor($x)
2859
    {
2860
        switch (MATH_BIGINTEGER_MODE) {
2861
            case self::MODE_GMP:
2862
                $temp = new static();
2863
                $temp->value = gmp_xor($this->value, $x->value);
2864
 
2865
                return $this->_normalize($temp);
2866
            case self::MODE_BCMATH:
2867
                $left = $this->toBytes();
2868
                $right = $x->toBytes();
2869
 
2870
                $length = max(strlen($left), strlen($right));
2871
 
2872
                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
2873
                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
2874
 
2875
                return $this->_normalize(new static($left ^ $right, 256));
2876
        }
2877
 
2878
        $length = max(count($this->value), count($x->value));
2879
        $result = $this->copy();
2880
        $result->value = array_pad($result->value, $length, 0);
2881
        $x->value = array_pad($x->value, $length, 0);
2882
 
2883
        for ($i = 0; $i < $length; ++$i) {
2884
            $result->value[$i]^= $x->value[$i];
2885
        }
2886
 
2887
        return $this->_normalize($result);
2888
    }
2889
 
2890
    /**
2891
     * Logical Not
2892
     *
2893
     * @access public
2894
     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
2895
     * @return \phpseclib\Math\BigInteger
2896
     */
2897
    function bitwise_not()
2898
    {
2899
        // calculuate "not" without regard to $this->precision
2900
        // (will always result in a smaller number.  ie. ~1 isn't 1111 1110 - it's 0)
2901
        $temp = $this->toBytes();
2902
        if ($temp == '') {
2903
            return '';
2904
        }
2905
        $pre_msb = decbin(ord($temp[0]));
2906
        $temp = ~$temp;
2907
        $msb = decbin(ord($temp[0]));
2908
        if (strlen($msb) == 8) {
2909
            $msb = substr($msb, strpos($msb, '0'));
2910
        }
2911
        $temp[0] = chr(bindec($msb));
2912
 
2913
        // see if we need to add extra leading 1's
2914
        $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8;
2915
        $new_bits = $this->precision - $current_bits;
2916
        if ($new_bits <= 0) {
2917
            return $this->_normalize(new static($temp, 256));
2918
        }
2919
 
2920
        // generate as many leading 1's as we need to.
2921
        $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3);
2922
        $this->_base256_lshift($leading_ones, $current_bits);
2923
 
2924
        $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT);
2925
 
2926
        return $this->_normalize(new static($leading_ones | $temp, 256));
2927
    }
2928
 
2929
    /**
2930
     * Logical Right Shift
2931
     *
2932
     * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift.
2933
     *
2934
     * @param int $shift
2935
     * @return \phpseclib\Math\BigInteger
2936
     * @access public
2937
     * @internal The only version that yields any speed increases is the internal version.
2938
     */
2939
    function bitwise_rightShift($shift)
2940
    {
2941
        $temp = new static();
2942
 
2943
        switch (MATH_BIGINTEGER_MODE) {
2944
            case self::MODE_GMP:
2945
                static $two;
2946
 
2947
                if (!isset($two)) {
2948
                    $two = gmp_init('2');
2949
                }
2950
 
2951
                $temp->value = gmp_div_q($this->value, gmp_pow($two, $shift));
2952
 
2953
                break;
2954
            case self::MODE_BCMATH:
2955
                $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0);
2956
 
2957
                break;
2958
            default: // could just replace _lshift with this, but then all _lshift() calls would need to be rewritten
2959
                     // and I don't want to do that...
2960
                $temp->value = $this->value;
2961
                $temp->_rshift($shift);
2962
        }
2963
 
2964
        return $this->_normalize($temp);
2965
    }
2966
 
2967
    /**
2968
     * Logical Left Shift
2969
     *
2970
     * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.
2971
     *
2972
     * @param int $shift
2973
     * @return \phpseclib\Math\BigInteger
2974
     * @access public
2975
     * @internal The only version that yields any speed increases is the internal version.
2976
     */
2977
    function bitwise_leftShift($shift)
2978
    {
2979
        $temp = new static();
2980
 
2981
        switch (MATH_BIGINTEGER_MODE) {
2982
            case self::MODE_GMP:
2983
                static $two;
2984
 
2985
                if (!isset($two)) {
2986
                    $two = gmp_init('2');
2987
                }
2988
 
2989
                $temp->value = gmp_mul($this->value, gmp_pow($two, $shift));
2990
 
2991
                break;
2992
            case self::MODE_BCMATH:
2993
                $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0);
2994
 
2995
                break;
2996
            default: // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten
2997
                     // and I don't want to do that...
2998
                $temp->value = $this->value;
2999
                $temp->_lshift($shift);
3000
        }
3001
 
3002
        return $this->_normalize($temp);
3003
    }
3004
 
3005
    /**
3006
     * Logical Left Rotate
3007
     *
3008
     * Instead of the top x bits being dropped they're appended to the shifted bit string.
3009
     *
3010
     * @param int $shift
3011
     * @return \phpseclib\Math\BigInteger
3012
     * @access public
3013
     */
3014
    function bitwise_leftRotate($shift)
3015
    {
3016
        $bits = $this->toBytes();
3017
 
3018
        if ($this->precision > 0) {
3019
            $precision = $this->precision;
3020
            if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
3021
                $mask = $this->bitmask->subtract(new static(1));
3022
                $mask = $mask->toBytes();
3023
            } else {
3024
                $mask = $this->bitmask->toBytes();
3025
            }
3026
        } else {
3027
            $temp = ord($bits[0]);
3028
            for ($i = 0; $temp >> $i; ++$i) {
3029
            }
3030
            $precision = 8 * strlen($bits) - 8 + $i;
3031
            $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3);
3032
        }
3033
 
3034
        if ($shift < 0) {
3035
            $shift+= $precision;
3036
        }
3037
        $shift%= $precision;
3038
 
3039
        if (!$shift) {
3040
            return $this->copy();
3041
        }
3042
 
3043
        $left = $this->bitwise_leftShift($shift);
3044
        $left = $left->bitwise_and(new static($mask, 256));
3045
        $right = $this->bitwise_rightShift($precision - $shift);
3046
        $result = MATH_BIGINTEGER_MODE != self::MODE_BCMATH ? $left->bitwise_or($right) : $left->add($right);
3047
        return $this->_normalize($result);
3048
    }
3049
 
3050
    /**
3051
     * Logical Right Rotate
3052
     *
3053
     * Instead of the bottom x bits being dropped they're prepended to the shifted bit string.
3054
     *
3055
     * @param int $shift
3056
     * @return \phpseclib\Math\BigInteger
3057
     * @access public
3058
     */
3059
    function bitwise_rightRotate($shift)
3060
    {
3061
        return $this->bitwise_leftRotate(-$shift);
3062
    }
3063
 
3064
    /**
3065
     * Generates a random BigInteger
3066
     *
3067
     * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not.
3068
     *
3069
     * @param int $length
3070
     * @return \phpseclib\Math\BigInteger
3071
     * @access private
3072
     */
3073
    function _random_number_helper($size)
3074
    {
3075
        if (class_exists('\phpseclib\Crypt\Random')) {
3076
            $random = Random::string($size);
3077
        } else {
3078
            $random = '';
3079
 
3080
            if ($size & 1) {
3081
                $random.= chr(mt_rand(0, 255));
3082
            }
3083
 
3084
            $blocks = $size >> 1;
3085
            for ($i = 0; $i < $blocks; ++$i) {
3086
                // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
3087
                $random.= pack('n', mt_rand(0, 0xFFFF));
3088
            }
3089
        }
3090
 
3091
        return new static($random, 256);
3092
    }
3093
 
3094
    /**
3095
     * Generate a random number
3096
     *
3097
     * Returns a random number between $min and $max where $min and $max
3098
     * can be defined using one of the two methods:
3099
     *
3100
     * $min->random($max)
3101
     * $max->random($min)
3102
     *
3103
     * @param \phpseclib\Math\BigInteger $arg1
3104
     * @param \phpseclib\Math\BigInteger $arg2
3105
     * @return \phpseclib\Math\BigInteger
3106
     * @access public
3107
     * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a BigInteger object.
3108
     *           That method is still supported for BC purposes.
3109
     */
3110
    function random($arg1, $arg2 = false)
3111
    {
3112
        if ($arg1 === false) {
3113
            return false;
3114
        }
3115
 
3116
        if ($arg2 === false) {
3117
            $max = $arg1;
3118
            $min = $this;
3119
        } else {
3120
            $min = $arg1;
3121
            $max = $arg2;
3122
        }
3123
 
3124
        $compare = $max->compare($min);
3125
 
3126
        if (!$compare) {
3127
            return $this->_normalize($min);
3128
        } elseif ($compare < 0) {
3129
            // if $min is bigger then $max, swap $min and $max
3130
            $temp = $max;
3131
            $max = $min;
3132
            $min = $temp;
3133
        }
3134
 
3135
        static $one;
3136
        if (!isset($one)) {
3137
            $one = new static(1);
3138
        }
3139
 
3140
        $max = $max->subtract($min->subtract($one));
3141
        $size = strlen(ltrim($max->toBytes(), chr(0)));
3142
 
3143
        /*
3144
            doing $random % $max doesn't work because some numbers will be more likely to occur than others.
3145
            eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145
3146
            would produce 5 whereas the only value of random that could produce 139 would be 139. ie.
3147
            not all numbers would be equally likely. some would be more likely than others.
3148
 
3149
            creating a whole new random number until you find one that is within the range doesn't work
3150
            because, for sufficiently small ranges, the likelihood that you'd get a number within that range
3151
            would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability
3152
            would be pretty high that $random would be greater than $max.
3153
 
3154
            phpseclib works around this using the technique described here:
3155
 
3156
            http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string
3157
        */
3158
        $random_max = new static(chr(1) . str_repeat("\0", $size), 256);
3159
        $random = $this->_random_number_helper($size);
3160
 
3161
        list($max_multiple) = $random_max->divide($max);
3162
        $max_multiple = $max_multiple->multiply($max);
3163
 
3164
        while ($random->compare($max_multiple) >= 0) {
3165
            $random = $random->subtract($max_multiple);
3166
            $random_max = $random_max->subtract($max_multiple);
3167
            $random = $random->bitwise_leftShift(8);
3168
            $random = $random->add($this->_random_number_helper(1));
3169
            $random_max = $random_max->bitwise_leftShift(8);
3170
            list($max_multiple) = $random_max->divide($max);
3171
            $max_multiple = $max_multiple->multiply($max);
3172
        }
3173
        list(, $random) = $random->divide($max);
3174
 
3175
        return $this->_normalize($random->add($min));
3176
    }
3177
 
3178
    /**
3179
     * Generate a random prime number.
3180
     *
3181
     * If there's not a prime within the given range, false will be returned.
3182
     * If more than $timeout seconds have elapsed, give up and return false.
3183
     *
3184
     * @param \phpseclib\Math\BigInteger $arg1
3185
     * @param \phpseclib\Math\BigInteger $arg2
3186
     * @param int $timeout
3187
     * @return Math_BigInteger|false
3188
     * @access public
3189
     * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.
3190
     */
3191
    function randomPrime($arg1, $arg2 = false, $timeout = false)
3192
    {
3193
        if ($arg1 === false) {
3194
            return false;
3195
        }
3196
 
3197
        if ($arg2 === false) {
3198
            $max = $arg1;
3199
            $min = $this;
3200
        } else {
3201
            $min = $arg1;
3202
            $max = $arg2;
3203
        }
3204
 
3205
        $compare = $max->compare($min);
3206
 
3207
        if (!$compare) {
3208
            return $min->isPrime() ? $min : false;
3209
        } elseif ($compare < 0) {
3210
            // if $min is bigger then $max, swap $min and $max
3211
            $temp = $max;
3212
            $max = $min;
3213
            $min = $temp;
3214
        }
3215
 
3216
        static $one, $two;
3217
        if (!isset($one)) {
3218
            $one = new static(1);
3219
            $two = new static(2);
3220
        }
3221
 
3222
        $start = time();
3223
 
3224
        $x = $this->random($min, $max);
3225
 
3226
        // gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
3227
        if (MATH_BIGINTEGER_MODE == self::MODE_GMP && extension_loaded('gmp')) {
3228
            $p = new static();
3229
            $p->value = gmp_nextprime($x->value);
3230
 
3231
            if ($p->compare($max) <= 0) {
3232
                return $p;
3233
            }
3234
 
3235
            if (!$min->equals($x)) {
3236
                $x = $x->subtract($one);
3237
            }
3238
 
3239
            return $x->randomPrime($min, $x);
3240
        }
3241
 
3242
        if ($x->equals($two)) {
3243
            return $x;
3244
        }
3245
 
3246
        $x->_make_odd();
3247
        if ($x->compare($max) > 0) {
3248
            // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range
3249
            if ($min->equals($max)) {
3250
                return false;
3251
            }
3252
            $x = $min->copy();
3253
            $x->_make_odd();
3254
        }
3255
 
3256
        $initial_x = $x->copy();
3257
 
3258
        while (true) {
3259
            if ($timeout !== false && time() - $start > $timeout) {
3260
                return false;
3261
            }
3262
 
3263
            if ($x->isPrime()) {
3264
                return $x;
3265
            }
3266
 
3267
            $x = $x->add($two);
3268
 
3269
            if ($x->compare($max) > 0) {
3270
                $x = $min->copy();
3271
                if ($x->equals($two)) {
3272
                    return $x;
3273
                }
3274
                $x->_make_odd();
3275
            }
3276
 
3277
            if ($x->equals($initial_x)) {
3278
                return false;
3279
            }
3280
        }
3281
    }
3282
 
3283
    /**
3284
     * Make the current number odd
3285
     *
3286
     * If the current number is odd it'll be unchanged.  If it's even, one will be added to it.
3287
     *
3288
     * @see self::randomPrime()
3289
     * @access private
3290
     */
3291
    function _make_odd()
3292
    {
3293
        switch (MATH_BIGINTEGER_MODE) {
3294
            case self::MODE_GMP:
3295
                gmp_setbit($this->value, 0);
3296
                break;
3297
            case self::MODE_BCMATH:
3298
                if ($this->value[strlen($this->value) - 1] % 2 == 0) {
3299
                    $this->value = bcadd($this->value, '1');
3300
                }
3301
                break;
3302
            default:
3303
                $this->value[0] |= 1;
3304
        }
3305
    }
3306
 
3307
    /**
3308
     * Checks a numer to see if it's prime
3309
     *
3310
     * Assuming the $t parameter is not set, this function has an error rate of 2**-80.  The main motivation for the
3311
     * $t parameter is distributability.  BigInteger::randomPrime() can be distributed across multiple pageloads
3312
     * on a website instead of just one.
3313
     *
3314
     * @param \phpseclib\Math\BigInteger $t
3315
     * @return bool
3316
     * @access public
3317
     * @internal Uses the
3318
     *     {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}.  See
3319
     *     {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24}.
3320
     */
3321
    function isPrime($t = false)
3322
    {
3323
        $length = strlen($this->toBytes());
3324
 
3325
        if (!$t) {
3326
            // see HAC 4.49 "Note (controlling the error probability)"
3327
            // @codingStandardsIgnoreStart
3328
                 if ($length >= 163) { $t =  2; } // floor(1300 / 8)
3329
            else if ($length >= 106) { $t =  3; } // floor( 850 / 8)
3330
            else if ($length >= 81 ) { $t =  4; } // floor( 650 / 8)
3331
            else if ($length >= 68 ) { $t =  5; } // floor( 550 / 8)
3332
            else if ($length >= 56 ) { $t =  6; } // floor( 450 / 8)
3333
            else if ($length >= 50 ) { $t =  7; } // floor( 400 / 8)
3334
            else if ($length >= 43 ) { $t =  8; } // floor( 350 / 8)
3335
            else if ($length >= 37 ) { $t =  9; } // floor( 300 / 8)
3336
            else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8)
3337
            else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8)
3338
            else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8)
3339
            else                     { $t = 27; }
3340
            // @codingStandardsIgnoreEnd
3341
        }
3342
 
3343
        // ie. gmp_testbit($this, 0)
3344
        // ie. isEven() or !isOdd()
3345
        switch (MATH_BIGINTEGER_MODE) {
3346
            case self::MODE_GMP:
3347
                return gmp_prob_prime($this->value, $t) != 0;
3348
            case self::MODE_BCMATH:
3349
                if ($this->value === '2') {
3350
                    return true;
3351
                }
3352
                if ($this->value[strlen($this->value) - 1] % 2 == 0) {
3353
                    return false;
3354
                }
3355
                break;
3356
            default:
3357
                if ($this->value == array(2)) {
3358
                    return true;
3359
                }
3360
                if (~$this->value[0] & 1) {
3361
                    return false;
3362
                }
3363
        }
3364
 
3365
        static $primes, $zero, $one, $two;
3366
 
3367
        if (!isset($primes)) {
3368
            $primes = array(
3369
                3,    5,    7,    11,   13,   17,   19,   23,   29,   31,   37,   41,   43,   47,   53,   59,
3370
                61,   67,   71,   73,   79,   83,   89,   97,   101,  103,  107,  109,  113,  127,  131,  137,
3371
                139,  149,  151,  157,  163,  167,  173,  179,  181,  191,  193,  197,  199,  211,  223,  227,
3372
                229,  233,  239,  241,  251,  257,  263,  269,  271,  277,  281,  283,  293,  307,  311,  313,
3373
                317,  331,  337,  347,  349,  353,  359,  367,  373,  379,  383,  389,  397,  401,  409,  419,
3374
                421,  431,  433,  439,  443,  449,  457,  461,  463,  467,  479,  487,  491,  499,  503,  509,
3375
                521,  523,  541,  547,  557,  563,  569,  571,  577,  587,  593,  599,  601,  607,  613,  617,
3376
                619,  631,  641,  643,  647,  653,  659,  661,  673,  677,  683,  691,  701,  709,  719,  727,
3377
                733,  739,  743,  751,  757,  761,  769,  773,  787,  797,  809,  811,  821,  823,  827,  829,
3378
                839,  853,  857,  859,  863,  877,  881,  883,  887,  907,  911,  919,  929,  937,  941,  947,
3379
                953,  967,  971,  977,  983,  991,  997
3380
            );
3381
 
3382
            if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
3383
                for ($i = 0; $i < count($primes); ++$i) {
3384
                    $primes[$i] = new static($primes[$i]);
3385
                }
3386
            }
3387
 
3388
            $zero = new static();
3389
            $one = new static(1);
3390
            $two = new static(2);
3391
        }
3392
 
3393
        if ($this->equals($one)) {
3394
            return false;
3395
        }
3396
 
3397
        // see HAC 4.4.1 "Random search for probable primes"
3398
        if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
3399
            foreach ($primes as $prime) {
3400
                list(, $r) = $this->divide($prime);
3401
                if ($r->equals($zero)) {
3402
                    return $this->equals($prime);
3403
                }
3404
            }
3405
        } else {
3406
            $value = $this->value;
3407
            foreach ($primes as $prime) {
3408
                list(, $r) = $this->_divide_digit($value, $prime);
3409
                if (!$r) {
3410
                    return count($value) == 1 && $value[0] == $prime;
3411
                }
3412
            }
3413
        }
3414
 
3415
        $n   = $this->copy();
3416
        $n_1 = $n->subtract($one);
3417
        $n_2 = $n->subtract($two);
3418
 
3419
        $r = $n_1->copy();
3420
        $r_value = $r->value;
3421
        // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));
3422
        if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
3423
            $s = 0;
3424
            // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier
3425
            while ($r->value[strlen($r->value) - 1] % 2 == 0) {
3426
                $r->value = bcdiv($r->value, '2', 0);
3427
                ++$s;
3428
            }
3429
        } else {
3430
            for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) {
3431
                $temp = ~$r_value[$i] & 0xFFFFFF;
3432
                for ($j = 1; ($temp >> $j) & 1; ++$j) {
3433
                }
3434
                if ($j != 25) {
3435
                    break;
3436
                }
3437
            }
3438
            $s = 26 * $i + $j - 1;
3439
            $r->_rshift($s);
3440
        }
3441
 
3442
        for ($i = 0; $i < $t; ++$i) {
3443
            $a = $this->random($two, $n_2);
3444
            $y = $a->modPow($r, $n);
3445
 
3446
            if (!$y->equals($one) && !$y->equals($n_1)) {
3447
                for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) {
3448
                    $y = $y->modPow($two, $n);
3449
                    if ($y->equals($one)) {
3450
                        return false;
3451
                    }
3452
                }
3453
 
3454
                if (!$y->equals($n_1)) {
3455
                    return false;
3456
                }
3457
            }
3458
        }
3459
        return true;
3460
    }
3461
 
3462
    /**
3463
     * Logical Left Shift
3464
     *
3465
     * Shifts BigInteger's by $shift bits.
3466
     *
3467
     * @param int $shift
3468
     * @access private
3469
     */
3470
    function _lshift($shift)
3471
    {
3472
        if ($shift == 0) {
3473
            return;
3474
        }
3475
 
3476
        $num_digits = (int) ($shift / self::$base);
3477
        $shift %= self::$base;
3478
        $shift = 1 << $shift;
3479
 
3480
        $carry = 0;
3481
 
3482
        for ($i = 0; $i < count($this->value); ++$i) {
3483
            $temp = $this->value[$i] * $shift + $carry;
3484
            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
3485
            $this->value[$i] = (int) ($temp - $carry * self::$baseFull);
3486
        }
3487
 
3488
        if ($carry) {
3489
            $this->value[count($this->value)] = $carry;
3490
        }
3491
 
3492
        while ($num_digits--) {
3493
            array_unshift($this->value, 0);
3494
        }
3495
    }
3496
 
3497
    /**
3498
     * Logical Right Shift
3499
     *
3500
     * Shifts BigInteger's by $shift bits.
3501
     *
3502
     * @param int $shift
3503
     * @access private
3504
     */
3505
    function _rshift($shift)
3506
    {
3507
        if ($shift == 0) {
3508
            return;
3509
        }
3510
 
3511
        $num_digits = (int) ($shift / self::$base);
3512
        $shift %= self::$base;
3513
        $carry_shift = self::$base - $shift;
3514
        $carry_mask = (1 << $shift) - 1;
3515
 
3516
        if ($num_digits) {
3517
            $this->value = array_slice($this->value, $num_digits);
3518
        }
3519
 
3520
        $carry = 0;
3521
 
3522
        for ($i = count($this->value) - 1; $i >= 0; --$i) {
3523
            $temp = $this->value[$i] >> $shift | $carry;
3524
            $carry = ($this->value[$i] & $carry_mask) << $carry_shift;
3525
            $this->value[$i] = $temp;
3526
        }
3527
 
3528
        $this->value = $this->_trim($this->value);
3529
    }
3530
 
3531
    /**
3532
     * Normalize
3533
     *
3534
     * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision
3535
     *
3536
     * @param \phpseclib\Math\BigInteger
3537
     * @return \phpseclib\Math\BigInteger
3538
     * @see self::_trim()
3539
     * @access private
3540
     */
3541
    function _normalize($result)
3542
    {
3543
        $result->precision = $this->precision;
3544
        $result->bitmask = $this->bitmask;
3545
 
3546
        switch (MATH_BIGINTEGER_MODE) {
3547
            case self::MODE_GMP:
3548
                if ($this->bitmask !== false) {
3549
                    $result->value = gmp_and($result->value, $result->bitmask->value);
3550
                }
3551
 
3552
                return $result;
3553
            case self::MODE_BCMATH:
3554
                if (!empty($result->bitmask->value)) {
3555
                    $result->value = bcmod($result->value, $result->bitmask->value);
3556
                }
3557
 
3558
                return $result;
3559
        }
3560
 
3561
        $value = &$result->value;
3562
 
3563
        if (!count($value)) {
3564
            return $result;
3565
        }
3566
 
3567
        $value = $this->_trim($value);
3568
 
3569
        if (!empty($result->bitmask->value)) {
3570
            $length = min(count($value), count($this->bitmask->value));
3571
            $value = array_slice($value, 0, $length);
3572
 
3573
            for ($i = 0; $i < $length; ++$i) {
3574
                $value[$i] = $value[$i] & $this->bitmask->value[$i];
3575
            }
3576
        }
3577
 
3578
        return $result;
3579
    }
3580
 
3581
    /**
3582
     * Trim
3583
     *
3584
     * Removes leading zeros
3585
     *
3586
     * @param array $value
3587
     * @return \phpseclib\Math\BigInteger
3588
     * @access private
3589
     */
3590
    function _trim($value)
3591
    {
3592
        for ($i = count($value) - 1; $i >= 0; --$i) {
3593
            if ($value[$i]) {
3594
                break;
3595
            }
3596
            unset($value[$i]);
3597
        }
3598
 
3599
        return $value;
3600
    }
3601
 
3602
    /**
3603
     * Array Repeat
3604
     *
3605
     * @param $input Array
3606
     * @param $multiplier mixed
3607
     * @return array
3608
     * @access private
3609
     */
3610
    function _array_repeat($input, $multiplier)
3611
    {
3612
        return ($multiplier) ? array_fill(0, $multiplier, $input) : array();
3613
    }
3614
 
3615
    /**
3616
     * Logical Left Shift
3617
     *
3618
     * Shifts binary strings $shift bits, essentially multiplying by 2**$shift.
3619
     *
3620
     * @param $x String
3621
     * @param $shift Integer
3622
     * @return string
3623
     * @access private
3624
     */
3625
    function _base256_lshift(&$x, $shift)
3626
    {
3627
        if ($shift == 0) {
3628
            return;
3629
        }
3630
 
3631
        $num_bytes = $shift >> 3; // eg. floor($shift/8)
3632
        $shift &= 7; // eg. $shift % 8
3633
 
3634
        $carry = 0;
3635
        for ($i = strlen($x) - 1; $i >= 0; --$i) {
3636
            $temp = ord($x[$i]) << $shift | $carry;
3637
            $x[$i] = chr($temp);
3638
            $carry = $temp >> 8;
3639
        }
3640
        $carry = ($carry != 0) ? chr($carry) : '';
3641
        $x = $carry . $x . str_repeat(chr(0), $num_bytes);
3642
    }
3643
 
3644
    /**
3645
     * Logical Right Shift
3646
     *
3647
     * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder.
3648
     *
3649
     * @param $x String
3650
     * @param $shift Integer
3651
     * @return string
3652
     * @access private
3653
     */
3654
    function _base256_rshift(&$x, $shift)
3655
    {
3656
        if ($shift == 0) {
3657
            $x = ltrim($x, chr(0));
3658
            return '';
3659
        }
3660
 
3661
        $num_bytes = $shift >> 3; // eg. floor($shift/8)
3662
        $shift &= 7; // eg. $shift % 8
3663
 
3664
        $remainder = '';
3665
        if ($num_bytes) {
3666
            $start = $num_bytes > strlen($x) ? -strlen($x) : -$num_bytes;
3667
            $remainder = substr($x, $start);
3668
            $x = substr($x, 0, -$num_bytes);
3669
        }
3670
 
3671
        $carry = 0;
3672
        $carry_shift = 8 - $shift;
3673
        for ($i = 0; $i < strlen($x); ++$i) {
3674
            $temp = (ord($x[$i]) >> $shift) | $carry;
3675
            $carry = (ord($x[$i]) << $carry_shift) & 0xFF;
3676
            $x[$i] = chr($temp);
3677
        }
3678
        $x = ltrim($x, chr(0));
3679
 
3680
        $remainder = chr($carry >> $carry_shift) . $remainder;
3681
 
3682
        return ltrim($remainder, chr(0));
3683
    }
3684
 
3685
    // one quirk about how the following functions are implemented is that PHP defines N to be an unsigned long
3686
    // at 32-bits, while java's longs are 64-bits.
3687
 
3688
    /**
3689
     * Converts 32-bit integers to bytes.
3690
     *
3691
     * @param int $x
3692
     * @return string
3693
     * @access private
3694
     */
3695
    function _int2bytes($x)
3696
    {
3697
        return ltrim(pack('N', $x), chr(0));
3698
    }
3699
 
3700
    /**
3701
     * Converts bytes to 32-bit integers
3702
     *
3703
     * @param string $x
3704
     * @return int
3705
     * @access private
3706
     */
3707
    function _bytes2int($x)
3708
    {
3709
        $temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT));
3710
        return $temp['int'];
3711
    }
3712
 
3713
    /**
3714
     * DER-encode an integer
3715
     *
3716
     * The ability to DER-encode integers is needed to create RSA public keys for use with OpenSSL
3717
     *
3718
     * @see self::modPow()
3719
     * @access private
3720
     * @param int $length
3721
     * @return string
3722
     */
3723
    function _encodeASN1Length($length)
3724
    {
3725
        if ($length <= 0x7F) {
3726
            return chr($length);
3727
        }
3728
 
3729
        $temp = ltrim(pack('N', $length), chr(0));
3730
        return pack('Ca*', 0x80 | strlen($temp), $temp);
3731
    }
3732
 
3733
    /**
3734
     * Single digit division
3735
     *
3736
     * Even if int64 is being used the division operator will return a float64 value
3737
     * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't
3738
     * have the precision of int64 this is a problem so, when int64 is being used,
3739
     * we'll guarantee that the dividend is divisible by first subtracting the remainder.
3740
     *
3741
     * @access private
3742
     * @param int $x
3743
     * @param int $y
3744
     * @return int
3745
     */
3746
    function _safe_divide($x, $y)
3747
    {
3748
        if (self::$base === 26) {
3749
            return (int) ($x / $y);
3750
        }
3751
 
3752
        // self::$base === 31
3753
        return ($x - ($x % $y)) / $y;
3754
    }
3755
}