Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
827 daniel-mar 1
<?php
2
 
3
/**
4
 * 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 and 7
10
 *
11
 * Here's an example of how to use this library:
12
 * <code>
13
 * <?php
14
 *    $a = new \phpseclib3\Math\BigInteger(2);
15
 *    $b = new \phpseclib3\Math\BigInteger(3);
16
 *
17
 *    $c = $a->add($b);
18
 *
19
 *    echo $c->toString(); // outputs 5
20
 * ?>
21
 * </code>
22
 *
23
 * @author    Jim Wigginton <terrafrost@php.net>
24
 * @copyright 2017 Jim Wigginton
25
 * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
26
 */
27
 
28
namespace phpseclib3\Math;
29
 
30
use phpseclib3\Exception\BadConfigurationException;
31
use phpseclib3\Math\BigInteger\Engines\Engine;
1411 daniel-mar 32
use UnexpectedValueException;
827 daniel-mar 33
 
34
/**
35
 * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256
36
 * numbers.
37
 *
38
 * @author  Jim Wigginton <terrafrost@php.net>
39
 */
40
class BigInteger implements \JsonSerializable
41
{
42
    /**
43
     * Main Engine
44
     *
45
     * @var class-string<Engine>
46
     */
47
    private static $mainEngine;
48
 
49
    /**
50
     * Selected Engines
51
     *
52
     * @var list<string>
53
     */
54
    private static $engines;
55
 
56
    /**
57
     * The actual BigInteger object
58
     *
59
     * @var object
60
     */
61
    private $value;
62
 
63
    /**
64
     * Mode independent value used for serialization.
65
     *
66
     * @see self::__sleep()
67
     * @see self::__wakeup()
68
     * @var string
69
     */
70
    private $hex;
71
 
72
    /**
73
     * Precision (used only for serialization)
74
     *
75
     * @see self::__sleep()
76
     * @see self::__wakeup()
77
     * @var int
78
     */
79
    private $precision;
80
 
81
    /**
82
     * Sets engine type.
83
     *
84
     * Throws an exception if the type is invalid
85
     *
86
     * @param string $main
87
     * @param list<string> $modexps optional
88
     * @return void
89
     */
90
    public static function setEngine($main, array $modexps = ['DefaultEngine'])
91
    {
92
        self::$engines = [];
93
 
94
        $fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main;
95
        if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) {
96
            throw new \InvalidArgumentException("$main is not a valid engine");
97
        }
98
        if (!$fqmain::isValidEngine()) {
99
            throw new BadConfigurationException("$main is not setup correctly on this system");
100
        }
101
        /** @var class-string<Engine> $fqmain */
102
        self::$mainEngine = $fqmain;
103
 
104
        $found = false;
105
        foreach ($modexps as $modexp) {
106
            try {
107
                $fqmain::setModExpEngine($modexp);
108
                $found = true;
109
                break;
110
            } catch (\Exception $e) {
111
            }
112
        }
113
 
114
        if (!$found) {
115
            throw new BadConfigurationException("No valid modular exponentiation engine found for $main");
116
        }
117
 
118
        self::$engines = [$main, $modexp];
119
    }
120
 
121
    /**
122
     * Returns the engine type
123
     *
124
     * @return string[]
125
     */
126
    public static function getEngine()
127
    {
128
        self::initialize_static_variables();
129
 
130
        return self::$engines;
131
    }
132
 
133
    /**
134
     * Initialize static variables
135
     */
136
    private static function initialize_static_variables()
137
    {
138
        if (!isset(self::$mainEngine)) {
139
            $engines = [
1339 daniel-mar 140
                ['GMP', ['DefaultEngine']],
827 daniel-mar 141
                ['PHP64', ['OpenSSL']],
142
                ['BCMath', ['OpenSSL']],
1324 daniel-mar 143
                ['PHP32', ['OpenSSL']],
144
                ['PHP64', ['DefaultEngine']],
145
                ['PHP32', ['DefaultEngine']]
827 daniel-mar 146
            ];
1411 daniel-mar 147
 
827 daniel-mar 148
            foreach ($engines as $engine) {
149
                try {
1339 daniel-mar 150
                    self::setEngine($engine[0], $engine[1]);
1411 daniel-mar 151
                    return;
827 daniel-mar 152
                } catch (\Exception $e) {
153
                }
154
            }
1411 daniel-mar 155
 
156
            throw new UnexpectedValueException('No valid BigInteger found. This is only possible when JIT is enabled on Windows and neither the GMP or BCMath extensions are available so either disable JIT or install GMP / BCMath');
827 daniel-mar 157
        }
158
    }
