phpseclib: BigInteger Examples and Notes

Action:

<?php
include('Math/BigInteger.php');

$a = new Math_BigInteger(5);
$b = new Math_BigInteger(3);
$c = new Math_BigInteger(4);

$a = new Math_BigInteger(50);
$b = new Math_BigInteger(30);

$a = new Math_BigInteger(30);
$b = new Math_BigInteger(50);

$a = new Math_BigInteger('1100', 2);
$b = new Math_BigInteger('1010', 2);

$a = new Math_BigInteger(pack('H*', 'FA'), 256);

echo $a->add($b); // outputs 5
echo $a->subtract($b); // outputs 2
echo $a->multiply($b); // outputs 15
list($quotient, $residue) = $a->divide($b);
echo $quotient . "\r\n<br />\r\n"; // outputs 1
echo $residue;                     // outputs 2
echo $a->powMod($b, $c); // outputs 1 (eg. 125 % (4 * 31))
echo $a->modInverse($b); // outputs 2
echo $a->gcd($b); // outputs 10
extract($a->extendedGCD($b));

echo $gcd. "\r\n<br />\r\n"; // outputs  10
echo $x  . "\r\n<br />\r\n"; // outputs  29
echo $y;                     // outputs -48
$a = new Math_BigInteger(-5);

echo $a->abs(); // outputs 5
echo $a->compare($b) . "\r\n<br />\r\n"; // outputs  1
echo $b->compare($a) . "\r\n<br />\r\n"; // outputs -1
echo $a->compare($a);                    // outputs  0
var_dump($a->equals($b)); // outputs bool(false)
$rand = new Math_BigInteger();
echo $rand->random($a, $b); // outputs random number between 30 and 50, inclusive
$rand = new Math_BigInteger();
echo $rand->randomPrime($a, $b); // outputs random prime between 30 and 50, inclusive
$a = new Math_BigInteger(47);
var_dump($a->isPrime()); // outputs bool(true)
$a = new Math_BigInteger(347);
$a->setPrecision(8);

echo $a->toBits() . "\r\n<br />\r\n"; // outputs 01011011
$a = $a->bitwise_leftRotate(2);
echo $a->toBits();                    // outputs 01101101
echo $a->bitwise_and($b)->toBits(); // outputs 1000
echo $a->bitwise_or($b)->toBits(); // outputs 1110
echo $a->bitwise_xor($b)->toBits(); // outputs 110
$a = new Math_BigInteger('010', 2);
$a->setPrecision(3);

echo $a->bitwise_not()->toBits(); // outputs 101
$a = new Math_BigInteger('11', 2);

echo $a->bitwise_leftShift(2)->toBits(); // outputs 1100
$a = new Math_BigInteger('1001', 2);
$a->setPrecision(4);

echo $a->bitwise_leftRotate(2)->toBits(); // outputs 0110
$a = new Math_BigInteger('11', 2);

echo $a->bitwise_leftShift(1)->toBits(); // outputs 1
$a = new Math_BigInteger('1001', 2);
$a->setPrecision(4);

echo $a->bitwise_leftRotate(2)->toBits(); // outputs 0110
// all of these are equal to 250
new Math_BigInteger(pack('H*', 'FA'),   256);
new Math_BigInteger(pack('H*', '00FA'),-256);
new Math_BigInteger('FA',   16);
new Math_BigInteger('00FA',-16);
new Math_BigInteger('250',  10);
new Math_BigInteger('250',-10);
new Math_BigInteger('11111010',  2);
new Math_BigInteger('011111010',-2);

// all of these are equal to -6
new Math_BigInteger(pack('H*', 'FA'), -256);
new Math_BigInteger('FA', -16);
new Math_BigInteger('-6', -10);
new Math_BigInteger('11111010', -2);
echo $a->toString(); // outputs 250
echo bin2hex($a->toBytes()) . "\r\n<br />\r\n"; // outputs fa
echo bin2hex($a->toBytes(true));                // outputs 00fa
echo $a->toHex() . "\r\n<br />\r\n"; // outputs fa
echo $a->toHex(true);                // outputs 00fa
echo $a->toBits() . "\r\n<br />\r\n"; // outputs  11111010
echo $a->toBits(true);                // outputs 011111010
?>

Notes

Returns an array whose first element contains the quotient and whose second element contains the"common residue". If the remainder would be positive, the "common residue" and the remainder are the same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder and the divisor (basically, the "common residue" is the first positive modulo).
Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses.
Calculates the greatest common divisor
Say you have 50 and 30. The GCD is 10. Bézout's identity states that there exist integers x and y such that 50*x + 30*y == 10. In point of fact, there are actually an infinite number of x and y combinations and which combination is returned is dependant upon which mode is in use. See Bézout's identity - Wikipedia for more information.
Absolute Value

$a->compare($b) returns 1 if $a > $b, 0 if $a == $b, and -1 if $a < $b. The reason for this is demonstrated thusly:

$x  > $y: $x->compare($y)  > 0
$x  < $y: $x->compare($y)  < 0
$x == $y: $x->compare($y) == 0
$x >= $y: $x->compare($y) >= 0
$x <= $y: $x->compare($y) <= 0

As a consequence of this, !$x->compare($y) does not mean $x != $y but rather $x == $y. If you want to test for equality, use $x->equals($y).

If you need to see if one number is greater than or less than another number, use Math_BigInteger::compare()

Function definition:

Math_BigInteger randomPrime(Math_BigInteger $min, Math_BigInteger $max, int $timeout = false)

If there's not a prime within the given range, false will be returned. If more than $timeout seconds have elapsed, function gives up and return false.

Some bitwise operations give different results depending on the precision being used. Examples include bitwise_leftShift, bitwise_not, bitwise_rightRotate and bitwise_leftRotate.

Whenever a new Math_BigInteger object is created it's precision is set to the same precision as the calling object. In other words, if you do $b = $a->bitwise_not() then $b will have the same precision as $a.

If the precision (see setPrecision) is not explicitely defined, $a->bitwise_not() will always yield a smaller value since the most significant bit is assumed to have a value of one. With fixed precision, however, the leading bit can be anything.

So without $a->setPrecision(3), bitwise_not() in the above example will return a bit value of 1 (with the two leading zero's dropped) whereas with it it returns 101.

The constructor takes two parameters. The first is the number and the second represents the base. Both are optional (if they're not provided, the Math_BigInteger object will assume a value of 0).

If the base is negative (-2, -16, -256) the number will be assumed to be encoded in two's complement.

Called automatically via the __toString magic method on PHP 5+.
If the optional parameter is set to bool(true) the number will be encoded in two's complement.