first commit

This commit is contained in:
annnj-company
2026-04-17 18:29:53 +08:00
parent e49fa5a215
commit 130c1026c4
5615 changed files with 1639145 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Mdanter\Ecc\Util;
class BinaryString
{
/**
* Multi-byte-safe string length calculation
*
* @param string $str
* @return int
*/
public static function length(string $str): int
{
// Premature optimization: cache the function_exists() result
static $exists = null;
if ($exists === null) {
$exists = function_exists('mb_strlen');
}
// If it exists, we need to make sure we're using 8bit mode
if ($exists) {
return mb_strlen($str, '8bit');
}
return strlen($str);
}
/**
* Multi-byte-safe substring calculation
*
* @param string $str
* @param int $start
* @param int $length (optional)
* @return string
*/
public static function substring(string $str, int $start = 0, int $length = null): string
{
// Premature optimization: cache the function_exists() result
static $exists = null;
if ($exists === null) {
$exists = function_exists('mb_substr');
}
// If it exists, we need to make sure we're using 8bit mode
if ($exists) {
return mb_substr($str, $start, $length, '8bit');
} elseif ($length !== null) {
return substr($str, $start, $length);
}
return substr($str, $start);
}
/**
* Equivalent to hash_equals() in PHP 5.6
*
* @param string $knownString
* @param string $userString
*
* @return bool
*/
public static function constantTimeCompare(string $knownString, string $userString): bool
{
return hash_equals($knownString, $userString);
}
}

View File

@@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
namespace Mdanter\Ecc\Util;
use Mdanter\Ecc\Math\GmpMathInterface;
class NumberSize
{
/**
* @param GmpMathInterface $adapter
* @param \GMP $x
* @return float
*/
public static function getCeiledByteSize(GmpMathInterface $adapter, \GMP $x): float
{
$log2 = self::bnNumBits($adapter, $x);
return ceil($log2 / 8);
}
/**
* @param GmpMathInterface $adapter
* @param \GMP $x
* @return float
*/
public static function getFlooredByteSize(GmpMathInterface $adapter, \GMP $x): float
{
$log2 = self::bnNumBits($adapter, $x);
return floor($log2 / 8) + 1;
}
/**
* Returns the number of minimum required bytes to store a given number. Non-significant upper bits are not counted.
*
* @param GmpMathInterface $adapter
* @param \GMP $x
* @return int
*
* @link https://www.openssl.org/docs/crypto/BN_num_bytes.html
*/
public static function bnNumBytes(GmpMathInterface $adapter, \GMP $x): int
{
// https://github.com/luvit/openssl/blob/master/openssl/crypto/bn/bn.h#L402
return (int) floor((self::bnNumBits($adapter, $x) + 7) / 8);
}
/**
* Returns the number of bits used to store this number. Non-significant upper bits are not counted.
*
* @param GmpMathInterface $adapter
* @param \GMP $x
* @return int
*
* @link https://www.openssl.org/docs/crypto/BN_num_bytes.html
*/
public static function bnNumBits(GmpMathInterface $adapter, \GMP $x): int
{
$zero = gmp_init(0, 10);
if ($adapter->equals($x, $zero)) {
return 0;
}
$log2 = 0;
while (false === $adapter->equals($x, $zero)) {
$x = $adapter->rightShift($x, 1);
$log2++;
}
return $log2 ;
}
}