159
 
160
    /**
161
     * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers.
162
     *
163
     * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
164
     * two's compliment.  The sole exception to this is -10, which is treated the same as 10 is.
165
     *
166
     * @param string|int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set.
167
     * @param int $base
168
     */
169
    public function __construct($x = 0, $base = 10)
170
    {
171
        self::initialize_static_variables();
172
 
173
        if ($x instanceof self::$mainEngine) {
174
            $this->value = clone $x;
175
        } elseif ($x instanceof BigInteger\Engines\Engine) {
176
            $this->value = new static("$x");
177
            $this->value->setPrecision($x->getPrecision());
178
        } else {
179
            $this->value = new self::$mainEngine($x, $base);
180
        }
181
    }
182
 
183
    /**
184
     * Converts a BigInteger to a base-10 number.
185
     *
186
     * @return string
187
     */
188
    public function toString()
189
    {
190
        return $this->value->toString();
191
    }
192
 
193
    /**
194
     *  __toString() magic method
195
     */
196
    public function __toString()
197
    {
198
        return (string)$this->value;
199
    }
200
 
201
    /**
202
     *  __debugInfo() magic method
203
     *
204
     * Will be called, automatically, when print_r() or var_dump() are called
205
     */
206
    public function __debugInfo()
207
    {
208
        return $this->value->__debugInfo();
209
    }
210
 
211
    /**
212
     * Converts a BigInteger to a byte string (eg. base-256).
213
     *
214
     * @param bool $twos_compliment
215
     * @return string
216
     */
217
    public function toBytes($twos_compliment = false)
218
    {
219
        return $this->value->toBytes($twos_compliment);
220
    }
221
 
222
    /**
223
     * Converts a BigInteger to a hex string (eg. base-16).
224
     *
225
     * @param bool $twos_compliment
226
     * @return string
227
     */
228
    public function toHex($twos_compliment = false)
229
    {
230
        return $this->value->toHex($twos_compliment);
231
    }
232
 
233
    /**
234
     * Converts a BigInteger to a bit string (eg. base-2).
235
     *
236
     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
237
     * saved as two's compliment.
238
     *
239
     * @param bool $twos_compliment
240
     * @return string
241
     */
242
    public function toBits($twos_compliment = false)
243
    {
244
        return $this->value->toBits($twos_compliment);
245
    }
246
 
247
    /**
248
     * Adds two BigIntegers.
249
     *
250
     * @param BigInteger $y
251
     * @return BigInteger
252
     */
253
    public function add(BigInteger $y)
254
    {
255
        return new static($this->value->add($y->value));
256
    }
257
 
258
    /**
259
     * Subtracts two BigIntegers.
260
     *
261
     * @param BigInteger $y
262
     * @return BigInteger
263
     */
264
    public function subtract(BigInteger $y)
265
    {
266
        return new static($this->value->subtract($y->value));
267
    }
268
 
269
    /**
270
     * Multiplies two BigIntegers
271
     *
272
     * @param BigInteger $x
273
     * @return BigInteger
274
     */
275
    public function multiply(BigInteger $x)
276
    {
277
        return new static($this->value->multiply($x->value));
278
    }
279
 
