protected function setIpAttribute($key, $value) { if (!is_null($value)) { $value = gmp_strval(gmp_import(inet_pton($value))); } $this->attributes[$key] = $value; return $this; }
public function checkAuth($nick, $passwd) { if (substr($this->pwdHash, 0, 3) === '#1#') { // 1st case: new, SHA256 SRP logins // https://tools.ietf.org/html/rfc2945#section-3 $pwdArr = explode('#', $this->pwdHash); $x = gmp_import(hash("sha256", base64_decode($pwdArr[2]) . hash("sha256", strtolower($nick) . ':' . $passwd, true), true), 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); $N = gmp_init("AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4" . "A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF60" . "95179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF" . "747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B907" . "8717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB37861" . "60279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DB" . "FBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73", 16); $g = gmp_init(2); $v = gmp_powm($g, $x, $N); // strpos to check if the saved has is the same as our hash, minus the possible base64 padding return strpos(base64_encode(gmp_export($v, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN)), $pwdArr[3]) === 0; } else { // 2nd case: old, pre-SRP logins using salted SHA1 // src/util/auth.cpp#34 at rev 0bf1984d2c9fb3a9dc73303551c18906c3c9482b // https://github.com/minetest/minetest/blob/0bf1984d2c9fb3a9dc73303551c18906c3c9482b/src/util/auth.cpp#L34 return strpos(base64_encode(hash("sha1", $nick . $passwd, true)), $this->pwdHash) === 0; } return false; }
/** * Encode a binary string to base58 * * @param $binary * @return string * @throws \Exception */ protected function encodeBase58($binary_bitcoin_address) { $size = strlen($binary_bitcoin_address); if ($size == 0) { return ''; } $orig = $binary_bitcoin_address; $decimal = gmp_import($binary_bitcoin_address); $return = ""; while (gmp_cmp($decimal, 0) > 0) { list($decimal, $rem) = gmp_div_qr($decimal, 58); $return = $return . self::$BASE_58_CHARS[gmp_intval($rem)]; } $return = strrev($return); //leading zeros for ($i = 0; $i < $size && $orig[$i] == ""; $i++) { $return = "1" . $return; } return $return; }
protected function round($K, $n, $T, $i, $B, $iv, $radix) { // $b is the length of the input when converted to radix=256, thus num of bytes (rounded) $b = (int) ceil(ceil(ceil($n / 2) * log($radix, 2)) / 8); $d = (int) (4 * ceil($b / 4)); // Input $Q = $T . str_repeat("", -strlen($T) - $b - 1 & 0xf) . chr($i) . $this->fixedLength(gmp_export(gmp_init($B, $radix)), $b); // Y = CBC-MAC_K(P·Q) // CBC-MAC is the same as the last block of cipher text of CBC mode and a zero iv (the iv used here is P') $Y = substr(openssl_encrypt($Q, $this->cipher . '-CBC', $K, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $iv), -16); // Y = first d + 4 bytes of (Y · AES_K(Y ⊕ [1]16) · AES_K(Y ⊕ [2]16) · AES_K(Y ⊕ [3]16)·· ) $E = ''; for ($j = 1; $j * 16 < $d + 4; $j++) { $J = $this->fixedLength(gmp_export(gmp_init($j)), 16); $E .= openssl_encrypt($Y ^ $J, $this->cipher . '-ECB', $K, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING); } $Y = substr($Y . $E, 0, $d + 4); // y = NUM_2(Y) $y = gmp_import($Y); $m = (int) ($i & 1 ? ceil($n / 2) : floor($n / 2)); // z = y mod radix^m is actually cropping the string length return $this->fixedLength(gmp_strval($y, $radix), $m, '0'); }
public function calculateSharedKey($publicKeyBin) { $length = strlen($publicKeyBin) - 1; if ($length % 2 != 0) { return; } $half = $length / 2; $x = substr($publicKeyBin, 1, $half); $gmpX = gmp_import($x, 1); $y = substr($publicKeyBin, $half + 1); $gmpY = gmp_import($y, 1); $curve = $this->getCurve(); $adapter = $this->getAdapter(); $gen = $this->getGenerator(); $ecdh = $this->getEcdh(); $point = $curve->getPoint($gmpX, $gmpY); $privateKey = $this->getPrivateKey(); $publicKey = new PublicKey($adapter, $gen, $point); $ecdh->setSenderKey($privateKey); $ecdh->setRecipientKey($publicKey); $sharedKey = $ecdh->calculateSharedKey(); return gmp_export($sharedKey); }
/** * Converts stream of bytes into hexadecimal string. * * @param mixed $raw Stream of bytes. * @param int $length Minimum output length. * * @return string Hex string. */ public static function rawToHex($raw, $length = 0) { $gmp = gmp_import($raw); $hex = gmp_strval($gmp, 16); return self::pad($hex, $length); }
/** * Convert string to GMP number. * * String is interpreted as an unsigned integer with big endian order and * the most significant byte first. * * @param string $data Binary data * @return \GMP */ public static function strToGMP($data) { return gmp_import($data, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); }
// Tests taken from GMPs own test suite. // format is [expected, size, options, input] $import = [['0', 1, GMP_BIG_ENDIAN, ''], ['12345678', 1, GMP_BIG_ENDIAN, '12345678'], ['12345678', 4, GMP_BIG_ENDIAN, '12345678'], ['12345678', 4, GMP_LSW_FIRST | GMP_BIG_ENDIAN, '12345678'], ['12345678', 1, GMP_LSW_FIRST | GMP_LITTLE_ENDIAN, '78563412'], ['12345678', 4, GMP_LITTLE_ENDIAN, '78563412'], ['12345678', 4, GMP_LSW_FIRST | GMP_LITTLE_ENDIAN, '78563412'], ['123456789abc', 2, GMP_BIG_ENDIAN, '123456789abc'], ['123456789abc', 2, GMP_LSW_FIRST | GMP_BIG_ENDIAN, '9abc56781234'], ['123456789abc', 2, GMP_LITTLE_ENDIAN, '34127856bc9a'], ['123456789abc', 2, GMP_LSW_FIRST | GMP_LITTLE_ENDIAN, 'bc9a78563412'], ['112233445566778899aabbcc', 4, GMP_BIG_ENDIAN, '112233445566778899aabbcc'], ['112233445566778899aabbcc', 4, GMP_LSW_FIRST | GMP_BIG_ENDIAN, '99aabbcc5566778811223344'], ['112233445566778899aabbcc', 4, GMP_LITTLE_ENDIAN, '4433221188776655ccbbaa99'], ['112233445566778899aabbcc', 4, GMP_LSW_FIRST | GMP_LITTLE_ENDIAN, 'ccbbaa998877665544332211'], ['100120023003400450056006700780089009a00ab00bc00c', 8, GMP_BIG_ENDIAN, '100120023003400450056006700780089009a00ab00bc00c'], ['100120023003400450056006700780089009a00ab00bc00c', 8, GMP_LSW_FIRST | GMP_BIG_ENDIAN, '9009a00ab00bc00c50056006700780081001200230034004'], ['100120023003400450056006700780089009a00ab00bc00c', 8, GMP_LITTLE_ENDIAN, '044003300220011008800770066005500cc00bb00aa00990'], ['100120023003400450056006700780089009a00ab00bc00c', 8, GMP_LSW_FIRST | GMP_LITTLE_ENDIAN, '0cc00bb00aa0099008800770066005500440033002200110']]; $passed = true; foreach ($import as $k => $test) { $gmp = gmp_import(hex2bin($test[3]), $test[1], $test[2]); if ($gmp instanceof GMP) { $result = gmp_strval($gmp, 16); if ($result !== $test[0]) { echo "{$k}: '{$result}' !== '{$test[0]}'\n"; $passed = false; } } else { $type = gettype($gmp); echo "{$k}: {$type} !== '{$test[0]}'\n"; } } var_dump($passed); // Invalid arguments (zpp failure) var_dump(gmp_import()); // Invalid word sizes var_dump(gmp_import('a', -1)); var_dump(gmp_import('a', 0)); // Invalid data lengths var_dump(gmp_import('a', 2)); var_dump(gmp_import('aa', 3)); var_dump(gmp_import(str_repeat('a', 100), 64)); // Invalid options var_dump(gmp_import('a', 1, GMP_MSW_FIRST | GMP_LSW_FIRST)); var_dump(gmp_import('a', 1, GMP_BIG_ENDIAN | GMP_LITTLE_ENDIAN));
/** * Initialize from a base256 number. * * Base64 number is an octet string of big endian, most significant word * first integer. * * @param string $octets * @return self */ public static function fromBase256($octets) { $num = gmp_import($octets, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); return new self($num); }
/** * Get flags as a base 10 integer. * * @return int|string */ public function number() { $num = gmp_import($this->_flags, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); $last_octet_bits = $this->_width % 8; $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0; $num >>= $unused_bits; return gmp_strval($num, 10); }
/** * Perform Octet-String-to-Integer Conversion. * * Defined in SEC 1 section 2.3.8. * * @param OctetString $os * @return Integer */ public static function octetStringToInteger(OctetString $os) { $num = gmp_import($os->string(), 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); return new Integer(gmp_strval($num, 10)); }