[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/phpseclib/phpseclib/phpseclib/Math/ -> BigInteger.php (source)

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