280
    /**
281
     * Divides two BigIntegers.
282
     *
283
     * Returns an array whose first element contains the quotient and whose second element contains the
284
     * "common residue".  If the remainder would be positive, the "common residue" and the remainder are the
285
     * same.  If the remainder would be negative, the "common residue" is equal to the sum of the remainder
286
     * and the divisor (basically, the "common residue" is the first positive modulo).
287
     *
288
     * Here's an example:
289
     * <code>
290
     * <?php
291
     *    $a = new \phpseclib3\Math\BigInteger('10');
292
     *    $b = new \phpseclib3\Math\BigInteger('20');
293
     *
294
     *    list($quotient, $remainder) = $a->divide($b);
295
     *
296
     *    echo $quotient->toString(); // outputs 0
297
     *    echo "\r\n";
298
     *    echo $remainder->toString(); // outputs 10
299
     * ?>
300
     * </code>
301
     *
302
     * @param BigInteger $y
303
     * @return BigInteger[]
304
     */
305
    public function divide(BigInteger $y)
306
    {
307
        list($q, $r) = $this->value->divide($y->value);
308
        return [
309
            new static($q),
310
            new static($r)
311
        ];
312
    }
313
 
314
    /**
315
     * Calculates modular inverses.
316
     *
317
     * Say you have (30 mod 17 * x mod 17) mod 17 == 1.  x can be found using modular inverses.
318
     *
319
     * @param BigInteger $n
320
     * @return BigInteger
321
     */
322
    public function modInverse(BigInteger $n)
323
    {
324
        return new static($this->value->modInverse($n->value));
325
    }
326
 
327
    /**
328
     * Calculates modular inverses.
329
     *
330
     * Say you have (30 mod 17 * x mod 17) mod 17 == 1.  x can be found using modular inverses.
331
     *
332
     * @param BigInteger $n
333
     * @return BigInteger[]
334
     */
335
    public function extendedGCD(BigInteger $n)
336
    {
337
        extract($this->value->extendedGCD($n->value));
338
        /**
339
         * @var BigInteger $gcd
340
         * @var BigInteger $x
341
         * @var BigInteger $y
342
         */
343
        return [
344
            'gcd' => new static($gcd),
345
            'x' => new static($x),
346
            'y' => new static($y)
347
        ];
348
    }
349
 
350
    /**
351
     * Calculates the greatest common divisor
352
     *
353
     * Say you have 693 and 609.  The GCD is 21.
354
     *
355
     * @param BigInteger $n
356
     * @return BigInteger
357
     */
358
    public function gcd(BigInteger $n)
359
    {
360
        return new static($this->value->gcd($n->value));
361
    }
362
 
363
    /**
364
     * Absolute value.
365
     *
366
     * @return BigInteger
367
     */
368
    public function abs()
369
    {
370
        return new static($this->value->abs());
371
    }
372
 
373
    /**
374
     * Set Precision
375
     *
376
     * Some bitwise operations give different results depending on the precision being used.  Examples include left
377
     * shift, not, and rotates.
378
     *
379
     * @param int $bits
380
     */
381
    public function setPrecision($bits)
382
    {
383
        $this->value->setPrecision($bits);
384
    }
385
 
386
    /**
387
     * Get Precision
388
     *
389
     * Returns the precision if it exists, false if it doesn't
390
     *
391
     * @return int|bool
392
     */
393
    public function getPrecision()
394
    {
395
        return $this->value->getPrecision();
396
    }
397
 
398
    /**
399
     * Serialize
400
     *
401
     * Will be called, automatically, when serialize() is called on a BigInteger object.
402
     *
403
     * __sleep() / __wakeup() have been around since PHP 4.0
404
     *
405
     * \Serializable was introduced in PHP 5.1 and deprecated in PHP 8.1:
406
     * https://wiki.php.net/rfc/phase_out_serializable
407
     *
408
     * __serialize() / __unserialize() were introduced in PHP 7.4:
409
     * https://wiki.php.net/rfc/custom_object_serialization
410
     *
411
     * @return array
412
     */
413
    public function __sleep()
414
    {
415
        $this->hex = $this->toHex(true);
416
        $vars = ['hex'];
417
        if ($this->getPrecision() > 0) {
418
            $vars[] = 'precision';
419
        }
420
        return $vars;
421
    }
422
 
423
    /**
424
     * Serialize
425
     *
426
     * Will be called, automatically, when unserialize() is called on a BigInteger object.
427
     */
428
    public function __wakeup()
