Ejemplo n.º 1
0
 public static function BitTest($Number, $Bit)
 {
     if (is_resource($Number) !== true) {
         $Number = gmp_init($Number);
     }
     return gmp_testbit($Number, $Bit - 1);
 }
Ejemplo n.º 2
0
 public function __construct($cipher, $key, $taglen)
 {
     $logging = \Plop\Plop::getInstance();
     $this->cipher = mcrypt_module_open($cipher, null, 'ecb', null);
     mcrypt_generic_init($this->cipher, $key, str_repeat("", 16));
     $this->taglen = $taglen;
     $logging->debug('Pre-computing GCM table');
     $H = gmp_init(bin2hex(mcrypt_generic($this->cipher, str_repeat("", 16))), 16);
     $H = str_pad(gmp_strval($H, 2), 128, '0', STR_PAD_LEFT);
     $R = gmp_init('E1000000000000000000000000000000', 16);
     $this->table = array();
     for ($i = 0; $i < 16; $i++) {
         $this->table[$i] = array();
         for ($j = 0; $j < 256; $j++) {
             $V = gmp_init(dechex($j) . str_repeat("00", $i), 16);
             $Z = gmp_init(0);
             for ($k = 0; $k < 128; $k++) {
                 // Compute Z_n+1
                 if ($H[$k]) {
                     $Z = gmp_xor($Z, $V);
                 }
                 // Compute V_n+1
                 $odd = gmp_testbit($V, 0);
                 $V = gmp_div_q($V, 2);
                 if ($odd) {
                     $V = gmp_xor($V, $R);
                 }
             }
             $this->table[$i][$j] = pack('H*', str_pad(gmp_strval($Z, 16), 32, 0, STR_PAD_LEFT));
         }
     }
     $logging->debug('Done pre-computing GCM table');
 }
Ejemplo n.º 3
0
 /**
  * @return array
  */
 public function getValues()
 {
     $values = [];
     for ($i = 0; $i < 8; $i++) {
         if (gmp_testbit($this->bits, $i)) {
             $values[] = $i;
         }
     }
     return $values;
 }
Ejemplo n.º 4
0
 public function has($value)
 {
     $hashes = $this->_hashes($value);
     if (function_exists('gmp_testbit')) {
         foreach ($hashes as $hash) {
             if (!gmp_testbit($this->_gmp, $hash)) {
                 return false;
             }
         }
     } else {
         foreach ($hashes as $hash) {
             if (gmp_scan1($this->_gmp, $hash) !== $hash) {
                 return false;
             }
         }
     }
     return true;
 }
Ejemplo n.º 5
0
<?php

var_dump(gmp_testbit("abc", 1));
Ejemplo n.º 6
0
list($sqrt2, $sqrt2rem) = gmp_sqrtrem("7");
list($sqrt3, $sqrt3rem) = gmp_sqrtrem("1048576");
echo gmp_strval($sqrt1) . ", " . gmp_strval($sqrt1rem) . "\n";
echo gmp_strval($sqrt2) . ", " . gmp_strval($sqrt2rem) . "\n";
echo gmp_strval($sqrt3) . ", " . gmp_strval($sqrt3rem) . "\n";
// gmp_strval
$a = gmp_init("0x41682179fbf5");
printf("Decimal: %s, 36-based: %s" . PHP_EOL, gmp_strval($a), gmp_strval($a, 36));
// gmp_sub
$sub = gmp_sub("281474976710656", "4294967296");
// 2^48 - 2^32
echo gmp_strval($sub) . "\n";
// gmp_testbit
$n = gmp_init("1000000");
var_dump(gmp_testbit($n, 1));
gmp_setbit($n, 1);
var_dump(gmp_testbit($n, 1));
// gmp_xor
$xor1 = gmp_init("1101101110011101", 2);
$xor2 = gmp_init("0110011001011001", 2);
$xor3 = gmp_xor($xor1, $xor2);
echo gmp_strval($xor3, 2) . "\n";
// misc
$someBigNumber = '521384146951941511609433057270365759591953092186117381932611' . '7931051185480744623799627495673518857527248912279381830119491298336733624' . '4065664308602139494639522473719070217986094370277293176752384674818467669' . '4051320005681271452635608277857713427577896091736371787214684409012654958' . '5371050792279689258923542019956112129021960864034418159813629774771309960' . '5187072113497804995105973173281609631859502445945534690830264252230825334' . '4685035261931188171010003137835332083814206171776691473035982534904287554' . '687311595628638823537875937519577818577805321712';
$a = gmp_init($someBigNumber, 10);
var_dump(gmp_strval($a) == $someBigNumber);
var_dump(gmp_strval($a, 32));
$b = gmp_init(0xffffff, 16);
var_dump(gmp_strval($b));
$c = gmp_init($b);
var_dump(gmp_strval($c, 16));
Ejemplo n.º 7
0
<?php