429
    {
430
        $temp = new static($this->hex, -16);
431
        $this->value = $temp->value;
432
        if ($this->precision > 0) {
433
            // recalculate $this->bitmask
434
            $this->setPrecision($this->precision);
435
        }
436
    }
437
 
438
    /**
439
     * JSON Serialize
440
     *
441
     * Will be called, automatically, when json_encode() is called on a BigInteger object.
1114 daniel-mar 442
     *
443
     * @return array{hex: string, precision?: int]
827 daniel-mar 444
     */
445
    #[\ReturnTypeWillChange]
446
    public function jsonSerialize()
447
    {
448
        $result = ['hex' => $this->toHex(true)];
449
        if ($this->precision > 0) {
450
            $result['precision'] = $this->getPrecision();
451
        }
452
        return $result;
453
    }
454
 
455
    /**
456
     * Performs modular exponentiation.
457
     *
458
     * @param BigInteger $e
459
     * @param BigInteger $n
460
     * @return BigInteger
461
     */
462
    public function powMod(BigInteger $e, BigInteger $n)
463
    {
464
        return new static($this->value->powMod($e->value, $n->value));
465
    }
466
 
467
    /**
468
     * Performs modular exponentiation.
469
     *
470
     * @param BigInteger $e
471
     * @param BigInteger $n
472
     * @return BigInteger
473
     */
474
    public function modPow(BigInteger $e, BigInteger $n)
475
    {
476
        return new static($this->value->modPow($e->value, $n->value));
477
    }
478
 
479
    /**
480
     * Compares two numbers.
481
     *
482
     * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite.  The reason for this
483
     * is demonstrated thusly:
484
     *
485
     * $x  > $y: $x->compare($y)  > 0
486
     * $x  < $y: $x->compare($y)  < 0
487
     * $x == $y: $x->compare($y) == 0
488
     *
489
     * Note how the same comparison operator is used.  If you want to test for equality, use $x->equals($y).
490
     *
491
     * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.}
492
     *
493
     * @param BigInteger $y
494
     * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
495
     * @see self::equals()
496
     */
497
    public function compare(BigInteger $y)
498
    {
499
        return $this->value->compare($y->value);
500
    }
501
 
502
    /**
503
     * Tests the equality of two numbers.
504
     *
505
     * If you need to see if one number is greater than or less than another number, use BigInteger::compare()
506
     *
507
     * @param BigInteger $x
508
     * @return bool
509
     */
510
    public function equals(BigInteger $x)
511
    {
512
        return $this->value->equals($x->value);
513
    }
514
 
515
    /**
516
     * Logical Not
517
     *
518
     * @return BigInteger
519
     */
520
    public function bitwise_not()
521
    {
522
        return new static($this->value->bitwise_not());
523
    }
524
 
525
    /**
526
     * Logical And
527
     *
528
     * @param BigInteger $x
529
     * @return BigInteger
530
     */
531
    public function bitwise_and(BigInteger $x)
532
    {
533
        return new static($this->value->bitwise_and($x->value));
534
    }
535
 
536
    /**
537
     * Logical Or
538
     *
539
     * @param BigInteger $x
540
     * @return BigInteger
541
     */
542
    public function bitwise_or(BigInteger $x)
543
    {
544
        return new static($this->value->bitwise_or($x->value));
545
    }
546
 
547
    /**
548
     * Logical Exclusive Or
549
     *
550
     * @param BigInteger $x
551
     * @return BigInteger
552
     */
553
    public function bitwise_xor(BigInteger $x)
554
    {
555
        return new static($this->value->bitwise_xor($x->value));
556
    }
557
 
558
    /**
559
     * Logical Right Shift
560
     *
561
     * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift.
562
     *
563
     * @param int $shift
564
     * @return BigInteger
565
     */
566
    public function bitwise_rightShift($shift)
567
    {
568
        return new static($this->value->bitwise_rightShift($shift));
569
    }
570
 
571
    /**
572
     * Logical Left Shift
573
     *
574
     * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.
575
     *
576
     * @param int $shift
577
     * @return BigInteger
578
     */
579
    public function bitwise_leftShift($shift)
580
    {
581
        return new static($this->value->bitwise_leftShift($shift));
582
    }