$n = gmp_init(0);
var_dump(gmp_testbit($n, -10));
var_dump(gmp_testbit($n, 0));
var_dump(gmp_testbit($n, 1));
var_dump(gmp_testbit($n, 100));
$n = gmp_init(-1);
var_dump(gmp_testbit($n, 1));
var_dump(gmp_testbit($n, -1));
$n = gmp_init("1000000");
var_dump(gmp_testbit($n, 1));
gmp_setbit($n, 1);
var_dump(gmp_testbit($n, 1));
var_dump(gmp_strval($n));
gmp_setbit($n, 5);
var_dump(gmp_testbit($n, 5));
var_dump(gmp_strval($n));
$n = gmp_init("238462734628347239571823641234");
var_dump(gmp_testbit($n, 5));
gmp_setbit($n, 5);
var_dump(gmp_testbit($n, 5));
var_dump(gmp_strval($n));
gmp_clrbit($n, 5);
var_dump(gmp_testbit($n, 5));
var_dump(gmp_strval($n));
echo "Done\n";
Ejemplo n.º 8
0
 /**
  * @interal Only works up to shift 63 (doesn't wrap bits around).
  * @param resource|int|string $g
  * @param int $shift number of bits to shift left
  * @return resource $g shifted left
  */
 static function shift_left($g, $shift)
 {
     if (0 == $shift) {
         return $g;
     }
     if (0 > gmp_sign($g)) {
         $g = self::gmp_twos_complement($g);
     }
     $m = gmp_mul($g, gmp_pow(self::gmp_2(), $shift));
     $m = gmp_and($m, self::gmp_0xfs());
     if (gmp_testbit($m, 63)) {
         $m = gmp_neg(gmp_add(gmp_and(gmp_com($m), self::gmp_0xfs()), self::gmp_1()));
     }
     return $m;
 }
Ejemplo n.º 9
0
 protected function readTextRecordInner(&$content, &$pos, $recordType)
 {
     switch ($recordType) {
         case Constants::RECORD_TYPE_ZERO_TEXT:
         case Constants::RECORD_TYPE_ZERO_TEXT_WITH_END_ELEMENT:
             return '0';
             break;
         case Constants::RECORD_TYPE_ONE_TEXT:
         case Constants::RECORD_TYPE_ONE_TEXT_WITH_END_ELEMENT:
             return '1';
             break;
         case Constants::RECORD_TYPE_FALSE_TEXT:
         case Constants::RECORD_TYPE_FALSE_TEXT_WITH_END_ELEMENT:
             return 'false';
             break;
         case Constants::RECORD_TYPE_TRUE_TEXT:
         case Constants::RECORD_TYPE_TRUE_TEXT_WITH_END_ELEMENT:
             return 'true';
             break;
         case Constants::RECORD_TYPE_INT8_TEXT:
         case Constants::RECORD_TYPE_INT8_TEXT_WITH_END_ELEMENT:
             $record = unpack('c*', $content[$pos]);
             $pos += 1;
             return (string) $record[1];
             break;
         case Constants::RECORD_TYPE_INT16_TEXT:
         case Constants::RECORD_TYPE_INT16_TEXT_WITH_END_ELEMENT:
             $record = unpack('s*', substr($content, $pos, 2));
             $pos += 2;
             return (string) $record[1];
             break;
         case Constants::RECORD_TYPE_INT32_TEXT:
         case Constants::RECORD_TYPE_INT32_TEXT_WITH_END_ELEMENT:
             $record = unpack('l*', substr($content, $pos, 4));
             $pos += 4;
             return (string) $record[1];
             break;
         case Constants::RECORD_TYPE_INT64_TEXT:
         case Constants::RECORD_TYPE_INT64_TEXT_WITH_END_ELEMENT:
             if (!function_exists('gmp_init')) {
                 throw new DecodingException('Int64 requires GMP extension');
             }
             list(, $int64Hex) = unpack('H*', strrev(substr($content, $pos, 8)));
             $pos += 8;
             return (string) gmp_strval(gmp_init($int64Hex, 16), 10);
             break;
         case Constants::RECORD_TYPE_FLOAT_TEXT:
         case Constants::RECORD_TYPE_FLOAT_TEXT_WITH_END_ELEMENT:
             $record = unpack('f*', substr($content, $pos, 4));
             $pos += 4;
             return (string) $record[1];
             break;
         case Constants::RECORD_TYPE_DOUBLE_TEXT:
         case Constants::RECORD_TYPE_DOUBLE_TEXT_WITH_END_ELEMENT:
             $record = unpack('d*', substr($content, $pos, 8));
             $pos += 8;
             return (string) $record[1];
             break;
         case Constants::RECORD_TYPE_DECIMAL_TEXT:
         case Constants::RECORD_TYPE_DECIMAL_TEXT_WITH_END_ELEMENT:
             if (!function_exists('gmp_init')) {
                 throw new DecodingException('Decimal requires GMP extension');
             }
             $pos += 2;
             // First 2 bytes reserved
             $scale = ord($content[$pos]);
             $pos += 1;
             $sign = ord($content[$pos]);
             $pos += 1;
             list(, $hi32Hex) = unpack('H*', strrev(substr($content, $pos, 4)));
             $pos += 4;
             $hi32 = gmp_init($hi32Hex, 16);
             list(, $lo64Hex) = unpack('H*', strrev(substr($content, $pos, 8)));
             $pos += 8;
             $lo64 = gmp_init($lo64Hex, 16);
             $value = gmp_add(gmp_mul($hi32, gmp_pow(2, 64)), $lo64);
             $record = gmp_strval($value, 10);
             if ($scale > 0) {
                 if ($scale > strlen($record)) {
                     $record = str_repeat('0', $scale - strlen($record)) . $record;
                 }
                 $record = substr($record, 0, strlen($record) - $scale) . '.' . substr($record, $scale * -1);
                 $record = trim($record, '0');
                 if ($record[0] == '.') {
                     $record = '0' . $record;
                 }
             }
             if ($sign == 0x80) {
                 $record = '-' . $record;
             }
             return $record;
             break;
         case Constants::RECORD_TYPE_DATETIME_TEXT:
         case Constants::RECORD_TYPE_DATETIME_TEXT_WITH_END_ELEMENT:
             if (!function_exists('gmp_init')) {
                 throw new DecodingException('Datetime requires GMP extension');
             }
             $binary = '';
             for ($i = 0; $i < 8; ++$i) {
                 list(, $byteint) = unpack('C*', $content[$pos + $i]);
                 $binary = sprintf('%08b', $byteint) . $binary;
             }
             $pos += 8;
             $value = gmp_init(substr($binary, 2, 62), 2);
             // Only calc with seconds, since PHP datetime doesn't support fractions
             $secsRemaining = gmp_div($value, '10000000');
             // Compensate for using unix timestamp
             $epochSecsRemaining = gmp_sub($secsRemaining, '62135596800');
             // Load PHP datetime with seconds remaining
             $datetime = new DateTime('@' . gmp_strval($epochSecsRemaining, 10), new DateTimeZone('UTC'));
             $date = $datetime->format('Y-m-d');
             $time = $datetime->format('H:i:s');
             // Get fractions
             $fraction = substr(gmp_strval($value, 10), -7);
             // Join different time elements
             if ($fraction !== '0000000') {
                 $record = "{$date}T{$time}.{$fraction}";
             } elseif ($time !== '00:00:00') {
                 $record = "{$date}T{$time}";
             } else {
                 $record = "{$date}";
             }
             // Add timezone info
             $tz = gmp_intval(gmp_init(substr($binary, 0, 2), 2));
             if ($tz == 2) {
                 // TODO: local time handling
             } elseif ($tz == 1) {
                 $record .= 'Z';
             }
             return $record;
             break;
         case Constants::RECORD_TYPE_CHARS8_TEXT:
         case Constants::RECORD_TYPE_CHARS8_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('C*', $content[$pos]);
             $pos += 1;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return $record;
             break;
         case Constants::RECORD_TYPE_CHARS16_TEXT:
         case Constants::RECORD_TYPE_CHARS16_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('S*', substr($content, $pos, 2));
             $pos += 2;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return $record;
             break;
         case Constants::RECORD_TYPE_CHARS32_TEXT:
         case Constants::RECORD_TYPE_CHARS32_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('l*', substr($content, $pos, 4));
             $pos += 4;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return $record;
             break;
         case Constants::RECORD_TYPE_BYTES8_TEXT:
         case Constants::RECORD_TYPE_BYTES8_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('C*', $content[$pos]);
             $pos += 1;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return base64_encode($record);
             break;
         case Constants::RECORD_TYPE_BYTES16_TEXT:
         case Constants::RECORD_TYPE_BYTES16_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('S*', substr($content, $pos, 2));
             $pos += 2;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return base64_encode($record);
             break;
         case Constants::RECORD_TYPE_BYTES32_TEXT:
         case Constants::RECORD_TYPE_BYTES32_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('l*', substr($content, $pos, 4));
             $pos += 4;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return base64_encode($record);
             break;
         case Constants::RECORD_TYPE_START_LIST_TEXT:
             $record = '';
             while (ord($content[$pos]) != Constants::RECORD_TYPE_END_LIST_TEXT) {
                 if ($record !== '') {
                     $record .= ' ';
                 }
                 $record .= $this->readTextRecord($content, $pos);
             }
             $pos += 1;
             // skip 1 for end list
             return $record;
             break;
         case Constants::RECORD_TYPE_EMPTY_TEXT:
         case Constants::RECORD_TYPE_EMPTY_TEXT_WITH_END_ELEMENT:
             return '';
             break;
         case Constants::RECORD_TYPE_DICTIONARY_TEXT:
         case Constants::RECORD_TYPE_DICTIONARY_TEXT_WITH_END_ELEMENT:
             return $this->readDictionaryString($content, $pos);
             break;
         case Constants::RECORD_TYPE_UNIQUEID_TEXT:
         case Constants::RECORD_TYPE_UNIQUEID_TEXT_WITH_END_ELEMENT:
         case Constants::RECORD_TYPE_UUID_TEXT:
         case Constants::RECORD_TYPE_UUID_TEXT_WITH_END_ELEMENT:
             list(, $data1) = unpack('H*', strrev(substr($content, $pos, 4)));
             $pos += 4;
             list(, $data2) = unpack('H*', strrev(substr($content, $pos, 2)));
             $pos += 2;
             list(, $data3) = unpack('H*', strrev(substr($content, $pos, 2)));
             $pos += 2;
             list(, $data4) = unpack('H*', substr($content, $pos, 2));
             $pos += 2;
             list(, $data5) = unpack('H*', substr($content, $pos, 6));
             $pos += 6;
             $record = "{$data1}-{$data2}-{$data3}-{$data4}-{$data5}";
             if ($recordType == Constants::RECORD_TYPE_UNIQUEID_TEXT || $recordType == Constants::RECORD_TYPE_UNIQUEID_TEXT_WITH_END_ELEMENT) {
                 $record = 'urn:uuid:' . $record;
             }
             return $record;
             break;
         case Constants::RECORD_TYPE_TIMESPAN_TEXT:
         case Constants::RECORD_TYPE_TIMESPAN_TEXT_WITH_END_ELEMENT:
             if (!function_exists('gmp_init')) {
                 throw new DecodingException('Timespan requires GMP extension');
             }
             $value = '';
             for ($i = 0; $i < 8; $i++) {
                 list(, $byte) = unpack('C*', $content[$pos + $i]);
                 $value = sprintf('%08b', $byte) . $value;
             }
             $pos += 8;
             $value = gmp_init($value, 2);
             $minus = false;
             if (gmp_testbit($value, 63)) {
                 $minus = true;
                 $mask = gmp_init(str_repeat('1', 64), '2');
                 $value = gmp_and(gmp_com($value), $mask);
                 $value = gmp_add($value, 1);
             }
             $remaining = gmp_abs($value);
             list($days, $remaining) = gmp_div_qr($remaining, gmp_init('864000000000'));
             list($hours, $remaining) = gmp_div_qr($remaining, gmp_init('36000000000'));
             list($mins, $remaining) = gmp_div_qr($remaining, gmp_init('600000000'));
             list($secs, $remaining) = gmp_div_qr($remaining, gmp_init('10000000'));
             $fracs = $remaining;
             $days = gmp_intval($days);
             $hours = gmp_intval($hours);
             $mins = gmp_intval($mins);
             $secs = gmp_intval($secs);
             $fracs = gmp_intval($fracs);
             $record = $minus ? '-P' : 'P';
             if ($days > 0) {
                 $record .= $days . 'D';
             }
             if ($hours > 0 || $mins > 0 || $secs > 0 || $fracs > 0) {
                 $record .= 'T';
                 if ($hours > 0) {
                     $record .= $hours . 'H';
                 }
                 if ($mins > 0) {
                     $record .= $mins . 'M';
                 }
                 if ($secs > 0 || $fracs > 0) {
                     $record .= $secs;
                     if ($fracs > 0) {
                         $record .= '.' . $fracs;
                     }
                     $record .= 'S';
                 }
             }
             return $record;
             break;
         case Constants::RECORD_TYPE_UINT64_TEXT:
         case Constants::RECORD_TYPE_UINT64_TEXT_WITH_END_ELEMENT:
             if (!function_exists('gmp_init')) {
                 throw new DecodingException('Uint64 requires GMP extension');
             }
             list(, $uint64Hex) = unpack('H*', strrev(substr($content, $pos, 8)));
             $pos += 8;
             return (string) gmp_strval(gmp_init($uint64Hex, 16), 10);
             break;
         case Constants::RECORD_TYPE_BOOL_TEXT:
         case Constants::RECORD_TYPE_BOOL_TEXT_WITH_END_ELEMENT:
             $record = ord($content[$pos]);
             $pos += 1;
             switch ($record) {
                 case 0:
                     return 'false';
                     break;
                 case 1:
                     return 'true';
                     break;
             }
             throw new DecodingException(sprintf('Unknown boolean value 0x%02X at position %d.', $record, $pos));
             break;
         case Constants::RECORD_TYPE_UNICODECHARS8_TEXT:
         case Constants::RECORD_TYPE_UNICODECHARS8_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('C*', $content[$pos]);
             $pos += 1;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return mb_convert_encoding($record, 'UTF-8', 'UTF-16');
             break;
         case Constants::RECORD_TYPE_UNICODECHARS16_TEXT:
         case Constants::RECORD_TYPE_UNICODECHARS16_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('S*', substr($content, $pos, 2));
             $pos += 2;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return mb_convert_encoding($record, 'UTF-8', 'UTF-16');
             break;
         case Constants::RECORD_TYPE_UNICODECHARS32_TEXT:
         case Constants::RECORD_TYPE_UNICODECHARS32_TEXT_WITH_END_ELEMENT:
             list(, $recordLength) = unpack('l*', substr($content, $pos, 4));
             $pos += 4;
             $record = substr($content, $pos, $recordLength);
             $pos += $recordLength;
             return mb_convert_encoding($record, 'UTF-8', 'UTF-16');
             break;
         case Constants::RECORD_TYPE_QNAMEDICTIONARY_TEXT:
         case Constants::RECORD_TYPE_QNAMEDICTIONARY_TEXT_WITH_END_ELEMENT:
             $prefix = chr(97 + ord($content[$pos]));
             $pos += 1;
             $name = $this->readDictionaryString($content, $pos);
             return $prefix . ':' . $name;
             break;
         default:
             throw new DecodingException(sprintf('Unknown record type 0x%02X at position %d.', $recordType, $pos));
             break;
     }
 }
Ejemplo n.º 10
0
	private static function inet_gmpton( $gmp )
	{
		// 16*8 == 128
		$addr = '';
		for( $bits = 0; $bits < 16; $bits++ )
		{
			$byte = 0;
			for( $b = 0; $b < 8; $b++ )
			{
				if( gmp_testbit( $gmp, (15-$bits)*8+$b ))
				{
					$byte |= 1<<$b;
				}
			}
			$addr .= chr( $byte );
		}
//		echo gmp_strval( $gmp, 16 ).' -> '.inet_ntop( $addr )."<br />\n";
		return $addr;
	}