583
 
584
    /**
585
     * Logical Left Rotate
586
     *
587
     * Instead of the top x bits being dropped they're appended to the shifted bit string.
588
     *
589
     * @param int $shift
590
     * @return BigInteger
591
     */
592
    public function bitwise_leftRotate($shift)
593
    {
594
        return new static($this->value->bitwise_leftRotate($shift));
595
    }
596
 
597
    /**
598
     * Logical Right Rotate
599
     *
600
     * Instead of the bottom x bits being dropped they're prepended to the shifted bit string.
601
     *
602
     * @param int $shift
603
     * @return BigInteger
604
     */
605
    public function bitwise_rightRotate($shift)
606
    {
607
        return new static($this->value->bitwise_rightRotate($shift));
608
    }
609
 
610
    /**
611
     * Returns the smallest and largest n-bit number
612
     *
613
     * @param int $bits
614
     * @return BigInteger[]
615
     */
616
    public static function minMaxBits($bits)
617
    {
618
        self::initialize_static_variables();
619
 
620
        $class = self::$mainEngine;
621
        extract($class::minMaxBits($bits));
622
        /** @var BigInteger $min
623
         * @var BigInteger $max
624
         */
625
        return [
626
            'min' => new static($min),
627
            'max' => new static($max)
628
        ];
629
    }
630
 
631
    /**
632
     * Return the size of a BigInteger in bits
633
     *
634
     * @return int
635
     */
636
    public function getLength()
637
    {
638
        return $this->value->getLength();
639
    }
640
 
641
    /**
642
     * Return the size of a BigInteger in bytes
643
     *
644
     * @return int
645
     */
646
    public function getLengthInBytes()
647
    {
648
        return $this->value->getLengthInBytes();
649
    }
650
 
651
    /**
652
     * Generates a random number of a certain size
653
     *
654
     * Bit length is equal to $size
655
     *
656
     * @param int $size
657
     * @return BigInteger
658
     */
659
    public static function random($size)
660
    {
661
        self::initialize_static_variables();
662
 
663
        $class = self::$mainEngine;
664
        return new static($class::random($size));
665
    }
666
 
667
    /**
668
     * Generates a random prime number of a certain size
669
     *
670
     * Bit length is equal to $size
671
     *
672
     * @param int $size
673
     * @return BigInteger
674
     */
675
    public static function randomPrime($size)
676
    {
677
        self::initialize_static_variables();
678
 
679
        $class = self::$mainEngine;
680
        return new static($class::randomPrime($size));
681
    }
682
 
683
    /**
684
     * Generate a random prime number between a range
685
     *
686
     * If there's not a prime within the given range, false will be returned.
687
     *
688
     * @param BigInteger $min
689
     * @param BigInteger $max
690
     * @return false|BigInteger
691
     */
692
    public static function randomRangePrime(BigInteger $min, BigInteger $max)
693
    {
694
        $class = self::$mainEngine;
695
        return new static($class::randomRangePrime($min->value, $max->value));
696
    }
697
 
698
    /**
699
     * Generate a random number between a range
700
     *
701
     * Returns a random number between $min and $max where $min and $max
702
     * can be defined using one of the two methods:
703
     *
704
     * BigInteger::randomRange($min, $max)
705
     * BigInteger::randomRange($max, $min)
706
     *
707
     * @param BigInteger $min
708
     * @param BigInteger $max
709
     * @return BigInteger
710
     */
711
    public static function randomRange(BigInteger $min, BigInteger $max)
712
    {
713
        $class = self::$mainEngine;
714
        return new static($class::randomRange($min->value, $max->value));
715
    }
716
 
717
    /**
718
     * Checks a numer to see if it's prime
719
     *
720
     * Assuming the $t parameter is not set, this function has an error rate of 2**-80.  The main motivation for the
721
     * $t parameter is distributability.  BigInteger::randomPrime() can be distributed across multiple pageloads
722
     * on a website instead of just one.
723
     *
724
     * @param int|bool $t
725
     * @return bool
726
     */
727
    public function isPrime($t = false)
728
    {
729
        return $this->value->isPrime($t);
730
    }
731
 
732
    /**
733
     * Calculates the nth root of a biginteger.
734
     *
735
     * Returns the nth root of a positive biginteger, where n defaults to 2
736
     *
737
     * @param int $n optional
738
     * @return BigInteger
739
     */
740
    public function root($n = 2)
741
    {
742
        return new static($this->value->root($n));
743
    }
744
 
745
    /**
746
     * Performs exponentiation.
747
     *
748
     * @param BigInteger $n
749
     * @return BigInteger
750
     */
751
    public function pow(BigInteger $n)
752
    {
753
        return new static($this->value->pow($n->value));
754
    }
755
 
756
    /**
757
     * Return the minimum BigInteger between an arbitrary number of BigIntegers.
758
     *
759
     * @param BigInteger ...$nums
760
     * @return BigInteger
761
     */
762
    public static function min(BigInteger ...$nums)
763
    {
764
        $class = self::$mainEngine;
765
        $nums = array_map(function ($num) {
766
            return $num->value;
767
        }, $nums);
768
        return new static($class::min(...$nums));
769
    }
770
 
771
    /**
772
     * Return the maximum BigInteger between an arbitrary number of BigIntegers.
773
     *
774
     * @param BigInteger ...$nums
775
     * @return BigInteger
776
     */
777
    public static function max(BigInteger ...$nums)
778
    {
779
        $class = self::$mainEngine;
780
        $nums = array_map(function ($num) {
781
            return $num->value;
782
        }, $nums);
783
        return new static($class::max(...$nums));
784
    }
785
 
786
    /**
787
     * Tests BigInteger to see if it is between two integers, inclusive
788
     *
789
     * @param BigInteger $min
790
     * @param BigInteger $max
791
     * @return bool
792
     */
793
    public function between(BigInteger $min, BigInteger $max)
794
    {
795
        return $this->value->between($min->value, $max->value);
796
    }
797
 
798
    /**
799
     * Clone
800
     */
801
    public function __clone()
802
    {
803
        $this->value = clone $this->value;
804
    }
805
 
806
    /**
807
     * Is Odd?
808
     *
809
     * @return bool
810
     */
811
    public function isOdd()
812
    {
813
        return $this->value->isOdd();
814
    }
815
 
816
    /**
817
     * Tests if a bit is set
818
     *
819
     * @param int $x
820
     * @return bool
821
     */
822
    public function testBit($x)
823
    {
824
        return $this->value->testBit($x);
825
    }
826
 
827
    /**
828
     * Is Negative?
829
     *
830
     * @return bool
831
     */
832
    public function isNegative()
833
    {
834
        return $this->value->isNegative();
835
    }
836
 
837
    /**
838
     * Negate
839
     *
840
     * Given $k, returns -$k
841
     *
842
     * @return BigInteger
843
     */
844
    public function negate()
845
    {
846
        return new static($this->value->negate());
847
    }
848
 
849
    /**
850
     * Scan for 1 and right shift by that amount
851
     *
852
     * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));
853
     *
854
     * @param BigInteger $r
855
     * @return int
856
     */
857
    public static function scan1divide(BigInteger $r)
858
    {
859
        $class = self::$mainEngine;
860
        return $class::scan1divide($r->value);
861
    }
862
 
863
    /**
864
     * Create Recurring Modulo Function
865
     *
866
     * Sometimes it may be desirable to do repeated modulos with the same number outside of
867
     * modular exponentiation
868
     *
869
     * @return callable
870
     */
871
    public function createRecurringModuloFunction()
872
    {
873
        $func = $this->value->createRecurringModuloFunction();
874
        return function (BigInteger $x) use ($func) {
875
            return new static($func($x->value));
876
        };
877
    }
878
 
879
    /**
880
     * Bitwise Split
881
     *
882
     * Splits BigInteger's into chunks of $split bits
883
     *
884
     * @param int $split
885
     * @return BigInteger[]
886
     */
887
    public function bitwise_split($split)
888
    {
889
        return array_map(function ($val) {
890
            return new static($val);
891
        }, $this->value->bitwise_split($split));
892
    }
1114 daniel-mar 893
}