init
This commit is contained in:
commit
7a3b2960f8
8
composer.json
Normal file
8
composer.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"require": {
|
||||
"workerman/workerman": "^4.2",
|
||||
"kornrunner/keccak": "^1.1",
|
||||
"simplito/elliptic-php": "^1.0",
|
||||
"workerman/globaldata": "^1.0"
|
||||
}
|
||||
}
|
||||
397
composer.lock
generated
Normal file
397
composer.lock
generated
Normal file
@ -0,0 +1,397 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "98dbfa81f42fcda4bf20440ae7f65a2f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "kornrunner/keccak",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kornrunner/php-keccak.git",
|
||||
"reference": "433749d28e117fb97baf9f2631b92b5d9ab3c890"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/kornrunner/php-keccak/zipball/433749d28e117fb97baf9f2631b92b5d9ab3c890",
|
||||
"reference": "433749d28e117fb97baf9f2631b92b5d9ab3c890",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
"symfony/polyfill-mbstring": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"kornrunner\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Boris Momcilovic",
|
||||
"homepage": "https://github.com/kornrunner/php-keccak"
|
||||
}
|
||||
],
|
||||
"description": "Pure PHP implementation of Keccak",
|
||||
"keywords": [
|
||||
"keccak",
|
||||
"sha-3",
|
||||
"sha3-256"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/kornrunner/php-keccak/issues",
|
||||
"source": "https://github.com/kornrunner/php-keccak/tree/1.1.0"
|
||||
},
|
||||
"time": "2020-12-07T15:40:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "simplito/bigint-wrapper-php",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplito/bigint-wrapper-php.git",
|
||||
"reference": "cf21ec76d33f103add487b3eadbd9f5033a25930"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplito/bigint-wrapper-php/zipball/cf21ec76d33f103add487b3eadbd9f5033a25930",
|
||||
"reference": "cf21ec76d33f103add487b3eadbd9f5033a25930",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BI\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for php_gmp and php_bcmath modules",
|
||||
"support": {
|
||||
"issues": "https://github.com/simplito/bigint-wrapper-php/issues",
|
||||
"source": "https://github.com/simplito/bigint-wrapper-php/tree/1.0.0"
|
||||
},
|
||||
"time": "2018-02-27T12:38:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "simplito/bn-php",
|
||||
"version": "1.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplito/bn-php.git",
|
||||
"reference": "83446756a81720eacc2ffb87ff97958431451fd6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplito/bn-php/zipball/83446756a81720eacc2ffb87ff97958431451fd6",
|
||||
"reference": "83446756a81720eacc2ffb87ff97958431451fd6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"simplito/bigint-wrapper-php": "~1.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BN\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"description": "Big number implementation compatible with bn.js",
|
||||
"support": {
|
||||
"issues": "https://github.com/simplito/bn-php/issues",
|
||||
"source": "https://github.com/simplito/bn-php/tree/1.1.4"
|
||||
},
|
||||
"time": "2024-01-10T16:16:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "simplito/elliptic-php",
|
||||
"version": "1.0.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplito/elliptic-php.git",
|
||||
"reference": "be321666781be2be2c89c79c43ffcac834bc8868"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplito/elliptic-php/zipball/be321666781be2be2c89c79c43ffcac834bc8868",
|
||||
"reference": "be321666781be2be2c89c79c43ffcac834bc8868",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gmp": "*",
|
||||
"simplito/bn-php": "~1.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpbench/phpbench": "@dev",
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Elliptic\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"description": "Fast elliptic curve cryptography",
|
||||
"homepage": "https://github.com/simplito/elliptic-php",
|
||||
"keywords": [
|
||||
"Curve25519",
|
||||
"ECDSA",
|
||||
"Ed25519",
|
||||
"EdDSA",
|
||||
"cryptography",
|
||||
"curve",
|
||||
"curve25519-weier",
|
||||
"ecc",
|
||||
"ecdh",
|
||||
"elliptic",
|
||||
"nistp192",
|
||||
"nistp224",
|
||||
"nistp256",
|
||||
"nistp384",
|
||||
"nistp521",
|
||||
"secp256k1"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/simplito/elliptic-php/issues",
|
||||
"source": "https://github.com/simplito/elliptic-php/tree/1.0.12"
|
||||
},
|
||||
"time": "2024-01-09T14:57:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-23T08:48:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "workerman/globaldata",
|
||||
"version": "v1.0.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/GlobalData.git",
|
||||
"reference": "9f5082ad712d98c0deedfbfe244661dce151926f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/GlobalData/zipball/9f5082ad712d98c0deedfbfe244661dce151926f",
|
||||
"reference": "9f5082ad712d98c0deedfbfe244661dce151926f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"workerman/workerman": ">=3.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GlobalData\\": "./src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"homepage": "http://www.workerman.net",
|
||||
"support": {
|
||||
"issues": "https://github.com/walkor/GlobalData/issues",
|
||||
"source": "https://github.com/walkor/GlobalData/tree/v1.0.6"
|
||||
},
|
||||
"time": "2024-12-27T12:40:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "workerman/workerman",
|
||||
"version": "v4.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/workerman.git",
|
||||
"reference": "cafb5a43d93d7d30a16b32a57948581cca993562"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/cafb5a43d93d7d30a16b32a57948581cca993562",
|
||||
"reference": "cafb5a43d93d7d30a16b32a57948581cca993562",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Workerman\\": "./"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "walkor",
|
||||
"email": "walkor@workerman.net",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"keywords": [
|
||||
"asynchronous",
|
||||
"event-loop"
|
||||
],
|
||||
"support": {
|
||||
"email": "walkor@workerman.net",
|
||||
"forum": "http://wenda.workerman.net/",
|
||||
"issues": "https://github.com/walkor/workerman/issues",
|
||||
"source": "https://github.com/walkor/workerman",
|
||||
"wiki": "http://doc.workerman.net/"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/workerman",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/walkor",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-24T11:45:37+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
10
config.php
Normal file
10
config.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
$options=[
|
||||
'workers'=>4,
|
||||
'numeric-only'=> false,
|
||||
'repeat'=>4,
|
||||
'logFile'=>'',
|
||||
'detailInfo'=> false,
|
||||
'staticSecond'=>5,
|
||||
];
|
||||
2
found.log
Normal file
2
found.log
Normal file
@ -0,0 +1,2 @@
|
||||
{"timestamp":"2025-10-09T11:32:29+00:00","address":"0xc3804ee34124040c543330b8bc9fed7a2301dddd","private_key":"cbb084d6de06c149220da85949db7b15a11e014ef25453b9493a48211dacefe0"}
|
||||
{"timestamp":"2025-10-09T11:32:47+00:00","address":"0x24ab4348cdd5488268df22b98837c019c1977777","private_key":"94df5e54b037e71387060d278691b48bf32716386165ed0b8d61d26ca821c991"}
|
||||
219
go.php
Normal file
219
go.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
// start.php
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
require __DIR__ . '/helper.php';
|
||||
require __DIR__ . '/config.php';
|
||||
require __DIR__ . '/version.php';
|
||||
|
||||
use Workerman\Worker;
|
||||
use Elliptic\EC;
|
||||
use kornrunner\Keccak;
|
||||
use Workerman\Timer;
|
||||
|
||||
|
||||
// 你应该实现这个函数:发现地址后要做的事(扫描、转账、上报等)
|
||||
// 这里只给出一个示例实现:异步-safe 的日志 + 简单输出。
|
||||
// 请根据你实际需要替换或扩展该函数内容。
|
||||
// 注意:这个函数在各个子进程中同步执行(阻塞该进程直至返回)。
|
||||
function scanwallet(string $address, string $privateKey): void {
|
||||
// === 示例逻辑(请替换为真实逻辑) ===
|
||||
// 1) 记录到日志文件(追加)
|
||||
global $logFile;
|
||||
$entry = [
|
||||
'timestamp' => date('c'),
|
||||
'address' => $address,
|
||||
'private_key' => $privateKey,
|
||||
];
|
||||
// 写入日志(追加,使用文件锁)
|
||||
$json = json_encode($entry, JSON_UNESCAPED_SLASHES) . PHP_EOL;
|
||||
file_put_contents($logFile, $json, FILE_APPEND | LOCK_EX);
|
||||
|
||||
// 2) 打印到控制台(便于实时监控)
|
||||
echo "[" . date('Y-m-d H:i:s') . "] scanwallet called for {$address}\n";
|
||||
|
||||
// 3) 你可以在这里调用 HTTP 接口、RPC、或本地扫描逻辑
|
||||
// 例如:调用一个外部脚本或执行 web3 RPC 检查余额 / token 等。
|
||||
// 如果操作可能耗时较长,考虑把耗时任务放到队列(Redis/Beanstalk/DB)或另起子进程处理。
|
||||
// =======================================
|
||||
}
|
||||
|
||||
// CLI 参数解析(可选)
|
||||
#$options = getopt('', ['workers::', 'repeat::', 'numeric-only::', 'logfile::']);
|
||||
#echo($options['repeat']);
|
||||
$workerCount = isset($options['workers']) ? (int)$options['workers'] : cpu_count()*4;
|
||||
$minRepeat = isset($options['repeat']) ? (int)$options['repeat'] : 4; // 默认至少 4 个相同
|
||||
$requireNumeric = isset($options['numeric-only']) ? (bool)$options['numeric-only'] : false;
|
||||
$logFile = isset($options['logfile']) ? $options['logfile'] : (__DIR__ . '/found.log');
|
||||
$detailInfo = isset($options['detailInfo']) ? (bool)$options['detailInfo'] : false;
|
||||
$staticSecond = isset($options['staticSecond']) ? (int)$options['staticSecond'] : 10;
|
||||
echo "配置: 详细输出={$detailInfo}, 进程:{$workerCount}, 相同数量={$minRepeat}, 仅数字=" . ($requireNumeric ? 'true' : 'false') . ", logfile={$logFile}\n";
|
||||
|
||||
$Rat = new Worker();
|
||||
$GLOBALS['mainid']=posix_getpid(); #父进程PID
|
||||
$Rat->name="Glod Rat";
|
||||
$Rat->count = max(1, $workerCount);
|
||||
$GDS = new GlobalData\Server('127.0.0.1', 2207);
|
||||
$Rat->onWorkerStart = function($Rat) use ($minRepeat, $requireNumeric,$detailInfo) {
|
||||
global $gd;
|
||||
$gd = new \GlobalData\Client('127.0.0.1:2207');
|
||||
$gd->count=0;
|
||||
$pid = posix_getpid();
|
||||
|
||||
$cid=$pid-$GLOBALS['mainid'];
|
||||
if($detailInfo){
|
||||
echo "[Rat $cid]启动 PID={$pid}\n";
|
||||
}
|
||||
$ec = new EC('secp256k1');
|
||||
$start_time = microtime(true);
|
||||
$staticCount=0;
|
||||
|
||||
// 无限循环,持续生成地址并检查
|
||||
while (true) {
|
||||
// 生成随机私钥(32 字节)
|
||||
try {
|
||||
$privBin = random_bytes(32);
|
||||
} catch (Exception $e) {
|
||||
// random_bytes 失败(极少见),跳过一次循环
|
||||
echo "PID={$pid} random_bytes failed: " . $e->getMessage() . "\n";
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
$privHex = bin2hex($privBin);
|
||||
|
||||
// 由私钥生成公钥(未压缩)
|
||||
$keyPair = $ec->keyFromPrivate($privHex);
|
||||
$pubHex = $keyPair->getPublic(false, 'hex'); // '04' + x + y
|
||||
$pubHexNoPrefix = (strpos($pubHex, '04') === 0) ? substr($pubHex, 2) : $pubHex;
|
||||
|
||||
// keccak256 公钥并取地址
|
||||
$hash = Keccak::hash(hex2bin($pubHexNoPrefix), 256); // 返回 hex
|
||||
$address = '0x' . substr($hash, -40);
|
||||
|
||||
$staticCount=$staticCount+1;
|
||||
if (microtime(true) - $start_time >= 5) {
|
||||
if($detailInfo){
|
||||
echo "[Rat $cid] digged $staticCount address in past 5s \n";
|
||||
}
|
||||
$gd->count=$gd->count+$staticCount;
|
||||
$staticCount=0;
|
||||
$start_time = microtime(true);
|
||||
}
|
||||
|
||||
|
||||
// 检查末尾连续相同字符(只检查尾部连续段)
|
||||
$addrRaw = strtolower(substr($address, 2)); // 纯 hex(40 chars)
|
||||
$len = strlen($addrRaw);
|
||||
$lastChar = $addrRaw[$len - 1];
|
||||
$count = 1;
|
||||
for ($i = $len - 2; $i >= 0; $i--) {
|
||||
if ($addrRaw[$i] === $lastChar) $count++;
|
||||
else break;
|
||||
}
|
||||
|
||||
// 如果满足重复数量,并且(可选)最后字符为数字
|
||||
if ($count >= $minRepeat) {
|
||||
if ($requireNumeric && !ctype_digit($lastChar)) {
|
||||
// 不满足数字要求,继续
|
||||
} else {
|
||||
// 匹配成功 —— 调用 scanwallet 并记录(但不退出,继续寻找)
|
||||
try {
|
||||
// 记录到控制台(便于监控)
|
||||
if($detailInfo){
|
||||
echo " [Rat $cid] PID={$pid} 找到匹配地址 {$address} (尾部 {$count} 个 '{$lastChar}'), 调用 scanwallet\n";
|
||||
}
|
||||
$gd->scount=$gd->scount+1;
|
||||
|
||||
// 可选:把结果也写入一个单独的结果文件(便于批处理)
|
||||
$result = [
|
||||
'pid' => $pid,
|
||||
'private_key' => $privHex,
|
||||
'address' => $address,
|
||||
'repeat_char' => $lastChar,
|
||||
'repeat_count' => $count,
|
||||
'timestamp' => date('c'),
|
||||
'count'=> $count,
|
||||
'char'=> $lastChar,
|
||||
];
|
||||
|
||||
// 调用用户实现的扫描函数(可能阻塞当前进程)
|
||||
# toCache($result);
|
||||
/**
|
||||
// 追加到 found.log(同 scanwallet 中的 global logfile)
|
||||
global $logFile;
|
||||
file_put_contents($logFile, json_encode($result, JSON_UNESCAPED_SLASHES) . PHP_EOL, FILE_APPEND | LOCK_EX);
|
||||
*/
|
||||
// 继续寻找(不要退出)
|
||||
} catch (Throwable $t) {
|
||||
// 避免 scanwallet 中的异常导致进程崩溃
|
||||
if($detailInfo){
|
||||
echo "PID={$pid} scanwallet 抛出异常: " . $t->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 若想降低 CPU 占用可在这里加短暂 sleep(但会降低查找速度)
|
||||
// usleep(0); // 等同于 yield
|
||||
}
|
||||
if($detailInfo){
|
||||
echo "PID={$pid} 退出循环(理论上不应到达)\n";
|
||||
}
|
||||
};
|
||||
$Rat->onWorkerStop = function($Rat) {
|
||||
$pid = posix_getpid();
|
||||
$cid=$pid-$GLOBALS['mainid'];
|
||||
echo "[Rat $cid]启动 PID={$pid} 已终止\n";
|
||||
};
|
||||
$Static = new Worker();
|
||||
$Static->name='Static Server';
|
||||
$Static->onWorkerStart = function($Static)use($staticSecond,$detailInfo) {
|
||||
$GLOBALS['starttime']=microtime(true);
|
||||
$GLOBALS['lc']=0;
|
||||
$GLOBALS['lsc']=0;
|
||||
Timer::add($staticSecond, function()use($staticSecond,$detailInfo){
|
||||
$gda = new \GlobalData\Client('127.0.0.1:2207');
|
||||
$staticCount=$gda->count;
|
||||
$avgCount=($staticCount-$GLOBALS['lc'])/$staticSecond;
|
||||
$successCount=$gda->scount;
|
||||
$avgsCount=($successCount-$GLOBALS['lsc']);
|
||||
$totalSpeed= ($successCount / (microtime(true)-$GLOBALS['starttime'])) * 3600;
|
||||
$running=formatSeconds(microtime(true)-$GLOBALS['starttime']);
|
||||
if(!$detailInfo){
|
||||
echo "\033[H"; // 光标回到左上角
|
||||
echo "\033[J";
|
||||
echo "
|
||||
.88888. dP dP 888888ba dP
|
||||
d8' `88 88 88 88 `8b 88
|
||||
88 .d8888b. 88 .d888b88 a88aaaa8P' .d8888b. d8888P
|
||||
88 YP88 88' `88 88 88' `88 88 `8b. 88' `88 88
|
||||
Y8. .88 88. .88 88 88. .88 88 88 88. .88 88
|
||||
`88888' `88888P' dP `88888P8 dP dP `88888P8 dP
|
||||
====================================================
|
||||
|| Gold Rat v".GR_VERSION." Build ".GR_BUILD." ||
|
||||
||Dig out wallet address with the beautiful number||
|
||||
|| As well as a CPU Benchmark tool ||
|
||||
====================================================
|
||||
";
|
||||
}
|
||||
echo "[STATIC] in last $staticSecond s:
|
||||
Avg: $avgCount adds/s, Total: $staticCount adds
|
||||
Succeed: $avgsCount adds, Total: $successCount adds
|
||||
Total Diging Speed: $totalSpeed adds/hour
|
||||
Total Runing Time: $running
|
||||
====================================================
|
||||
Enter Ctrl+C to Exit.
|
||||
————————————————————————————————————————————————————
|
||||
©Gold Rat by LayFi.de
|
||||
\n";
|
||||
|
||||
$GLOBALS['lc']=$staticCount;
|
||||
$GLOBALS['lsc']=$successCount;
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Worker::runAll();
|
||||
36
helper.php
Normal file
36
helper.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
function cpu_count(): int
|
||||
{
|
||||
// Windows does not support the number of processes setting.
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
return 1;
|
||||
}
|
||||
$count = 4;
|
||||
if (is_callable('shell_exec')) {
|
||||
if (strtolower(PHP_OS) === 'darwin') {
|
||||
$count = (int)shell_exec('sysctl -n machdep.cpu.core_count');
|
||||
} else {
|
||||
try {
|
||||
$count = (int)shell_exec('nproc');
|
||||
} catch (\Throwable $ex) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
return $count > 0 ? $count : 4;
|
||||
}
|
||||
function formatSeconds($seconds) {
|
||||
$days = floor($seconds / 86400);
|
||||
$hours = floor(($seconds % 86400) / 3600);
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$secs = $seconds % 60;
|
||||
|
||||
$result = '';
|
||||
if ($days > 0) $result .= $days."D ";
|
||||
if ($hours > 0) $result .= $hours."H ";
|
||||
if ($minutes > 0) $result .= $minutes."M ";
|
||||
if ($secs > 0 || $result === '') $result .= $secs."S";
|
||||
|
||||
return $result;
|
||||
}
|
||||
16
readme.md
Normal file
16
readme.md
Normal file
@ -0,0 +1,16 @@
|
||||
```
|
||||
.88888. dP dP 888888ba dP
|
||||
d8' `88 88 88 88 `8b 88
|
||||
88 .d8888b. 88 .d888b88 a88aaaa8P' .d8888b. d8888P
|
||||
88 YP88 88' `88 88 88' `88 88 `8b. 88' `88 88
|
||||
Y8. .88 88. .88 88 88. .88 88 88 88. .88 88
|
||||
`88888' `88888P' dP `88888P8 dP dP `88888P8 dP
|
||||
```
|
||||
|
||||
# GOLD RAT
|
||||
|
||||
## What is Gold Rat?
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
4
toCache.php
Normal file
4
toCache.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
function toCache($result){
|
||||
|
||||
}
|
||||
25
vendor/autoload.php
vendored
Normal file
25
vendor/autoload.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit54847d6030d29731b0e767d050d22a36::getLoader();
|
||||
579
vendor/composer/ClassLoader.php
vendored
Normal file
579
vendor/composer/ClassLoader.php
vendored
Normal file
@ -0,0 +1,579 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var string|null */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array<string, list<string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* List of PSR-0 prefixes
|
||||
*
|
||||
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
|
||||
*
|
||||
* @var array<string, array<string, list<string>>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var string|null */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var array<string, self>
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param string|null $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string> Array of classname => path
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $classMap Class to filename map
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
$paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
$paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders keyed by their corresponding vendor directories.
|
||||
*
|
||||
* @return array<string, self>
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
359
vendor/composer/InstalledVersions.php
vendored
Normal file
359
vendor/composer/InstalledVersions.php
vendored
Normal file
@ -0,0 +1,359 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints((string) $constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require __DIR__ . '/installed.php';
|
||||
self::$installed = $required;
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$installed !== array()) {
|
||||
$installed[] = self::$installed;
|
||||
}
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
21
vendor/composer/LICENSE
vendored
Normal file
21
vendor/composer/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
10
vendor/composer/autoload_classmap.php
vendored
Normal file
10
vendor/composer/autoload_classmap.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
);
|
||||
10
vendor/composer/autoload_files.php
vendored
Normal file
10
vendor/composer/autoload_files.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
);
|
||||
9
vendor/composer/autoload_namespaces.php
vendored
Normal file
9
vendor/composer/autoload_namespaces.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
16
vendor/composer/autoload_psr4.php
vendored
Normal file
16
vendor/composer/autoload_psr4.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'kornrunner\\' => array($vendorDir . '/kornrunner/keccak/src'),
|
||||
'Workerman\\' => array($vendorDir . '/workerman/workerman'),
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'GlobalData\\' => array($vendorDir . '/workerman/globaldata/src'),
|
||||
'Elliptic\\' => array($vendorDir . '/simplito/elliptic-php/lib'),
|
||||
'BN\\' => array($vendorDir . '/simplito/bn-php/lib'),
|
||||
'BI\\' => array($vendorDir . '/simplito/bigint-wrapper-php/lib'),
|
||||
);
|
||||
50
vendor/composer/autoload_real.php
vendored
Normal file
50
vendor/composer/autoload_real.php
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit54847d6030d29731b0e767d050d22a36
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit54847d6030d29731b0e767d050d22a36', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit54847d6030d29731b0e767d050d22a36', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit54847d6030d29731b0e767d050d22a36::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit54847d6030d29731b0e767d050d22a36::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
$requireFile($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
85
vendor/composer/autoload_static.php
vendored
Normal file
85
vendor/composer/autoload_static.php
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit54847d6030d29731b0e767d050d22a36
|
||||
{
|
||||
public static $files = array (
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'k' =>
|
||||
array (
|
||||
'kornrunner\\' => 11,
|
||||
),
|
||||
'W' =>
|
||||
array (
|
||||
'Workerman\\' => 10,
|
||||
),
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||
),
|
||||
'G' =>
|
||||
array (
|
||||
'GlobalData\\' => 11,
|
||||
),
|
||||
'E' =>
|
||||
array (
|
||||
'Elliptic\\' => 9,
|
||||
),
|
||||
'B' =>
|
||||
array (
|
||||
'BN\\' => 3,
|
||||
'BI\\' => 3,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'kornrunner\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/kornrunner/keccak/src',
|
||||
),
|
||||
'Workerman\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/workerman',
|
||||
),
|
||||
'Symfony\\Polyfill\\Mbstring\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
|
||||
),
|
||||
'GlobalData\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/globaldata/src',
|
||||
),
|
||||
'Elliptic\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/simplito/elliptic-php/lib',
|
||||
),
|
||||
'BN\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/simplito/bn-php/lib',
|
||||
),
|
||||
'BI\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/simplito/bigint-wrapper-php/lib',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit54847d6030d29731b0e767d050d22a36::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit54847d6030d29731b0e767d050d22a36::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit54847d6030d29731b0e767d050d22a36::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
405
vendor/composer/installed.json
vendored
Normal file
405
vendor/composer/installed.json
vendored
Normal file
@ -0,0 +1,405 @@
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "kornrunner/keccak",
|
||||
"version": "1.1.0",
|
||||
"version_normalized": "1.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kornrunner/php-keccak.git",
|
||||
"reference": "433749d28e117fb97baf9f2631b92b5d9ab3c890"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/kornrunner/php-keccak/zipball/433749d28e117fb97baf9f2631b92b5d9ab3c890",
|
||||
"reference": "433749d28e117fb97baf9f2631b92b5d9ab3c890",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
"symfony/polyfill-mbstring": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.2"
|
||||
},
|
||||
"time": "2020-12-07T15:40:44+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"kornrunner\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Boris Momcilovic",
|
||||
"homepage": "https://github.com/kornrunner/php-keccak"
|
||||
}
|
||||
],
|
||||
"description": "Pure PHP implementation of Keccak",
|
||||
"keywords": [
|
||||
"keccak",
|
||||
"sha-3",
|
||||
"sha3-256"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/kornrunner/php-keccak/issues",
|
||||
"source": "https://github.com/kornrunner/php-keccak/tree/1.1.0"
|
||||
},
|
||||
"install-path": "../kornrunner/keccak"
|
||||
},
|
||||
{
|
||||
"name": "simplito/bigint-wrapper-php",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplito/bigint-wrapper-php.git",
|
||||
"reference": "cf21ec76d33f103add487b3eadbd9f5033a25930"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplito/bigint-wrapper-php/zipball/cf21ec76d33f103add487b3eadbd9f5033a25930",
|
||||
"reference": "cf21ec76d33f103add487b3eadbd9f5033a25930",
|
||||
"shasum": ""
|
||||
},
|
||||
"time": "2018-02-27T12:38:08+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BI\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for php_gmp and php_bcmath modules",
|
||||
"support": {
|
||||
"issues": "https://github.com/simplito/bigint-wrapper-php/issues",
|
||||
"source": "https://github.com/simplito/bigint-wrapper-php/tree/1.0.0"
|
||||
},
|
||||
"install-path": "../simplito/bigint-wrapper-php"
|
||||
},
|
||||
{
|
||||
"name": "simplito/bn-php",
|
||||
"version": "1.1.4",
|
||||
"version_normalized": "1.1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplito/bn-php.git",
|
||||
"reference": "83446756a81720eacc2ffb87ff97958431451fd6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplito/bn-php/zipball/83446756a81720eacc2ffb87ff97958431451fd6",
|
||||
"reference": "83446756a81720eacc2ffb87ff97958431451fd6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"simplito/bigint-wrapper-php": "~1.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"time": "2024-01-10T16:16:59+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BN\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"description": "Big number implementation compatible with bn.js",
|
||||
"support": {
|
||||
"issues": "https://github.com/simplito/bn-php/issues",
|
||||
"source": "https://github.com/simplito/bn-php/tree/1.1.4"
|
||||
},
|
||||
"install-path": "../simplito/bn-php"
|
||||
},
|
||||
{
|
||||
"name": "simplito/elliptic-php",
|
||||
"version": "1.0.12",
|
||||
"version_normalized": "1.0.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplito/elliptic-php.git",
|
||||
"reference": "be321666781be2be2c89c79c43ffcac834bc8868"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplito/elliptic-php/zipball/be321666781be2be2c89c79c43ffcac834bc8868",
|
||||
"reference": "be321666781be2be2c89c79c43ffcac834bc8868",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gmp": "*",
|
||||
"simplito/bn-php": "~1.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpbench/phpbench": "@dev",
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"time": "2024-01-09T14:57:04+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Elliptic\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"description": "Fast elliptic curve cryptography",
|
||||
"homepage": "https://github.com/simplito/elliptic-php",
|
||||
"keywords": [
|
||||
"Curve25519",
|
||||
"ECDSA",
|
||||
"Ed25519",
|
||||
"EdDSA",
|
||||
"cryptography",
|
||||
"curve",
|
||||
"curve25519-weier",
|
||||
"ecc",
|
||||
"ecdh",
|
||||
"elliptic",
|
||||
"nistp192",
|
||||
"nistp224",
|
||||
"nistp256",
|
||||
"nistp384",
|
||||
"nistp521",
|
||||
"secp256k1"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/simplito/elliptic-php/issues",
|
||||
"source": "https://github.com/simplito/elliptic-php/tree/1.0.12"
|
||||
},
|
||||
"install-path": "../simplito/elliptic-php"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.33.0",
|
||||
"version_normalized": "1.33.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"time": "2024-12-23T08:48:59+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/polyfill-mbstring"
|
||||
},
|
||||
{
|
||||
"name": "workerman/globaldata",
|
||||
"version": "v1.0.6",
|
||||
"version_normalized": "1.0.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/GlobalData.git",
|
||||
"reference": "9f5082ad712d98c0deedfbfe244661dce151926f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/GlobalData/zipball/9f5082ad712d98c0deedfbfe244661dce151926f",
|
||||
"reference": "9f5082ad712d98c0deedfbfe244661dce151926f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"workerman/workerman": ">=3.3.0"
|
||||
},
|
||||
"time": "2024-12-27T12:40:16+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GlobalData\\": "./src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"homepage": "http://www.workerman.net",
|
||||
"support": {
|
||||
"issues": "https://github.com/walkor/GlobalData/issues",
|
||||
"source": "https://github.com/walkor/GlobalData/tree/v1.0.6"
|
||||
},
|
||||
"install-path": "../workerman/globaldata"
|
||||
},
|
||||
{
|
||||
"name": "workerman/workerman",
|
||||
"version": "v4.2.1",
|
||||
"version_normalized": "4.2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/workerman.git",
|
||||
"reference": "cafb5a43d93d7d30a16b32a57948581cca993562"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/cafb5a43d93d7d30a16b32a57948581cca993562",
|
||||
"reference": "cafb5a43d93d7d30a16b32a57948581cca993562",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
},
|
||||
"time": "2024-11-24T11:45:37+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Workerman\\": "./"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "walkor",
|
||||
"email": "walkor@workerman.net",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"keywords": [
|
||||
"asynchronous",
|
||||
"event-loop"
|
||||
],
|
||||
"support": {
|
||||
"email": "walkor@workerman.net",
|
||||
"forum": "http://wenda.workerman.net/",
|
||||
"issues": "https://github.com/walkor/workerman/issues",
|
||||
"source": "https://github.com/walkor/workerman",
|
||||
"wiki": "http://doc.workerman.net/"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/workerman",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/walkor",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"install-path": "../workerman/workerman"
|
||||
}
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": []
|
||||
}
|
||||
86
vendor/composer/installed.php
vendored
Normal file
86
vendor/composer/installed.php
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => '__root__',
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => NULL,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'__root__' => array(
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => NULL,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'kornrunner/keccak' => array(
|
||||
'pretty_version' => '1.1.0',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => '433749d28e117fb97baf9f2631b92b5d9ab3c890',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../kornrunner/keccak',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'simplito/bigint-wrapper-php' => array(
|
||||
'pretty_version' => '1.0.0',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => 'cf21ec76d33f103add487b3eadbd9f5033a25930',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../simplito/bigint-wrapper-php',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'simplito/bn-php' => array(
|
||||
'pretty_version' => '1.1.4',
|
||||
'version' => '1.1.4.0',
|
||||
'reference' => '83446756a81720eacc2ffb87ff97958431451fd6',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../simplito/bn-php',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'simplito/elliptic-php' => array(
|
||||
'pretty_version' => '1.0.12',
|
||||
'version' => '1.0.12.0',
|
||||
'reference' => 'be321666781be2be2c89c79c43ffcac834bc8868',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../simplito/elliptic-php',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '6d857f4d76bd4b343eac26d6b539585d2bc56493',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/globaldata' => array(
|
||||
'pretty_version' => 'v1.0.6',
|
||||
'version' => '1.0.6.0',
|
||||
'reference' => '9f5082ad712d98c0deedfbfe244661dce151926f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../workerman/globaldata',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/workerman' => array(
|
||||
'pretty_version' => 'v4.2.1',
|
||||
'version' => '4.2.1.0',
|
||||
'reference' => 'cafb5a43d93d7d30a16b32a57948581cca993562',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../workerman/workerman',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
26
vendor/composer/platform_check.php
vendored
Normal file
26
vendor/composer/platform_check.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 80000)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
3
vendor/kornrunner/keccak/.coveralls.yml
vendored
Normal file
3
vendor/kornrunner/keccak/.coveralls.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
service_name: travis-ci
|
||||
coverage_clover: build/logs/clover.xml
|
||||
json_path: coveralls-upload.json
|
||||
10
vendor/kornrunner/keccak/.gitignore
vendored
Normal file
10
vendor/kornrunner/keccak/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
composer.phar
|
||||
/vendor/
|
||||
|
||||
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
|
||||
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
|
||||
# composer.lock
|
||||
nbproject/
|
||||
build/
|
||||
.phpunit.result.cache
|
||||
infection.log
|
||||
23
vendor/kornrunner/keccak/.travis.yml
vendored
Normal file
23
vendor/kornrunner/keccak/.travis.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 7.3
|
||||
- 7.4
|
||||
- 8.0
|
||||
- nightly
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
|
||||
install:
|
||||
- phpenv config-rm xdebug.ini || true
|
||||
- travis_retry composer install --prefer-dist -n
|
||||
|
||||
script:
|
||||
- mkdir -p build/logs
|
||||
- phpdbg -qrr vendor/bin/phpunit
|
||||
|
||||
after_success:
|
||||
- composer require php-coveralls/php-coveralls
|
||||
- travis_retry vendor/bin/php-coveralls -v
|
||||
21
vendor/kornrunner/keccak/LICENSE
vendored
Normal file
21
vendor/kornrunner/keccak/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Boris Momčilović
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
32
vendor/kornrunner/keccak/README.md
vendored
Normal file
32
vendor/kornrunner/keccak/README.md
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
# php-keccak [](https://travis-ci.org/kornrunner/php-keccak) [](https://ci.appveyor.com/project/kornrunner/php-keccak/branch/master) [](https://coveralls.io/github/kornrunner/php-keccak?branch=master) [](https://packagist.org/packages/kornrunner/keccak)
|
||||
Pure PHP implementation of Keccak (SHA-3)
|
||||
|
||||
## Usage
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use kornrunner\Keccak;
|
||||
|
||||
Keccak::hash('', 224);
|
||||
// f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd
|
||||
|
||||
Keccak::hash('', 256);
|
||||
// c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
|
||||
|
||||
Keccak::hash('', 384);
|
||||
// 2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff
|
||||
|
||||
Keccak::hash('', 512);
|
||||
// 0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e
|
||||
|
||||
Keccak::shake('', 128, 256);
|
||||
// 7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26
|
||||
|
||||
Keccak::shake('', 256, 512);
|
||||
// 46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be
|
||||
```
|
||||
|
||||
[ 0x9c7b7a00972121fb843af7af74526d7eb585b171][Ethereum]
|
||||
|
||||
[Ethereum]: https://etherscan.io/address/0x9c7b7a00972121fb843af7af74526d7eb585b171 "Donate with Ethereum"
|
||||
48
vendor/kornrunner/keccak/appveyor.yml
vendored
Normal file
48
vendor/kornrunner/keccak/appveyor.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
build: false
|
||||
shallow_clone: true
|
||||
clone_folder: c:\php-keccak
|
||||
platform: x64
|
||||
|
||||
cache:
|
||||
- c:\php -> appveyor.yml
|
||||
- vendor -> composer.lock
|
||||
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- PHP_VERSION: '7.3.7'
|
||||
PHP_DOWNLOAD_URL: 'https://windows.php.net/downloads/releases/archives/php-7.3.7-nts-Win32-VC15-x64.zip'
|
||||
- PHP_VERSION: '7.4.3'
|
||||
PHP_DOWNLOAD_URL: 'https://windows.php.net/downloads/releases/archives/php-7.4.3-nts-Win32-vc15-x64.zip'
|
||||
- PHP_VERSION: '8.0.0'
|
||||
PHP_DOWNLOAD_URL: 'https://windows.php.net/downloads/releases/php-8.0.0-nts-Win32-vs16-x64.zip'
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
init:
|
||||
- SET PATH=c:\php\%PHP_VERSION%;%PATH%
|
||||
- set COMPOSER_NO_INTERACTION=1
|
||||
|
||||
install:
|
||||
- IF NOT EXIST c:\php mkdir c:\php
|
||||
- IF NOT EXIST c:\php\%PHP_VERSION% mkdir c:\php\%PHP_VERSION%
|
||||
- cd c:\php\%PHP_VERSION%
|
||||
- IF NOT EXIST php-installed.txt curl --fail --location --silent --show-error -o php.zip %PHP_DOWNLOAD_URL%
|
||||
- IF NOT EXIST php-installed.txt 7z x php.zip -y
|
||||
- IF NOT EXIST php-installed.txt del /Q *.zip
|
||||
- IF NOT EXIST php-installed.txt copy /Y php.ini-development php.ini
|
||||
- IF NOT EXIST php-installed.txt echo max_execution_time=1200 >> php.ini
|
||||
- IF NOT EXIST php-installed.txt echo date.timezone="UTC" >> php.ini
|
||||
- IF NOT EXIST php-installed.txt echo extension_dir=ext >> php.ini
|
||||
- IF NOT EXIST php-installed.txt echo extension=php_openssl.dll >> php.ini
|
||||
- IF NOT EXIST php-installed.txt echo extension=php_mbstring.dll >> php.ini
|
||||
- IF NOT EXIST php-installed.txt appveyor DownloadFile https://getcomposer.org/composer.phar
|
||||
- IF NOT EXIST php-installed.txt echo @php %%~dp0composer.phar %%* > composer.bat
|
||||
- IF NOT EXIST php-installed.txt type nul >> php-installed.txt
|
||||
- cd c:\php-keccak
|
||||
|
||||
test_script:
|
||||
- composer install
|
||||
- vendor/bin/phpunit.bat --coverage-text
|
||||
|
||||
29
vendor/kornrunner/keccak/composer.json
vendored
Normal file
29
vendor/kornrunner/keccak/composer.json
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "kornrunner/keccak",
|
||||
"description": "Pure PHP implementation of Keccak",
|
||||
"keywords": ["keccak", "sha-3", "sha3-256"],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Boris Momcilovic",
|
||||
"homepage": "https://github.com/kornrunner/php-keccak"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
"symfony/polyfill-mbstring": "^1.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"kornrunner\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"kornrunner\\": "test"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.2"
|
||||
}
|
||||
}
|
||||
1870
vendor/kornrunner/keccak/composer.lock
generated
vendored
Normal file
1870
vendor/kornrunner/keccak/composer.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
14
vendor/kornrunner/keccak/infection.json.dist
vendored
Normal file
14
vendor/kornrunner/keccak/infection.json.dist
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"timeout": 10,
|
||||
"source": {
|
||||
"directories": [
|
||||
"src"
|
||||
]
|
||||
},
|
||||
"logs": {
|
||||
"text": "infection.log"
|
||||
},
|
||||
"mutators": {
|
||||
"@default": true
|
||||
}
|
||||
}
|
||||
33
vendor/kornrunner/keccak/phpunit.xml.dist
vendored
Normal file
33
vendor/kornrunner/keccak/phpunit.xml.dist
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="vendor/autoload.php"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Keccak Test Suite">
|
||||
<directory>test</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<logging>
|
||||
<log type="tap" target="build/report.tap"/>
|
||||
<log type="junit" target="build/report.junit.xml"/>
|
||||
<log type="coverage-html" target="build/coverage"/>
|
||||
<log type="coverage-text" target="build/coverage.txt"/>
|
||||
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
||||
</logging>
|
||||
</phpunit>
|
||||
312
vendor/kornrunner/keccak/src/Keccak.php
vendored
Normal file
312
vendor/kornrunner/keccak/src/Keccak.php
vendored
Normal file
@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
namespace kornrunner;
|
||||
|
||||
use Exception;
|
||||
use function mb_strlen;
|
||||
use function mb_substr;
|
||||
|
||||
final class Keccak
|
||||
{
|
||||
private const KECCAK_ROUNDS = 24;
|
||||
private const LFSR = 0x01;
|
||||
private const ENCODING = '8bit';
|
||||
private static $keccakf_rotc = [1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44];
|
||||
private static $keccakf_piln = [10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12,2, 20, 14, 22, 9, 6, 1];
|
||||
private static $x64 = (PHP_INT_SIZE === 8);
|
||||
|
||||
private static function keccakf64(&$st, $rounds): void {
|
||||
$keccakf_rndc = [
|
||||
[0x00000000, 0x00000001], [0x00000000, 0x00008082], [0x80000000, 0x0000808a], [0x80000000, 0x80008000],
|
||||
[0x00000000, 0x0000808b], [0x00000000, 0x80000001], [0x80000000, 0x80008081], [0x80000000, 0x00008009],
|
||||
[0x00000000, 0x0000008a], [0x00000000, 0x00000088], [0x00000000, 0x80008009], [0x00000000, 0x8000000a],
|
||||
[0x00000000, 0x8000808b], [0x80000000, 0x0000008b], [0x80000000, 0x00008089], [0x80000000, 0x00008003],
|
||||
[0x80000000, 0x00008002], [0x80000000, 0x00000080], [0x00000000, 0x0000800a], [0x80000000, 0x8000000a],
|
||||
[0x80000000, 0x80008081], [0x80000000, 0x00008080], [0x00000000, 0x80000001], [0x80000000, 0x80008008]
|
||||
];
|
||||
|
||||
$bc = [];
|
||||
for ($round = 0; $round < $rounds; $round++) {
|
||||
|
||||
// Theta
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$bc[$i] = [
|
||||
$st[$i][0] ^ $st[$i + 5][0] ^ $st[$i + 10][0] ^ $st[$i + 15][0] ^ $st[$i + 20][0],
|
||||
$st[$i][1] ^ $st[$i + 5][1] ^ $st[$i + 10][1] ^ $st[$i + 15][1] ^ $st[$i + 20][1]
|
||||
];
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$t = [
|
||||
$bc[($i + 4) % 5][0] ^ (($bc[($i + 1) % 5][0] << 1) | ($bc[($i + 1) % 5][1] >> 31)) & (0xFFFFFFFF),
|
||||
$bc[($i + 4) % 5][1] ^ (($bc[($i + 1) % 5][1] << 1) | ($bc[($i + 1) % 5][0] >> 31)) & (0xFFFFFFFF)
|
||||
];
|
||||
|
||||
for ($j = 0; $j < 25; $j += 5) {
|
||||
$st[$j + $i] = [
|
||||
$st[$j + $i][0] ^ $t[0],
|
||||
$st[$j + $i][1] ^ $t[1]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Rho Pi
|
||||
$t = $st[1];
|
||||
for ($i = 0; $i < 24; $i++) {
|
||||
$j = self::$keccakf_piln[$i];
|
||||
|
||||
$bc[0] = $st[$j];
|
||||
|
||||
$n = self::$keccakf_rotc[$i];
|
||||
$hi = $t[0];
|
||||
$lo = $t[1];
|
||||
if ($n >= 32) {
|
||||
$n -= 32;
|
||||
$hi = $t[1];
|
||||
$lo = $t[0];
|
||||
}
|
||||
|
||||
$st[$j] =[
|
||||
(($hi << $n) | ($lo >> (32 - $n))) & (0xFFFFFFFF),
|
||||
(($lo << $n) | ($hi >> (32 - $n))) & (0xFFFFFFFF)
|
||||
];
|
||||
|
||||
$t = $bc[0];
|
||||
}
|
||||
|
||||
// Chi
|
||||
for ($j = 0; $j < 25; $j += 5) {
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$bc[$i] = $st[$j + $i];
|
||||
}
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$st[$j + $i] = [
|
||||
$st[$j + $i][0] ^ ~$bc[($i + 1) % 5][0] & $bc[($i + 2) % 5][0],
|
||||
$st[$j + $i][1] ^ ~$bc[($i + 1) % 5][1] & $bc[($i + 2) % 5][1]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Iota
|
||||
$st[0] = [
|
||||
$st[0][0] ^ $keccakf_rndc[$round][0],
|
||||
$st[0][1] ^ $keccakf_rndc[$round][1]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private static function keccak64($in_raw, int $capacity, int $outputlength, $suffix, bool $raw_output): string {
|
||||
$capacity /= 8;
|
||||
|
||||
$inlen = mb_strlen($in_raw, self::ENCODING);
|
||||
|
||||
$rsiz = 200 - 2 * $capacity;
|
||||
$rsizw = $rsiz / 8;
|
||||
|
||||
$st = [];
|
||||
for ($i = 0; $i < 25; $i++) {
|
||||
$st[] = [0, 0];
|
||||
}
|
||||
|
||||
for ($in_t = 0; $inlen >= $rsiz; $inlen -= $rsiz, $in_t += $rsiz) {
|
||||
for ($i = 0; $i < $rsizw; $i++) {
|
||||
$t = unpack('V*', mb_substr($in_raw, intval($i * 8 + $in_t), 8, self::ENCODING));
|
||||
|
||||
$st[$i] = [
|
||||
$st[$i][0] ^ $t[2],
|
||||
$st[$i][1] ^ $t[1]
|
||||
];
|
||||
}
|
||||
|
||||
self::keccakf64($st, self::KECCAK_ROUNDS);
|
||||
}
|
||||
|
||||
$temp = mb_substr($in_raw, (int) $in_t, (int) $inlen, self::ENCODING);
|
||||
$temp = str_pad($temp, (int) $rsiz, "\x0", STR_PAD_RIGHT);
|
||||
$temp = substr_replace($temp, chr($suffix), $inlen, 1);
|
||||
$temp = substr_replace($temp, chr(ord($temp[intval($rsiz - 1)]) | 0x80), $rsiz - 1, 1);
|
||||
|
||||
for ($i = 0; $i < $rsizw; $i++) {
|
||||
$t = unpack('V*', mb_substr($temp, $i * 8, 8, self::ENCODING));
|
||||
|
||||
$st[$i] = [
|
||||
$st[$i][0] ^ $t[2],
|
||||
$st[$i][1] ^ $t[1]
|
||||
];
|
||||
}
|
||||
|
||||
self::keccakf64($st, self::KECCAK_ROUNDS);
|
||||
|
||||
$out = '';
|
||||
for ($i = 0; $i < 25; $i++) {
|
||||
$out .= $t = pack('V*', $st[$i][1], $st[$i][0]);
|
||||
}
|
||||
$r = mb_substr($out, 0, intval($outputlength / 8), self::ENCODING);
|
||||
|
||||
return $raw_output ? $r : bin2hex($r);
|
||||
}
|
||||
|
||||
private static function keccakf32(&$st, $rounds): void {
|
||||
$keccakf_rndc = [
|
||||
[0x0000, 0x0000, 0x0000, 0x0001], [0x0000, 0x0000, 0x0000, 0x8082], [0x8000, 0x0000, 0x0000, 0x0808a], [0x8000, 0x0000, 0x8000, 0x8000],
|
||||
[0x0000, 0x0000, 0x0000, 0x808b], [0x0000, 0x0000, 0x8000, 0x0001], [0x8000, 0x0000, 0x8000, 0x08081], [0x8000, 0x0000, 0x0000, 0x8009],
|
||||
[0x0000, 0x0000, 0x0000, 0x008a], [0x0000, 0x0000, 0x0000, 0x0088], [0x0000, 0x0000, 0x8000, 0x08009], [0x0000, 0x0000, 0x8000, 0x000a],
|
||||
[0x0000, 0x0000, 0x8000, 0x808b], [0x8000, 0x0000, 0x0000, 0x008b], [0x8000, 0x0000, 0x0000, 0x08089], [0x8000, 0x0000, 0x0000, 0x8003],
|
||||
[0x8000, 0x0000, 0x0000, 0x8002], [0x8000, 0x0000, 0x0000, 0x0080], [0x0000, 0x0000, 0x0000, 0x0800a], [0x8000, 0x0000, 0x8000, 0x000a],
|
||||
[0x8000, 0x0000, 0x8000, 0x8081], [0x8000, 0x0000, 0x0000, 0x8080], [0x0000, 0x0000, 0x8000, 0x00001], [0x8000, 0x0000, 0x8000, 0x8008]
|
||||
];
|
||||
|
||||
$bc = [];
|
||||
for ($round = 0; $round < $rounds; $round++) {
|
||||
|
||||
// Theta
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$bc[$i] = [
|
||||
$st[$i][0] ^ $st[$i + 5][0] ^ $st[$i + 10][0] ^ $st[$i + 15][0] ^ $st[$i + 20][0],
|
||||
$st[$i][1] ^ $st[$i + 5][1] ^ $st[$i + 10][1] ^ $st[$i + 15][1] ^ $st[$i + 20][1],
|
||||
$st[$i][2] ^ $st[$i + 5][2] ^ $st[$i + 10][2] ^ $st[$i + 15][2] ^ $st[$i + 20][2],
|
||||
$st[$i][3] ^ $st[$i + 5][3] ^ $st[$i + 10][3] ^ $st[$i + 15][3] ^ $st[$i + 20][3]
|
||||
];
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$t = [
|
||||
$bc[($i + 4) % 5][0] ^ ((($bc[($i + 1) % 5][0] << 1) | ($bc[($i + 1) % 5][1] >> 15)) & (0xFFFF)),
|
||||
$bc[($i + 4) % 5][1] ^ ((($bc[($i + 1) % 5][1] << 1) | ($bc[($i + 1) % 5][2] >> 15)) & (0xFFFF)),
|
||||
$bc[($i + 4) % 5][2] ^ ((($bc[($i + 1) % 5][2] << 1) | ($bc[($i + 1) % 5][3] >> 15)) & (0xFFFF)),
|
||||
$bc[($i + 4) % 5][3] ^ ((($bc[($i + 1) % 5][3] << 1) | ($bc[($i + 1) % 5][0] >> 15)) & (0xFFFF))
|
||||
];
|
||||
|
||||
for ($j = 0; $j < 25; $j += 5) {
|
||||
$st[$j + $i] = [
|
||||
$st[$j + $i][0] ^ $t[0],
|
||||
$st[$j + $i][1] ^ $t[1],
|
||||
$st[$j + $i][2] ^ $t[2],
|
||||
$st[$j + $i][3] ^ $t[3]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Rho Pi
|
||||
$t = $st[1];
|
||||
for ($i = 0; $i < 24; $i++) {
|
||||
$j = self::$keccakf_piln[$i];
|
||||
$bc[0] = $st[$j];
|
||||
|
||||
|
||||
$n = self::$keccakf_rotc[$i] >> 4;
|
||||
$m = self::$keccakf_rotc[$i] % 16;
|
||||
|
||||
$st[$j] = [
|
||||
((($t[(0+$n) %4] << $m) | ($t[(1+$n) %4] >> (16-$m))) & (0xFFFF)),
|
||||
((($t[(1+$n) %4] << $m) | ($t[(2+$n) %4] >> (16-$m))) & (0xFFFF)),
|
||||
((($t[(2+$n) %4] << $m) | ($t[(3+$n) %4] >> (16-$m))) & (0xFFFF)),
|
||||
((($t[(3+$n) %4] << $m) | ($t[(0+$n) %4] >> (16-$m))) & (0xFFFF))
|
||||
];
|
||||
|
||||
$t = $bc[0];
|
||||
}
|
||||
|
||||
// Chi
|
||||
for ($j = 0; $j < 25; $j += 5) {
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$bc[$i] = $st[$j + $i];
|
||||
}
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$st[$j + $i] = [
|
||||
$st[$j + $i][0] ^ ~$bc[($i + 1) % 5][0] & $bc[($i + 2) % 5][0],
|
||||
$st[$j + $i][1] ^ ~$bc[($i + 1) % 5][1] & $bc[($i + 2) % 5][1],
|
||||
$st[$j + $i][2] ^ ~$bc[($i + 1) % 5][2] & $bc[($i + 2) % 5][2],
|
||||
$st[$j + $i][3] ^ ~$bc[($i + 1) % 5][3] & $bc[($i + 2) % 5][3]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Iota
|
||||
$st[0] = [
|
||||
$st[0][0] ^ $keccakf_rndc[$round][0],
|
||||
$st[0][1] ^ $keccakf_rndc[$round][1],
|
||||
$st[0][2] ^ $keccakf_rndc[$round][2],
|
||||
$st[0][3] ^ $keccakf_rndc[$round][3]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private static function keccak32($in_raw, int $capacity, int $outputlength, $suffix, bool $raw_output): string {
|
||||
$capacity /= 8;
|
||||
|
||||
$inlen = mb_strlen($in_raw, self::ENCODING);
|
||||
|
||||
$rsiz = 200 - 2 * $capacity;
|
||||
$rsizw = $rsiz / 8;
|
||||
|
||||
$st = [];
|
||||
for ($i = 0; $i < 25; $i++) {
|
||||
$st[] = [0, 0, 0, 0];
|
||||
}
|
||||
|
||||
for ($in_t = 0; $inlen >= $rsiz; $inlen -= $rsiz, $in_t += $rsiz) {
|
||||
for ($i = 0; $i < $rsizw; $i++) {
|
||||
$t = unpack('v*', mb_substr($in_raw, intval($i * 8 + $in_t), 8, self::ENCODING));
|
||||
|
||||
$st[$i] = [
|
||||
$st[$i][0] ^ $t[4],
|
||||
$st[$i][1] ^ $t[3],
|
||||
$st[$i][2] ^ $t[2],
|
||||
$st[$i][3] ^ $t[1]
|
||||
];
|
||||
}
|
||||
|
||||
self::keccakf32($st, self::KECCAK_ROUNDS);
|
||||
}
|
||||
|
||||
$temp = mb_substr($in_raw, (int) $in_t, (int) $inlen, self::ENCODING);
|
||||
$temp = str_pad($temp, (int) $rsiz, "\x0", STR_PAD_RIGHT);
|
||||
$temp = substr_replace($temp, chr($suffix), $inlen, 1);
|
||||
$temp = substr_replace($temp, chr((int) $temp[intval($rsiz - 1)] | 0x80), $rsiz - 1, 1);
|
||||
|
||||
for ($i = 0; $i < $rsizw; $i++) {
|
||||
$t = unpack('v*', mb_substr($temp, $i * 8, 8, self::ENCODING));
|
||||
|
||||
$st[$i] = [
|
||||
$st[$i][0] ^ $t[4],
|
||||
$st[$i][1] ^ $t[3],
|
||||
$st[$i][2] ^ $t[2],
|
||||
$st[$i][3] ^ $t[1]
|
||||
];
|
||||
}
|
||||
|
||||
self::keccakf32($st, self::KECCAK_ROUNDS);
|
||||
|
||||
$out = '';
|
||||
for ($i = 0; $i < 25; $i++) {
|
||||
$out .= $t = pack('v*', $st[$i][3],$st[$i][2], $st[$i][1], $st[$i][0]);
|
||||
}
|
||||
$r = mb_substr($out, 0, intval($outputlength / 8), self::ENCODING);
|
||||
|
||||
return $raw_output ? $r: bin2hex($r);
|
||||
}
|
||||
|
||||
private static function keccak($in_raw, int $capacity, int $outputlength, $suffix, bool $raw_output): string {
|
||||
return self::$x64
|
||||
? self::keccak64($in_raw, $capacity, $outputlength, $suffix, $raw_output)
|
||||
: self::keccak32($in_raw, $capacity, $outputlength, $suffix, $raw_output);
|
||||
}
|
||||
|
||||
public static function hash($in, int $mdlen, bool $raw_output = false): string {
|
||||
if (!in_array($mdlen, [224, 256, 384, 512], true)) {
|
||||
throw new Exception('Unsupported Keccak Hash output size.');
|
||||
}
|
||||
|
||||
return self::keccak($in, $mdlen, $mdlen, self::LFSR, $raw_output);
|
||||
}
|
||||
|
||||
public static function shake($in, int $security_level, int $outlen, bool $raw_output = false): string {
|
||||
if (!in_array($security_level, [128, 256], true)) {
|
||||
throw new Exception('Unsupported Keccak Shake security level.');
|
||||
}
|
||||
|
||||
return self::keccak($in, $security_level, $outlen, 0x1f, $raw_output);
|
||||
}
|
||||
|
||||
}
|
||||
140
vendor/kornrunner/keccak/test/KeccakTest.php
vendored
Normal file
140
vendor/kornrunner/keccak/test/KeccakTest.php
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace kornrunner;
|
||||
|
||||
/**
|
||||
*@see https://gist.github.com/Souptacular/f50128d63b5188490fa2
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class KeccakTest extends TestCase
|
||||
{
|
||||
private const SHORT = "52A608AB21CCDD8A4457A57EDE782176";
|
||||
private const LONG = "3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F5623CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A15358F336D03AE18F666C7573D55C4FD181C29E6CCFDE63EA35F0ADF5885CFC0A3D84A2B2E4DD24496DB789E663170CEF74798AA1BBCD4574EA0BBA40489D764B2F83AADC66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43C70088B6183639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D817FC2534A52F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E085172E328807C02D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1";
|
||||
private static $x64;
|
||||
|
||||
public static function setUpBeforeClass(): void {
|
||||
parent::setUpBeforeClass();
|
||||
$class = new \ReflectionClass(Keccak::class);
|
||||
self::$x64 = $class->getProperty('x64');
|
||||
self::$x64->setAccessible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider hash
|
||||
*/
|
||||
public function testHash($level, $tests) {
|
||||
$x64_values = [true, false];
|
||||
foreach ($x64_values as $x64_bit) {
|
||||
self::$x64->setValue($x64_bit);
|
||||
|
||||
foreach($tests as $test) {
|
||||
$message = $test[0];
|
||||
$expected = $test[1];
|
||||
$this->assertEquals($expected, Keccak::hash($message, $level));
|
||||
$this->assertEquals(hex2bin($expected), Keccak::hash($message, $level, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function hash(): array {
|
||||
return [
|
||||
/**
|
||||
* @see https://emn178.github.io/online-tools/keccak_512.html
|
||||
*/
|
||||
[512, [
|
||||
['','0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e'],
|
||||
['testing', '9558a7ba9ac74b33b347703ffe33f8d561d86d9fcad1cfd63225fb55dfea50a0953a0efafd6072377f4c396e806d5bda0294cba28762740d8446fee45a276e4a'],
|
||||
['The quick brown fox jumps over the lazy dog', 'd135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609'],
|
||||
['The quick brown fox jumps over the lazy dog.','ab7192d2b11f51c7dd744e7b3441febf397ca07bf812cceae122ca4ded6387889064f8db9230f173f6d1ab6e24b6e50f065b039f799f5592360a6558eb52d760'],
|
||||
[hex2bin(self::SHORT), '4b39d3da5bcdf4d9b769015995644311c14c435bf72b1009d6dd71b01a63b97cfb596418e8e42342d117e07471a8914314ba7b0e264dadf0cea381868cbd43d1'],
|
||||
[hex2bin(self::LONG), '81950e7096d31d4f22e3db71cac725bf59e81af54c7ca9e6aeee71c010fc5467466312a01aa5c137cfb140646941556796f612c9351268737c7e9a2b9631d1fa']
|
||||
]],
|
||||
/**
|
||||
* @see https://emn178.github.io/online-tools/keccak_384.html
|
||||
*/
|
||||
[384, [
|
||||
['', '2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff'],
|
||||
['testing', '1020b1c91956efe79b89c387b54de4f7a9c187c3970552f9f48c0da176f6326b7aa694795d2c9adcf2bdd20aec605588'],
|
||||
['The quick brown fox jumps over the lazy dog', '283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3'],
|
||||
['The quick brown fox jumps over the lazy dog.', '9ad8e17325408eddb6edee6147f13856ad819bb7532668b605a24a2d958f88bd5c169e56dc4b2f89ffd325f6006d820b'],
|
||||
[hex2bin(self::SHORT), '18422ac1d3a1e54bad876883d2d6dd65f65c1d5f33a7125cc4c186405a12ed64ba96672eedda8c5a6331d28683f488eb'],
|
||||
[hex2bin(self::LONG), '6bff1c8405a3fe594e360e3bccea1ebcd509310dc79b9e45c263783d7a5dd662c6789b18bd567dbdda1554f5bee6a860'],
|
||||
[hex2bin('E35780EB9799AD4C77535D4DDB683CF33EF367715327CF4C4A58ED9CBDCDD486F669F80189D549A9364FA82A51A52654EC721BB3AAB95DCEB4A86A6AFA93826DB923517E928F33E3FBA850D45660EF83B9876ACCAFA2A9987A254B137C6E140A21691E1069413848'), '9fb5700502e01926824f46e9f61894f9487dbcf8ae6217203c85606f975566539376d6239db04aef9bf48ca4f191a90b'],
|
||||
]],
|
||||
/**
|
||||
* @see https://emn178.github.io/online-tools/keccak_256.html
|
||||
*/
|
||||
[256, [
|
||||
['', 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'],
|
||||
['testing', '5f16f4c7f149ac4f9510d9cf8cf384038ad348b3bcdc01915f95de12df9d1b02'],
|
||||
['The quick brown fox jumps over the lazy dog', '4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15'],
|
||||
['The quick brown fox jumps over the lazy dog.', '578951e24efd62a3d63a86f7cd19aaa53c898fe287d2552133220370240b572d'],
|
||||
[hex2bin(self::SHORT), '0e32defa2071f0b5ac0e6a108b842ed0f1d3249712f58ee0ddf956fe332a5f95'],
|
||||
[hex2bin(self::LONG), '348fb774adc970a16b1105669442625e6adaa8257a89effdb5a802f161b862ea'],
|
||||
[hex2bin('9F2FCC7C90DE090D6B87CD7E9718C1EA6CB21118FC2D5DE9F97E5DB6AC1E9C10'), '24dd2ee02482144f539f810d2caa8a7b75d0fa33657e47932122d273c3f6f6d1'],
|
||||
]],
|
||||
/**
|
||||
* @see https://emn178.github.io/online-tools/keccak_224.html
|
||||
*/
|
||||
[224, [
|
||||
['', 'f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd'],
|
||||
['testing', '7b77b0b01d9b669ec7637ae75fd2f0ce234c8c8c835723b6715f4b59'],
|
||||
['The quick brown fox jumps over the lazy dog', '310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe'],
|
||||
['The quick brown fox jumps over the lazy dog.', 'c59d4eaeac728671c635ff645014e2afa935bebffdb5fbd207ffdeab'],
|
||||
[hex2bin(self::SHORT), '5679cd509c5120af54795cf477149641cf27b2ebb6a5f90340704e57'],
|
||||
[hex2bin(self::LONG), '5af56987ea9cf11fcd0eac5ebc14b037365e9b1123e31cb2dfc7929a'],
|
||||
]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider Shake
|
||||
*/
|
||||
public function testShake($level, $size, $tests)
|
||||
{
|
||||
$x64_values = [true, false];
|
||||
foreach ($x64_values as $x64_bit) {
|
||||
self::$x64->setValue($x64_bit);
|
||||
|
||||
foreach($tests as $test) {
|
||||
$message = $test[0];
|
||||
$expected = $test[1];
|
||||
$this->assertEquals($expected, Keccak::shake($message, $level, $size));
|
||||
$this->assertEquals(hex2bin($expected), Keccak::shake($message, $level, $size, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function shake(): array {
|
||||
return [
|
||||
[128, 256, [
|
||||
['', '7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26'],
|
||||
[hex2bin(self::SHORT), '3a0faca70c9d2b81d1064d429ea3b05ad27366f64985379ddd75bc73d6a83810'],
|
||||
[hex2bin(self::LONG), '14236e75b9784df4f57935f945356cbe383fe513ed30286f91060759bcb0ef4b'],
|
||||
['The quick brown fox jumps over the lazy dog', 'f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66e'],
|
||||
['The quick brown fox jumps over the lazy dof', '853f4538be0db9621a6cea659a06c1107b1f83f02b13d18297bd39d7411cf10c'],
|
||||
]],
|
||||
[256, 512, [
|
||||
['', '46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be'],
|
||||
[hex2bin(self::SHORT), '57119c4507f975ad0e9ea4f1166e5f9b590bf2671aaeb41d130d2c570bafc579b0b9ec485cc736a0a848bbc886cbaa79ffcd067ce64b3b410741ab011c544225'],
|
||||
[hex2bin(self::LONG), '8a5199b4a7e133e264a86202720655894d48cff344a928cf8347f48379cef347dfc5bcffab99b27b1f89aa2735e23d30088ffa03b9edb02b9635470ab9f10389'],
|
||||
]],
|
||||
];
|
||||
}
|
||||
|
||||
public function testUnsupportedHashOutputSize()
|
||||
{
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('Unsupported Keccak Hash output size.');
|
||||
Keccak::hash('', 225);
|
||||
}
|
||||
|
||||
public function testUnsupportedShakeSecurityLevel()
|
||||
{
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('Unsupported Keccak Shake security level.');
|
||||
Keccak::shake('', 129, 256);
|
||||
}
|
||||
}
|
||||
23
vendor/simplito/bigint-wrapper-php/LICENSE.md
vendored
Normal file
23
vendor/simplito/bigint-wrapper-php/LICENSE.md
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
## MIT LICENSE
|
||||
|
||||
Copyright (C) 2018 Simplito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
190
vendor/simplito/bigint-wrapper-php/README.md
vendored
Normal file
190
vendor/simplito/bigint-wrapper-php/README.md
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
|
||||
# BigInteger wrapper library for PHP
|
||||
|
||||
## Information
|
||||
|
||||
This library is a common interface for php_gmp and php_bcmath modules. It automatically detects supported modules and uses the best of them (gmp>bcmath). Gmp is a lot faster, but is also missing on many hosting services -- that is why this wrapper has been created. It is used for example in encryption functions of the [PrivMX WebMail](https://privmx.com) software.
|
||||
|
||||
## Installation
|
||||
|
||||
You can install this library via Composer:
|
||||
```
|
||||
composer require simplito/bigint-wrapper-php
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
If you want to force using a specific implementation, then define constant S_MATH_BIGINTEGER_MODE - set it to "gmp" or "bcmath". If you do not do this, mode of operation and the constant will be set automatically.
|
||||
|
||||
If there are no gmp and bcmath modules, an exception will be thrown. If you want to prevent this, then simply define S_MATH_BIGINTEGER_QUIET constant.
|
||||
|
||||
All functions of this library are implemented as members of class BigInteger, which is located under BI namespace. Instances of BigInteger are immutable - member functions usually return new instances of the BigInteger class.
|
||||
|
||||
|
||||
### ConvertibleToBi - a placeholder type
|
||||
|
||||
To make the below documentation more readable we use the "ConvertibleToBi" type symbol, which in reality can be one of the following types:
|
||||
- an instance of the BigInteger class
|
||||
- an integer
|
||||
- a decimal string
|
||||
- a gmp resource or class (only when you are in gmp mode)
|
||||
|
||||
If you have a non-decimal string and want to use it -- first you have to convert it to BigInteger class using:
|
||||
```
|
||||
new BigInteger($myNonDecimalString, $baseOfMyNonDecimalString)
|
||||
```
|
||||
|
||||
### BI\BigInteger class members
|
||||
|
||||
#### construct(ConvertibleToBi $value = 0, int $base = 10)
|
||||
Creates a new instance of BigInteger. If you pass an invalid value, an exception will be thrown. If $base === true then passed $value will be used without any check and conversion. Supported bases: 2, 10, 16, 256.
|
||||
- **GMP implementation:** gmp_init + bin2hex for 256 base
|
||||
- **Bcmath implementation:** custom(bcadd + bcmul)
|
||||
|
||||
#### static BigInteger|false createSafe(ConvertibleToBi $value = 0, int $base = 10)
|
||||
Creates a new BigInteger instance in the same way as constructor, but if there is an error, false will be returned instead of throwing an exception.
|
||||
|
||||
#### BigInteger add(ConvertibleToBi $x)
|
||||
Adds numbers
|
||||
- **GMP implementation:** gmp_add
|
||||
- **Bcmath implementation:** bcadd
|
||||
|
||||
#### BigInteger sub(ConvertibleToBi $x)
|
||||
Subtracts numbers
|
||||
- **GMP implementation:** gmp_sub
|
||||
- **Bcmath implementation:** bcsub
|
||||
|
||||
#### BigInteger mul(ConvertibleToBi $x)
|
||||
Multiplies numbers
|
||||
- **GMP implementation:** gmp_mul
|
||||
- **Bcmath implementation:** bcmul
|
||||
|
||||
#### BigInteger div(ConvertibleToBi $x)
|
||||
Divides numbers
|
||||
- **GMP implementation:** gmp_div_q
|
||||
- **Bcmath implementation:** bcdiv
|
||||
|
||||
#### BigInteger divR(ConvertibleToBi $x)
|
||||
Returns a remainder of the division of numbers. The remainder has the sign of the divided number.
|
||||
- **GMP implementation:** gmp_div_r
|
||||
- **Bcmath implementation:** bcmod
|
||||
|
||||
#### array(BigInteger, BigInteger) divQR(ConvertibleToBi $x)
|
||||
Divides numbers and returns quotient and remainder. Returns an array(), with the first element being quotient, and the second being remainder.
|
||||
- **GMP implementation:** gmp_div_qr
|
||||
- **Bcmath implementation:** div + divR
|
||||
|
||||
#### BigInteger mod(ConvertibleToBi $x)
|
||||
The "division modulo" operation. The result is always non-negative, the sign of divider is ignored.
|
||||
- **GMP implementation:** gmp_mod
|
||||
- **Bcmath implementation:** custom (bcmod + bcadd)
|
||||
|
||||
#### BigInteger gcd(ConvertibleToBi $x)
|
||||
Calculates greatest common divisor
|
||||
- **GMP implementation:** gmp_gcd
|
||||
- **Bcmath implementation:** custom (bccomp + bcdiv + bcsub + bcmul)
|
||||
|
||||
#### BigInteger|false modInverse(ConvertibleToBi $x)
|
||||
Inverses by modulo, returns false if inversion does not exist.
|
||||
- **GMP implementation:** gmp_invert
|
||||
- **Bcmath implementation:** custom (gcd)
|
||||
|
||||
#### BigInteger pow(ConvertibleToBi $x)
|
||||
The power function.
|
||||
- **GMP implementation:** gmp_pow
|
||||
- **Bcmath implementation:** bcpow
|
||||
|
||||
#### BigInteger powMod(ConvertibleToBi $x, ConvertibleToBi $n)
|
||||
The modular power function.
|
||||
- **GMP implementation:** gmp_powm
|
||||
- **Bcmath implementation:** bcpowmod
|
||||
|
||||
#### BigInteger abs()
|
||||
Returns absolute value.
|
||||
- **GMP implementation:** gmp_abs
|
||||
- **Bcmath implementation:** check first character
|
||||
|
||||
#### BigInteger neg()
|
||||
Negates the number
|
||||
- **GMP implementation:** gmp_neg
|
||||
- **Bcmath implementation:** check first character
|
||||
|
||||
#### BigInteger binaryAnd(ConvertibleToBi $x)
|
||||
Bitwise AND.
|
||||
- **GMP implementation:** gmp_and
|
||||
- **Bcmath implementation:** custom (toBytes + php string and)
|
||||
|
||||
#### BigInteger binaryOr(ConvertibleToBi $x)
|
||||
Bitwise OR
|
||||
- **GMP implementation:** gmp_or
|
||||
- **Bcmath implementation:** custom (toBytes + php string or)
|
||||
|
||||
#### BigInteger binaryXor(ConvertibleToBi $x)
|
||||
Bitwise XOR
|
||||
- **GMP implementation:** gmp_xor
|
||||
- **Bcmath implementation:** custom (toBytes + php string xor)
|
||||
|
||||
#### BigInteger setbit($index, $bitOn = true)
|
||||
Sets bit at given index
|
||||
- **GMP implementation:** gmp_setbit
|
||||
- **Bcmath implementation:** custom (toBits)
|
||||
|
||||
#### bool testbit($index)
|
||||
Tests if a bit at given index is set
|
||||
- **GMP implementation:** gmp_testbit
|
||||
- **Bcmath implementation:** custom (toBits)
|
||||
|
||||
#### int scan0($start)
|
||||
Scans for 0, and returns index of first found bit
|
||||
- **GMP implementation:** gmp_scan0
|
||||
- **Bcmath implementation:** custom (toBits)
|
||||
|
||||
#### int scan1($start)
|
||||
Scans for 1, and returns index of first found bit
|
||||
- **GMP implementation:** gmp_scan1
|
||||
- **Bcmath implementation:** custom (toBits)
|
||||
|
||||
#### int cmp(ConvertibleToBi $x)
|
||||
Compares numbers, returns <0, 0, >0
|
||||
- **GMP implementation:** gmp_cmp
|
||||
- **Bcmath implementation:** bccomp
|
||||
|
||||
#### bool equals(ConvertibleToBi $x)
|
||||
Checks if numbers are equal
|
||||
- **GMP implementation:** gmp_cmp
|
||||
- **Bcmath implementation:** bccomp
|
||||
|
||||
#### int sign()
|
||||
Sign of number, returns -1, 0, 1
|
||||
- **GMP implementation:** gmp_sign
|
||||
- **Bcmath implementation:** check first character
|
||||
|
||||
#### int toNumber()
|
||||
Converts to number (use only with small 32/64bit numbers)
|
||||
- **GMP implementation:** gmp_intval
|
||||
- **Bcmath implementation:** intval
|
||||
|
||||
#### string toDec()
|
||||
Converts to decimal string
|
||||
- **GMP implementation:** gmp_strval
|
||||
- **Bcmath implementation:** just the value
|
||||
|
||||
#### string toHex()
|
||||
Converts to hex string
|
||||
- **GMP implementation:** gmp_strval
|
||||
- **Bcmath implementation:** toBytes + bin2hex
|
||||
|
||||
#### string toBytes
|
||||
Converts to binary string
|
||||
- **GMP implementation:** gmp_strval + hex2bin
|
||||
- **Bcmath implementation:** custom (bcmod + bcdiv + bccomp)
|
||||
|
||||
#### string toBits()
|
||||
Converts to bits string (0 and 1 characters)
|
||||
- **GMP implementation:** gmp_strval
|
||||
- **Bcmath implementation:** toBytes + decbin
|
||||
|
||||
#### string toString(int $base = 10)
|
||||
Converts to string using given base (supported bases 2-62, 256)
|
||||
- **GMP implementation:** all above toX functions, and for non standard gmp_strval
|
||||
- **Bcmath implementation:** all above toX functions, and for non standard bcmod + bcdiv + bccomp
|
||||
17
vendor/simplito/bigint-wrapper-php/composer.json
vendored
Normal file
17
vendor/simplito/bigint-wrapper-php/composer.json
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "simplito/bigint-wrapper-php",
|
||||
"description": "Common interface for php_gmp and php_bcmath modules",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BI\\": "lib/"
|
||||
}
|
||||
}
|
||||
}
|
||||
635
vendor/simplito/bigint-wrapper-php/lib/BigInteger.php
vendored
Normal file
635
vendor/simplito/bigint-wrapper-php/lib/BigInteger.php
vendored
Normal file
@ -0,0 +1,635 @@
|
||||
<?php
|
||||
|
||||
namespace BI;
|
||||
|
||||
if (!defined("S_MATH_BIGINTEGER_MODE")) {
|
||||
if (extension_loaded("gmp")) {
|
||||
define("S_MATH_BIGINTEGER_MODE", "gmp");
|
||||
}
|
||||
else if (extension_loaded("bcmath")) {
|
||||
define("S_MATH_BIGINTEGER_MODE", "bcmath");
|
||||
}
|
||||
else {
|
||||
if (!defined("S_MATH_BIGINTEGER_QUIET")) {
|
||||
throw new \Exception("Cannot use BigInteger. Neither gmp nor bcmath module is loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (S_MATH_BIGINTEGER_MODE == "gmp") {
|
||||
|
||||
if (!extension_loaded("gmp")) {
|
||||
throw new \Exception("Extension gmp not loaded");
|
||||
}
|
||||
|
||||
class BigInteger {
|
||||
|
||||
public $value;
|
||||
|
||||
public function __construct($value = 0, $base = 10) {
|
||||
$this->value = $base === true ? $value : BigInteger::getGmp($value, $base);
|
||||
}
|
||||
|
||||
public static function createSafe($value = 0, $base = 10) {
|
||||
try {
|
||||
return new BigInteger($value, $base);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function isGmp($var) {
|
||||
if (is_resource($var)) {
|
||||
return get_resource_type($var) == "GMP integer";
|
||||
}
|
||||
if (class_exists("GMP") && $var instanceof \GMP) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getGmp($value = 0, $base = 10) {
|
||||
if ($value instanceof BigInteger) {
|
||||
return $value->value;
|
||||
}
|
||||
if (BigInteger::isGmp($value)) {
|
||||
return $value;
|
||||
}
|
||||
$type = gettype($value);
|
||||
if ($type == "integer") {
|
||||
$gmp = gmp_init($value);
|
||||
if ($gmp === false) {
|
||||
throw new \Exception("Cannot initialize");
|
||||
}
|
||||
return $gmp;
|
||||
}
|
||||
if ($type == "string") {
|
||||
if ($base != 2 && $base != 10 && $base != 16 && $base != 256) {
|
||||
throw new \Exception("Unsupported BigInteger base");
|
||||
}
|
||||
if ($base == 256) {
|
||||
$value = bin2hex($value);
|
||||
$base = 16;
|
||||
}
|
||||
$level = error_reporting();
|
||||
error_reporting(0);
|
||||
$gmp = gmp_init($value, $base);
|
||||
error_reporting($level);
|
||||
if ($gmp === false) {
|
||||
throw new \Exception("Cannot initialize");
|
||||
}
|
||||
return $gmp;
|
||||
}
|
||||
throw new \Exception("Unsupported value, only string and integer are allowed, receive " . $type . ($type == "object" ? ", class: " . get_class($value) : ""));
|
||||
}
|
||||
|
||||
public function toDec() {
|
||||
return gmp_strval($this->value, 10);
|
||||
}
|
||||
|
||||
public function toHex() {
|
||||
$hex = gmp_strval($this->value, 16);
|
||||
return strlen($hex) % 2 == 1 ? "0". $hex : $hex;
|
||||
}
|
||||
|
||||
public function toBytes() {
|
||||
return hex2bin($this->toHex());
|
||||
}
|
||||
|
||||
public function toBase($base) {
|
||||
if ($base < 2 || $base > 62) {
|
||||
throw new \Exception("Invalid base");
|
||||
}
|
||||
return gmp_strval($this->value, $base);
|
||||
}
|
||||
|
||||
public function toBits() {
|
||||
return gmp_strval($this->value, 2);
|
||||
}
|
||||
|
||||
public function toString($base = 10) {
|
||||
if ($base == 2) {
|
||||
return $this->toBits();
|
||||
}
|
||||
if ($base == 10) {
|
||||
return $this->toDec();
|
||||
}
|
||||
if ($base == 16) {
|
||||
return $this->toHex();
|
||||
}
|
||||
if ($base == 256) {
|
||||
return $this->toBytes();
|
||||
}
|
||||
return $this->toBase($base);
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
public function toNumber() {
|
||||
return gmp_intval($this->value);
|
||||
}
|
||||
|
||||
public function add($x) {
|
||||
return new BigInteger(gmp_add($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function sub($x) {
|
||||
return new BigInteger(gmp_sub($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function mul($x) {
|
||||
return new BigInteger(gmp_mul($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function div($x) {
|
||||
return new BigInteger(gmp_div_q($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function divR($x) {
|
||||
return new BigInteger(gmp_div_r($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function divQR($x) {
|
||||
$res = gmp_div_qr($this->value, BigInteger::getGmp($x));
|
||||
return array(new BigInteger($res[0], true), new BigInteger($res[1], true));
|
||||
}
|
||||
|
||||
public function mod($x) {
|
||||
return new BigInteger(gmp_mod($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function gcd($x) {
|
||||
return new BigInteger(gmp_gcd($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function modInverse($x) {
|
||||
$res = gmp_invert($this->value, BigInteger::getGmp($x));
|
||||
return $res === false ? false : new BigInteger($res, true);
|
||||
}
|
||||
|
||||
public function pow($x) {
|
||||
return new BigInteger(gmp_pow($this->value, (new BigInteger($x))->toNumber()), true);
|
||||
}
|
||||
|
||||
public function powMod($x, $n) {
|
||||
return new BigInteger(gmp_powm($this->value, BigInteger::getGmp($x), BigInteger::getGmp($n)), true);
|
||||
}
|
||||
|
||||
public function abs() {
|
||||
return new BigInteger(gmp_abs($this->value), true);
|
||||
}
|
||||
|
||||
public function neg() {
|
||||
return new BigInteger(gmp_neg($this->value), true);
|
||||
}
|
||||
|
||||
public function binaryAnd($x) {
|
||||
return new BigInteger(gmp_and($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function binaryOr($x) {
|
||||
return new BigInteger(gmp_or($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function binaryXor($x) {
|
||||
return new BigInteger(gmp_xor($this->value, BigInteger::getGmp($x)), true);
|
||||
}
|
||||
|
||||
public function setbit($index, $bitOn = true) {
|
||||
$cpy = gmp_init(gmp_strval($this->value, 16), 16);
|
||||
gmp_setbit($cpy, $index, $bitOn);
|
||||
return new BigInteger($cpy, true);
|
||||
}
|
||||
|
||||
public function testbit($index) {
|
||||
return gmp_testbit($this->value, $index);
|
||||
}
|
||||
|
||||
public function scan0($start) {
|
||||
return gmp_scan0($this->value, $start);
|
||||
}
|
||||
|
||||
public function scan1($start) {
|
||||
return gmp_scan1($this->value, $start);
|
||||
}
|
||||
|
||||
public function cmp($x) {
|
||||
return gmp_cmp($this->value, BigInteger::getGmp($x));
|
||||
}
|
||||
|
||||
public function equals($x) {
|
||||
return $this->cmp($x) === 0;
|
||||
}
|
||||
|
||||
public function sign() {
|
||||
return gmp_sign($this->value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (S_MATH_BIGINTEGER_MODE == "bcmath") {
|
||||
|
||||
if (!extension_loaded("bcmath")) {
|
||||
throw new \Exception("Extension bcmath not loaded");
|
||||
}
|
||||
|
||||
class BigInteger{
|
||||
|
||||
public static $chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv";
|
||||
public $value;
|
||||
|
||||
public function __construct($value = 0, $base = 10) {
|
||||
$this->value = $base === true ? $value : BigInteger::getBC($value, $base);
|
||||
}
|
||||
|
||||
public static function createSafe($value = 0, $base = 10) {
|
||||
try {
|
||||
return new BigInteger($value, $base);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function checkBinary($str) {
|
||||
$len = strlen($str);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$c = ord($str[$i]);
|
||||
if (($i != 0 || $c != 45) && ($c < 48 || $c > 49)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function checkDecimal($str) {
|
||||
$len = strlen($str);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$c = ord($str[$i]);
|
||||
if (($i != 0 || $c != 45) && ($c < 48 || $c > 57)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function checkHex($str) {
|
||||
$len = strlen($str);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$c = ord($str[$i]);
|
||||
if (($i != 0 || $c != 45) && ($c < 48 || $c > 57) && ($c < 65 || $c > 70) && ($c < 97 || $c > 102)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getBC($value = 0, $base = 10) {
|
||||
if ($value instanceof BigInteger) {
|
||||
return $value->value;
|
||||
}
|
||||
$type = gettype($value);
|
||||
if ($type == "integer") {
|
||||
return strval($value);
|
||||
}
|
||||
if ($type == "string") {
|
||||
if ($base == 2) {
|
||||
$value = str_replace(" ", "", $value);
|
||||
if (!BigInteger::checkBinary($value)) {
|
||||
throw new \Exception("Invalid characters");
|
||||
}
|
||||
$minus = $value[0] == "-";
|
||||
if ($minus) {
|
||||
$value = substr($value, 1);
|
||||
}
|
||||
$len = strlen($value);
|
||||
$m = 1;
|
||||
$res = "0";
|
||||
for ($i = $len - 1; $i >= 0; $i -= 8) {
|
||||
$h = $i - 7 < 0 ? substr($value, 0, $i + 1) : substr($value, $i - 7, 8);
|
||||
$res = bcadd($res, bcmul(bindec($h), $m, 0), 0);
|
||||
$m = bcmul($m, "256", 0);
|
||||
}
|
||||
return ($minus ? "-" : "") . $res;
|
||||
}
|
||||
if ($base == 10) {
|
||||
$value = str_replace(" ", "", $value);
|
||||
if (!BigInteger::checkDecimal($value)) {
|
||||
throw new \Exception("Invalid characters");
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
if ($base == 16) {
|
||||
$value = str_replace(" ", "", $value);
|
||||
if (!BigInteger::checkHex($value)) {
|
||||
throw new \Exception("Invalid characters");
|
||||
}
|
||||
$minus = $value[0] == "-";
|
||||
if ($minus) {
|
||||
$value = substr($value, 1);
|
||||
}
|
||||
$len = strlen($value);
|
||||
$m = 1;
|
||||
$res = "0";
|
||||
for ($i = $len - 1; $i >= 0; $i -= 2) {
|
||||
$h = $i == 0 ? "0" . substr($value, 0, 1) : substr($value, $i - 1, 2);
|
||||
$res = bcadd($res, bcmul(hexdec($h), $m, 0), 0);
|
||||
$m = bcmul($m, "256", 0);
|
||||
}
|
||||
return ($minus ? "-" : "") . $res;
|
||||
}
|
||||
if ($base == 256) {
|
||||
$len = strlen($value);
|
||||
$m = 1;
|
||||
$res = "0";
|
||||
for ($i = $len - 1; $i >= 0; $i -= 6) {
|
||||
$h = $i - 5 < 0 ? substr($value, 0, $i + 1) : substr($value, $i - 5, 6);
|
||||
$res = bcadd($res, bcmul(base_convert(bin2hex($h), 16, 10), $m, 0), 0);
|
||||
$m = bcmul($m, "281474976710656", 0);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
throw new \Exception("Unsupported BigInteger base");
|
||||
}
|
||||
throw new \Exception("Unsupported value, only string and integer are allowed, receive " . $type . ($type == "object" ? ", class: " . get_class($value) : ""));
|
||||
}
|
||||
|
||||
public function toDec() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function toHex() {
|
||||
return bin2hex($this->toBytes());
|
||||
}
|
||||
|
||||
public function toBytes() {
|
||||
$value = "";
|
||||
$current = $this->value;
|
||||
if ($current[0] == "-") {
|
||||
$current = substr($current, 1);
|
||||
}
|
||||
while (bccomp($current, "0", 0) > 0) {
|
||||
$temp = bcmod($current, "281474976710656");
|
||||
$value = hex2bin(str_pad(base_convert($temp, 10, 16), 12, "0", STR_PAD_LEFT)) . $value;
|
||||
$current = bcdiv($current, "281474976710656", 0);
|
||||
}
|
||||
return ltrim($value, chr(0));
|
||||
}
|
||||
|
||||
public function toBase($base) {
|
||||
if ($base < 2 || $base > 62) {
|
||||
throw new \Exception("Invalid base");
|
||||
}
|
||||
$value = '';
|
||||
$current = $this->value;
|
||||
$base = BigInteger::getBC($base);
|
||||
|
||||
if ($current[0] == '-') {
|
||||
$current = substr($current, 1);
|
||||
}
|
||||
|
||||
while (bccomp($current, '0', 0) > 0) {
|
||||
$v = bcmod($current, $base);
|
||||
$value = BigInteger::$chars[$v] . $value;
|
||||
$current = bcdiv($current, $base, 0);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function toBits() {
|
||||
$bytes = $this->toBytes();
|
||||
$res = "";
|
||||
$len = strlen($bytes);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$b = decbin(ord($bytes[$i]));
|
||||
$res .= strlen($b) != 8 ? str_pad($b, 8, "0", STR_PAD_LEFT) : $b;
|
||||
}
|
||||
$res = ltrim($res, "0");
|
||||
return strlen($res) == 0 ? "0" : $res;
|
||||
}
|
||||
|
||||
public function toString($base = 10) {
|
||||
if ($base == 2) {
|
||||
return $this->toBits();
|
||||
}
|
||||
if ($base == 10) {
|
||||
return $this->toDec();
|
||||
}
|
||||
if ($base == 16) {
|
||||
return $this->toHex();
|
||||
}
|
||||
if ($base == 256) {
|
||||
return $this->toBytes();
|
||||
}
|
||||
return $this->toBase($base);
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
public function toNumber() {
|
||||
return intval($this->value);
|
||||
}
|
||||
|
||||
public function add($x) {
|
||||
return new BigInteger(bcadd($this->value, BigInteger::getBC($x), 0), true);
|
||||
}
|
||||
|
||||
public function sub($x) {
|
||||
return new BigInteger(bcsub($this->value, BigInteger::getBC($x), 0), true);
|
||||
}
|
||||
|
||||
public function mul($x) {
|
||||
return new BigInteger(bcmul($this->value, BigInteger::getBC($x), 0), true);
|
||||
}
|
||||
|
||||
public function div($x) {
|
||||
return new BigInteger(bcdiv($this->value, BigInteger::getBC($x), 0), true);
|
||||
}
|
||||
|
||||
public function divR($x) {
|
||||
return new BigInteger(bcmod($this->value, BigInteger::getBC($x)), true);
|
||||
}
|
||||
|
||||
public function divQR($x) {
|
||||
return array(
|
||||
$this->div($x),
|
||||
$this->divR($x)
|
||||
);
|
||||
}
|
||||
|
||||
public function mod($x) {
|
||||
$xv = BigInteger::getBC($x);
|
||||
$mod = bcmod($this->value, $xv);
|
||||
if ($mod[0] == "-") {
|
||||
$mod = bcadd($mod, $xv[0] == "-" ? substr($xv, 1) : $xv, 0);
|
||||
}
|
||||
return new BigInteger($mod, true);
|
||||
}
|
||||
|
||||
public function extendedGcd($n) {
|
||||
$u = $this->value;
|
||||
$v = (new BigInteger($n))->abs()->value;
|
||||
|
||||
$a = "1";
|
||||
$b = "0";
|
||||
$c = "0";
|
||||
$d = "1";
|
||||
|
||||
while (bccomp($v, "0", 0) != 0) {
|
||||
$q = bcdiv($u, $v, 0);
|
||||
|
||||
$temp = $u;
|
||||
$u = $v;
|
||||
$v = bcsub($temp, bcmul($v, $q, 0), 0);
|
||||
|
||||
$temp = $a;
|
||||
$a = $c;
|
||||
$c = bcsub($temp, bcmul($a, $q, 0), 0);
|
||||
|
||||
$temp = $b;
|
||||
$b = $d;
|
||||
$d = bcsub($temp, bcmul($b, $q, 0), 0);
|
||||
}
|
||||
|
||||
return array(
|
||||
"gcd" => new BigInteger($u, true),
|
||||
"x" => new BigInteger($a, true),
|
||||
"y" => new BigInteger($b, true)
|
||||
);
|
||||
}
|
||||
|
||||
public function gcd($x) {
|
||||
return $this->extendedGcd($x)["gcd"];
|
||||
}
|
||||
|
||||
public function modInverse($n) {
|
||||
$n = (new BigInteger($n))->abs();
|
||||
|
||||
if ($this->sign() < 0) {
|
||||
$temp = $this->abs();
|
||||
$temp = $temp->modInverse($n);
|
||||
return $n->sub($temp);
|
||||
}
|
||||
|
||||
extract($this->extendedGcd($n));
|
||||
|
||||
if (!$gcd->equals(1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$x = $x->sign() < 0 ? $x->add($n) : $x;
|
||||
|
||||
return $this->sign() < 0 ? $n->sub($x) : $x;
|
||||
}
|
||||
|
||||
public function pow($x) {
|
||||
return new BigInteger(bcpow($this->value, BigInteger::getBC($x), 0), true);
|
||||
}
|
||||
|
||||
public function powMod($x, $n) {
|
||||
return new BigInteger(bcpowmod($this->value, BigInteger::getBC($x), BigInteger::getBC($n), 0), true);
|
||||
}
|
||||
|
||||
public function abs() {
|
||||
return new BigInteger($this->value[0] == "-" ? substr($this->value, 1) : $this->value, true);
|
||||
}
|
||||
|
||||
public function neg() {
|
||||
return new BigInteger($this->value[0] == "-" ? substr($this->value, 1) : "-" . $this->value, true);
|
||||
}
|
||||
|
||||
public function binaryAnd($x) {
|
||||
$left = $this->toBytes();
|
||||
$right = (new BigInteger($x))->toBytes();
|
||||
|
||||
$length = max(strlen($left), strlen($right));
|
||||
|
||||
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
|
||||
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
|
||||
|
||||
return new BigInteger($left & $right, 256);
|
||||
}
|
||||
|
||||
public function binaryOr($x) {
|
||||
$left = $this->toBytes();
|
||||
$right = (new BigInteger($x))->toBytes();
|
||||
|
||||
$length = max(strlen($left), strlen($right));
|
||||
|
||||
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
|
||||
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
|
||||
|
||||
return new BigInteger($left | $right, 256);
|
||||
}
|
||||
|
||||
public function binaryXor($x) {
|
||||
$left = $this->toBytes();
|
||||
$right = (new BigInteger($x))->toBytes();
|
||||
|
||||
$length = max(strlen($left), strlen($right));
|
||||
|
||||
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
|
||||
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
|
||||
|
||||
return new BigInteger($left ^ $right, 256);
|
||||
}
|
||||
|
||||
public function setbit($index, $bitOn = true) {
|
||||
$bits = $this->toBits();
|
||||
$bits[strlen($bits) - $index - 1] = $bitOn ? "1" : "0";
|
||||
return new BigInteger($bits, 2);
|
||||
}
|
||||
|
||||
public function testbit($index) {
|
||||
$bytes = $this->toBytes();
|
||||
$bytesIndex = intval($index / 8);
|
||||
$len = strlen($bytes);
|
||||
$b = $bytesIndex >= $len ? 0 : ord($bytes[$len - $bytesIndex - 1]);
|
||||
$v = 1 << ($index % 8);
|
||||
return ($b & $v) === $v;
|
||||
}
|
||||
|
||||
public function scan0($start) {
|
||||
$bits = $this->toBits();
|
||||
$len = strlen($bits);
|
||||
if ($start < 0 || $start >= $len) {
|
||||
return -1;
|
||||
}
|
||||
$pos = strrpos($bits, "0", -1 - $start);
|
||||
return $pos === false ? -1 : $len - $pos - 1;
|
||||
}
|
||||
|
||||
public function scan1($start) {
|
||||
$bits = $this->toBits();
|
||||
$len = strlen($bits);
|
||||
if ($start < 0 || $start >= $len) {
|
||||
return -1;
|
||||
}
|
||||
$pos = strrpos($bits, "1", -1 - $start);
|
||||
return $pos === false ? -1 : $len - $pos - 1;
|
||||
}
|
||||
|
||||
public function cmp($x) {
|
||||
return bccomp($this->value, BigInteger::getBC($x));
|
||||
}
|
||||
|
||||
public function equals($x) {
|
||||
return $this->value === BigInteger::getBC($x);
|
||||
}
|
||||
|
||||
public function sign() {
|
||||
return $this->value[0] === "-" ? -1 : ($this->value === "0" ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if (!defined("S_MATH_BIGINTEGER_QUIET")) {
|
||||
throw new \Exception("Unsupported S_MATH_BIGINTEGER_MODE " . S_MATH_BIGINTEGER_MODE);
|
||||
}
|
||||
}
|
||||
29
vendor/simplito/bigint-wrapper-php/test/perf.php
vendored
Normal file
29
vendor/simplito/bigint-wrapper-php/test/perf.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
define('S_MATH_BIGINTEGER_MODE', "bcmath");
|
||||
|
||||
require(__DIR__ . "/../lib/BigInteger.php");
|
||||
|
||||
use BI\BigInteger;
|
||||
|
||||
$a = new BigInteger("4547395333333333333333333333333333333333333343587493875493579375498759837593574935739857");
|
||||
$b = new BigInteger("-4547395333333333333333333333333333333333333343587493875493579375498759837593574935739857");
|
||||
$c = new BigInteger("0");
|
||||
$hex = "eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3";
|
||||
$bytes = hex2bin($hex);
|
||||
|
||||
function test($v, $b) {
|
||||
$start = microtime(true);
|
||||
$count = 10000;
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$v->binaryAnd($b);
|
||||
//$v->toBytes();
|
||||
//BigInteger::getBC($v, 256);
|
||||
}
|
||||
$end = microtime(true);
|
||||
error_log($end - $start);
|
||||
}
|
||||
|
||||
test($a, $a);
|
||||
test($b, $b);
|
||||
//test($bytes, $b);
|
||||
119
vendor/simplito/bigint-wrapper-php/test/test.php
vendored
Normal file
119
vendor/simplito/bigint-wrapper-php/test/test.php
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
use BI\BigInteger;
|
||||
|
||||
function test($a, $b, $message = "") {
|
||||
error_log(($a === $b ? "PASS" : "FAIL get: " . $a . ", expected: " . $b) . " " . $message);
|
||||
}
|
||||
|
||||
function testB($a, $b, $message = "") {
|
||||
error_log(($a->toString() === $b ? "PASS" : "FAIL get: " . $a . ", expected: " . $b) . " " . $message);
|
||||
}
|
||||
|
||||
function testSerialization($b, $msg = "") {
|
||||
test($b->toBits(), "1010000", $msg . " toBits");
|
||||
test($b->toBytes(), hex2bin("50"), $msg . " toBytes");
|
||||
test($b->toHex(), "50", $msg . " toHex");
|
||||
test($b->toDec(), "80", $msg . " toDec");
|
||||
test($b->toNumber(), 80, $msg . " toNumber");
|
||||
test($b->toBase(58), "1M", $msg . " to58");
|
||||
}
|
||||
|
||||
function testCreate() {
|
||||
error_log("=============\nTest serialization\n=============");
|
||||
testSerialization(new BigInteger("1010000", 2), "bits");
|
||||
testSerialization(new BigInteger(hex2bin("50"), 256), "bytes");
|
||||
testSerialization(new BigInteger("50", 16), "hex");
|
||||
testSerialization(new BigInteger("80", 10), "dec");
|
||||
testSerialization(new BigInteger("80"), "dec2");
|
||||
testSerialization(new BigInteger(80), "number");
|
||||
}
|
||||
|
||||
function testCreateSafeSingle($value, $base, $msg) {
|
||||
try {
|
||||
$z = new BigInteger($value, $base);
|
||||
error_log("FAIL exception during create " . $msg);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
error_log("PASS exception during create " . $msg);
|
||||
}
|
||||
test(BigInteger::createSafe($value, $base), false, "createSafe " . $msg);
|
||||
}
|
||||
|
||||
function testCreateSafe() {
|
||||
error_log("=============\nTest create safe\n=============");
|
||||
testCreateSafeSingle("zz", 2, "bin");
|
||||
testCreateSafeSingle("zz", 10, "dec");
|
||||
testCreateSafeSingle("zz", 16, "hex");
|
||||
}
|
||||
|
||||
function testSpaces() {
|
||||
error_log("=============\nTest spaces\n=============");
|
||||
test((new BigInteger("11 0 1", 2))->toBits(), "1101", "bin");
|
||||
test((new BigInteger("6 2 0 6", 10))->toDec(), "6206", "dec");
|
||||
test((new BigInteger("f3 5 12 ac 0", 16))->toHex(), "f3512ac0", "hex");
|
||||
}
|
||||
|
||||
function testOp() {
|
||||
error_log("=============\nTest op\n=============");
|
||||
testB((new BigInteger(20))->add(34), "54", "add");
|
||||
testB((new BigInteger(20))->sub(14), "6", "sub");
|
||||
testB((new BigInteger(20))->mul(12), "240", "mul");
|
||||
testB((new BigInteger(20))->div(4), "5", "div");
|
||||
testB((new BigInteger(20))->divR(7), "6", "divR");
|
||||
$qr = (new BigInteger(20))->divQR(6);
|
||||
testB($qr[0], "3", "divQR[0]");
|
||||
testB($qr[1], "2", "divQR[1]");
|
||||
testB((new BigInteger(20))->mod(3), "2", "mod");
|
||||
testB((new BigInteger(54))->gcd(81), "27", "gcd");
|
||||
testB((new BigInteger(3))->modInverse(10), "7", "modInverse");
|
||||
testB((new BigInteger(3))->pow(4), "81", "pow");
|
||||
testB((new BigInteger(3))->powMod(4, 10), "1", "powMod");
|
||||
testB((new BigInteger(20))->abs(), "20", "abs");
|
||||
testB((new BigInteger(20))->neg(), "-20", "neg");
|
||||
testB((new BigInteger(20))->binaryAnd(18), "16", "binaryAnd");
|
||||
testB((new BigInteger(20))->binaryOr(18), "22", "binaryOr");
|
||||
testB((new BigInteger(20))->binaryXor(18), "6", "binaryXor");
|
||||
testB((new BigInteger(20))->setbit(3), "28", "setbit");
|
||||
test((new BigInteger(20))->testbit(4), true, "testbit true");
|
||||
test((new BigInteger(20))->testbit(3), false, "testbit false");
|
||||
test((new BigInteger(5))->testbit(0), true, "testbit 0 true");
|
||||
test((new BigInteger(6))->testbit(0), false, "testbit 0 false");
|
||||
test((new BigInteger(6))->testbit(1), true, "testbit 1 true");
|
||||
test((new BigInteger(5))->testbit(1), false, "testbit 1 false");
|
||||
test((new BigInteger(132))->testbit(7), true, "testbit 7 true");
|
||||
test((new BigInteger(81))->testbit(7), false, "testbit 7 false");
|
||||
test((new BigInteger(258))->testbit(8), true, "testbit 8 true");
|
||||
test((new BigInteger(253))->testbit(8), false, "testbit 8 false");
|
||||
test((new BigInteger(20))->scan0(2), 3, "scan0");
|
||||
test((new BigInteger(20))->scan1(3), 4, "scan1");
|
||||
test((new BigInteger(20))->cmp(22), -1, "cmp -1");
|
||||
test((new BigInteger(20))->cmp(20), 0, "cmp 0");
|
||||
test((new BigInteger(20))->cmp(18), 1, "cmp 1");
|
||||
test((new BigInteger(20))->equals(20), true, "equals true");
|
||||
test((new BigInteger(20))->equals(21), false, "equals false");
|
||||
test((new BigInteger(-20))->sign(), -1, "sign -1");
|
||||
test((new BigInteger(0))->sign(), 0, "sign 0");
|
||||
test((new BigInteger(20))->sign(), 1, "sign 1");
|
||||
testB(new BigInteger("-20"), "-20", "minus");
|
||||
testB(new BigInteger("-14", 16), "-20", "minus");
|
||||
testB(new BigInteger("-10100", 2), "-20", "minus");
|
||||
}
|
||||
|
||||
function testBig() {
|
||||
error_log("=============\nTest big\n=============");
|
||||
$bits = "1001010111010010100001000101110110100001000101101000110101010101001";
|
||||
$hex = "eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3";
|
||||
$dec = "436529472098746319073192837123683467019263172846";
|
||||
$bytes = hex2bin($hex);
|
||||
test((new BigInteger($bits, 2))->toBits(), $bits, "init big from binary");
|
||||
test((new BigInteger($dec, 10))->toDec(), $dec, "init big from dec");
|
||||
test((new BigInteger($hex, 16))->toHex(), $hex, "init big from hex");
|
||||
test((new BigInteger($bytes, 256))->toBytes(), $bytes, "init big from buffer");
|
||||
}
|
||||
|
||||
testCreate();
|
||||
testCreateSafe();
|
||||
testSpaces();
|
||||
testOp();
|
||||
testBig();
|
||||
6
vendor/simplito/bigint-wrapper-php/test/testbc.php
vendored
Normal file
6
vendor/simplito/bigint-wrapper-php/test/testbc.php
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
define('S_MATH_BIGINTEGER_MODE', "bcmath");
|
||||
|
||||
require(__DIR__ . "/../lib/BigInteger.php");
|
||||
require(__DIR__ . "/test.php");
|
||||
6
vendor/simplito/bigint-wrapper-php/test/testgmp.php
vendored
Normal file
6
vendor/simplito/bigint-wrapper-php/test/testgmp.php
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
define('S_MATH_BIGINTEGER_MODE', "gmp");
|
||||
|
||||
require(__DIR__ . "/../lib/BigInteger.php");
|
||||
require(__DIR__ . "/test.php");
|
||||
4
vendor/simplito/bn-php/.gitignore
vendored
Normal file
4
vendor/simplito/bn-php/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/vendor/
|
||||
.settings
|
||||
.project
|
||||
.buildpath
|
||||
23
vendor/simplito/bn-php/LICENSE.md
vendored
Normal file
23
vendor/simplito/bn-php/LICENSE.md
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
## MIT LICENSE
|
||||
|
||||
Copyright (C) 2018 Simplito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
17
vendor/simplito/bn-php/README.md
vendored
Normal file
17
vendor/simplito/bn-php/README.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
# BigNum library for PHP
|
||||
|
||||
|
||||
## Information
|
||||
|
||||
This library provides a PHP Big Number API compatible with [bn.js](https://github.com/indutny/bn.js) and is used in Fast PHP ECC library [elliptic-php](https://github.com/simplito/elliptic-php).
|
||||
|
||||
This software is licensed under the MIT License.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
You can install this library via Composer:
|
||||
```
|
||||
composer require simplito/bn-php
|
||||
```
|
||||
23
vendor/simplito/bn-php/composer.json
vendored
Normal file
23
vendor/simplito/bn-php/composer.json
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "simplito/bn-php",
|
||||
"description": "Big number implementation compatible with bn.js",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"simplito/bigint-wrapper-php": "~1.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BN\\": "lib/"
|
||||
}
|
||||
}
|
||||
}
|
||||
768
vendor/simplito/bn-php/lib/BN.php
vendored
Normal file
768
vendor/simplito/bn-php/lib/BN.php
vendored
Normal file
@ -0,0 +1,768 @@
|
||||
<?php
|
||||
namespace BN;
|
||||
|
||||
use \JsonSerializable;
|
||||
use \Exception;
|
||||
use \BI\BigInteger;
|
||||
|
||||
class BN implements JsonSerializable
|
||||
{
|
||||
public static $ASSERT_ENABLED;
|
||||
public $bi;
|
||||
public $red;
|
||||
|
||||
function __construct($number, $base = 10, $endian = null)
|
||||
{
|
||||
if( $number instanceof BN ) {
|
||||
$this->bi = $number->bi;
|
||||
$this->red = $number->red;
|
||||
return;
|
||||
}
|
||||
|
||||
// Reduction context
|
||||
$this->red = null;
|
||||
|
||||
if ( $number instanceof BigInteger ) {
|
||||
$this->bi = $number;
|
||||
return;
|
||||
}
|
||||
|
||||
if( is_array($number) )
|
||||
{
|
||||
$number = call_user_func_array("pack", array_merge(array("C*"), $number));
|
||||
$number = bin2hex($number);
|
||||
$base = 16;
|
||||
}
|
||||
|
||||
if( $base == "hex" )
|
||||
$base = 16;
|
||||
|
||||
if ($endian == 'le') {
|
||||
if ($base != 16)
|
||||
throw new \Exception("Not implemented");
|
||||
$number = bin2hex(strrev(hex2bin($number)));
|
||||
}
|
||||
|
||||
$this->bi = new BigInteger($number, $base);
|
||||
}
|
||||
|
||||
public function negative() {
|
||||
return $this->bi->sign() < 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
public static function isBN($num) {
|
||||
return ($num instanceof BN);
|
||||
}
|
||||
|
||||
public static function max($left, $right) {
|
||||
return ( $left->cmp($right) > 0 ) ? $left : $right;
|
||||
}
|
||||
|
||||
public static function min($left, $right) {
|
||||
return ( $left->cmp($right) < 0 ) ? $left : $right;
|
||||
}
|
||||
|
||||
public function copy($dest)
|
||||
{
|
||||
$dest->bi = $this->bi;
|
||||
$dest->red = $this->red;
|
||||
}
|
||||
|
||||
public function _clone() {
|
||||
return clone($this);
|
||||
}
|
||||
|
||||
public function toString($base = 10, $padding = 0)
|
||||
{
|
||||
if( $base == "hex" )
|
||||
$base = 16;
|
||||
$str = $this->bi->abs()->toString($base);
|
||||
if ($padding > 0) {
|
||||
$len = strlen($str);
|
||||
$mod = $len % $padding;
|
||||
if ($mod > 0)
|
||||
$len = $len + $padding - $mod;
|
||||
$str = str_pad($str, $len, "0", STR_PAD_LEFT);
|
||||
}
|
||||
if( $this->negative() )
|
||||
return "-" . $str;
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function toNumber() {
|
||||
return $this->bi->toNumber();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize() {
|
||||
return $this->toString(16);
|
||||
}
|
||||
|
||||
public function toArray($endian = "be", $length = -1)
|
||||
{
|
||||
$hex = $this->toString(16);
|
||||
if( $hex[0] === "-" )
|
||||
$hex = substr($hex, 1);
|
||||
|
||||
if( strlen($hex) % 2 )
|
||||
$hex = "0" . $hex;
|
||||
|
||||
$bytes = array_map(
|
||||
function($v) { return hexdec($v); },
|
||||
str_split($hex, 2)
|
||||
);
|
||||
|
||||
if( $length > 0 )
|
||||
{
|
||||
$count = count($bytes);
|
||||
if( $count > $length )
|
||||
throw new Exception("Byte array longer than desired length");
|
||||
|
||||
for($i = $count; $i < $length; $i++)
|
||||
array_unshift($bytes, 0);
|
||||
}
|
||||
|
||||
if( $endian === "le" )
|
||||
$bytes = array_reverse($bytes);
|
||||
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
public function bitLength() {
|
||||
$bin = $this->toString(2);
|
||||
return strlen($bin) - ( $bin[0] === "-" ? 1 : 0 );
|
||||
}
|
||||
|
||||
public function zeroBits() {
|
||||
return $this->bi->scan1(0);
|
||||
}
|
||||
|
||||
public function byteLength() {
|
||||
return ceil($this->bitLength() / 8);
|
||||
}
|
||||
|
||||
//TODO toTwos, fromTwos
|
||||
|
||||
public function isNeg() {
|
||||
return $this->negative() !== 0;
|
||||
}
|
||||
|
||||
// Return negative clone of `this`
|
||||
public function neg() {
|
||||
return $this->_clone()->ineg();
|
||||
}
|
||||
|
||||
public function ineg() {
|
||||
$this->bi = $this->bi->neg();
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Or `num` with `this` in-place
|
||||
public function iuor(BN $num) {
|
||||
$this->bi = $this->bi->binaryOr($num->bi);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function ior(BN $num) {
|
||||
if (BN::$ASSERT_ENABLED) assert(!$this->negative() && !$num->negative());
|
||||
return $this->iuor($num);
|
||||
}
|
||||
|
||||
// Or `num` with `this`
|
||||
public function _or(BN $num) {
|
||||
if( $this->ucmp($num) > 0 )
|
||||
return $this->_clone()->ior($num);
|
||||
return $num->_clone()->ior($this);
|
||||
}
|
||||
|
||||
public function uor(BN $num) {
|
||||
if( $this->ucmp($num) > 0 )
|
||||
return $this->_clone()->iuor($num);
|
||||
return $num->_clone()->ior($this);
|
||||
}
|
||||
|
||||
// And `num` with `this` in-place
|
||||
public function iuand(BN $num) {
|
||||
$this->bi = $this->bi->binaryAnd($num->bi);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function iand(BN $num) {
|
||||
if (BN::$ASSERT_ENABLED) assert(!$this->negative() && !$num->negative());
|
||||
return $this->iuand($num);
|
||||
}
|
||||
|
||||
// And `num` with `this`
|
||||
public function _and(BN $num) {
|
||||
if( $this->ucmp($num) > 0 )
|
||||
return $this->_clone()->iand($num);
|
||||
return $num->_clone()->iand($this);
|
||||
}
|
||||
|
||||
public function uand(BN $num) {
|
||||
if( $this->ucmp($num) > 0 )
|
||||
return $this->_clone()->iuand($num);
|
||||
return $num->_clone()->iuand($this);
|
||||
}
|
||||
|
||||
// Xor `num` with `this` in-place
|
||||
public function iuxor(BN $num) {
|
||||
$this->bi = $this->bi->binaryXor($num->bi);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function ixor(BN $num) {
|
||||
if (BN::$ASSERT_ENABLED) assert(!$this->negative() && !$num->negative());
|
||||
return $this->iuxor($num);
|
||||
}
|
||||
|
||||
// Xor `num` with `this`
|
||||
public function _xor(BN $num) {
|
||||
if( $this->ucmp($num) > 0 )
|
||||
return $this->_clone()->ixor($num);
|
||||
return $num->_clone()->ixor($this);
|
||||
}
|
||||
|
||||
public function uxor(BN $num) {
|
||||
if( $this->ucmp($num) > 0 )
|
||||
return $this->_clone()->iuxor($num);
|
||||
return $num->_clone()->iuxor($this);
|
||||
}
|
||||
|
||||
// Not ``this`` with ``width`` bitwidth
|
||||
public function inotn($width)
|
||||
{
|
||||
assert(is_integer($width) && $width >= 0);
|
||||
$neg = false;
|
||||
if( $this->isNeg() )
|
||||
{
|
||||
$this->negi();
|
||||
$neg = true;
|
||||
}
|
||||
|
||||
for($i = 0; $i < $width; $i++)
|
||||
$this->bi = $this->bi->setbit($i, !$this->bi->testbit($i));
|
||||
|
||||
return $neg ? $this->negi() : $this;
|
||||
}
|
||||
|
||||
public function notn($width) {
|
||||
return $this->_clone()->inotn($width);
|
||||
}
|
||||
|
||||
// Set `bit` of `this`
|
||||
public function setn($bit, $val) {
|
||||
assert(is_integer($bit) && $bit > 0);
|
||||
$this->bi = $this->bi->setbit($bit, !!$val);
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Add `num` to `this` in-place
|
||||
public function iadd(BN $num) {
|
||||
$this->bi = $this->bi->add($num->bi);
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Add `num` to `this`
|
||||
public function add(BN $num) {
|
||||
return $this->_clone()->iadd($num);
|
||||
}
|
||||
|
||||
// Subtract `num` from `this` in-place
|
||||
public function isub(BN $num) {
|
||||
$this->bi = $this->bi->sub($num->bi);
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Subtract `num` from `this`
|
||||
public function sub(BN $num) {
|
||||
return $this->_clone()->isub($num);
|
||||
}
|
||||
|
||||
// Multiply `this` by `num`
|
||||
public function mul(BN $num) {
|
||||
return $this->_clone()->imul($num);
|
||||
}
|
||||
|
||||
// In-place Multiplication
|
||||
public function imul(BN $num) {
|
||||
$this->bi = $this->bi->mul($num->bi);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function imuln($num)
|
||||
{
|
||||
assert(is_numeric($num));
|
||||
$int = intval($num);
|
||||
$res = $this->bi->mul($int);
|
||||
|
||||
if( ($num - $int) > 0 )
|
||||
{
|
||||
$mul = 10;
|
||||
$frac = ($num - $int) * $mul;
|
||||
$int = intval($frac);
|
||||
while( ($frac - $int) > 0 )
|
||||
{
|
||||
$mul *= 10;
|
||||
$frac *= 10;
|
||||
$int = intval($frac);
|
||||
}
|
||||
|
||||
$tmp = $this->bi->mul($int);
|
||||
$tmp = $tmp->div($mul);
|
||||
$res = $res->add($tmp);
|
||||
}
|
||||
|
||||
$this->bi = $res;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function muln($num) {
|
||||
return $this->_clone()->imuln($num);
|
||||
}
|
||||
|
||||
// `this` * `this`
|
||||
public function sqr() {
|
||||
return $this->mul($this);
|
||||
}
|
||||
|
||||
// `this` * `this` in-place
|
||||
public function isqr() {
|
||||
return $this->imul($this);
|
||||
}
|
||||
|
||||
// Math.pow(`this`, `num`)
|
||||
public function pow(BN $num) {
|
||||
$res = clone($this);
|
||||
$res->bi = $res->bi->pow($num->bi);
|
||||
return $res;
|
||||
}
|
||||
|
||||
// Shift-left in-place
|
||||
public function iushln($bits) {
|
||||
assert(is_integer($bits) && $bits >= 0);
|
||||
if ($bits < 54) {
|
||||
$this->bi = $this->bi->mul(1 << $bits);
|
||||
} else {
|
||||
$this->bi = $this->bi->mul((new BigInteger(2))->pow($bits));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function ishln($bits) {
|
||||
if (BN::$ASSERT_ENABLED) assert(!$this->negative());
|
||||
return $this->iushln($bits);
|
||||
}
|
||||
|
||||
// Shift-right in-place
|
||||
// NOTE: `hint` is a lowest bit before trailing zeroes
|
||||
// NOTE: if `extended` is present - it will be filled with destroyed bits
|
||||
public function iushrn($bits, $hint = 0, &$extended = null) {
|
||||
if( $hint != 0 )
|
||||
throw new Exception("Not implemented");
|
||||
|
||||
assert(is_integer($bits) && $bits >= 0);
|
||||
|
||||
if( $extended != null )
|
||||
$extended = $this->maskn($bits);
|
||||
|
||||
if ($bits < 54) {
|
||||
$this->bi = $this->bi->div(1 << $bits);
|
||||
} else {
|
||||
$this->bi = $this->bi->div((new BigInteger(2))->pow($bits));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function ishrn($bits, $hint = null, $extended = null) {
|
||||
if (BN::$ASSERT_ENABLED) assert(!$this->negative());
|
||||
return $this->iushrn($bits, $hint, $extended);
|
||||
}
|
||||
|
||||
// Shift-left
|
||||
public function shln($bits) {
|
||||
return $this->_clone()->ishln($bits);
|
||||
}
|
||||
|
||||
public function ushln($bits) {
|
||||
return $this->_clone()->iushln($bits);
|
||||
}
|
||||
|
||||
// Shift-right
|
||||
public function shrn($bits) {
|
||||
return $this->_clone()->ishrn($bits);
|
||||
}
|
||||
|
||||
public function ushrn($bits) {
|
||||
return $this->_clone()->iushrn($bits);
|
||||
}
|
||||
|
||||
// Test if n bit is set
|
||||
public function testn($bit) {
|
||||
assert(is_integer($bit) && $bit >= 0);
|
||||
return $this->bi->testbit($bit);
|
||||
}
|
||||
|
||||
// Return only lowers bits of number (in-place)
|
||||
public function imaskn($bits) {
|
||||
assert(is_integer($bits) && $bits >= 0);
|
||||
if (BN::$ASSERT_ENABLED) assert(!$this->negative());
|
||||
$mask = "";
|
||||
for($i = 0; $i < $bits; $i++)
|
||||
$mask .= "1";
|
||||
return $this->iand(new BN($mask, 2));
|
||||
}
|
||||
|
||||
// Return only lowers bits of number
|
||||
public function maskn($bits) {
|
||||
return $this->_clone()->imaskn($bits);
|
||||
}
|
||||
|
||||
// Add plain number `num` to `this`
|
||||
public function iaddn($num) {
|
||||
assert(is_numeric($num));
|
||||
$this->bi = $this->bi->add(intval($num));
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Subtract plain number `num` from `this`
|
||||
public function isubn($num) {
|
||||
assert(is_numeric($num));
|
||||
$this->bi = $this->bi->sub(intval($num));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addn($num) {
|
||||
return $this->_clone()->iaddn($num);
|
||||
}
|
||||
|
||||
public function subn($num) {
|
||||
return $this->_clone()->isubn($num);
|
||||
}
|
||||
|
||||
public function iabs() {
|
||||
if ($this->bi->sign() < 0) {
|
||||
$this->bi = $this->bi->abs();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function abs() {
|
||||
$res = clone($this);
|
||||
if ($res->bi->sign() < 0)
|
||||
$res->bi = $res->bi->abs();
|
||||
return $res;
|
||||
}
|
||||
|
||||
// Find `this` / `num`
|
||||
public function div(BN $num) {
|
||||
if (BN::$ASSERT_ENABLED) assert(!$num->isZero());
|
||||
$res = clone($this);
|
||||
$res->bi = $res->bi->div($num->bi);
|
||||
return $res;
|
||||
}
|
||||
|
||||
// Find `this` % `num`
|
||||
public function mod(BN $num) {
|
||||
if (BN::$ASSERT_ENABLED) assert(!$num->isZero());
|
||||
$res = clone($this);
|
||||
$res->bi = $res->bi->divR($num->bi);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function umod(BN $num) {
|
||||
if (BN::$ASSERT_ENABLED) assert(!$num->isZero());
|
||||
$tmp = $num->bi->sign() < 0 ? $num->bi->abs() : $num->bi;
|
||||
$res = clone($this);
|
||||
$res->bi = $this->bi->mod($tmp);
|
||||
return $res;
|
||||
}
|
||||
|
||||
// Find Round(`this` / `num`)
|
||||
public function divRound(BN $num)
|
||||
{
|
||||
if (BN::$ASSERT_ENABLED) assert(!$num->isZero());
|
||||
|
||||
$negative = $this->negative() !== $num->negative();
|
||||
|
||||
$res = $this->_clone()->abs();
|
||||
$arr = $res->bi->divQR($num->bi->abs());
|
||||
$res->bi = $arr[0];
|
||||
$tmp = $num->bi->sub($arr[1]->mul(2));
|
||||
if( $tmp->cmp(0) <= 0 && (!$negative || $this->negative() === 0) )
|
||||
$res->iaddn(1);
|
||||
return $negative ? $res->negi() : $res;
|
||||
}
|
||||
|
||||
public function modn($num) {
|
||||
assert(is_numeric($num) && $num != 0);
|
||||
return $this->bi->divR(intval($num))->toNumber();
|
||||
}
|
||||
|
||||
// In-place division by number
|
||||
public function idivn($num) {
|
||||
assert(is_numeric($num) && $num != 0);
|
||||
$this->bi = $this->bi->div(intval($num));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function divn($num) {
|
||||
return $this->_clone()->idivn($num);
|
||||
}
|
||||
|
||||
public function gcd(BN $num) {
|
||||
$res = clone($this);
|
||||
$res->bi = $this->bi->gcd($num->bi);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function invm(BN $num) {
|
||||
$res = clone($this);
|
||||
$res->bi = $res->bi->modInverse($num->bi);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function isEven() {
|
||||
return !$this->bi->testbit(0);
|
||||
}
|
||||
|
||||
public function isOdd() {
|
||||
return $this->bi->testbit(0);
|
||||
}
|
||||
|
||||
public function andln($num) {
|
||||
assert(is_numeric($num));
|
||||
return $this->bi->binaryAnd($num)->toNumber();
|
||||
}
|
||||
|
||||
public function bincn($num) {
|
||||
$tmp = (new BN(1))->iushln($num);
|
||||
return $this->add($tmp);
|
||||
}
|
||||
|
||||
public function isZero() {
|
||||
return $this->bi->sign() == 0;
|
||||
}
|
||||
|
||||
public function cmpn($num) {
|
||||
assert(is_numeric($num));
|
||||
return $this->bi->cmp($num);
|
||||
}
|
||||
|
||||
// Compare two numbers and return:
|
||||
// 1 - if `this` > `num`
|
||||
// 0 - if `this` == `num`
|
||||
// -1 - if `this` < `num`
|
||||
public function cmp(BN $num) {
|
||||
return $this->bi->cmp($num->bi);
|
||||
}
|
||||
|
||||
public function ucmp(BN $num) {
|
||||
return $this->bi->abs()->cmp($num->bi->abs());
|
||||
}
|
||||
|
||||
public function gtn($num) {
|
||||
return $this->cmpn($num) > 0;
|
||||
}
|
||||
|
||||
public function gt(BN $num) {
|
||||
return $this->cmp($num) > 0;
|
||||
}
|
||||
|
||||
public function gten($num) {
|
||||
return $this->cmpn($num) >= 0;
|
||||
}
|
||||
|
||||
public function gte(BN $num) {
|
||||
return $this->cmp($num) >= 0;
|
||||
}
|
||||
|
||||
public function ltn($num) {
|
||||
return $this->cmpn($num) < 0;
|
||||
}
|
||||
|
||||
public function lt(BN $num) {
|
||||
return $this->cmp($num) < 0;
|
||||
}
|
||||
|
||||
public function lten($num) {
|
||||
return $this->cmpn($num) <= 0;
|
||||
}
|
||||
|
||||
public function lte(BN $num) {
|
||||
return $this->cmp($num) <= 0;
|
||||
}
|
||||
|
||||
public function eqn($num) {
|
||||
return $this->cmpn($num) === 0;
|
||||
}
|
||||
|
||||
public function eq(BN $num) {
|
||||
return $this->cmp($num) === 0;
|
||||
}
|
||||
|
||||
public function toRed(Red &$ctx) {
|
||||
if( $this->red !== null )
|
||||
throw new Exception("Already a number in reduction context");
|
||||
if( $this->negative() !== 0 )
|
||||
throw new Exception("red works only with positives");
|
||||
return $ctx->convertTo($this)->_forceRed($ctx);
|
||||
}
|
||||
|
||||
public function fromRed() {
|
||||
if( $this->red === null )
|
||||
throw new Exception("fromRed works only with numbers in reduction context");
|
||||
return $this->red->convertFrom($this);
|
||||
}
|
||||
|
||||
public function _forceRed(Red &$ctx) {
|
||||
$this->red = $ctx;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function forceRed(Red &$ctx) {
|
||||
if( $this->red !== null )
|
||||
throw new Exception("Already a number in reduction context");
|
||||
return $this->_forceRed($ctx);
|
||||
}
|
||||
|
||||
public function redAdd(BN $num) {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redAdd works only with red numbers");
|
||||
|
||||
$res = clone($this);
|
||||
$res->bi = $res->bi->add($num->bi);
|
||||
if ($res->bi->cmp($this->red->m->bi) >= 0)
|
||||
$res->bi = $res->bi->sub($this->red->m->bi);
|
||||
return $res;
|
||||
// return $this->red->add($this, $num);
|
||||
}
|
||||
|
||||
public function redIAdd(BN $num) {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redIAdd works only with red numbers");
|
||||
$res = $this;
|
||||
$res->bi = $res->bi->add($num->bi);
|
||||
if ($res->bi->cmp($this->red->m->bi) >= 0)
|
||||
$res->bi = $res->bi->sub($this->red->m->bi);
|
||||
return $res;
|
||||
//return $this->red->iadd($this, $num);
|
||||
}
|
||||
|
||||
public function redSub(BN $num) {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redSub works only with red numbers");
|
||||
$res = clone($this);
|
||||
$res->bi = $this->bi->sub($num->bi);
|
||||
if ($res->bi->sign() < 0)
|
||||
$res->bi = $res->bi->add($this->red->m->bi);
|
||||
return $res;
|
||||
//return $this->red->sub($this, $num);
|
||||
}
|
||||
|
||||
public function redISub(BN $num) {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redISub works only with red numbers");
|
||||
$this->bi = $this->bi->sub($num->bi);
|
||||
if ($this->bi->sign() < 0)
|
||||
$this->bi = $this->bi->add($this->red->m->bi);
|
||||
return $this;
|
||||
|
||||
// return $this->red->isub($this, $num);
|
||||
}
|
||||
|
||||
public function redShl(BN $num) {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redShl works only with red numbers");
|
||||
return $this->red->shl($this, $num);
|
||||
}
|
||||
|
||||
public function redMul(BN $num) {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redMul works only with red numbers");
|
||||
$res = clone($this);
|
||||
$res->bi = $this->bi->mul($num->bi)->mod($this->red->m->bi);
|
||||
return $res;
|
||||
/*
|
||||
return $this->red->mul($this, $num);
|
||||
*/
|
||||
}
|
||||
|
||||
public function redIMul(BN $num) {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redIMul works only with red numbers");
|
||||
$this->bi = $this->bi->mul($num->bi)->mod($this->red->m->bi);
|
||||
return $this;
|
||||
//return $this->red->imul($this, $num);
|
||||
}
|
||||
|
||||
public function redSqr() {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redSqr works only with red numbers");
|
||||
$res = clone($this);
|
||||
$res->bi = $this->bi->mul($this->bi)->mod($this->red->m->bi);
|
||||
return $res;
|
||||
/*
|
||||
$this->red->verify1($this);
|
||||
return $this->red->sqr($this);
|
||||
*/
|
||||
}
|
||||
|
||||
public function redISqr() {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redISqr works only with red numbers");
|
||||
$res = $this;
|
||||
$res->bi = $this->bi->mul($this->bi)->mod($this->red->m->bi);
|
||||
return $res;
|
||||
/* $this->red->verify1($this);
|
||||
return $this->red->isqr($this);
|
||||
*/
|
||||
}
|
||||
|
||||
public function redSqrt() {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redSqrt works only with red numbers");
|
||||
$this->red->verify1($this);
|
||||
return $this->red->sqrt($this);
|
||||
}
|
||||
|
||||
public function redInvm() {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redInvm works only with red numbers");
|
||||
$this->red->verify1($this);
|
||||
return $this->red->invm($this);
|
||||
}
|
||||
|
||||
public function redNeg() {
|
||||
if( $this->red === null )
|
||||
throw new Exception("redNeg works only with red numbers");
|
||||
$this->red->verify1($this);
|
||||
return $this->red->neg($this);
|
||||
}
|
||||
|
||||
public function redPow(BN $num) {
|
||||
$this->red->verify2($this, $num);
|
||||
return $this->red->pow($this, $num);
|
||||
}
|
||||
|
||||
public static function red($num) {
|
||||
return new Red($num);
|
||||
}
|
||||
|
||||
public static function mont($num) {
|
||||
return new Red($num);
|
||||
}
|
||||
|
||||
public function inspect() {
|
||||
return ($this->red == null ? "<BN: " : "<BN-R: ") . $this->toString(16) . ">";
|
||||
}
|
||||
|
||||
public function __debugInfo() {
|
||||
if ($this->red != null) {
|
||||
return ["BN-R" => $this->toString(16)];
|
||||
} else {
|
||||
return ["BN" => $this->toString(16)];
|
||||
}
|
||||
}
|
||||
}
|
||||
BN::$ASSERT_ENABLED = ini_get("zend.assertions") === "1";
|
||||
221
vendor/simplito/bn-php/lib/Red.php
vendored
Normal file
221
vendor/simplito/bn-php/lib/Red.php
vendored
Normal file
@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
namespace BN;
|
||||
|
||||
use \Exception;
|
||||
use \BI\BigInteger;
|
||||
|
||||
class Red
|
||||
{
|
||||
public static $ASSERT_ENABLED;
|
||||
public $m;
|
||||
|
||||
function __construct($m) {
|
||||
if( is_string($m) )
|
||||
$this->m = Red::primeByName($m);
|
||||
else
|
||||
$this->m = $m;
|
||||
|
||||
if( !$this->m->gtn(1) )
|
||||
throw new Exception("Modulus must be greater than 1");
|
||||
}
|
||||
|
||||
|
||||
public static function primeByName($name)
|
||||
{
|
||||
switch($name) {
|
||||
case "k256":
|
||||
return new BN("ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f", 16);
|
||||
case "p224":
|
||||
return new BN("ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001", 16);
|
||||
case "p192":
|
||||
return new BN("ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff", 16);
|
||||
case "p25519":
|
||||
return new BN("7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed", 16);
|
||||
default:
|
||||
throw new Exception("Unknown prime name " . $name);
|
||||
}
|
||||
}
|
||||
|
||||
public function verify1(BN $num)
|
||||
{
|
||||
if (Red::$ASSERT_ENABLED) assert(!$num->negative()); //,"red works only with positives");
|
||||
assert($num->red); //, "red works only with red numbers");
|
||||
}
|
||||
|
||||
public function verify2(BN $a, BN $b)
|
||||
{
|
||||
if (Red::$ASSERT_ENABLED) assert(!$a->negative() && !$b->negative()); //, "red works only with positives");
|
||||
assert($a->red && ($a->red == $b->red)); //, "red works only with red numbers");
|
||||
}
|
||||
|
||||
public function imod(BN &$a) {
|
||||
return $a->umod($this->m)->_forceRed($this);
|
||||
}
|
||||
|
||||
public function neg(BN $a)
|
||||
{
|
||||
if( $a->isZero() )
|
||||
return $a->_clone();
|
||||
return $this->m->sub($a)->_forceRed($this);
|
||||
}
|
||||
|
||||
public function add(BN $a, BN $b)
|
||||
{
|
||||
$this->verify2($a, $b);
|
||||
|
||||
$res = $a->add($b);
|
||||
if( $res->cmp($this->m) >= 0 )
|
||||
$res->isub($this->m);
|
||||
return $res->_forceRed($this);
|
||||
}
|
||||
|
||||
public function iadd(BN &$a, BN $b)
|
||||
{
|
||||
$this->verify2($a, $b);
|
||||
|
||||
$a->iadd($b);
|
||||
if( $a->cmp($this->m) >= 0 )
|
||||
$a->isub($this->m);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public function sub(BN $a, BN $b)
|
||||
{
|
||||
$this->verify2($a, $b);
|
||||
|
||||
$res = $a->sub($b);
|
||||
if( $res->negative() )
|
||||
$res->iadd($this->m);
|
||||
|
||||
return $res->_forceRed($this);
|
||||
}
|
||||
|
||||
public function isub(BN &$a, $b)
|
||||
{
|
||||
$this->verify2($a, $b);
|
||||
|
||||
$a->isub($b);
|
||||
if( $a->negative() )
|
||||
$a->iadd($this->m);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public function shl(BN $a, $num) {
|
||||
$this->verify1($a);
|
||||
return $this->imod($a->ushln($num));
|
||||
}
|
||||
|
||||
public function imul(BN &$a, BN $b) {
|
||||
$this->verify2($a, $b);
|
||||
$res = $a->imul($b);
|
||||
return $this->imod($res);
|
||||
}
|
||||
|
||||
public function mul(BN $a, BN $b) {
|
||||
$this->verify2($a, $b);
|
||||
$res = $a->mul($b);
|
||||
return $this->imod($res);
|
||||
}
|
||||
|
||||
public function sqr(BN $a) {
|
||||
$res = $a->_clone();
|
||||
return $this->imul($res, $a);
|
||||
}
|
||||
|
||||
public function isqr(BN &$a) {
|
||||
return $this->imul($a, $a);
|
||||
}
|
||||
|
||||
public function sqrt(BN $a) {
|
||||
if ($a->isZero())
|
||||
return $a->_clone();
|
||||
|
||||
$mod3 = $this->m->andln(3);
|
||||
assert($mod3 % 2 == 1);
|
||||
|
||||
// Fast case
|
||||
if ($mod3 == 3) {
|
||||
$pow = $this->m->add(new BN(1))->iushrn(2);
|
||||
return $this->pow($a, $pow);
|
||||
}
|
||||
|
||||
// Tonelli-Shanks algorithm (Totally unoptimized and slow)
|
||||
//
|
||||
// Find Q and S, that Q * 2 ^ S = (P - 1)
|
||||
$q = $this->m->subn(1);
|
||||
$s = 0;
|
||||
while (!$q->isZero() && $q->andln(1) == 0) {
|
||||
$s++;
|
||||
$q->iushrn(1);
|
||||
}
|
||||
if (Red::$ASSERT_ENABLED) assert(!$q->isZero());
|
||||
|
||||
$one = (new BN(1))->toRed($this);
|
||||
$nOne = $one->redNeg();
|
||||
|
||||
// Find quadratic non-residue
|
||||
// NOTE: Max is such because of generalized Riemann hypothesis.
|
||||
$lpow = $this->m->subn(1)->iushrn(1);
|
||||
$z = $this->m->bitLength();
|
||||
$z = (new BN(2 * $z * $z))->toRed($this);
|
||||
|
||||
while ($this->pow($z, $lpow)->cmp($nOne) != 0) {
|
||||
$z->redIAdd($nOne);
|
||||
}
|
||||
|
||||
$c = $this->pow($z, $q);
|
||||
$r = $this->pow($a, $q->addn(1)->iushrn(1));
|
||||
$t = $this->pow($a, $q);
|
||||
$m = $s;
|
||||
while ($t->cmp($one) != 0) {
|
||||
$tmp = $t;
|
||||
for ($i = 0; $tmp->cmp($one) != 0; $i++) {
|
||||
$tmp = $tmp->redSqr();
|
||||
}
|
||||
if ($i >= $m) {
|
||||
throw new \Exception("Assertion failed");
|
||||
}
|
||||
if ($m - $i - 1 > 54) {
|
||||
$b = $this->pow($c, (new BN(1))->iushln($m - $i - 1));
|
||||
} else {
|
||||
$b = clone($c);
|
||||
$b->bi = $c->bi->powMod(1 << ($m - $i - 1), $this->m->bi);
|
||||
}
|
||||
|
||||
$r = $r->redMul($b);
|
||||
$c = $b->redSqr();
|
||||
$t = $t->redMul($c);
|
||||
$m = $i;
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
public function invm(BN &$a) {
|
||||
$res = $a->invm($this->m);
|
||||
return $this->imod($res);
|
||||
}
|
||||
|
||||
public function pow(BN $a, BN $num) {
|
||||
$r = clone($a);
|
||||
$r->bi = $a->bi->powMod($num->bi, $this->m->bi);
|
||||
return $r;
|
||||
}
|
||||
|
||||
public function convertTo(BN $num) {
|
||||
$r = $num->umod($this->m);
|
||||
return $r === $num ? $r->_clone() : $r;
|
||||
}
|
||||
|
||||
public function convertFrom(BN $num) {
|
||||
$res = $num->_clone();
|
||||
$res->red = null;
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
Red::$ASSERT_ENABLED = ini_get("zend.assertions") === "1";
|
||||
|
||||
?>
|
||||
8
vendor/simplito/elliptic-php/.gitignore
vendored
Normal file
8
vendor/simplito/elliptic-php/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
.vscode
|
||||
/vendor/
|
||||
node_modules
|
||||
composer.lock
|
||||
.project
|
||||
.settings
|
||||
.buildpath
|
||||
/.idea
|
||||
23
vendor/simplito/elliptic-php/LICENSE.md
vendored
Normal file
23
vendor/simplito/elliptic-php/LICENSE.md
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
## MIT LICENSE
|
||||
|
||||
Copyright (C) 2016 Simplito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
13
vendor/simplito/elliptic-php/Makefile
vendored
Normal file
13
vendor/simplito/elliptic-php/Makefile
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
all: test bench coverage
|
||||
|
||||
test:
|
||||
vendor/bin/phpunit --testdox
|
||||
|
||||
bench:
|
||||
vendor/bin/phpbench run --report=simple
|
||||
|
||||
coverage:
|
||||
sudo php5enmod xdebug
|
||||
vendor/bin/phpunit --coverage-html=coverage
|
||||
sudo php5dismod xdebug
|
||||
xdg-open coverage/index.html
|
||||
350
vendor/simplito/elliptic-php/README.md
vendored
Normal file
350
vendor/simplito/elliptic-php/README.md
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
|
||||
# Fast Elliptic Curve Cryptography in PHP
|
||||
|
||||
|
||||
## Information
|
||||
|
||||
This library is a PHP port of [elliptic](https://github.com/indutny/elliptic), a great JavaScript ECC library.
|
||||
|
||||
* Supported curve types: Short Weierstrass, Montgomery, Edwards, Twisted Edwards.
|
||||
* Curve 'presets': `secp256k1`, `p192`, `p224`, `p256`, `p384`, `p521`, `curve25519`, `ed25519`.
|
||||
|
||||
This software is licensed under the MIT License.
|
||||
|
||||
Projects which use Fast ECC PHP library: [PrivMX WebMail](https://privmx.com), ...
|
||||
|
||||
|
||||
## Benchmarks
|
||||
|
||||
```
|
||||
+------------------------+----------------+--------+-----+------+
|
||||
| subject | mode | rstdev | its | revs |
|
||||
+------------------------+----------------+--------+-----+------+
|
||||
| elliptic#genKeyPair | 323.682ops/s | 2.72% | 5 | 50 |
|
||||
| mdanter#genKeyPair | 13.794ops/s | 3.18% | 5 | 50 |
|
||||
+------------------------+----------------+--------+-----+------+
|
||||
| elliptic#sign | 307.228ops/s | 3.82% | 5 | 50 |
|
||||
| mdanter#sign | 14.118ops/s | 2.12% | 5 | 50 |
|
||||
+------------------------+----------------+--------+-----+------+
|
||||
| elliptic#verify | 93.913ops/s | 5.93% | 5 | 50 |
|
||||
| mdanter#verify | 6.859ops/s | 2.95% | 5 | 50 |
|
||||
+------------------------+----------------+--------+-----+------+
|
||||
| elliptic#dh | 135.166ops/s | 1.67% | 5 | 50 |
|
||||
| mdanter#dh | 14.302ops/s | 0.89% | 5 | 50 |
|
||||
+------------------------+----------------+--------+-----+------+
|
||||
| elliptic#EdDSASign | 296.756ops/s | 1.09% | 5 | 50 |
|
||||
+------------------------+----------------+--------+-----+------+
|
||||
| elliptic#EdDSAVerify | 67.481ops/s | 2.76% | 5 | 50 |
|
||||
+------------------------+----------------+--------+-----+------+
|
||||
```
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
You can install this library via Composer:
|
||||
```
|
||||
composer require simplito/elliptic-php
|
||||
```
|
||||
|
||||
|
||||
## Implementation details
|
||||
|
||||
ECDSA is using deterministic `k` value generation as per [RFC6979][0]. Most of
|
||||
the curve operations are performed on non-affine coordinates (either projective
|
||||
or extended), various windowing techniques are used for different cases.
|
||||
|
||||
NOTE: `curve25519` could not be used for ECDSA, use `ed25519` instead.
|
||||
|
||||
All operations are performed in reduction context using [bn-php][1].
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### ECDSA
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Elliptic\EC;
|
||||
|
||||
// Create and initialize EC context
|
||||
// (better do it once and reuse it)
|
||||
$ec = new EC('secp256k1');
|
||||
|
||||
// Generate keys
|
||||
$key = $ec->genKeyPair();
|
||||
|
||||
// Sign message (can be hex sequence or array)
|
||||
$msg = 'ab4c3451';
|
||||
$signature = $key->sign($msg);
|
||||
|
||||
// Export DER encoded signature to hex string
|
||||
$derSign = $signature->toDER('hex');
|
||||
|
||||
// Verify signature
|
||||
echo "Verified: " . (($key->verify($msg, $derSign) == TRUE) ? "true" : "false") . "\n";
|
||||
|
||||
// CHECK WITH NO PRIVATE KEY
|
||||
|
||||
// Public key as '04 + x + y'
|
||||
$pub = "049a1eedae838f2f8ad94597dc4368899ecc751342b464862da80c280d841875ab4607fb6ce14100e71dd7648dd6b417c7872a6ff1ff29195dabd99f15eff023e5";
|
||||
|
||||
// Signature MUST be either:
|
||||
// 1) hex-string of DER-encoded signature; or
|
||||
// 2) DER-encoded signature as byte array; or
|
||||
// 3) object with two hex-string properties (r and s)
|
||||
|
||||
// case 1
|
||||
$sig = '30450220233f8bab3f5df09e3d02f45914b0b519d2c04d13ac6964495623806a015df1cd022100c0c279c989b79885b3cc0f117643317bc59414bfb581f38e03557b8532f06603';
|
||||
|
||||
// case 2
|
||||
$sig = [48,69,2,32,35,63,139,171,63,93,240,158,61,2,244,89,20,176,181,25,210,192,77,19,172,105,100,73,86,35,128,106,1,93,241,205,2,33,0,192,194,121,201,137,183,152,133,179,204,15,17,118,67,49,123,197,148,20,191,181,129,243,142,3,85,123,133,50,240,102,3];
|
||||
|
||||
// case 3
|
||||
$sig = ['r' => '233f8bab3f5df09e3d02f45914b0b519d2c04d13ac6964495623806a015df1cd', 's' => 'c0c279c989b79885b3cc0f117643317bc59414bfb581f38e03557b8532f06603'];
|
||||
|
||||
|
||||
// Import public key
|
||||
$key = $ec->keyFromPublic($pub, 'hex');
|
||||
|
||||
// Verify signature
|
||||
echo "Verified: " . (($key->verify($msg, $sig) == TRUE) ? "true" : "false") . "\n";
|
||||
```
|
||||
|
||||
### EdDSA
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Elliptic\EdDSA;
|
||||
|
||||
// Create and initialize EdDSA context
|
||||
// (better do it once and reuse it)
|
||||
$ec = new EdDSA('ed25519');
|
||||
|
||||
// Create key pair from secret
|
||||
$key = $ec->keyFromSecret('61233ca4590acd'); // hex string or array of bytes
|
||||
|
||||
// Sign message (can be hex sequence or array)
|
||||
$msg = 'ab4c3451';
|
||||
$signature = $key->sign($msg)->toHex();
|
||||
|
||||
// Verify signature
|
||||
echo "Verified: " . (($key->verify($msg, $signature) == TRUE) ? "true" : "false") . "\n";
|
||||
|
||||
// CHECK WITH NO PRIVATE KEY
|
||||
|
||||
// Import public key
|
||||
$pub = '2763d01c334250d3e2dda459e5e3f949f667c6bbf0a35012c77ad40b00f0374d';
|
||||
$key = $ec->keyFromPublic($pub, 'hex');
|
||||
|
||||
// Verify signature
|
||||
$signature = '93899915C2919181A3D244AAAC032CE78EF76D2FFC0355D4BE2C70F48202EBC5F2BB0541D236182F55B11AC6346B524150695E5DE1FEA570786E1CC1F7999404';
|
||||
echo "Verified: " . (($key->verify($msg, $signature) == TRUE) ? "true" : "false") . "\n";
|
||||
```
|
||||
|
||||
### ECDH
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Elliptic\EC;
|
||||
|
||||
$ec = new EC('curve25519');
|
||||
|
||||
// Generate keys
|
||||
$key1 = $ec->genKeyPair();
|
||||
$key2 = $ec->genKeyPair();
|
||||
|
||||
$shared1 = $key1->derive($key2->getPublic());
|
||||
$shared2 = $key2->derive($key1->getPublic());
|
||||
|
||||
echo "Both shared secrets are BN instances\n";
|
||||
echo $shared1->toString(16) . "\n";
|
||||
echo $shared2->toString(16) . "\n";
|
||||
```
|
||||
|
||||
NOTE: `.derive()` returns a [BN][1] instance. The resulting hex string is not zero-padded to constant size. Note that when interoperating with other libraries or using the result in a hash function.
|
||||
|
||||
### Using EC directly
|
||||
|
||||
Use case examples:
|
||||
|
||||
#### Computing public key from private
|
||||
|
||||
```php
|
||||
use Elliptic\EC;
|
||||
|
||||
$ec = new EC('secp256k1');
|
||||
|
||||
$priv_hex = "751ce088f64404e5889bf7e9e5c280b200b2dc158461e96b921df39a1dbc6635";
|
||||
$pub_hex = "03a319a1d10a91ada9a01ab121b81ae5f14580083a976e74945cdb014a4a52bae6";
|
||||
|
||||
$priv = $ec->keyFromPrivate($priv_hex);
|
||||
if ($pub_hex == $priv->getPublic(true, "hex")) {
|
||||
echo "Success\n";
|
||||
} else {
|
||||
echo "Fail\n";
|
||||
}
|
||||
```
|
||||
|
||||
#### Verifying Bitcoin Message Signature
|
||||
|
||||
```php
|
||||
use Elliptic\EC;
|
||||
use StephenHill\Base58;
|
||||
|
||||
// see: https://en.bitcoin.it/wiki/List_of_address_prefixes
|
||||
const MainNetId = "\x00";
|
||||
const TestNetId = "\x6F";
|
||||
const PrefixNetIdMap = [ "1" => MainNetId, "m" => TestNetId ];
|
||||
|
||||
function pubKeyAddress($pubkey, $netid = MainNetId) {
|
||||
$b58 = new Base58();
|
||||
|
||||
$pubenc = hex2bin($pubkey->encode("hex", true));
|
||||
$pubhash = $netid . hash('ripemd160', hash('sha256', $pubenc, true), true);
|
||||
$checksum = substr( hash('sha256', hash('sha256', $pubhash, true), true), 0, 4);
|
||||
|
||||
return $b58->encode($pubhash . $checksum);
|
||||
}
|
||||
|
||||
function verifySignature($message, $signature, $address) {
|
||||
$signbin = base64_decode($signature);
|
||||
|
||||
$signarr = [ "r" => bin2hex(substr($signbin, 1, 32)),
|
||||
"s" => bin2hex(substr($signbin, 33, 32)) ];
|
||||
|
||||
$nv = ord(substr($signbin, 0, 1)) - 27;
|
||||
if ($nv != ($nv & 7))
|
||||
return false;
|
||||
|
||||
$recid = ($nv & 3);
|
||||
$compressed = ($nv & 4) != 0;
|
||||
|
||||
$msglen = strlen($message);
|
||||
$hash = hash('sha256', hash('sha256', "\x18Bitcoin Signed Message:\n" . chr($msglen) . $message, true));
|
||||
|
||||
$ec = new EC('secp256k1');
|
||||
$pub = $ec->recoverPubKey($hash, $signarr, $recid);
|
||||
|
||||
$result = pubKeyAddress($pub, PrefixNetIdMap[$address[0]]);
|
||||
return $result == $address;
|
||||
}
|
||||
|
||||
$message = "I like signatures";
|
||||
$signature = "H/zugYITIQTk8ZFWeXkbGCV2MzvMtbh+CnKBctbM9tP2UCb1B4LdyWFQuTZKxLdIDgP8Vsvl+0AEkBlY1HoyVw8=";
|
||||
$address = "mxQadqtYQXYeUsSqdMdJxZwkzxbd2tuMdc";
|
||||
|
||||
if (verifySignature($message, $signature, $address)) {
|
||||
echo "Success\n";
|
||||
} else {
|
||||
echo "Fail\n";
|
||||
}
|
||||
```
|
||||
|
||||
#### Verifying Ethereum Signature
|
||||
|
||||
```php
|
||||
use Elliptic\EC;
|
||||
use kornrunner\Keccak;
|
||||
|
||||
function pubKeyToAddress($pubkey) {
|
||||
return "0x" . substr(Keccak::hash(substr(hex2bin($pubkey->encode("hex")), 1), 256), 24);
|
||||
}
|
||||
|
||||
function verifySignature($message, $signature, $address) {
|
||||
$msglen = strlen($message);
|
||||
$hash = Keccak::hash("\x19Ethereum Signed Message:\n{$msglen}{$message}", 256);
|
||||
$sign = ["r" => substr($signature, 2, 64),
|
||||
"s" => substr($signature, 66, 64)];
|
||||
$recid = ord(hex2bin(substr($signature, 130, 2))) - 27;
|
||||
if ($recid != ($recid & 1))
|
||||
return false;
|
||||
|
||||
$ec = new EC('secp256k1');
|
||||
$pubkey = $ec->recoverPubKey($hash, $sign, $recid);
|
||||
|
||||
return $address == pubKeyToAddress($pubkey);
|
||||
}
|
||||
|
||||
$address = "0x5a214a45585b336a776b62a3a61dbafd39f9fa2a";
|
||||
$message = "I like signatures";
|
||||
// signature returned by eth.sign(address, message)
|
||||
$signature = "0xacb175089543ac060ed48c3e25ada5ffeed6f008da9eaca3806e4acb707b9481401409ae1f5f9f290f54f29684e7bac1d79b2964e0edcb7f083bacd5fc48882e1b";
|
||||
|
||||
if (verifySignature($message, $signature, $address)) {
|
||||
echo "Success\n";
|
||||
} else {
|
||||
echo "Fail\n";
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### ECDH (secret based, base58 format)
|
||||
|
||||
For usage in ed25519 oriented platforms like e.g. BigChainDB who use base58 encoded public / private keys.
|
||||
|
||||
```php
|
||||
use Elliptic\EdDSA;
|
||||
use StephenHill\Base58;
|
||||
|
||||
$mnemonic = "scheme spot photo card baby mountain device kick cradle pact join borrow";
|
||||
$secret = hash_pbkdf2('sha512', $mnemonic, 'mnemonic', 2048);
|
||||
|
||||
$ec = new EdDSA('ed25519');
|
||||
$kp = $ec->keyFromSecret($secret);
|
||||
|
||||
assert($secret == $kp->getSecret('hex'));
|
||||
echo "Secret: " . $kp->getSecret('hex') . PHP_EOL;
|
||||
|
||||
echo "Private: " . $kp->priv()->toString('hex') . PHP_EOL;
|
||||
echo "Public: " . $kp->getPublic('hex') . PHP_EOL;
|
||||
|
||||
$b58 = new Base58();
|
||||
echo PHP_EOL;
|
||||
echo "B58 Private: " . $b58->encode(hex2bin($kp->priv()->toString('hex'))) . PHP_EOL;
|
||||
echo "B58 Public: " . $b58->encode(hex2bin($kp->getPublic('hex'))) . PHP_EOL;
|
||||
```
|
||||
|
||||
#### BIP32 Public Parent Key -> Public Child Key derivation example
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Elliptic\EC;
|
||||
use BN\BN;
|
||||
|
||||
$ec = new EC('secp256k1');
|
||||
|
||||
// See: http://bip32.org using Derive From BIP32 Key
|
||||
// xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8
|
||||
$c_par = "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508";
|
||||
$K_par = "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2";
|
||||
|
||||
// Derived public child key
|
||||
// Derivation path Simple: m/i
|
||||
// Keypair index i: 2018
|
||||
// xpub68Gmy5EVb2Begkah8BxugKchT5SExW5p9gEHBLnEvYSuwVppt2TzD3WTjxNk14R8pmHbz3MHB9n75M2zNYgkJUCwV9pYwU9Z21Awj7Cr5U9
|
||||
$expected_c_child = "a7470737ffde1458292e19e838534f400ad3c0f72e12f08eff79dee4fce11bed";
|
||||
$expected_K_child = "0376499d06f9e9df71d7ee08d13a91337fa2b92182d4afcddf917b8d9983eb4615";
|
||||
|
||||
$i = 2018;
|
||||
$I_key = hex2bin($c_par);
|
||||
$I_data = hex2bin($K_par) . pack("N", $i);
|
||||
$I = hash_hmac("sha512", $I_data, $I_key);
|
||||
$I_L = substr($I, 0, 64);
|
||||
$I_R = substr($I, 64, 64);
|
||||
$c_i = $I_R;
|
||||
|
||||
$K_par_point = $ec->curve->decodePoint($K_par, "hex");
|
||||
$I_L_point = $ec->g->mul(new BN($I_L, 16));
|
||||
$K_i = $K_par_point->add($I_L_point);
|
||||
$K_i = $K_i->encodeCompressed("hex");
|
||||
|
||||
if ($expected_c_child == $c_i && $expected_K_child == $K_i) {
|
||||
echo "Success!\n";
|
||||
} else {
|
||||
echo "Failure!\n";
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
[0]: http://tools.ietf.org/html/rfc6979
|
||||
[1]: https://github.com/simplito/bn-php
|
||||
64
vendor/simplito/elliptic-php/benchmarks/EllipticBench.php
vendored
Normal file
64
vendor/simplito/elliptic-php/benchmarks/EllipticBench.php
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
require __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
/**
|
||||
* @BeforeMethods({"init"})
|
||||
*
|
||||
* @Iterations(5)
|
||||
* @Revs(50)
|
||||
* @OutputTimeUnit("seconds")
|
||||
* @OutputMode("throughput")
|
||||
*/
|
||||
class EllipticBench {
|
||||
private $ec;
|
||||
private $keys;
|
||||
private $hash;
|
||||
|
||||
static $msg = [ 0xB, 0xE, 0xE, 0xF ];
|
||||
|
||||
public function init() {
|
||||
$this->ec = new \Elliptic\EC('secp256k1');
|
||||
$this->priv = $this->ec->genKeyPair();
|
||||
$this->pub = $this->priv->getPublic();
|
||||
$this->hash = hash('sha256', 'hello world');
|
||||
$this->sign = $this->priv->sign($this->hash);
|
||||
$this->priv2 = $this->ec->genKeyPair();
|
||||
$this->pub2 = $this->priv2->getPublic();
|
||||
|
||||
$this->ed25519 = new \Elliptic\EdDSA('ed25519');
|
||||
$secret = array_fill(0, 32, 0);
|
||||
$this->edkey = $this->ed25519->keyFromSecret($secret);
|
||||
$this->edsig = $this->edkey->sign(self::$msg);
|
||||
}
|
||||
|
||||
public function benchGenKeyPair() {
|
||||
$this->ec->genKeyPair();
|
||||
}
|
||||
|
||||
public function benchGenKeyPairWithPublicKey() {
|
||||
$priv = $this->ec->genKeyPair();
|
||||
$pub = $priv->getPublic();
|
||||
}
|
||||
|
||||
public function benchSign() {
|
||||
$this->priv->sign($this->hash);
|
||||
}
|
||||
|
||||
public function benchVerify() {
|
||||
if ( !$this->ec->verify($this->hash, $this->sign, $this->pub) )
|
||||
throw new \Exception("unexpected");
|
||||
}
|
||||
|
||||
public function benchDH() {
|
||||
$this->priv->derive($this->pub2);
|
||||
}
|
||||
|
||||
public function benchEdDSASign() {
|
||||
$this->edkey->sign(self::$msg);
|
||||
}
|
||||
|
||||
public function benchEdDSAVerify() {
|
||||
if ( !$this->edkey->verify(self::$msg, $this->edsig) )
|
||||
throw new \Exception("unexpected");
|
||||
}
|
||||
}
|
||||
34
vendor/simplito/elliptic-php/composer.json
vendored
Normal file
34
vendor/simplito/elliptic-php/composer.json
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "simplito/elliptic-php",
|
||||
"description": "Fast elliptic curve cryptography",
|
||||
"type": "library",
|
||||
"homepage": "https://github.com/simplito/elliptic-php",
|
||||
"keywords": ["elliptic", "curve", "cryptography", "ECC",
|
||||
"ECDH", "ECDSA", "EdDSA",
|
||||
"secp256k1", "curve25519", "curve25519-weier", "ed25519",
|
||||
"nistp192", "nistp224", "nistp256", "nistp384", "nistp521"],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Simplito Team",
|
||||
"email": "s.smyczynski@simplito.com",
|
||||
"homepage": "https://simplito.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"ext-gmp": "*",
|
||||
"simplito/bn-php": "~1.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "*",
|
||||
"phpbench/phpbench": "@dev"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Elliptic\\": "lib/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit --verbose"
|
||||
}
|
||||
}
|
||||
321
vendor/simplito/elliptic-php/lib/Curve/BaseCurve.php
vendored
Normal file
321
vendor/simplito/elliptic-php/lib/Curve/BaseCurve.php
vendored
Normal file
@ -0,0 +1,321 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\Curve;
|
||||
|
||||
use Elliptic\Utils;
|
||||
use \Exception;
|
||||
use BN\BN;
|
||||
|
||||
abstract class BaseCurve
|
||||
{
|
||||
public $type;
|
||||
public $p;
|
||||
public $red;
|
||||
public $zero;
|
||||
public $one;
|
||||
public $two;
|
||||
public $n;
|
||||
public $g;
|
||||
protected $_wnafT1;
|
||||
protected $_wnafT2;
|
||||
protected $_wnafT3;
|
||||
protected $_wnafT4;
|
||||
public $redN;
|
||||
public $_maxwellTrick;
|
||||
|
||||
function __construct($type, $conf)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->p = new BN($conf["p"], 16);
|
||||
|
||||
//Use Montgomery, when there is no fast reduction for the prime
|
||||
$this->red = isset($conf["prime"]) ? BN::red($conf["prime"]) : BN::mont($this->p);
|
||||
|
||||
//Useful for many curves
|
||||
$this->zero = (new BN(0))->toRed($this->red);
|
||||
$this->one = (new BN(1))->toRed($this->red);
|
||||
$this->two = (new BN(2))->toRed($this->red);
|
||||
|
||||
//Curve configuration, optional
|
||||
$this->n = isset($conf["n"]) ? new BN($conf["n"], 16) : null;
|
||||
$this->g = isset($conf["g"]) ? $this->pointFromJSON($conf["g"], isset($conf["gRed"]) ? $conf["gRed"] : null) : null;
|
||||
|
||||
//Temporary arrays
|
||||
$this->_wnafT1 = array(0,0,0,0);
|
||||
$this->_wnafT2 = array(0,0,0,0);
|
||||
$this->_wnafT3 = array(0,0,0,0);
|
||||
$this->_wnafT4 = array(0,0,0,0);
|
||||
|
||||
//Generalized Greg Maxwell's trick
|
||||
$adjustCount = $this->n != null ? $this->p->div($this->n) : null;
|
||||
if( $adjustCount == null || $adjustCount->cmpn(100) > 0 )
|
||||
{
|
||||
$this->redN = null;
|
||||
$this->_maxwellTrick = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->redN = $this->n->toRed($this->red);
|
||||
$this->_maxwellTrick = true;
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function point($x, $z);
|
||||
abstract public function validate($point);
|
||||
|
||||
public function _fixedNafMul($p, $k)
|
||||
{
|
||||
assert(isset($p->precomputed));
|
||||
|
||||
$doubles = $p->_getDoubles();
|
||||
$naf = Utils::getNAF($k, 1);
|
||||
$I = (1 << ($doubles["step"] + 1)) - ($doubles["step"] % 2 == 0 ? 2 : 1);
|
||||
$I = $I / 3;
|
||||
|
||||
//Translate to more windowed form
|
||||
$repr = array();
|
||||
for($j = 0; $j < count($naf); $j += $doubles["step"])
|
||||
{
|
||||
$nafW = 0;
|
||||
for($k = $j + $doubles["step"] - 1; $k >= $j; $k--)
|
||||
$nafW = ($nafW << 1) + (isset($naf[$k]) ? $naf[$k] : 0);
|
||||
array_push($repr, $nafW);
|
||||
}
|
||||
|
||||
$a = $this->jpoint(null, null, null);
|
||||
$b = $this->jpoint(null, null, null);
|
||||
|
||||
for($i = $I; $i > 0; $i--)
|
||||
{
|
||||
for($j = 0; $j < count($repr); $j++)
|
||||
{
|
||||
$nafW = $repr[$j];
|
||||
if ($nafW == $i) {
|
||||
$b = $b->mixedAdd($doubles["points"][$j]);
|
||||
} else if($nafW == -$i) {
|
||||
$b = $b->mixedAdd($doubles["points"][$j]->neg());
|
||||
}
|
||||
}
|
||||
$a = $a->add($b);
|
||||
}
|
||||
|
||||
return $a->toP();
|
||||
}
|
||||
|
||||
public function _wnafMul($p, $k)
|
||||
{
|
||||
$w = 4;
|
||||
|
||||
//Precompute window
|
||||
$nafPoints = $p->_getNAFPoints($w);
|
||||
$w = $nafPoints["wnd"];
|
||||
$wnd = $nafPoints["points"];
|
||||
|
||||
//Get NAF form
|
||||
$naf = Utils::getNAF($k, $w);
|
||||
|
||||
//Add `this`*(N+1) for every w-NAF index
|
||||
$acc = $this->jpoint(null, null, null);
|
||||
for($i = count($naf) - 1; $i >= 0; $i--)
|
||||
{
|
||||
//Count zeros
|
||||
for($k = 0; $i >= 0 && $naf[$i] == 0; $i--)
|
||||
$k++;
|
||||
|
||||
if($i >= 0)
|
||||
$k++;
|
||||
$acc = $acc->dblp($k);
|
||||
|
||||
if($i < 0)
|
||||
break;
|
||||
$z = $naf[$i];
|
||||
|
||||
assert($z != 0);
|
||||
|
||||
if( $p->type == "affine" )
|
||||
{
|
||||
//J +- P
|
||||
if( $z > 0 )
|
||||
$acc = $acc->mixedAdd($wnd[($z - 1) >> 1]);
|
||||
else
|
||||
$acc = $acc->mixedAdd($wnd[(-$z - 1) >> 1]->neg());
|
||||
}
|
||||
else
|
||||
{
|
||||
//J +- J
|
||||
if( $z > 0 )
|
||||
$acc = $acc->add($wnd[($z - 1) >> 1]);
|
||||
else
|
||||
$acc = $acc->add($wnd[(-$z - 1) >> 1]->neg());
|
||||
}
|
||||
}
|
||||
return $p->type == "affine" ? $acc->toP() : $acc;
|
||||
}
|
||||
|
||||
public function _wnafMulAdd($defW, $points, $coeffs, $len, $jacobianResult = false)
|
||||
{
|
||||
$wndWidth = &$this->_wnafT1;
|
||||
$wnd = &$this->_wnafT2;
|
||||
$naf = &$this->_wnafT3;
|
||||
|
||||
//Fill all arrays
|
||||
$max = 0;
|
||||
for($i = 0; $i < $len; $i++)
|
||||
{
|
||||
$p = $points[$i];
|
||||
$nafPoints = $p->_getNAFPoints($defW);
|
||||
$wndWidth[$i] = $nafPoints["wnd"];
|
||||
$wnd[$i] = $nafPoints["points"];
|
||||
}
|
||||
//Comb all window NAFs
|
||||
for($i = $len - 1; $i >= 1; $i -= 2)
|
||||
{
|
||||
$a = $i - 1;
|
||||
$b = $i;
|
||||
if( $wndWidth[$a] != 1 || $wndWidth[$b] != 1 )
|
||||
{
|
||||
$naf[$a] = Utils::getNAF($coeffs[$a], $wndWidth[$a]);
|
||||
$naf[$b] = Utils::getNAF($coeffs[$b], $wndWidth[$b]);
|
||||
$max = max(count($naf[$a]), $max);
|
||||
$max = max(count($naf[$b]), $max);
|
||||
continue;
|
||||
}
|
||||
|
||||
$comb = array(
|
||||
$points[$a], /* 1 */
|
||||
null, /* 3 */
|
||||
null, /* 5 */
|
||||
$points[$b] /* 7 */
|
||||
);
|
||||
|
||||
//Try to avoid Projective points, if possible
|
||||
if( $points[$a]->y->cmp($points[$b]->y) == 0 )
|
||||
{
|
||||
$comb[1] = $points[$a]->add($points[$b]);
|
||||
$comb[2] = $points[$a]->toJ()->mixedAdd($points[$b]->neg());
|
||||
}
|
||||
elseif( $points[$a]->y->cmp($points[$b]->y->redNeg()) == 0 )
|
||||
{
|
||||
$comb[1] = $points[$a]->toJ()->mixedAdd($points[$b]);
|
||||
$comb[2] = $points[$a]->add($points[$b]->neg());
|
||||
}
|
||||
else
|
||||
{
|
||||
$comb[1] = $points[$a]->toJ()->mixedAdd($points[$b]);
|
||||
$comb[2] = $points[$a]->toJ()->mixedAdd($points[$b]->neg());
|
||||
}
|
||||
|
||||
$index = array(
|
||||
-3, /* -1 -1 */
|
||||
-1, /* -1 0 */
|
||||
-5, /* -1 1 */
|
||||
-7, /* 0 -1 */
|
||||
0, /* 0 0 */
|
||||
7, /* 0 1 */
|
||||
5, /* 1 -1 */
|
||||
1, /* 1 0 */
|
||||
3 /* 1 1 */
|
||||
);
|
||||
|
||||
$jsf = Utils::getJSF($coeffs[$a], $coeffs[$b]);
|
||||
$max = max(count($jsf[0]), $max);
|
||||
if ($max > 0) {
|
||||
$naf[$a] = array_fill(0, $max, 0);
|
||||
$naf[$b] = array_fill(0, $max, 0);
|
||||
} else {
|
||||
$naf[$a] = [];
|
||||
$naf[$b] = [];
|
||||
}
|
||||
|
||||
for($j = 0; $j < $max; $j++)
|
||||
{
|
||||
$ja = isset($jsf[0][$j]) ? $jsf[0][$j] : 0;
|
||||
$jb = isset($jsf[1][$j]) ? $jsf[1][$j] : 0;
|
||||
|
||||
$naf[$a][$j] = $index[($ja + 1) * 3 + ($jb + 1)];
|
||||
$naf[$b][$j] = 0;
|
||||
$wnd[$a] = $comb;
|
||||
}
|
||||
}
|
||||
|
||||
$acc = $this->jpoint(null, null, null);
|
||||
$tmp = &$this->_wnafT4;
|
||||
for($i = $max; $i >= 0; $i--)
|
||||
{
|
||||
$k = 0;
|
||||
|
||||
while($i >= 0)
|
||||
{
|
||||
$zero = true;
|
||||
for($j = 0; $j < $len; $j++)
|
||||
{
|
||||
$tmp[$j] = isset($naf[$j][$i]) ? $naf[$j][$i] : 0;
|
||||
if( $tmp[$j] != 0 )
|
||||
$zero = false;
|
||||
}
|
||||
if( !$zero )
|
||||
break;
|
||||
$k++;
|
||||
$i--;
|
||||
}
|
||||
|
||||
if( $i >=0 )
|
||||
$k++;
|
||||
|
||||
$acc = $acc->dblp($k);
|
||||
if( $i < 0 )
|
||||
break;
|
||||
|
||||
for($j = 0; $j < $len; $j++)
|
||||
{
|
||||
$z = $tmp[$j];
|
||||
$p = null;
|
||||
if( $z == 0 )
|
||||
continue;
|
||||
elseif( $z > 0 )
|
||||
$p = $wnd[$j][($z - 1) >> 1];
|
||||
elseif( $z < 0 )
|
||||
$p = $wnd[$j][(-$z - 1) >> 1]->neg();
|
||||
|
||||
if( $p->type == "affine" )
|
||||
$acc = $acc->mixedAdd($p);
|
||||
else
|
||||
$acc = $acc->add($p);
|
||||
}
|
||||
}
|
||||
|
||||
//Zeroify references
|
||||
for($i = 0; $i < $len; $i++)
|
||||
$wnd[$i] = null;
|
||||
|
||||
if( $jacobianResult )
|
||||
return $acc;
|
||||
else
|
||||
return $acc->toP();
|
||||
}
|
||||
|
||||
public function decodePoint($bytes, $enc = false)
|
||||
{
|
||||
$bytes = Utils::toArray($bytes, $enc);
|
||||
$len = $this->p->byteLength();
|
||||
|
||||
$count = count($bytes);
|
||||
//uncompressed, hybrid-odd, hybrid-even
|
||||
if(($bytes[0] == 0x04 || $bytes[0] == 0x06 || $bytes[0] == 0x07) && ($count - 1) == (2 * $len) )
|
||||
{
|
||||
if( $bytes[0] == 0x06 )
|
||||
assert($bytes[$count - 1] % 2 == 0);
|
||||
elseif( $bytes[0] == 0x07 )
|
||||
assert($bytes[$count - 1] % 2 == 1);
|
||||
|
||||
return $this->point(array_slice($bytes, 1, $len), array_slice($bytes, 1 + $len, $len));
|
||||
}
|
||||
|
||||
if( ($bytes[0] == 0x02 || $bytes[0] == 0x03) && ($count - 1) == $len )
|
||||
return $this->pointFromX(array_slice($bytes, 1, $len), $bytes[0] == 0x03);
|
||||
|
||||
throw new Exception("Unknown point format");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
120
vendor/simplito/elliptic-php/lib/Curve/BaseCurve/Point.php
vendored
Normal file
120
vendor/simplito/elliptic-php/lib/Curve/BaseCurve/Point.php
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\Curve\BaseCurve;
|
||||
|
||||
use Elliptic\Utils;
|
||||
|
||||
abstract class Point
|
||||
{
|
||||
public $curve;
|
||||
public $type;
|
||||
public $precomputed;
|
||||
|
||||
function __construct($curve, $type)
|
||||
{
|
||||
$this->curve = $curve;
|
||||
$this->type = $type;
|
||||
$this->precomputed = null;
|
||||
}
|
||||
|
||||
abstract public function eq($other);
|
||||
|
||||
public function validate() {
|
||||
return $this->curve->validate($this);
|
||||
}
|
||||
|
||||
public function encodeCompressed($enc) {
|
||||
return $this->encode($enc, true);
|
||||
}
|
||||
|
||||
public function encode($enc, $compact = false) {
|
||||
return Utils::encode($this->_encode($compact), $enc);
|
||||
}
|
||||
|
||||
protected function _encode($compact)
|
||||
{
|
||||
$len = $this->curve->p->byteLength();
|
||||
$x = $this->getX()->toArray("be", $len);
|
||||
|
||||
if( $compact )
|
||||
{
|
||||
array_unshift($x, ($this->getY()->isEven() ? 0x02 : 0x03));
|
||||
return $x;
|
||||
}
|
||||
|
||||
return array_merge(array(0x04), $x, $this->getY()->toArray("be", $len));
|
||||
}
|
||||
|
||||
public function precompute($power = null)
|
||||
{
|
||||
if( isset($this->precomputed) )
|
||||
return $this;
|
||||
|
||||
$this->precomputed = array(
|
||||
"naf" => $this->_getNAFPoints(8),
|
||||
"doubles" => $this->_getDoubles(4, $power),
|
||||
"beta" => $this->_getBeta()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function _hasDoubles($k)
|
||||
{
|
||||
if( !isset($this->precomputed) || !isset($this->precomputed["doubles"]) )
|
||||
return false;
|
||||
|
||||
return count($this->precomputed["doubles"]["points"]) >= ceil(($k->bitLength() + 1) / $this->precomputed["doubles"]["step"]);
|
||||
}
|
||||
|
||||
public function _getDoubles($step = null, $power = null)
|
||||
{
|
||||
if( isset($this->precomputed) && isset($this->precomputed["doubles"]) )
|
||||
return $this->precomputed["doubles"];
|
||||
|
||||
$doubles = array( $this );
|
||||
$acc = $this;
|
||||
for($i = 0; $i < $power; $i += $step)
|
||||
{
|
||||
for($j = 0; $j < $step; $j++)
|
||||
$acc = $acc->dbl();
|
||||
array_push($doubles, $acc);
|
||||
}
|
||||
|
||||
return array(
|
||||
"step" => $step,
|
||||
"points" => $doubles
|
||||
);
|
||||
}
|
||||
|
||||
public function _getNAFPoints($wnd)
|
||||
{
|
||||
if( isset($this->precomputed) && isset($this->precomputed["naf"]) )
|
||||
return $this->precomputed["naf"];
|
||||
|
||||
$res = array( $this );
|
||||
$max = (1 << $wnd) - 1;
|
||||
$dbl = $max === 1 ? null : $this->dbl();
|
||||
for($i = 1; $i < $max; $i++)
|
||||
array_push($res, $res[$i - 1]->add($dbl));
|
||||
|
||||
return array(
|
||||
"wnd" => $wnd,
|
||||
"points" => $res
|
||||
);
|
||||
}
|
||||
|
||||
public function _getBeta() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function dblp($k)
|
||||
{
|
||||
$r = $this;
|
||||
for($i = 0; $i < $k; $i++)
|
||||
$r = $r->dbl();
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
131
vendor/simplito/elliptic-php/lib/Curve/EdwardsCurve.php
vendored
Normal file
131
vendor/simplito/elliptic-php/lib/Curve/EdwardsCurve.php
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
namespace Elliptic\Curve;
|
||||
|
||||
use Elliptic\Curve\EdwardsCurve\Point;
|
||||
use Elliptic\Utils;
|
||||
use BN\BN;
|
||||
|
||||
class EdwardsCurve extends BaseCurve
|
||||
{
|
||||
public $twisted;
|
||||
public $mOneA;
|
||||
public $extended;
|
||||
public $a;
|
||||
public $c;
|
||||
public $c2;
|
||||
public $d;
|
||||
public $d2;
|
||||
public $dd;
|
||||
public $oneC;
|
||||
|
||||
function __construct($conf)
|
||||
{
|
||||
// NOTE: Important as we are creating point in Base.call()
|
||||
$this->twisted = ($conf["a"] | 0) != 1;
|
||||
$this->mOneA = $this->twisted && ($conf["a"] | 0) == -1;
|
||||
$this->extended = $this->mOneA;
|
||||
parent::__construct("edward", $conf);
|
||||
|
||||
$this->a = (new BN($conf["a"], 16))->umod($this->red->m);
|
||||
$this->a = $this->a->toRed($this->red);
|
||||
$this->c = (new BN($conf["c"], 16))->toRed($this->red);
|
||||
$this->c2 = $this->c->redSqr();
|
||||
$this->d = (new BN($conf["d"], 16))->toRed($this->red);
|
||||
$this->dd = $this->d->redAdd($this->d);
|
||||
if (Utils::$ASSERT_ENABLED) {
|
||||
assert(!$this->twisted || $this->c->fromRed()->cmpn(1) == 0);
|
||||
}
|
||||
$this->oneC = ($conf["c"] | 0) == 1;
|
||||
}
|
||||
|
||||
public function _mulA($num) {
|
||||
if ($this->mOneA)
|
||||
return $num->redNeg();
|
||||
else
|
||||
return $this->a->redMul($num);
|
||||
}
|
||||
|
||||
public function _mulC($num) {
|
||||
if ($this->oneC)
|
||||
return $num;
|
||||
else
|
||||
return $this->c->redMul($num);
|
||||
}
|
||||
|
||||
// Just for compatibility with Short curve
|
||||
public function jpoint($x, $y, $z, $t = null) {
|
||||
return $this->point($x, $y, $z, $t);
|
||||
}
|
||||
|
||||
public function pointFromX($x, $odd = false) {
|
||||
$x = new BN($x, 16);
|
||||
if (!$x->red)
|
||||
$x = $x->toRed($this->red);
|
||||
|
||||
$x2 = $x->redSqr();
|
||||
$rhs = $this->c2->redSub($this->a->redMul($x2));
|
||||
$lhs = $this->one->redSub($this->c2->redMul($this->d)->redMul($x2));
|
||||
|
||||
$y2 = $rhs->redMul($lhs->redInvm());
|
||||
$y = $y2->redSqrt();
|
||||
if ($y->redSqr()->redSub($y2)->cmp($this->zero) != 0)
|
||||
throw new \Exception('invalid point');
|
||||
|
||||
$isOdd = $y->fromRed()->isOdd();
|
||||
if ($odd && !$isOdd || !$odd && $isOdd)
|
||||
$y = $y->redNeg();
|
||||
|
||||
return $this->point($x, $y);
|
||||
}
|
||||
|
||||
public function pointFromY($y, $odd = false) {
|
||||
$y = new BN($y, 16);
|
||||
if (!$y->red)
|
||||
$y = $y->toRed($this->red);
|
||||
|
||||
// x^2 = (y^2 - 1) / (d y^2 + 1)
|
||||
$y2 = $y->redSqr();
|
||||
$lhs = $y2->redSub($this->one);
|
||||
$rhs = $y2->redMul($this->d)->redAdd($this->one);
|
||||
$x2 = $lhs->redMul($rhs->redInvm());
|
||||
|
||||
if ($x2->cmp($this->zero) == 0) {
|
||||
if ($odd)
|
||||
throw new \Exception('invalid point');
|
||||
else
|
||||
return $this->point($this->zero, $y);
|
||||
}
|
||||
|
||||
$x = $x2->redSqrt();
|
||||
if ($x->redSqr()->redSub($x2)->cmp($this->zero) != 0)
|
||||
throw new \Exception('invalid point');
|
||||
|
||||
if ($x->isOdd() != $odd)
|
||||
$x = $x->redNeg();
|
||||
|
||||
return $this->point($x, $y);
|
||||
}
|
||||
|
||||
public function validate($point) {
|
||||
if ($point->isInfinity())
|
||||
return true;
|
||||
|
||||
// Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
|
||||
$point->normalize();
|
||||
|
||||
$x2 = $point->x->redSqr();
|
||||
$y2 = $point->y->redSqr();
|
||||
$lhs = $x2->redMul($this->a)->redAdd($y2);
|
||||
$rhs = $this->c2->redMul($this->one->redAdd($this->d->redMul($x2)->redMul($y2)));
|
||||
|
||||
return $lhs->cmp($rhs) == 0;
|
||||
}
|
||||
|
||||
public function pointFromJSON($obj) {
|
||||
return Point::fromJSON($this, $obj);
|
||||
}
|
||||
|
||||
public function point($x = null, $y = null, $z = null, $t = null) {
|
||||
return new Point($this, $x, $y, $z, $t);
|
||||
}
|
||||
}
|
||||
323
vendor/simplito/elliptic-php/lib/Curve/EdwardsCurve/Point.php
vendored
Normal file
323
vendor/simplito/elliptic-php/lib/Curve/EdwardsCurve/Point.php
vendored
Normal file
@ -0,0 +1,323 @@
|
||||
<?php
|
||||
namespace Elliptic\Curve\EdwardsCurve;
|
||||
|
||||
use BN\BN;
|
||||
|
||||
class Point extends \Elliptic\Curve\BaseCurve\Point
|
||||
{
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $t;
|
||||
public $zOne;
|
||||
|
||||
function __construct($curve, $x = null, $y = null, $z = null, $t = null) {
|
||||
parent::__construct($curve, 'projective');
|
||||
if ($x == null && $y == null && $z == null) {
|
||||
$this->x = $this->curve->zero;
|
||||
$this->y = $this->curve->one;
|
||||
$this->z = $this->curve->one;
|
||||
$this->t = $this->curve->zero;
|
||||
$this->zOne = true;
|
||||
} else {
|
||||
$this->x = new BN($x, 16);
|
||||
$this->y = new BN($y, 16);
|
||||
$this->z = $z ? new BN($z, 16) : $this->curve->one;
|
||||
$this->t = $t ? new BN($t, 16) : null;
|
||||
if (!$this->x->red)
|
||||
$this->x = $this->x->toRed($this->curve->red);
|
||||
if (!$this->y->red)
|
||||
$this->y = $this->y->toRed($this->curve->red);
|
||||
if (!$this->z->red)
|
||||
$this->z = $this->z->toRed($this->curve->red);
|
||||
if ($this->t && !$this->t->red)
|
||||
$this->t = $this->t->toRed($this->curve->red);
|
||||
$this->zOne = $this->z == $this->curve->one;
|
||||
|
||||
// Use extended coordinates
|
||||
if ($this->curve->extended && !$this->t) {
|
||||
$this->t = $this->x->redMul($this->y);
|
||||
if (!$this->zOne)
|
||||
$this->t = $this->t->redMul($this->z->redInvm());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function fromJSON($curve, $obj) {
|
||||
return new Point($curve,
|
||||
isset($obj[0]) ? $obj[0] : null,
|
||||
isset($obj[1]) ? $obj[1] : null,
|
||||
isset($obj[2]) ? $obj[2] : null
|
||||
);
|
||||
}
|
||||
|
||||
public function inspect() {
|
||||
if ($this->isInfinity())
|
||||
return '<EC Point Infinity>';
|
||||
return '<EC Point x: ' . $this->x->fromRed()->toString(16, 2) .
|
||||
' y: ' . $this->y->fromRed()->toString(16, 2) .
|
||||
' z: ' . $this->z->fromRed()->toString(16, 2) . '>';
|
||||
}
|
||||
|
||||
public function isInfinity() {
|
||||
// XXX This code assumes that zero is always zero in red
|
||||
return $this->x->cmpn(0) == 0 &&
|
||||
$this->y->cmp($this->z) == 0;
|
||||
}
|
||||
|
||||
public function _extDbl() {
|
||||
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
||||
// #doubling-dbl-2008-hwcd
|
||||
// 4M + 4S
|
||||
|
||||
// A = X1^2
|
||||
$a = $this->x->redSqr();
|
||||
// B = Y1^2
|
||||
$b = $this->y->redSqr();
|
||||
// C = 2 * Z1^2
|
||||
$c = $this->z->redSqr();
|
||||
$c = $c->redIAdd($c);
|
||||
// D = a * A
|
||||
$d = $this->curve->_mulA($a);
|
||||
// E = (X1 + Y1)^2 - A - B
|
||||
$e = $this->x->redAdd($this->y)->redSqr()->redISub($a)->redISub($b);
|
||||
// G = D + B
|
||||
$g = $d->redAdd($b);
|
||||
// F = G - C
|
||||
$f = $g->redSub($c);
|
||||
// H = D - B
|
||||
$h = $d->redSub($b);
|
||||
// X3 = E * F
|
||||
$nx = $e->redMul($f);
|
||||
// Y3 = G * H
|
||||
$ny = $g->redMul($h);
|
||||
// T3 = E * H
|
||||
$nt = $e->redMul($h);
|
||||
// Z3 = F * G
|
||||
$nz = $f->redMul($g);
|
||||
return $this->curve->point($nx, $ny, $nz, $nt);
|
||||
}
|
||||
|
||||
public function _projDbl() {
|
||||
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
|
||||
// #doubling-dbl-2008-bbjlp
|
||||
// #doubling-dbl-2007-bl
|
||||
// and others
|
||||
// Generally 3M + 4S or 2M + 4S
|
||||
|
||||
// B = (X1 + Y1)^2
|
||||
$b = $this->x->redAdd($this->y)->redSqr();
|
||||
// C = X1^2
|
||||
$c = $this->x->redSqr();
|
||||
// D = Y1^2
|
||||
$d = $this->y->redSqr();
|
||||
|
||||
if ($this->curve->twisted) {
|
||||
// E = a * C
|
||||
$e = $this->curve->_mulA($c);
|
||||
// F = E + D
|
||||
$f = $e->redAdd($d);
|
||||
if ($this->zOne) {
|
||||
// X3 = (B - C - D) * (F - 2)
|
||||
$nx = $b->redSub($c)->redSub($d)->redMul($f->redSub($this->curve->two));
|
||||
// Y3 = F * (E - D)
|
||||
$ny = $f->redMul($e->redSub($d));
|
||||
// Z3 = F^2 - 2 * F
|
||||
$nz = $f->redSqr()->redSub($f)->redSub($f);
|
||||
} else {
|
||||
// H = Z1^2
|
||||
$h = $this->z->redSqr();
|
||||
// J = F - 2 * H
|
||||
$j = $f->redSub($h)->redISub($h);
|
||||
// X3 = (B-C-D)*J
|
||||
$nx = $b->redSub($c)->redISub($d)->redMul($j);
|
||||
// Y3 = F * (E - D)
|
||||
$ny = $f->redMul($e->redSub($d));
|
||||
// Z3 = F * J
|
||||
$nz = $f->redMul($j);
|
||||
}
|
||||
} else {
|
||||
// E = C + D
|
||||
$e = $c->redAdd($d);
|
||||
// H = (c * Z1)^2
|
||||
$h = $this->curve->_mulC($this->c->redMul($this->z))->redSqr();
|
||||
// J = E - 2 * H
|
||||
$j = $e->redSub($h)->redSub($h);
|
||||
// X3 = c * (B - E) * J
|
||||
$nx = $this->curve->_mulC($b->redISub($e))->redMul($j);
|
||||
// Y3 = c * E * (C - D)
|
||||
$ny = $this->curve->_mulC($e)->redMul($c->redISub($d));
|
||||
// Z3 = E * J
|
||||
$nz = $e->redMul($j);
|
||||
}
|
||||
return $this->curve->point($nx, $ny, $nz);
|
||||
}
|
||||
|
||||
public function dbl() {
|
||||
if ($this->isInfinity())
|
||||
return $this;
|
||||
|
||||
// Double in extended coordinates
|
||||
if ($this->curve->extended)
|
||||
return $this->_extDbl();
|
||||
else
|
||||
return $this->_projDbl();
|
||||
}
|
||||
|
||||
public function _extAdd($p) {
|
||||
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
||||
// #addition-add-2008-hwcd-3
|
||||
// 8M
|
||||
|
||||
// A = (Y1 - X1) * (Y2 - X2)
|
||||
$a = $this->y->redSub($this->x)->redMul($p->y->redSub($p->x));
|
||||
// B = (Y1 + X1) * (Y2 + X2)
|
||||
$b = $this->y->redAdd($this->x)->redMul($p->y->redAdd($p->x));
|
||||
// C = T1 * k * T2
|
||||
$c = $this->t->redMul($this->curve->dd)->redMul($p->t);
|
||||
// D = Z1 * 2 * Z2
|
||||
$d = $this->z->redMul($p->z->redAdd($p->z));
|
||||
// E = B - A
|
||||
$e = $b->redSub($a);
|
||||
// F = D - C
|
||||
$f = $d->redSub($c);
|
||||
// G = D + C
|
||||
$g = $d->redAdd($c);
|
||||
// H = B + A
|
||||
$h = $b->redAdd($a);
|
||||
// X3 = E * F
|
||||
$nx = $e->redMul($f);
|
||||
// Y3 = G * H
|
||||
$ny = $g->redMul($h);
|
||||
// T3 = E * H
|
||||
$nt = $e->redMul($h);
|
||||
// Z3 = F * G
|
||||
$nz = $f->redMul($g);
|
||||
return $this->curve->point($nx, $ny, $nz, $nt);
|
||||
}
|
||||
|
||||
public function _projAdd($p) {
|
||||
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
|
||||
// #addition-add-2008-bbjlp
|
||||
// #addition-add-2007-bl
|
||||
// 10M + 1S
|
||||
|
||||
// A = Z1 * Z2
|
||||
$a = $this->z->redMul($p->z);
|
||||
// B = A^2
|
||||
$b = $a->redSqr();
|
||||
// C = X1 * X2
|
||||
$c = $this->x->redMul($p->x);
|
||||
// D = Y1 * Y2
|
||||
$d = $this->y->redMul($p->y);
|
||||
// E = d * C * D
|
||||
$e = $this->curve->d->redMul($c)->redMul($d);
|
||||
// F = B - E
|
||||
$f = $b->redSub($e);
|
||||
// G = B + E
|
||||
$g = $b->redAdd($e);
|
||||
// X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
|
||||
$tmp = $this->x->redAdd($this->y)->redMul($p->x->redAdd($p->y))->redISub($c)->redISub($d);
|
||||
$nx = $a->redMul($f)->redMul($tmp);
|
||||
if ($this->curve->twisted) {
|
||||
// Y3 = A * G * (D - a * C)
|
||||
$ny = $a->redMul($g)->redMul($d->redSub($this->curve->_mulA($c)));
|
||||
// Z3 = F * G
|
||||
$nz = $f->redMul($g);
|
||||
} else {
|
||||
// Y3 = A * G * (D - C)
|
||||
$ny = $a->redMul($g)->redMul($d->redSub($c));
|
||||
// Z3 = c * F * G
|
||||
$nz = $this->curve->_mulC($f)->redMul($g);
|
||||
}
|
||||
return $this->curve->point($nx, $ny, $nz);
|
||||
}
|
||||
|
||||
public function add($p) {
|
||||
if ($this->isInfinity())
|
||||
return $p;
|
||||
if ($p->isInfinity())
|
||||
return $this;
|
||||
|
||||
if ($this->curve->extended)
|
||||
return $this->_extAdd($p);
|
||||
else
|
||||
return $this->_projAdd($p);
|
||||
}
|
||||
|
||||
public function mul($k) {
|
||||
if ($this->_hasDoubles($k))
|
||||
return $this->curve->_fixedNafMul($this, $k);
|
||||
else
|
||||
return $this->curve->_wnafMul($this, $k);
|
||||
}
|
||||
|
||||
public function mulAdd($k1, $p, $k2) {
|
||||
return $this->curve->_wnafMulAdd(1, [ $this, $p ], [ $k1, $k2 ], 2, false);
|
||||
}
|
||||
|
||||
public function jmulAdd($k1, $p, $k2) {
|
||||
return $this->curve->_wnafMulAdd(1, [ $this, $p ], [ $k1, $k2 ], 2, true);
|
||||
}
|
||||
|
||||
public function normalize() {
|
||||
if ($this->zOne)
|
||||
return $this;
|
||||
|
||||
// Normalize coordinates
|
||||
$zi = $this->z->redInvm();
|
||||
$this->x = $this->x->redMul($zi);
|
||||
$this->y = $this->y->redMul($zi);
|
||||
if ($this->t)
|
||||
$this->t = $this->t->redMul($zi);
|
||||
$this->z = $this->curve->one;
|
||||
$this->zOne = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function neg() {
|
||||
return $this->curve->point($this->x->redNeg(),
|
||||
$this->y,
|
||||
$this->z,
|
||||
($this->t != null) ? $this->t->redNeg() : null);
|
||||
}
|
||||
|
||||
public function getX() {
|
||||
$this->normalize();
|
||||
return $this->x->fromRed();
|
||||
}
|
||||
|
||||
public function getY() {
|
||||
$this->normalize();
|
||||
return $this->y->fromRed();
|
||||
}
|
||||
|
||||
public function eq($other) {
|
||||
return $this == $other ||
|
||||
$this->getX()->cmp($other->getX()) == 0 &&
|
||||
$this->getY()->cmp($other->getY()) == 0;
|
||||
}
|
||||
|
||||
public function eqXToP($x) {
|
||||
$rx = $x->toRed($this->curve->red)->redMul($this->z);
|
||||
if ($this->x->cmp($rx) == 0)
|
||||
return true;
|
||||
|
||||
$xc = $x->_clone();
|
||||
$t = $this->curve->redN->redMul($this->z);
|
||||
for (;;) {
|
||||
$xc->iadd($this->curve->n);
|
||||
if ($xc->cmp($this->curve->p) >= 0)
|
||||
return false;
|
||||
|
||||
$rx->redIAdd($t);
|
||||
if ($this->x->cmp($rx) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compatibility with BaseCurve
|
||||
public function toP() { return $this->normalize(); }
|
||||
public function mixedAdd($p) { return $this->add($p); }
|
||||
}
|
||||
49
vendor/simplito/elliptic-php/lib/Curve/MontCurve.php
vendored
Normal file
49
vendor/simplito/elliptic-php/lib/Curve/MontCurve.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\Curve;
|
||||
|
||||
use Elliptic\Curve\MontCurve\Point;
|
||||
use Elliptic\Utils;
|
||||
use BN\BN;
|
||||
|
||||
class MontCurve extends BaseCurve
|
||||
{
|
||||
public $a;
|
||||
public $b;
|
||||
public $i4;
|
||||
public $a24;
|
||||
|
||||
function __construct($conf)
|
||||
{
|
||||
parent::__construct("mont", $conf);
|
||||
|
||||
$this->a = (new BN($conf["a"], 16))->toRed($this->red);
|
||||
$this->b = (new BN($conf["b"], 16))->toRed($this->red);
|
||||
$this->i4 = (new BN(4))->toRed($this->red)->redInvm();
|
||||
$this->a24 = $this->i4->redMul($this->a->redAdd($this->two));
|
||||
}
|
||||
|
||||
public function validate($point)
|
||||
{
|
||||
$x = $point->normalize()->x;
|
||||
$x2 = $x->redSqr();
|
||||
$rhs = $x2->redMul($x)->redAdd($x2->redMul($this->a))->redAdd($x);
|
||||
$y = $rhs->redSqr();
|
||||
|
||||
return $y->redSqr()->cmp($rhs) ===0;
|
||||
}
|
||||
|
||||
public function decodePoint($bytes, $enc = false) {
|
||||
return $this->point(Utils::toArray($bytes, $enc), 1);
|
||||
}
|
||||
|
||||
public function point($x, $z) {
|
||||
return new Point($this, $x, $z);
|
||||
}
|
||||
|
||||
public function pointFromJSON($obj) {
|
||||
return Point::fromJSON($this, $obj);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
160
vendor/simplito/elliptic-php/lib/Curve/MontCurve/Point.php
vendored
Normal file
160
vendor/simplito/elliptic-php/lib/Curve/MontCurve/Point.php
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\Curve\MontCurve;
|
||||
|
||||
use BN\BN;
|
||||
|
||||
class Point extends \Elliptic\Curve\BaseCurve\Point
|
||||
{
|
||||
public $x;
|
||||
public $z;
|
||||
|
||||
function __construct($curve, $x, $z)
|
||||
{
|
||||
parent::__construct($curve, "projective");
|
||||
if( $x == null && $z == null )
|
||||
{
|
||||
$this->x = $this->curve->one;
|
||||
$this->z = $this->curve->zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->x = new BN($x, 16);
|
||||
$this->z = new BN($z, 16);
|
||||
if( !$this->x->red )
|
||||
$this->x = $this->x->toRed($this->curve->red);
|
||||
if( !$this->z->red )
|
||||
$this->z = $this->z->toRed($this->curve->red);
|
||||
}
|
||||
}
|
||||
|
||||
public function precompute($power = null) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
protected function _encode($compact) {
|
||||
return $this->getX()->toArray("be", $this->curve->p->byteLength());
|
||||
}
|
||||
|
||||
public static function fromJSON($curve, $obj) {
|
||||
return new Point($curve, $obj[0], isset($obj[1]) ? $obj[1] : $curve->one);
|
||||
}
|
||||
|
||||
public function inspect()
|
||||
{
|
||||
if( $this->isInfinity() )
|
||||
return "<EC Point Infinity>";
|
||||
return "<EC Point x: " . $this->x->fromRed()->toString(16, 2) .
|
||||
" z: " . $this->z->fromRed()->toString(16, 2) . ">";
|
||||
}
|
||||
|
||||
public function isInfinity() {
|
||||
// XXX This code assumes that zero is always zero in red
|
||||
return $this->z->isZero();
|
||||
}
|
||||
|
||||
public function dbl()
|
||||
{
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
|
||||
// 2M + 2S + 4A
|
||||
|
||||
// A = X1 + Z1
|
||||
$a = $this->x->redAdd($this->z);
|
||||
// AA = A^2
|
||||
$aa = $a->redSqr();
|
||||
// B = X1 - Z1
|
||||
$b = $this->x->redSub($this->z);
|
||||
// BB = B^2
|
||||
$bb = $b->redSqr();
|
||||
// C = AA - BB
|
||||
$c = $aa->redSub($bb);
|
||||
// X3 = AA * BB
|
||||
$nx = $aa->redMul($bb);
|
||||
// Z3 = C * (BB + A24 * C)
|
||||
$nz = $c->redMul( $bb->redAdd($this->curve->a24->redMul($c)) );
|
||||
return $this->curve->point($nx, $nz);
|
||||
}
|
||||
|
||||
public function add($p) {
|
||||
throw new \Exception('Not supported on Montgomery curve');
|
||||
}
|
||||
|
||||
public function diffAdd($p, $diff)
|
||||
{
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
|
||||
// 4M + 2S + 6A
|
||||
|
||||
// A = X2 + Z2
|
||||
$a = $this->x->redAdd($this->z);
|
||||
// B = X2 - Z2
|
||||
$b = $this->x->redSub($this->z);
|
||||
// C = X3 + Z3
|
||||
$c = $p->x->redAdd($p->z);
|
||||
// D = X3 - Z3
|
||||
$d = $p->x->redSub($p->z);
|
||||
// DA = D * A
|
||||
$da = $d->redMul($a);
|
||||
// CB = C * B
|
||||
$cb = $c->redMul($b);
|
||||
// X5 = Z1 * (DA + CB)^2
|
||||
$nx = $diff->z->redMul($da->redAdd($cb)->redSqr());
|
||||
// Z5 = X1 * (DA - CB)^2
|
||||
$nz = $diff->x->redMul($da->redSub($cb)->redSqr());
|
||||
|
||||
return $this->curve->point($nx, $nz);
|
||||
}
|
||||
|
||||
public function mul($k)
|
||||
{
|
||||
$t = $k->_clone();
|
||||
$a = $this; // (N / 2) * Q + Q
|
||||
$b = $this->curve->point(null, null); // (N / 2) * Q
|
||||
$c = $this; // Q
|
||||
|
||||
$bits = array();
|
||||
while( !$t->isZero() )
|
||||
{
|
||||
// TODO: Maybe it is faster to use toString(2)?
|
||||
array_push($bits, $t->andln(1));
|
||||
$t->iushrn(1);
|
||||
}
|
||||
|
||||
for($i = count($bits) - 1; $i >= 0; $i--)
|
||||
{
|
||||
if( $bits[$i] === 0 )
|
||||
{
|
||||
// N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
|
||||
$a = $a->diffAdd($b, $c);
|
||||
// N * Q = 2 * ((N / 2) * Q + Q))
|
||||
$b = $b->dbl();
|
||||
}
|
||||
else
|
||||
{
|
||||
// N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
|
||||
$b = $a->diffAdd($b, $c);
|
||||
// N * Q + Q = 2 * ((N / 2) * Q + Q)
|
||||
$a = $a->dbl();
|
||||
}
|
||||
}
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
public function eq($other) {
|
||||
return $this->getX()->cmp($other->getX()) === 0;
|
||||
}
|
||||
|
||||
public function normalize()
|
||||
{
|
||||
$this->x = $this->x->redMul($this->z->redInvm());
|
||||
$this->z = $this->curve->one;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getX() {
|
||||
$this->normalize();
|
||||
return $this->x->fromRed();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
27
vendor/simplito/elliptic-php/lib/Curve/PresetCurve.php
vendored
Normal file
27
vendor/simplito/elliptic-php/lib/Curve/PresetCurve.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\Curve;
|
||||
|
||||
class PresetCurve
|
||||
{
|
||||
public $curve;
|
||||
public $g;
|
||||
public $n;
|
||||
public $hash;
|
||||
|
||||
function __construct($options)
|
||||
{
|
||||
if ( $options["type"] === "short" )
|
||||
$this->curve = new ShortCurve($options);
|
||||
elseif ( $options["type"] === "edwards" )
|
||||
$this->curve = new EdwardsCurve($options);
|
||||
else
|
||||
$this->curve = new MontCurve($options);
|
||||
|
||||
$this->g = $this->curve->g;
|
||||
$this->n = $this->curve->n;
|
||||
$this->hash = isset($options["hash"]) ? $options["hash"] : null;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
305
vendor/simplito/elliptic-php/lib/Curve/ShortCurve.php
vendored
Normal file
305
vendor/simplito/elliptic-php/lib/Curve/ShortCurve.php
vendored
Normal file
@ -0,0 +1,305 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\Curve;
|
||||
|
||||
use Elliptic\Curve\ShortCurve\Point;
|
||||
use Elliptic\Curve\ShortCurve\JPoint;
|
||||
use Elliptic\Utils;
|
||||
use BN\BN;
|
||||
use \Exception;
|
||||
|
||||
class ShortCurve extends BaseCurve
|
||||
{
|
||||
public $a;
|
||||
public $b;
|
||||
public $tinv;
|
||||
public $zeroA;
|
||||
public $threeA;
|
||||
public $endo;
|
||||
private $_endoWnafT1;
|
||||
private $_endoWnafT2;
|
||||
|
||||
function __construct($conf)
|
||||
{
|
||||
parent::__construct("short", $conf);
|
||||
|
||||
$this->a = (new BN($conf["a"], 16))->toRed($this->red);
|
||||
$this->b = (new BN($conf["b"], 16))->toRed($this->red);
|
||||
$this->tinv = $this->two->redInvm();
|
||||
|
||||
$this->zeroA = $this->a->fromRed()->isZero();
|
||||
$this->threeA = $this->a->fromRed()->sub($this->p)->cmpn(-3) === 0;
|
||||
|
||||
// If curve is endomorphic, precalculate beta and lambda
|
||||
$this->endo = $this->_getEndomorphism($conf);
|
||||
$this->_endoWnafT1 = array(0,0,0,0);
|
||||
$this->_endoWnafT2 = array(0,0,0,0);
|
||||
}
|
||||
|
||||
private function _getEndomorphism($conf)
|
||||
{
|
||||
// No efficient endomorphism
|
||||
if( !$this->zeroA || !isset($this->g) || !isset($this->n) || $this->p->modn(3) != 1 )
|
||||
return null;
|
||||
|
||||
// Compute beta and lambda, that lambda * P = (beta * Px; Py)
|
||||
$beta = null;
|
||||
$lambda = null;
|
||||
if( isset($conf["beta"]) )
|
||||
$beta = (new BN($conf["beta"], 16))->toRed($this->red);
|
||||
else
|
||||
{
|
||||
$betas = $this->_getEndoRoots($this->p);
|
||||
// Choose smallest beta
|
||||
$beta = $betas[0]->cmp($betas[1]) < 0 ? $betas[0] : $betas[1];
|
||||
$beta = $beta->toRed($this->red);
|
||||
}
|
||||
|
||||
if( isset($conf["lambda"]) )
|
||||
$lambda = new BN($conf["lambda"], 16);
|
||||
else
|
||||
{
|
||||
// Choose the lambda that is matching selected beta
|
||||
$lambdas = $this->_getEndoRoots($this->n);
|
||||
if( $this->g->mul($lambdas[0])->x->cmp($this->g->x->redMul($beta)) == 0 )
|
||||
$lambda = $lambdas[0];
|
||||
else
|
||||
{
|
||||
$lambda = $lambdas[1];
|
||||
if (Utils::$ASSERT_ENABLED) {
|
||||
assert($this->g->mul($lambda)->x->cmp($this->g->x->redMul($beta)) === 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get basis vectors, used for balanced length-two representation
|
||||
$basis = null;
|
||||
if( !isset($conf["basis"]) )
|
||||
$basis = $this->_getEndoBasis($lambda);
|
||||
else
|
||||
{
|
||||
$callback = function($vector) {
|
||||
return array(
|
||||
"a" => new BN($vector["a"], 16),
|
||||
"b" => new BN($vector["b"], 16)
|
||||
);
|
||||
};
|
||||
$basis = array_map($callback, $conf["basis"]);
|
||||
}
|
||||
|
||||
return array(
|
||||
"beta" => $beta,
|
||||
"lambda" => $lambda,
|
||||
"basis" => $basis
|
||||
);
|
||||
}
|
||||
|
||||
private function _getEndoRoots($num)
|
||||
{
|
||||
// Find roots of for x^2 + x + 1 in F
|
||||
// Root = (-1 +- Sqrt(-3)) / 2
|
||||
//
|
||||
$red = $num === $this->p ? $this->red : BN::mont($num);
|
||||
$tinv = (new BN(2))->toRed($red)->redInvm();
|
||||
$ntinv = $tinv->redNeg();
|
||||
|
||||
$s = (new BN(3))->toRed($red)->redNeg()->redSqrt()->redMul($tinv);
|
||||
|
||||
return array(
|
||||
$ntinv->redAdd($s)->fromRed(),
|
||||
$ntinv->redSub($s)->fromRed()
|
||||
);
|
||||
}
|
||||
|
||||
private function _getEndoBasis($lambda)
|
||||
{
|
||||
// aprxSqrt >= sqrt(this.n)
|
||||
$aprxSqrt = $this->n->ushrn(intval($this->n->bitLength() / 2));
|
||||
|
||||
// 3.74
|
||||
// Run EGCD, until r(L + 1) < aprxSqrt
|
||||
$u = $lambda;
|
||||
$v = $this->n->_clone();
|
||||
$x1 = new BN(1);
|
||||
$y1 = new BN(0);
|
||||
$x2 = new BN(0);
|
||||
$y2 = new BN(1);
|
||||
|
||||
// NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
|
||||
$a0 = 0;
|
||||
$b0 = 0;
|
||||
// First vector
|
||||
$a1 = 0;
|
||||
$b1 = 0;
|
||||
// Second vector
|
||||
$a2 = 0;
|
||||
$b2 = 0;
|
||||
|
||||
$prevR = 0;
|
||||
$i = 0;
|
||||
$r = 0;
|
||||
$x = 0;
|
||||
|
||||
while( ! $u->isZero() )
|
||||
{
|
||||
$q = $v->div($u);
|
||||
$r = $v->sub($q->mul($u));
|
||||
$x = $x2->sub($q->mul($x1));
|
||||
$y = $y2->sub($q->mul($y2));
|
||||
|
||||
if( !$a1 && $r->cmp($aprxSqrt) < 0 )
|
||||
{
|
||||
$a0 = $prevR->neg();
|
||||
$b0 = $x1;
|
||||
$a1 = $r->neg();
|
||||
$b1 = $x;
|
||||
}
|
||||
elseif($a1 && ++$i === 2)
|
||||
break;
|
||||
|
||||
$prevR = $r;
|
||||
$v = $u;
|
||||
$u = $r;
|
||||
$x2 = $x1;
|
||||
$x1 = $x;
|
||||
$y2 = $y1;
|
||||
$y1 = $y;
|
||||
}
|
||||
$a2 = $r->neg();
|
||||
$b2 = $x;
|
||||
|
||||
$len1 = $a1->sqr()->add($b1->sqr());
|
||||
$len2 = $a2->sqr()->add($b2->sqr());
|
||||
if( $len2->cmp($len1) >= 0 )
|
||||
{
|
||||
$a2 = $a0;
|
||||
$b2 = $b0;
|
||||
}
|
||||
|
||||
// Normalize signs
|
||||
if( $a1->negative() )
|
||||
{
|
||||
$a1 = $a1->neg();
|
||||
$b1 = $b1->neg();
|
||||
}
|
||||
|
||||
if( $a2->negative() )
|
||||
{
|
||||
$a2 = $a2->neg();
|
||||
$b2 = $b2->neg();
|
||||
}
|
||||
|
||||
return array(
|
||||
array( "a" => $a1, "b" => $b1 ),
|
||||
array( "a" => $a2, "b" => $b2 ),
|
||||
);
|
||||
}
|
||||
|
||||
public function _endoSplit($k)
|
||||
{
|
||||
$basis = $this->endo["basis"];
|
||||
$v1 = $basis[0];
|
||||
$v2 = $basis[1];
|
||||
|
||||
$c1 = $v2["b"]->mul($k)->divRound($this->n);
|
||||
$c2 = $v1["b"]->neg()->mul($k)->divRound($this->n);
|
||||
|
||||
$p1 = $c1->mul($v1["a"]);
|
||||
$p2 = $c2->mul($v2["a"]);
|
||||
$q1 = $c1->mul($v1["b"]);
|
||||
$q2 = $c2->mul($v2["b"]);
|
||||
|
||||
//Calculate answer
|
||||
$k1 = $k->sub($p1)->sub($p2);
|
||||
$k2 = $q1->add($q2)->neg();
|
||||
|
||||
return array( "k1" => $k1, "k2" => $k2 );
|
||||
}
|
||||
|
||||
public function pointFromX($x, $odd)
|
||||
{
|
||||
$x = new BN($x, 16);
|
||||
if( !$x->red )
|
||||
$x = $x->toRed($this->red);
|
||||
|
||||
$y2 = $x->redSqr()->redMul($x)->redIAdd($x->redMul($this->a))->redIAdd($this->b);
|
||||
$y = $y2->redSqrt();
|
||||
if( $y->redSqr()->redSub($y2)->cmp($this->zero) !== 0 )
|
||||
throw new Exception("Invalid point");
|
||||
|
||||
// XXX Is there any way to tell if the number is odd without converting it
|
||||
// to non-red form?
|
||||
$isOdd = $y->fromRed()->isOdd();
|
||||
if( $odd != $isOdd )
|
||||
$y = $y->redNeg();
|
||||
|
||||
return $this->point($x, $y);
|
||||
}
|
||||
|
||||
public function validate($point)
|
||||
{
|
||||
if( $point->inf )
|
||||
return true;
|
||||
|
||||
$x = $point->x;
|
||||
$y = $point->y;
|
||||
|
||||
$ax = $this->a->redMul($x);
|
||||
$rhs = $x->redSqr()->redMul($x)->redIAdd($ax)->redIAdd($this->b);
|
||||
return $y->redSqr()->redISub($rhs)->isZero();
|
||||
}
|
||||
|
||||
public function _endoWnafMulAdd($points, $coeffs, $jacobianResult = false)
|
||||
{
|
||||
$npoints = &$this->_endoWnafT1;
|
||||
$ncoeffs = &$this->_endoWnafT2;
|
||||
|
||||
for($i = 0; $i < count($points); $i++)
|
||||
{
|
||||
$split = $this->_endoSplit($coeffs[$i]);
|
||||
$p = $points[$i];
|
||||
$beta = $p->_getBeta();
|
||||
|
||||
if( $split["k1"]->negative() )
|
||||
{
|
||||
$split["k1"]->ineg();
|
||||
$p = $p->neg(true);
|
||||
}
|
||||
|
||||
if( $split["k2"]->negative() )
|
||||
{
|
||||
$split["k2"]->ineg();
|
||||
$beta = $beta->neg(true);
|
||||
}
|
||||
|
||||
$npoints[$i * 2] = $p;
|
||||
$npoints[$i * 2 + 1] = $beta;
|
||||
$ncoeffs[$i * 2] = $split["k1"];
|
||||
$ncoeffs[$i * 2 + 1] = $split["k2"];
|
||||
}
|
||||
$res = $this->_wnafMulAdd(1, $npoints, $ncoeffs, $i * 2, $jacobianResult);
|
||||
|
||||
// Clean-up references to points and coefficients
|
||||
for($j = 0; $j < 2 * $i; $j++)
|
||||
{
|
||||
$npoints[$j] = null;
|
||||
$ncoeffs[$j] = null;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function point($x, $y, $isRed = false) {
|
||||
return new Point($this, $x, $y, $isRed);
|
||||
}
|
||||
|
||||
public function pointFromJSON($obj, $red) {
|
||||
return Point::fromJSON($this, $obj, $red);
|
||||
}
|
||||
|
||||
public function jpoint($x, $y, $z) {
|
||||
return new JPoint($this, $x, $y, $z);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
488
vendor/simplito/elliptic-php/lib/Curve/ShortCurve/JPoint.php
vendored
Normal file
488
vendor/simplito/elliptic-php/lib/Curve/ShortCurve/JPoint.php
vendored
Normal file
@ -0,0 +1,488 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\Curve\ShortCurve;
|
||||
|
||||
use BN\BN;
|
||||
|
||||
class JPoint extends \Elliptic\Curve\BaseCurve\Point
|
||||
{
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $zOne;
|
||||
|
||||
function __construct($curve, $x, $y, $z)
|
||||
{
|
||||
parent::__construct($curve, "jacobian");
|
||||
|
||||
if( $x == null && $y == null && $z == null )
|
||||
{
|
||||
$this->x = $this->curve->one;
|
||||
$this->y = $this->curve->one;
|
||||
$this->z = new BN(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->x = new BN($x, 16);
|
||||
$this->y = new BN($y, 16);
|
||||
$this->z = new BN($z, 16);
|
||||
}
|
||||
|
||||
if( !$this->x->red )
|
||||
$this->x = $this->x->toRed($this->curve->red);
|
||||
if( !$this->y->red )
|
||||
$this->y = $this->y->toRed($this->curve->red);
|
||||
if( !$this->z->red )
|
||||
$this->z = $this->z->toRed($this->curve->red);
|
||||
|
||||
return $this->zOne = $this->z == $this->curve->one;
|
||||
}
|
||||
|
||||
public function toP()
|
||||
{
|
||||
if( $this->isInfinity() )
|
||||
return $this->curve->point(null, null);
|
||||
|
||||
$zinv = $this->z->redInvm();
|
||||
$zinv2 = $zinv->redSqr();
|
||||
$ax = $this->x->redMul($zinv2);
|
||||
$ay = $this->y->redMul($zinv2)->redMul($zinv);
|
||||
|
||||
return $this->curve->point($ax, $ay);
|
||||
}
|
||||
|
||||
public function neg() {
|
||||
return $this->curve->jpoint($this->x, $this->y->redNeg(), $this->z);
|
||||
}
|
||||
|
||||
public function add($p)
|
||||
{
|
||||
// O + P = P
|
||||
if( $this->isInfinity() )
|
||||
return $p;
|
||||
|
||||
// P + O = P
|
||||
if( $p->isInfinity() )
|
||||
return $this;
|
||||
|
||||
// 12M + 4S + 7A
|
||||
$pz2 = $p->z->redSqr();
|
||||
$z2 = $this->z->redSqr();
|
||||
$u1 = $this->x->redMul($pz2);
|
||||
$u2 = $p->x->redMul($z2);
|
||||
$s1 = $this->y->redMul($pz2->redMul($p->z));
|
||||
$s2 = $p->y->redMul($z2->redMul($this->z));
|
||||
|
||||
$h = $u1->redSub($u2);
|
||||
$r = $s1->redSub($s2);
|
||||
|
||||
if( $h->isZero() )
|
||||
{
|
||||
if( ! $r->isZero() )
|
||||
return $this->curve->jpoint(null, null, null);
|
||||
else
|
||||
return $this->dbl();
|
||||
}
|
||||
|
||||
$h2 = $h->redSqr();
|
||||
$h3 = $h2->redMul($h);
|
||||
$v = $u1->redMul($h2);
|
||||
|
||||
$nx = $r->redSqr()->redIAdd($h3)->redISub($v)->redISub($v);
|
||||
$ny = $r->redMul($v->redISub($nx))->redISub($s1->redMul($h3));
|
||||
$nz = $this->z->redMul($p->z)->redMul($h);
|
||||
|
||||
return $this->curve->jpoint($nx, $ny, $nz);
|
||||
}
|
||||
|
||||
public function mixedAdd($p)
|
||||
{
|
||||
// O + P = P
|
||||
if( $this->isInfinity() )
|
||||
return $p->toJ();
|
||||
|
||||
// P + O = P
|
||||
if( $p->isInfinity() )
|
||||
return $this;
|
||||
|
||||
// 8M + 3S + 7A
|
||||
$z2 = $this->z->redSqr();
|
||||
$u1 = $this->x;
|
||||
$u2 = $p->x->redMul($z2);
|
||||
$s1 = $this->y;
|
||||
$s2 = $p->y->redMul($z2)->redMul($this->z);
|
||||
|
||||
$h = $u1->redSub($u2);
|
||||
$r = $s1->redSub($s2);
|
||||
|
||||
if( $h->isZero() )
|
||||
{
|
||||
if( ! $r->isZero() )
|
||||
return $this->curve->jpoint(null, null, null);
|
||||
else
|
||||
return $this->dbl();
|
||||
}
|
||||
|
||||
$h2 = $h->redSqr();
|
||||
$h3 = $h2->redMul($h);
|
||||
$v = $u1->redMul($h2);
|
||||
|
||||
$nx = $r->redSqr()->redIAdd($h3)->redISub($v)->redISub($v);
|
||||
$ny = $r->redMul($v->redISub($nx))->redISub($s1->redMul($h3));
|
||||
$nz = $this->z->redMul($h);
|
||||
|
||||
return $this->curve->jpoint($nx, $ny, $nz);
|
||||
}
|
||||
|
||||
public function dblp($pow = null)
|
||||
{
|
||||
if( $pow == 0 || $this->isInfinity() )
|
||||
return $this;
|
||||
|
||||
if( $pow == null )
|
||||
return $this->dbl();
|
||||
|
||||
if( $this->curve->zeroA || $this->curve->threeA )
|
||||
{
|
||||
$r = $this;
|
||||
for($i = 0; $i < $pow; $i++)
|
||||
$r = $r->dbl();
|
||||
return $r;
|
||||
}
|
||||
|
||||
// 1M + 2S + 1A + N * (4S + 5M + 8A)
|
||||
// N = 1 => 6M + 6S + 9A
|
||||
$jx = $this->x;
|
||||
$jy = $this->y;
|
||||
$jz = $this->z;
|
||||
$jz4 = $jz->redSqr()->redSqr();
|
||||
|
||||
//Reuse results
|
||||
$jyd = $jy->redAdd($jy);
|
||||
for($i = 0; $i < $pow; $i++)
|
||||
{
|
||||
$jx2 = $jx->redSqr();
|
||||
$jyd2 = $jyd->redSqr();
|
||||
$jyd4 = $jyd2->redSqr();
|
||||
$c = $jx2->redAdd($jx2)->redIAdd($jx2)->redIAdd($this->curve->a->redMul($jz4));
|
||||
|
||||
$t1 = $jx->redMul($jyd2);
|
||||
$nx = $c->redSqr()->redISub($t1->redAdd($t1));
|
||||
$t2 = $t1->redISub($nx);
|
||||
$dny = $c->redMul($t2);
|
||||
$dny = $dny->redIAdd($dny)->redISub($jyd4);
|
||||
$nz = $jyd->redMul($jz);
|
||||
if( ($i + 1) < $pow)
|
||||
$jz4 = $jz4->redMul($jyd4);
|
||||
|
||||
$jx = $nx;
|
||||
$jz = $nz;
|
||||
$jyd = $dny;
|
||||
}
|
||||
|
||||
return $this->curve->jpoint($jx, $jyd->redMul($this->curve->tinv), $jz);
|
||||
}
|
||||
|
||||
public function dbl()
|
||||
{
|
||||
if( $this->isInfinity() )
|
||||
return $this;
|
||||
|
||||
if( $this->curve->zeroA )
|
||||
return $this->_zeroDbl();
|
||||
elseif( $this->curve->threeA )
|
||||
return $this->_threeDbl();
|
||||
return $this->_dbl();
|
||||
}
|
||||
|
||||
private function _zOneDbl($withA)
|
||||
{
|
||||
$xx = $this->x->redSqr();
|
||||
$yy = $this->y->redSqr();
|
||||
$yyyy = $yy->redSqr();
|
||||
|
||||
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
||||
$s = $this->x->redAdd($yy)->redSqr()->redISub($xx)->redISub($yyyy);
|
||||
$s = $s->redIAdd($s);
|
||||
|
||||
// M = 3 * XX + a; a = 0
|
||||
$m = null;
|
||||
if( $withA )
|
||||
$m = $xx->redAdd($xx)->redIAdd($xx)->redIAdd($this->curve->a);
|
||||
else
|
||||
$m = $xx->redAdd($xx)->redIAdd($xx);
|
||||
|
||||
// T = M ^ 2 - 2*S
|
||||
$t = $m->redSqr()->redISub($s)->redISub($s);
|
||||
|
||||
$yyyy8 = $yyyy->redIAdd($yyyy);
|
||||
$yyyy8 = $yyyy8->redIAdd($yyyy8);
|
||||
$yyyy8 = $yyyy8->redIAdd($yyyy8);
|
||||
|
||||
$ny = $m->redMul($s->redISub($t))->redISub($yyyy8);
|
||||
$nz = $this->y->redAdd($this->y);
|
||||
return $this->curve->jpoint($t, $ny, $nz);
|
||||
}
|
||||
|
||||
private function _zeroDbl()
|
||||
{
|
||||
// Z = 1
|
||||
if( $this->zOne )
|
||||
{
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
||||
// #doubling-mdbl-2007-bl
|
||||
// 1M + 5S + 14A
|
||||
return $this->_zOneDbl(false);
|
||||
}
|
||||
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
||||
// #doubling-dbl-2009-l
|
||||
// 2M + 5S + 13A
|
||||
|
||||
$a = $this->x->redSqr();
|
||||
$b = $this->y->redSqr();
|
||||
$c = $b->redSqr();
|
||||
// D = 2 * ((X1 + B)^2 - A - C)
|
||||
$d = $this->x->redAdd($b)->redSqr()->redISub($a)->redISub($c);
|
||||
$d = $d->redIAdd($d);
|
||||
$e = $a->redAdd($a)->redIAdd($a);
|
||||
$f = $e->redSqr();
|
||||
|
||||
$c8 = $c->redIAdd($c);
|
||||
$c8 = $c8->redIAdd($c8);
|
||||
$c8 = $c8->redIAdd($c8);
|
||||
|
||||
// X3 = F - 2 * D
|
||||
$nx = $f->redISub($d)->redISub($d);
|
||||
// Y3 = E * (D - X3) - 8 * C
|
||||
$ny = $e->redMul($d->redISub($nx))->redISub($c8);
|
||||
// Z3 = 2 * Y1 * Z1
|
||||
$nz = $this->y->redMul($this->z);
|
||||
$nz = $nz->redIAdd($nz);
|
||||
|
||||
return $this->curve->jpoint($nx, $ny, $nz);
|
||||
}
|
||||
|
||||
private function _threeDbl()
|
||||
{
|
||||
if( $this->zOne )
|
||||
{
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
|
||||
// #doubling-mdbl-2007-bl
|
||||
// 1M + 5S + 15A
|
||||
|
||||
// XX = X1^2
|
||||
$xx = $this->x->redSqr();
|
||||
// YY = Y1^2
|
||||
$yy = $this->y->redSqr();
|
||||
// YYYY = YY^2
|
||||
$yyyy = $yy->redSqr();
|
||||
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
||||
$s = $this->x->redAdd($yy)->redSqr()->redISub($xx)->redISub($yyyy);
|
||||
$s = $s->redIAdd($s);
|
||||
// M = 3 * XX + a
|
||||
$m = $xx->redAdd($xx)->redIAdd($xx)->redIAdd($this->curve->a);
|
||||
// T = M^2 - 2 * S
|
||||
$t = $m->redSqr()->redISub($s)->redISub($s);
|
||||
// X3 = T
|
||||
$nx = $t;
|
||||
// Y3 = M * (S - T) - 8 * YYYY
|
||||
$yyyy8 = $yyyy->redIAdd($yyyy);
|
||||
$yyyy8 = $yyyy8->redIAdd($yyyy8);
|
||||
$yyyy8 = $yyyy8->redIAdd($yyyy8);
|
||||
$ny = $m->redMul($s->redISub($t))->redISub($yyyy8);
|
||||
// Z3 = 2 * Y1
|
||||
$nz = $this->y->redAdd($this->y);
|
||||
} else {
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
|
||||
// 3M + 5S
|
||||
|
||||
// delta = Z1^2
|
||||
$delta = $this->z->redSqr();
|
||||
// gamma = Y1^2
|
||||
$gamma = $this->y->redSqr();
|
||||
// beta = X1 * gamma
|
||||
$beta = $this->x->redMul($gamma);
|
||||
// alpha = 3 * (X1 - delta) * (X1 + delta)
|
||||
$alpha = $this->x->redSub($delta)->redMul($this->x->redAdd($delta));
|
||||
$alpha = $alpha->redAdd($alpha)->redIAdd($alpha);
|
||||
// X3 = alpha^2 - 8 * beta
|
||||
$beta4 = $beta->redIAdd($beta);
|
||||
$beta4 = $beta4->redIAdd($beta4);
|
||||
$beta8 = $beta4->redAdd($beta4);
|
||||
$nx = $alpha->redSqr()->redISub($beta8);
|
||||
// Z3 = (Y1 + Z1)^2 - gamma - delta
|
||||
$nz = $this->y->redAdd($this->z)->redSqr()->redISub($gamma)->redISub($delta);
|
||||
|
||||
$ggamma8 = $gamma->redSqr();
|
||||
$ggamma8 = $ggamma8->redIAdd($ggamma8);
|
||||
$ggamma8 = $ggamma8->redIAdd($ggamma8);
|
||||
$ggamma8 = $ggamma8->redIAdd($ggamma8);
|
||||
// Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
|
||||
$ny = $alpha->redMul($beta4->redISub($nx))->redISub($ggamma8);
|
||||
}
|
||||
return $this->curve->jpoint($nx, $ny, $nz);
|
||||
}
|
||||
|
||||
private function _dbl()
|
||||
{
|
||||
// 4M + 6S + 10A
|
||||
$jx = $this->x;
|
||||
$jy = $this->y;
|
||||
$jz = $this->z;
|
||||
$jz4 = $jz->redSqr()->redSqr();
|
||||
|
||||
$jx2 = $jx->redSqr();
|
||||
$jy2 = $jy->redSqr();
|
||||
|
||||
$c = $jx2->redAdd($jx2)->redIAdd($jx2)->redIAdd($this->curve->a->redMul($jz4));
|
||||
$jxd4 = $jx->redAdd($jx);
|
||||
$jxd4 = $jxd4->redIAdd($jxd4);
|
||||
$t1 = $jxd4->redMul($jy2);
|
||||
$nx = $c->redSqr()->redISub($t1->redAdd($t1));
|
||||
$t2 = $t1->redISub($nx);
|
||||
|
||||
$jyd8 = $jy2->redSqr();
|
||||
$jyd8 = $jyd8->redIAdd($jyd8);
|
||||
$jyd8 = $jyd8->redIAdd($jyd8);
|
||||
$jyd8 = $jyd8->redIAdd($jyd8);
|
||||
|
||||
$ny = $c->redMul($t2)->redISub($jyd8);
|
||||
$nz = $jy->redAdd($jy)->redMul($jz);
|
||||
|
||||
return $this->curve->jpoint($nx, $ny, $nz);
|
||||
}
|
||||
|
||||
public function trpl()
|
||||
{
|
||||
if( !$this->curve->zeroA )
|
||||
return $this->dbl()->add($this);
|
||||
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
|
||||
// 5M + 10S + ...
|
||||
|
||||
$xx = $this->x->redSqr();
|
||||
$yy = $this->y->redSqr();
|
||||
$zz = $this->z->redSqr();
|
||||
// YYYY = YY^2
|
||||
$yyyy = $yy->redSqr();
|
||||
|
||||
// M = 3 * XX + a * ZZ2; a = 0
|
||||
$m = $xx->redAdd($xx)->redIAdd($xx);
|
||||
// MM = M^2
|
||||
$mm = $m->redSqr();
|
||||
|
||||
// E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
|
||||
$e = $this->x->redAdd($yy)->redSqr()->redISub($xx)->redISub($yyyy);
|
||||
$e = $e->redIAdd($e);
|
||||
$e = $e->redAdd($e)->redIAdd($e);
|
||||
$e = $e->redISub($mm);
|
||||
|
||||
$ee = $e->redSqr();
|
||||
// T = 16*YYYY
|
||||
$t = $yyyy->redIAdd($yyyy);
|
||||
$t = $t->redIAdd($t);
|
||||
$t = $t->redIAdd($t);
|
||||
$t = $t->redIAdd($t);
|
||||
|
||||
// U = (M + E)^2 - MM - EE - T
|
||||
$u = $m->redAdd($e)->redSqr()->redISub($mm)->redISub($ee)->redISub($t);
|
||||
|
||||
$yyu4 = $yy->redMul($u);
|
||||
$yyu4 = $yyu4->redIAdd($yyu4);
|
||||
$yyu4 = $yyu4->redIAdd($yyu4);
|
||||
|
||||
// X3 = 4 * (X1 * EE - 4 * YY * U)
|
||||
$nx = $this->x->redMul($ee)->redISub($yyu4);
|
||||
$nx = $nx->redIAdd($nx);
|
||||
$nx = $nx->redIAdd($nx);
|
||||
|
||||
// Y3 = 8 * Y1 * (U * (T - U) - E * EE)
|
||||
$ny = $this->y->redMul($u->redMul($t->redISub($u))->redISub($e->redMul($ee)));
|
||||
$ny = $ny->redIAdd($ny);
|
||||
$ny = $ny->redIAdd($ny);
|
||||
$ny = $ny->redIAdd($ny);
|
||||
|
||||
// Z3 = (Z1 + E)^2 - ZZ - EE
|
||||
$nz = $this->z->redAdd($e)->redSqr()->redISub($zz)->redISub($ee);
|
||||
|
||||
return $this->curve->jpoint($nx, $ny, $nz);
|
||||
}
|
||||
|
||||
public function mul($k, $kbase) {
|
||||
return $this->curve->_wnafMul($this, new BN($k, $kbase));
|
||||
}
|
||||
|
||||
public function eq($p)
|
||||
{
|
||||
if( $p->type == "affine" )
|
||||
return $this->eq($p->toJ());
|
||||
|
||||
if( $this == $p )
|
||||
return true;
|
||||
|
||||
// x1 * z2^2 == x2 * z1^2
|
||||
$z2 = $this->z->redSqr();
|
||||
$pz2 = $p->z->redSqr();
|
||||
if( ! $this->x->redMul($pz2)->redISub($p->x->redMul($z2))->isZero() )
|
||||
return false;
|
||||
|
||||
// y1 * z2^3 == y2 * z1^3
|
||||
$z3 = $z2->redMul($this->z);
|
||||
$pz3 = $pz2->redMul($p->z);
|
||||
|
||||
return $this->y->redMul($pz3)->redISub($p->y->redMul($z3))->isZero();
|
||||
}
|
||||
|
||||
public function eqXToP($x)
|
||||
{
|
||||
$zs = $this->z->redSqr();
|
||||
$rx = $x->toRed($this->curve->red)->redMul($zs);
|
||||
if( $this->x->cmp($rx) == 0 )
|
||||
return true;
|
||||
|
||||
$xc = $x->_clone();
|
||||
$t = $this->curve->redN->redMul($zs);
|
||||
|
||||
while(true)
|
||||
{
|
||||
$xc->iadd($this->curve->n);
|
||||
if( $xc->cmp($this->curve->p) >= 0 )
|
||||
return false;
|
||||
|
||||
$rx->redIAdd($t);
|
||||
if( $this->x->cmp($rx) == 0 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function inspect()
|
||||
{
|
||||
if( $this->isInfinity() )
|
||||
return "<EC JPoint Infinity>";
|
||||
|
||||
return "<EC JPoint x: " . $this->x->toString(16, 2) .
|
||||
" y: " . $this->y->toString(16, 2) .
|
||||
" z: " . $this->z->toString(16, 2) . ">";
|
||||
}
|
||||
|
||||
public function __debugInfo() {
|
||||
return [
|
||||
"EC JPoint" => ($this->isInfinity() ?
|
||||
"Infinity" :
|
||||
[
|
||||
"x" => $this->x->toString(16,2),
|
||||
"y" => $this->y->toString(16,2),
|
||||
"z" => $this->z->toString(16,2)
|
||||
]
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
public function isInfinity() {
|
||||
// XXX This code assumes that zero is always zero in red
|
||||
return $this->z->isZero();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
317
vendor/simplito/elliptic-php/lib/Curve/ShortCurve/Point.php
vendored
Normal file
317
vendor/simplito/elliptic-php/lib/Curve/ShortCurve/Point.php
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\Curve\ShortCurve;
|
||||
|
||||
use JsonSerializable;
|
||||
use BN\BN;
|
||||
|
||||
class Point extends \Elliptic\Curve\BaseCurve\Point implements JsonSerializable
|
||||
{
|
||||
public $x;
|
||||
public $y;
|
||||
public $inf;
|
||||
|
||||
function __construct($curve, $x, $y, $isRed)
|
||||
{
|
||||
parent::__construct($curve, 'affine');
|
||||
|
||||
if( $x == null && $y == null )
|
||||
{
|
||||
$this->x = null;
|
||||
$this->y = null;
|
||||
$this->inf = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->x = new BN($x, 16);
|
||||
$this->y = new BN($y, 16);
|
||||
// Force redgomery representation when loading from JSON
|
||||
if( $isRed )
|
||||
{
|
||||
$this->x->forceRed($this->curve->red);
|
||||
$this->y->forceRed($this->curve->red);
|
||||
}
|
||||
|
||||
if( !$this->x->red )
|
||||
$this->x = $this->x->toRed($this->curve->red);
|
||||
if( !$this->y->red )
|
||||
$this->y = $this->y->toRed($this->curve->red);
|
||||
$this->inf = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function _getBeta()
|
||||
{
|
||||
if( !isset($this->curve->endo) )
|
||||
return null;
|
||||
|
||||
if( isset($this->precomputed) && isset($this->precomputed["beta"]) )
|
||||
return $this->precomputed["beta"];
|
||||
|
||||
$beta = $this->curve->point($this->x->redMul($this->curve->endo["beta"]), $this->y);
|
||||
if( isset($this->precomputed) )
|
||||
{
|
||||
$endoMul = function($p) {
|
||||
return $this->curve->point($p->x->redMul($this->curve->endo["beta"]), $p->y);
|
||||
};
|
||||
$beta->precomputed = array(
|
||||
"beta" => null,
|
||||
"naf" => null,
|
||||
"doubles" => null
|
||||
);
|
||||
|
||||
if( isset($this->precomputed["naf"]) )
|
||||
{
|
||||
$beta->precomputed["naf"] = array(
|
||||
"wnd" => $this->precomputed["naf"]["wnd"],
|
||||
"points" => array_map($endoMul, $this->precomputed["naf"]["points"])
|
||||
);
|
||||
}
|
||||
|
||||
if( isset($this->precomputed["doubles"]) )
|
||||
{
|
||||
$beta->precomputed["doubles"] = array(
|
||||
"step" => $this->precomputed["doubles"]["step"],
|
||||
"points" => array_map($endoMul, $this->precomputed["doubles"]["points"])
|
||||
);
|
||||
}
|
||||
$this->precomputed["beta"] = $beta;
|
||||
}
|
||||
return $beta;
|
||||
}
|
||||
|
||||
//toJSON()
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$res = array($this->x, $this->y);
|
||||
|
||||
if( !isset($this->precomputed) )
|
||||
return $res;
|
||||
|
||||
$pre = array();
|
||||
$addPre = false;
|
||||
if( isset($this->precomputed["doubles"]) )
|
||||
{
|
||||
$pre["doubles"] = array(
|
||||
"step" => $this->precomputed["doubles"]["step"],
|
||||
"points" => array_slice($this->precomputed["doubles"]["points"], 1)
|
||||
);
|
||||
$addPre = true;
|
||||
}
|
||||
|
||||
if( isset($this->precomputed["naf"]) )
|
||||
{
|
||||
$pre["naf"] = array(
|
||||
"naf" => $this->precomputed["naf"]["wnd"],
|
||||
"points" => array_slice($this->precomputed["naf"]["points"], 1)
|
||||
);
|
||||
$addPre = true;
|
||||
}
|
||||
|
||||
if( $addPre )
|
||||
array_push($res, $pre);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function fromJSON($curve, $obj, $red)
|
||||
{
|
||||
if( is_string($obj) )
|
||||
$obj = json_decode($obj);
|
||||
|
||||
$point = $curve->point($obj[0], $obj[1], $red);
|
||||
if( count($obj) === 2 )
|
||||
return $point;
|
||||
|
||||
$pre = $obj[2];
|
||||
$point->precomputed = array("beta" => null);
|
||||
$obj2point = function($obj) use ($curve, $red) {
|
||||
return $curve->point($obj[0], $obj[1], $red);
|
||||
};
|
||||
|
||||
if( isset($pre["doubles"]) )
|
||||
{
|
||||
$tmp = array_map($obj2point, $pre["doubles"]["points"]);
|
||||
array_unshift($tmp, $point);
|
||||
$point->precomputed["doubles"] = array(
|
||||
"step" => $pre["doubles"]["step"],
|
||||
"points" => $tmp
|
||||
);
|
||||
}
|
||||
|
||||
if( isset($pre["naf"]) )
|
||||
{
|
||||
$tmp = array_map($obj2point, $pre["naf"]["points"]);
|
||||
array_unshift($tmp, $point);
|
||||
$point->precomputed["naf"] = array(
|
||||
"wnd" => $pre["naf"]["wnd"],
|
||||
"points" => $tmp
|
||||
);
|
||||
}
|
||||
|
||||
return $point;
|
||||
}
|
||||
|
||||
public function inspect()
|
||||
{
|
||||
if( $this->isInfinity() )
|
||||
return "<EC Point Infinity>";
|
||||
|
||||
return "<EC Point x: " . $this->x->fromRed()->toString(16, 2) .
|
||||
" y: " . $this->y->fromRed()->toString(16, 2) . ">";
|
||||
}
|
||||
|
||||
public function __debugInfo() {
|
||||
return [
|
||||
"EC Point" => ($this->isInfinity() ?
|
||||
"Infinity" :
|
||||
[
|
||||
"x" => $this->x->fromRed()->toString(16, 2),
|
||||
"y" => $this->y->fromRed()->toString(16, 2)
|
||||
])
|
||||
];
|
||||
}
|
||||
public function isInfinity() {
|
||||
return $this->inf;
|
||||
}
|
||||
|
||||
public function add($point)
|
||||
{
|
||||
// O + P = P
|
||||
if( $this->inf )
|
||||
return $point;
|
||||
|
||||
// P + O = P
|
||||
if( $point->inf )
|
||||
return $this;
|
||||
|
||||
// P + P = 2P
|
||||
if( $this->eq($point) )
|
||||
return $this->dbl();
|
||||
|
||||
// P + (-P) = O
|
||||
if( $this->neg()->eq($point) )
|
||||
return $this->curve->point(null, null);
|
||||
|
||||
// P + Q = O
|
||||
if( $this->x->cmp($point->x) === 0 )
|
||||
return $this->curve->point(null, null);
|
||||
|
||||
$c = $this->y->redSub($point->y);
|
||||
if( ! $c->isZero() )
|
||||
$c = $c->redMul($this->x->redSub($point->x)->redInvm());
|
||||
$nx = $c->redSqr()->redISub($this->x)->redISub($point->x);
|
||||
$ny = $c->redMul($this->x->redSub($nx))->redISub($this->y);
|
||||
|
||||
return $this->curve->point($nx, $ny);
|
||||
}
|
||||
|
||||
public function dbl()
|
||||
{
|
||||
if( $this->inf )
|
||||
return $this;
|
||||
|
||||
// 2P = 0
|
||||
$ys1 = $this->y->redAdd($this->y);
|
||||
if( $ys1->isZero() )
|
||||
return $this->curve->point(null, null);
|
||||
|
||||
$x2 = $this->x->redSqr();
|
||||
$dyinv = $ys1->redInvm();
|
||||
$c = $x2->redAdd($x2)->redIAdd($x2)->redIAdd($this->curve->a)->redMul($dyinv);
|
||||
|
||||
$nx = $c->redSqr()->redISub($this->x->redAdd($this->x));
|
||||
$ny = $c->redMul($this->x->redSub($nx))->redISub($this->y);
|
||||
|
||||
return $this->curve->point($nx, $ny);
|
||||
}
|
||||
|
||||
public function getX() {
|
||||
return $this->x->fromRed();
|
||||
}
|
||||
|
||||
public function getY() {
|
||||
return $this->y->fromRed();
|
||||
}
|
||||
|
||||
public function mul($k)
|
||||
{
|
||||
$k = new BN($k, 16);
|
||||
|
||||
if( $this->_hasDoubles($k) )
|
||||
return $this->curve->_fixedNafMul($this, $k);
|
||||
elseif( isset($this->curve->endo) )
|
||||
return $this->curve->_endoWnafMulAdd(array($this), array($k));
|
||||
|
||||
return $this->curve->_wnafMul($this, $k);
|
||||
}
|
||||
|
||||
public function mulAdd($k1, $p2, $k2, $j = false)
|
||||
{
|
||||
$points = array($this, $p2);
|
||||
$coeffs = array($k1, $k2);
|
||||
|
||||
if( isset($this->curve->endo) )
|
||||
return $this->curve->_endoWnafMulAdd($points, $coeffs, $j);
|
||||
|
||||
return $this->curve->_wnafMulAdd(1, $points, $coeffs, 2, $j);
|
||||
}
|
||||
|
||||
public function jmulAdd($k1, $p2, $k2) {
|
||||
return $this->mulAdd($k1, $p2, $k2, true);
|
||||
}
|
||||
|
||||
public function eq($point)
|
||||
{
|
||||
return (
|
||||
$this === $point ||
|
||||
$this->inf === $point->inf &&
|
||||
($this->inf || $this->x->cmp($point->x) === 0 && $this->y->cmp($point->y) === 0)
|
||||
);
|
||||
}
|
||||
|
||||
public function neg($precompute = false)
|
||||
{
|
||||
if( $this->inf )
|
||||
return $this;
|
||||
|
||||
$res = $this->curve->point($this->x, $this->y->redNeg());
|
||||
if( $precompute && isset($this->precomputed) )
|
||||
{
|
||||
$res->precomputed = array();
|
||||
$pre = $this->precomputed;
|
||||
$negate = function($point) {
|
||||
return $point->neg();
|
||||
};
|
||||
|
||||
if( isset($pre["naf"]) )
|
||||
{
|
||||
$res->precomputed["naf"] = array(
|
||||
"wnd" => $pre["naf"]["wnd"],
|
||||
"points" => array_map($negate, $pre["naf"]["points"])
|
||||
);
|
||||
}
|
||||
|
||||
if( isset($pre["doubles"]) )
|
||||
{
|
||||
$res->precomputed["doubles"] = array(
|
||||
"step" => $pre["doubles"]["step"],
|
||||
"points" => array_map($negate, $pre["doubles"]["points"])
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function toJ()
|
||||
{
|
||||
if( $this->inf )
|
||||
return $this->curve->jpoint(null, null, null);
|
||||
|
||||
return $this->curve->jpoint($this->x, $this->y, $this->curve->one);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
990
vendor/simplito/elliptic-php/lib/Curves.php
vendored
Normal file
990
vendor/simplito/elliptic-php/lib/Curves.php
vendored
Normal file
@ -0,0 +1,990 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic;
|
||||
|
||||
use Elliptic\Curve\PresetCurve;
|
||||
|
||||
class Curves
|
||||
{
|
||||
private static $curves;
|
||||
|
||||
public static function hasCurve($name) {
|
||||
return isset(self::$curves[$name]);
|
||||
}
|
||||
public static function getCurve($name) {
|
||||
if (!isset(self::$curves[$name])) {
|
||||
throw new \Exception('Unknown curve ' . $name);
|
||||
}
|
||||
return self::$curves[$name];
|
||||
}
|
||||
|
||||
public static function defineCurve($name, $options)
|
||||
{
|
||||
self::$curves[$name] = new PresetCurve($options);
|
||||
}
|
||||
}
|
||||
|
||||
$sha256 = [ "blockSize" => 512, "outSize" => 256, "hmacStrength" => 192, "padLength" => 64, "algo" => 'sha256' ];
|
||||
$sha224 = [ "blockSize" => 512, "outSize" => 224, "hmacStrength" => 192, "padLength" => 64, "algo" => 'sha224' ];
|
||||
$sha512 = [ "blockSize" => 1024, "outSize" => 512, "hmacStrength" => 192, "padLength" => 128, "algo" => 'sha512' ];
|
||||
$sha384 = [ "blockSize" => 1024, "outSize" => 384, "hmacStrength" => 192, "padLength" => 128, "algo" => 'sha384' ];
|
||||
$sha1 = [ "blockSize" => 512, "outSize" => 160, "hmacStrength" => 80, "padLength" => 64, "algo" => 'sha1' ];
|
||||
|
||||
Curves::defineCurve("p192", array(
|
||||
"type" => "short",
|
||||
"prime" => "p192",
|
||||
"p" => "ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff",
|
||||
"a" => "ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc",
|
||||
"b" => "64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1",
|
||||
"n" => "ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831",
|
||||
"hash" => $sha256,
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012",
|
||||
"07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811"
|
||||
)
|
||||
));
|
||||
|
||||
Curves::defineCurve("p224", array(
|
||||
"type" => "short",
|
||||
"prime" => "p224",
|
||||
"p" => "ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001",
|
||||
"a" => "ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe",
|
||||
"b" => "b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4",
|
||||
"n" => "ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d",
|
||||
"hash" => $sha256,
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21",
|
||||
"bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34"
|
||||
)
|
||||
));
|
||||
|
||||
Curves::defineCurve("p256", array(
|
||||
"type" => "short",
|
||||
"prime" => null,
|
||||
"p" => "ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff",
|
||||
"a" => "ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc",
|
||||
"b" => "5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b",
|
||||
"n" => "ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551",
|
||||
"hash" => $sha256,
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296",
|
||||
"4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5"
|
||||
)
|
||||
));
|
||||
|
||||
Curves::defineCurve("p384", array(
|
||||
"type" => "short",
|
||||
"prime" => null,
|
||||
"p" => "ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff " .
|
||||
"fffffffe ffffffff 00000000 00000000 ffffffff",
|
||||
"a" => "ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff " .
|
||||
"fffffffe ffffffff 00000000 00000000 fffffffc",
|
||||
"b" => "b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f " .
|
||||
"5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef",
|
||||
"n" => "ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 " .
|
||||
"f4372ddf 581a0db2 48b0a77a ecec196a ccc52973",
|
||||
"hash" => $sha384,
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 " .
|
||||
"5502f25d bf55296c 3a545e38 72760ab7",
|
||||
"3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 " .
|
||||
"0a60b1ce 1d7e819d 7a431d7c 90ea0e5f"
|
||||
)
|
||||
));
|
||||
|
||||
Curves::defineCurve("p521", array(
|
||||
"type" => "short",
|
||||
"prime" => null,
|
||||
"p" => "000001ff ffffffff ffffffff ffffffff ffffffff ffffffff " .
|
||||
"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff " .
|
||||
"ffffffff ffffffff ffffffff ffffffff ffffffff",
|
||||
"a" => "000001ff ffffffff ffffffff ffffffff ffffffff ffffffff " .
|
||||
"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff " .
|
||||
"ffffffff ffffffff ffffffff ffffffff fffffffc",
|
||||
"b" => "00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b " .
|
||||
"99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd " .
|
||||
"3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00",
|
||||
"n" => "000001ff ffffffff ffffffff ffffffff ffffffff ffffffff " .
|
||||
"ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 " .
|
||||
"f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409",
|
||||
"hash" => $sha512,
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 " .
|
||||
"053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 " .
|
||||
"a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66",
|
||||
"00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 " .
|
||||
"579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 " .
|
||||
"3fad0761 353c7086 a272c240 88be9476 9fd16650"
|
||||
)
|
||||
));
|
||||
|
||||
Curves::defineCurve("curve25519", array(
|
||||
"type" => "mont",
|
||||
"prime" => "p25519",
|
||||
"p" => "7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",
|
||||
"a" => "76d06",
|
||||
"b" => "0",
|
||||
"n" => "1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",
|
||||
"hash" => $sha256,
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"9"
|
||||
)
|
||||
));
|
||||
|
||||
Curves:: defineCurve("curve25519-weier", array(
|
||||
"type" => "short",
|
||||
"prime" => "p25519",
|
||||
"p" => "7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",
|
||||
"a" => "2aaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaa984914a144",
|
||||
"b" => "7b425ed097b425ed 097b425ed097b425 ed097b425ed097b4 260b5e9c7710c864",
|
||||
"n" => "1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",
|
||||
"hash" => $sha256,
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad245a",
|
||||
"20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9"
|
||||
)
|
||||
));
|
||||
|
||||
Curves::defineCurve("ed25519", array(
|
||||
"type" => "edwards",
|
||||
"prime" => "p25519",
|
||||
"p" => "7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",
|
||||
"a" => "-1",
|
||||
"c" => "1",
|
||||
// -121665 * (121666^(-1)) (mod P)
|
||||
"d" => "52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3",
|
||||
"n" => "1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",
|
||||
"hash" => $sha256,
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a",
|
||||
// 4/5
|
||||
"6666666666666666666666666666666666666666666666666666666666666658"
|
||||
)
|
||||
));
|
||||
|
||||
$pre = array(
|
||||
"doubles" => array(
|
||||
"step" => 4,
|
||||
"points" => array(
|
||||
array(
|
||||
"e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a",
|
||||
"f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821"
|
||||
),
|
||||
array(
|
||||
"8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508",
|
||||
"11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf"
|
||||
),
|
||||
array(
|
||||
"175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739",
|
||||
"d3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695"
|
||||
),
|
||||
array(
|
||||
"363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640",
|
||||
"4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9"
|
||||
),
|
||||
array(
|
||||
"8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c",
|
||||
"4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36"
|
||||
),
|
||||
array(
|
||||
"723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda",
|
||||
"96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f"
|
||||
),
|
||||
array(
|
||||
"eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa",
|
||||
"5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999"
|
||||
),
|
||||
array(
|
||||
"100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0",
|
||||
"cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09"
|
||||
),
|
||||
array(
|
||||
"e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d",
|
||||
"9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d"
|
||||
),
|
||||
array(
|
||||
"feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d",
|
||||
"e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088"
|
||||
),
|
||||
array(
|
||||
"da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1",
|
||||
"9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d"
|
||||
),
|
||||
array(
|
||||
"53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0",
|
||||
"5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8"
|
||||
),
|
||||
array(
|
||||
"8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047",
|
||||
"10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a"
|
||||
),
|
||||
array(
|
||||
"385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862",
|
||||
"283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453"
|
||||
),
|
||||
array(
|
||||
"6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7",
|
||||
"7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160"
|
||||
),
|
||||
array(
|
||||
"3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd",
|
||||
"56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0"
|
||||
),
|
||||
array(
|
||||
"85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83",
|
||||
"7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6"
|
||||
),
|
||||
array(
|
||||
"948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a",
|
||||
"53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589"
|
||||
),
|
||||
array(
|
||||
"6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8",
|
||||
"bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17"
|
||||
),
|
||||
array(
|
||||
"e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d",
|
||||
"4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda"
|
||||
),
|
||||
array(
|
||||
"e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725",
|
||||
"7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd"
|
||||
),
|
||||
array(
|
||||
"213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754",
|
||||
"4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2"
|
||||
),
|
||||
array(
|
||||
"4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c",
|
||||
"17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6"
|
||||
),
|
||||
array(
|
||||
"fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6",
|
||||
"6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f"
|
||||
),
|
||||
array(
|
||||
"76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39",
|
||||
"c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01"
|
||||
),
|
||||
array(
|
||||
"c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891",
|
||||
"893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3"
|
||||
),
|
||||
array(
|
||||
"d895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b",
|
||||
"febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f"
|
||||
),
|
||||
array(
|
||||
"b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03",
|
||||
"2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7"
|
||||
),
|
||||
array(
|
||||
"e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d",
|
||||
"eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78"
|
||||
),
|
||||
array(
|
||||
"a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070",
|
||||
"7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1"
|
||||
),
|
||||
array(
|
||||
"90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4",
|
||||
"e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150"
|
||||
),
|
||||
array(
|
||||
"8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da",
|
||||
"662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82"
|
||||
),
|
||||
array(
|
||||
"e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11",
|
||||
"1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc"
|
||||
),
|
||||
array(
|
||||
"8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e",
|
||||
"efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b"
|
||||
),
|
||||
array(
|
||||
"e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41",
|
||||
"2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51"
|
||||
),
|
||||
array(
|
||||
"b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef",
|
||||
"67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45"
|
||||
),
|
||||
array(
|
||||
"d68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8",
|
||||
"db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120"
|
||||
),
|
||||
array(
|
||||
"324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d",
|
||||
"648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84"
|
||||
),
|
||||
array(
|
||||
"4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96",
|
||||
"35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d"
|
||||
),
|
||||
array(
|
||||
"9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd",
|
||||
"ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d"
|
||||
),
|
||||
array(
|
||||
"6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5",
|
||||
"9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8"
|
||||
),
|
||||
array(
|
||||
"a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266",
|
||||
"40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8"
|
||||
),
|
||||
array(
|
||||
"7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71",
|
||||
"34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac"
|
||||
),
|
||||
array(
|
||||
"928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac",
|
||||
"c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f"
|
||||
),
|
||||
array(
|
||||
"85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751",
|
||||
"1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962"
|
||||
),
|
||||
array(
|
||||
"ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e",
|
||||
"493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907"
|
||||
),
|
||||
array(
|
||||
"827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241",
|
||||
"c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec"
|
||||
),
|
||||
array(
|
||||
"eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3",
|
||||
"be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d"
|
||||
),
|
||||
array(
|
||||
"e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f",
|
||||
"4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414"
|
||||
),
|
||||
array(
|
||||
"1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19",
|
||||
"aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd"
|
||||
),
|
||||
array(
|
||||
"146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be",
|
||||
"b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0"
|
||||
),
|
||||
array(
|
||||
"fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9",
|
||||
"6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811"
|
||||
),
|
||||
array(
|
||||
"da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2",
|
||||
"8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1"
|
||||
),
|
||||
array(
|
||||
"a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13",
|
||||
"7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c"
|
||||
),
|
||||
array(
|
||||
"174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c",
|
||||
"ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73"
|
||||
),
|
||||
array(
|
||||
"959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba",
|
||||
"2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd"
|
||||
),
|
||||
array(
|
||||
"d2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151",
|
||||
"e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405"
|
||||
),
|
||||
array(
|
||||
"64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073",
|
||||
"d99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589"
|
||||
),
|
||||
array(
|
||||
"8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458",
|
||||
"38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e"
|
||||
),
|
||||
array(
|
||||
"13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b",
|
||||
"69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27"
|
||||
),
|
||||
array(
|
||||
"bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366",
|
||||
"d3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1"
|
||||
),
|
||||
array(
|
||||
"8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa",
|
||||
"40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482"
|
||||
),
|
||||
array(
|
||||
"8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0",
|
||||
"620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945"
|
||||
),
|
||||
array(
|
||||
"dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787",
|
||||
"7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573"
|
||||
),
|
||||
array(
|
||||
"f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e",
|
||||
"ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82"
|
||||
)
|
||||
)
|
||||
),
|
||||
"naf" => array(
|
||||
"wnd" => 7,
|
||||
"points" => array(
|
||||
array(
|
||||
"f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9",
|
||||
"388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672"
|
||||
),
|
||||
array(
|
||||
"2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4",
|
||||
"d8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6"
|
||||
),
|
||||
array(
|
||||
"5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc",
|
||||
"6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da"
|
||||
),
|
||||
array(
|
||||
"acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe",
|
||||
"cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37"
|
||||
),
|
||||
array(
|
||||
"774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb",
|
||||
"d984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b"
|
||||
),
|
||||
array(
|
||||
"f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8",
|
||||
"ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81"
|
||||
),
|
||||
array(
|
||||
"d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e",
|
||||
"581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58"
|
||||
),
|
||||
array(
|
||||
"defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34",
|
||||
"4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77"
|
||||
),
|
||||
array(
|
||||
"2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c",
|
||||
"85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a"
|
||||
),
|
||||
array(
|
||||
"352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5",
|
||||
"321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c"
|
||||
),
|
||||
array(
|
||||
"2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f",
|
||||
"2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67"
|
||||
),
|
||||
array(
|
||||
"9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714",
|
||||
"73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402"
|
||||
),
|
||||
array(
|
||||
"daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729",
|
||||
"a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55"
|
||||
),
|
||||
array(
|
||||
"c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db",
|
||||
"2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482"
|
||||
),
|
||||
array(
|
||||
"6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4",
|
||||
"e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82"
|
||||
),
|
||||
array(
|
||||
"1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5",
|
||||
"b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396"
|
||||
),
|
||||
array(
|
||||
"605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479",
|
||||
"2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49"
|
||||
),
|
||||
array(
|
||||
"62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d",
|
||||
"80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf"
|
||||
),
|
||||
array(
|
||||
"80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f",
|
||||
"1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a"
|
||||
),
|
||||
array(
|
||||
"7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb",
|
||||
"d0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7"
|
||||
),
|
||||
array(
|
||||
"d528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9",
|
||||
"eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933"
|
||||
),
|
||||
array(
|
||||
"49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963",
|
||||
"758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a"
|
||||
),
|
||||
array(
|
||||
"77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74",
|
||||
"958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6"
|
||||
),
|
||||
array(
|
||||
"f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530",
|
||||
"e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37"
|
||||
),
|
||||
array(
|
||||
"463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b",
|
||||
"5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e"
|
||||
),
|
||||
array(
|
||||
"f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247",
|
||||
"cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6"
|
||||
),
|
||||
array(
|
||||
"caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1",
|
||||
"cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476"
|
||||
),
|
||||
array(
|
||||
"2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120",
|
||||
"4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40"
|
||||
),
|
||||
array(
|
||||
"7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435",
|
||||
"91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61"
|
||||
),
|
||||
array(
|
||||
"754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18",
|
||||
"673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683"
|
||||
),
|
||||
array(
|
||||
"e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8",
|
||||
"59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5"
|
||||
),
|
||||
array(
|
||||
"186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb",
|
||||
"3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b"
|
||||
),
|
||||
array(
|
||||
"df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f",
|
||||
"55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417"
|
||||
),
|
||||
array(
|
||||
"5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143",
|
||||
"efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868"
|
||||
),
|
||||
array(
|
||||
"290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba",
|
||||
"e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a"
|
||||
),
|
||||
array(
|
||||
"af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45",
|
||||
"f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6"
|
||||
),
|
||||
array(
|
||||
"766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a",
|
||||
"744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996"
|
||||
),
|
||||
array(
|
||||
"59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e",
|
||||
"c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e"
|
||||
),
|
||||
array(
|
||||
"f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8",
|
||||
"e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d"
|
||||
),
|
||||
array(
|
||||
"7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c",
|
||||
"30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2"
|
||||
),
|
||||
array(
|
||||
"948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519",
|
||||
"e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e"
|
||||
),
|
||||
array(
|
||||
"7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab",
|
||||
"100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437"
|
||||
),
|
||||
array(
|
||||
"3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca",
|
||||
"ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311"
|
||||
),
|
||||
array(
|
||||
"d3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf",
|
||||
"8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4"
|
||||
),
|
||||
array(
|
||||
"1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610",
|
||||
"68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575"
|
||||
),
|
||||
array(
|
||||
"733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4",
|
||||
"f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d"
|
||||
),
|
||||
array(
|
||||
"15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c",
|
||||
"d56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d"
|
||||
),
|
||||
array(
|
||||
"a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940",
|
||||
"edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629"
|
||||
),
|
||||
array(
|
||||
"e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980",
|
||||
"a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06"
|
||||
),
|
||||
array(
|
||||
"311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3",
|
||||
"66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374"
|
||||
),
|
||||
array(
|
||||
"34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf",
|
||||
"9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee"
|
||||
),
|
||||
array(
|
||||
"f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63",
|
||||
"4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1"
|
||||
),
|
||||
array(
|
||||
"d7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448",
|
||||
"fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b"
|
||||
),
|
||||
array(
|
||||
"32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf",
|
||||
"5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661"
|
||||
),
|
||||
array(
|
||||
"7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5",
|
||||
"8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6"
|
||||
),
|
||||
array(
|
||||
"ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6",
|
||||
"8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e"
|
||||
),
|
||||
array(
|
||||
"16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5",
|
||||
"5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d"
|
||||
),
|
||||
array(
|
||||
"eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99",
|
||||
"f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc"
|
||||
),
|
||||
array(
|
||||
"78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51",
|
||||
"f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4"
|
||||
),
|
||||
array(
|
||||
"494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5",
|
||||
"42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c"
|
||||
),
|
||||
array(
|
||||
"a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5",
|
||||
"204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b"
|
||||
),
|
||||
array(
|
||||
"c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997",
|
||||
"4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913"
|
||||
),
|
||||
array(
|
||||
"841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881",
|
||||
"73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154"
|
||||
),
|
||||
array(
|
||||
"5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5",
|
||||
"39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865"
|
||||
),
|
||||
array(
|
||||
"36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66",
|
||||
"d2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc"
|
||||
),
|
||||
array(
|
||||
"336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726",
|
||||
"ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224"
|
||||
),
|
||||
array(
|
||||
"8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede",
|
||||
"6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e"
|
||||
),
|
||||
array(
|
||||
"1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94",
|
||||
"60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6"
|
||||
),
|
||||
array(
|
||||
"85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31",
|
||||
"3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511"
|
||||
),
|
||||
array(
|
||||
"29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51",
|
||||
"b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b"
|
||||
),
|
||||
array(
|
||||
"a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252",
|
||||
"ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2"
|
||||
),
|
||||
array(
|
||||
"4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5",
|
||||
"cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c"
|
||||
),
|
||||
array(
|
||||
"d24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b",
|
||||
"6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3"
|
||||
),
|
||||
array(
|
||||
"ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4",
|
||||
"322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d"
|
||||
),
|
||||
array(
|
||||
"af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f",
|
||||
"6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700"
|
||||
),
|
||||
array(
|
||||
"e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889",
|
||||
"2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4"
|
||||
),
|
||||
array(
|
||||
"591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246",
|
||||
"b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196"
|
||||
),
|
||||
array(
|
||||
"11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984",
|
||||
"998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4"
|
||||
),
|
||||
array(
|
||||
"3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a",
|
||||
"b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257"
|
||||
),
|
||||
array(
|
||||
"cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030",
|
||||
"bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13"
|
||||
),
|
||||
array(
|
||||
"c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197",
|
||||
"6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096"
|
||||
),
|
||||
array(
|
||||
"c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593",
|
||||
"c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38"
|
||||
),
|
||||
array(
|
||||
"a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef",
|
||||
"21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f"
|
||||
),
|
||||
array(
|
||||
"347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38",
|
||||
"60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448"
|
||||
),
|
||||
array(
|
||||
"da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a",
|
||||
"49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a"
|
||||
),
|
||||
array(
|
||||
"c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111",
|
||||
"5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4"
|
||||
),
|
||||
array(
|
||||
"4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502",
|
||||
"7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437"
|
||||
),
|
||||
array(
|
||||
"3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea",
|
||||
"be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7"
|
||||
),
|
||||
array(
|
||||
"cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26",
|
||||
"8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d"
|
||||
),
|
||||
array(
|
||||
"b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986",
|
||||
"39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a"
|
||||
),
|
||||
array(
|
||||
"d4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e",
|
||||
"62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54"
|
||||
),
|
||||
array(
|
||||
"48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4",
|
||||
"25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77"
|
||||
),
|
||||
array(
|
||||
"dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda",
|
||||
"ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517"
|
||||
),
|
||||
array(
|
||||
"6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859",
|
||||
"cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10"
|
||||
),
|
||||
array(
|
||||
"e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f",
|
||||
"f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125"
|
||||
),
|
||||
array(
|
||||
"eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c",
|
||||
"6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e"
|
||||
),
|
||||
array(
|
||||
"13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942",
|
||||
"fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1"
|
||||
),
|
||||
array(
|
||||
"ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a",
|
||||
"1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2"
|
||||
),
|
||||
array(
|
||||
"b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80",
|
||||
"5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423"
|
||||
),
|
||||
array(
|
||||
"ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d",
|
||||
"438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8"
|
||||
),
|
||||
array(
|
||||
"8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1",
|
||||
"cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758"
|
||||
),
|
||||
array(
|
||||
"52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63",
|
||||
"c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375"
|
||||
),
|
||||
array(
|
||||
"e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352",
|
||||
"6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d"
|
||||
),
|
||||
array(
|
||||
"7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193",
|
||||
"ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec"
|
||||
),
|
||||
array(
|
||||
"5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00",
|
||||
"9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0"
|
||||
),
|
||||
array(
|
||||
"32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58",
|
||||
"ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c"
|
||||
),
|
||||
array(
|
||||
"e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7",
|
||||
"d3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4"
|
||||
),
|
||||
array(
|
||||
"8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8",
|
||||
"c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f"
|
||||
),
|
||||
array(
|
||||
"4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e",
|
||||
"67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649"
|
||||
),
|
||||
array(
|
||||
"3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d",
|
||||
"cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826"
|
||||
),
|
||||
array(
|
||||
"674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b",
|
||||
"299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5"
|
||||
),
|
||||
array(
|
||||
"d32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f",
|
||||
"f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87"
|
||||
),
|
||||
array(
|
||||
"30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6",
|
||||
"462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b"
|
||||
),
|
||||
array(
|
||||
"be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297",
|
||||
"62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc"
|
||||
),
|
||||
array(
|
||||
"93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a",
|
||||
"7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c"
|
||||
),
|
||||
array(
|
||||
"b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c",
|
||||
"ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f"
|
||||
),
|
||||
array(
|
||||
"d5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52",
|
||||
"4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a"
|
||||
),
|
||||
array(
|
||||
"d3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb",
|
||||
"bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46"
|
||||
),
|
||||
array(
|
||||
"463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065",
|
||||
"bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f"
|
||||
),
|
||||
array(
|
||||
"7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917",
|
||||
"603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03"
|
||||
),
|
||||
array(
|
||||
"74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9",
|
||||
"cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08"
|
||||
),
|
||||
array(
|
||||
"30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3",
|
||||
"553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8"
|
||||
),
|
||||
array(
|
||||
"9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57",
|
||||
"712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373"
|
||||
),
|
||||
array(
|
||||
"176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66",
|
||||
"ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3"
|
||||
),
|
||||
array(
|
||||
"75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8",
|
||||
"9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8"
|
||||
),
|
||||
array(
|
||||
"809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721",
|
||||
"9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1"
|
||||
),
|
||||
array(
|
||||
"1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180",
|
||||
"4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9"
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
Curves::defineCurve("secp256k1", array(
|
||||
"type" => "short",
|
||||
"prime" => "k256",
|
||||
"p" => "ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f",
|
||||
"a" => "0",
|
||||
"b" => "7",
|
||||
"n" => "ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141",
|
||||
"h" => "1",
|
||||
"hash" => array(
|
||||
"outSize" => 256,
|
||||
"hmacStrength" => 192,
|
||||
"algo" => "sha256"
|
||||
),
|
||||
|
||||
// Precomputed endomorphism
|
||||
"beta" => "7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee",
|
||||
"lambda" => "5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72",
|
||||
"basis" => array(
|
||||
array(
|
||||
"a" => "3086d221a7d46bcde86c90e49284eb15",
|
||||
"b" => "-e4437ed6010e88286f547fa90abfe4c3"
|
||||
),
|
||||
array(
|
||||
"a" => "114ca50f7a8e2f3f657c1108d9d44cfd8",
|
||||
"b" => "3086d221a7d46bcde86c90e49284eb15"
|
||||
)
|
||||
),
|
||||
|
||||
"gRed" => false,
|
||||
"g" => array(
|
||||
"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
||||
"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
|
||||
$pre
|
||||
)
|
||||
));
|
||||
|
||||
?>
|
||||
278
vendor/simplito/elliptic-php/lib/EC.php
vendored
Normal file
278
vendor/simplito/elliptic-php/lib/EC.php
vendored
Normal file
@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic;
|
||||
|
||||
use Elliptic\Curve\PresetCurve;
|
||||
use Elliptic\EC\KeyPair;
|
||||
use Elliptic\EC\Signature;
|
||||
use BN\BN;
|
||||
|
||||
class EC
|
||||
{
|
||||
public $curve;
|
||||
public $n;
|
||||
public $nh;
|
||||
public $g;
|
||||
public $hash;
|
||||
|
||||
function __construct($options)
|
||||
{
|
||||
if( is_string($options) )
|
||||
{
|
||||
$options = Curves::getCurve($options);
|
||||
}
|
||||
|
||||
if( $options instanceof PresetCurve )
|
||||
$options = array("curve" => $options);
|
||||
|
||||
$this->curve = $options["curve"]->curve;
|
||||
$this->n = $this->curve->n;
|
||||
$this->nh = $this->n->ushrn(1);
|
||||
|
||||
//Point on curve
|
||||
$this->g = $options["curve"]->g;
|
||||
$this->g->precompute($options["curve"]->n->bitLength() + 1);
|
||||
|
||||
//Hash for function for DRBG
|
||||
if( isset($options["hash"]) )
|
||||
$this->hash = $options["hash"];
|
||||
else
|
||||
$this->hash = $options["curve"]->hash;
|
||||
}
|
||||
|
||||
public function keyPair(#[\SensitiveParameter]
|
||||
$options) {
|
||||
return new KeyPair($this, $options);
|
||||
}
|
||||
|
||||
public function keyFromPrivate(#[\SensitiveParameter]
|
||||
$priv, $enc = false) {
|
||||
return KeyPair::fromPrivate($this, $priv, $enc);
|
||||
}
|
||||
|
||||
public function keyFromPublic($pub, $enc = false) {
|
||||
return KeyPair::fromPublic($this, $pub, $enc);
|
||||
}
|
||||
|
||||
public function genKeyPair($options = null)
|
||||
{
|
||||
// Instantiate HmacDRBG
|
||||
$drbg = new HmacDRBG(array(
|
||||
"hash" => $this->hash,
|
||||
"pers" => isset($options["pers"]) ? $options["pers"] : "",
|
||||
"entropy" => isset($options["entropy"]) ? $options["entropy"] : Utils::randBytes($this->hash["hmacStrength"]),
|
||||
"nonce" => $this->n->toArray()
|
||||
));
|
||||
|
||||
$bytes = $this->n->byteLength();
|
||||
$ns2 = $this->n->sub(new BN(2));
|
||||
while(true)
|
||||
{
|
||||
$priv = new BN($drbg->generate($bytes));
|
||||
if( $priv->cmp($ns2) > 0 )
|
||||
continue;
|
||||
|
||||
$priv->iaddn(1);
|
||||
return $this->keyFromPrivate($priv);
|
||||
}
|
||||
}
|
||||
|
||||
private function _truncateToN($msg, $truncOnly = false)
|
||||
{
|
||||
$delta = intval(($msg->byteLength() * 8) - $this->n->bitLength());
|
||||
if( $delta > 0 ) {
|
||||
$msg = $msg->ushrn($delta);
|
||||
}
|
||||
if( $truncOnly || $msg->cmp($this->n) < 0 )
|
||||
return $msg;
|
||||
|
||||
return $msg->sub($this->n);
|
||||
}
|
||||
|
||||
public function sign($msg, #[\SensitiveParameter]
|
||||
$key, $enc = null, $options = null)
|
||||
{
|
||||
if( !is_string($enc) )
|
||||
{
|
||||
$options = $enc;
|
||||
$enc = null;
|
||||
}
|
||||
|
||||
$key = $this->keyFromPrivate($key, $enc);
|
||||
$msg = $this->_truncateToN(new BN($msg, 16));
|
||||
|
||||
// Zero-extend key to provide enough entropy
|
||||
$bytes = $this->n->byteLength();
|
||||
$bkey = $key->getPrivate()->toArray("be", $bytes);
|
||||
|
||||
// Zero-extend nonce to have the same byte size as N
|
||||
$nonce = $msg->toArray("be", $bytes);
|
||||
|
||||
$kFunc = null;
|
||||
if( isset($options["k"]) )
|
||||
$kFunc = $options["k"];
|
||||
else
|
||||
{
|
||||
// Instatiate HmacDRBG
|
||||
$drbg = new HmacDRBG(array(
|
||||
"hash" => $this->hash,
|
||||
"entropy" => $bkey,
|
||||
"nonce" => $nonce,
|
||||
"pers" => isset($options["pers"]) ? $options["pers"] : "",
|
||||
"persEnc" => isset($options["persEnc"]) ? $options["persEnc"] : false
|
||||
));
|
||||
|
||||
$kFunc = function($iter) use ($drbg, $bytes) {
|
||||
return new BN($drbg->generate($bytes));
|
||||
};
|
||||
}
|
||||
|
||||
// Number of bytes to generate
|
||||
$ns1 = $this->n->sub(new BN(1));
|
||||
|
||||
$canonical = isset($options["canonical"]) ? $options["canonical"] : false;
|
||||
for($iter = 0; true; $iter++)
|
||||
{
|
||||
$k = $kFunc($iter);
|
||||
$k = $this->_truncateToN($k, true);
|
||||
|
||||
if( $k->cmpn(1) <= 0 || $k->cmp($ns1) >= 0 )
|
||||
continue;
|
||||
|
||||
// Fix the bit-length of the random nonce,
|
||||
// so that it doesn't leak via timing.
|
||||
// This does not change that ks = k mod k
|
||||
$ks = $k->add($this->n);
|
||||
$kt = $ks->add($this->n);
|
||||
if ($ks->bitLength() === $this->n->bitLength()) {
|
||||
$kp = $this->g->mul($kt);
|
||||
} else {
|
||||
$kp = $this->g->mul($ks);
|
||||
}
|
||||
|
||||
if( $kp->isInfinity() )
|
||||
continue;
|
||||
|
||||
$kpX = $kp->getX();
|
||||
$r = $kpX->umod($this->n);
|
||||
if( $r->isZero() )
|
||||
continue;
|
||||
|
||||
$s = $k->invm($this->n)->mul($r->mul($key->getPrivate())->iadd($msg));
|
||||
$s = $s->umod($this->n);
|
||||
if( $s->isZero() )
|
||||
continue;
|
||||
|
||||
$recoveryParam = ($kp->getY()->isOdd() ? 1 : 0) | ($kpX->cmp($r) !== 0 ? 2 : 0);
|
||||
|
||||
// Use complement of `s`, if it is > `n / 2`
|
||||
if( $canonical && $s->cmp($this->nh) > 0 )
|
||||
{
|
||||
$s = $this->n->sub($s);
|
||||
$recoveryParam ^= 1;
|
||||
}
|
||||
|
||||
return new Signature(array(
|
||||
"r" => $r,
|
||||
"s" => $s,
|
||||
"recoveryParam" => $recoveryParam
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function verify($msg, $signature, $key, $enc = false)
|
||||
{
|
||||
$msg = $this->_truncateToN(new BN($msg, 16));
|
||||
$key = $this->keyFromPublic($key, $enc);
|
||||
$signature = new Signature($signature, "hex");
|
||||
|
||||
// Perform primitive values validation
|
||||
$r = $signature->r;
|
||||
$s = $signature->s;
|
||||
|
||||
if( $r->cmpn(1) < 0 || $r->cmp($this->n) >= 0 )
|
||||
return false;
|
||||
if( $s->cmpn(1) < 0 || $s->cmp($this->n) >= 0 )
|
||||
return false;
|
||||
|
||||
// Validate signature
|
||||
$sinv = $s->invm($this->n);
|
||||
$u1 = $sinv->mul($msg)->umod($this->n);
|
||||
$u2 = $sinv->mul($r)->umod($this->n);
|
||||
|
||||
if( !$this->curve->_maxwellTrick )
|
||||
{
|
||||
$p = $this->g->mulAdd($u1, $key->getPublic(), $u2);
|
||||
if( $p->isInfinity() )
|
||||
return false;
|
||||
|
||||
return $p->getX()->umod($this->n)->cmp($r) === 0;
|
||||
}
|
||||
|
||||
// NOTE: Greg Maxwell's trick, inspired by:
|
||||
// https://git.io/vad3K
|
||||
|
||||
$p = $this->g->jmulAdd($u1, $key->getPublic(), $u2);
|
||||
if( $p->isInfinity() )
|
||||
return false;
|
||||
|
||||
// Compare `p.x` of Jacobian point with `r`,
|
||||
// this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
|
||||
// inverse of `p.z^2`
|
||||
return $p->eqXToP($r);
|
||||
}
|
||||
|
||||
public function recoverPubKey($msg, $signature, $j, $enc = false)
|
||||
{
|
||||
assert((3 & $j) === $j); //, "The recovery param is more than two bits");
|
||||
$signature = new Signature($signature, $enc);
|
||||
|
||||
$e = new BN($msg, 16);
|
||||
$r = $signature->r;
|
||||
$s = $signature->s;
|
||||
|
||||
// A set LSB signifies that the y-coordinate is odd
|
||||
$isYOdd = ($j & 1) == 1;
|
||||
$isSecondKey = $j >> 1;
|
||||
|
||||
if ($r->cmp($this->curve->p->umod($this->curve->n)) >= 0 && $isSecondKey)
|
||||
throw new \Exception("Unable to find second key candinate");
|
||||
|
||||
// 1.1. Let x = r + jn.
|
||||
if( $isSecondKey )
|
||||
$r = $this->curve->pointFromX($r->add($this->curve->n), $isYOdd);
|
||||
else
|
||||
$r = $this->curve->pointFromX($r, $isYOdd);
|
||||
|
||||
$eNeg = $this->n->sub($e);
|
||||
|
||||
// 1.6.1 Compute Q = r^-1 (sR - eG)
|
||||
// Q = r^-1 (sR + -eG)
|
||||
$rInv = $signature->r->invm($this->n);
|
||||
return $this->g->mulAdd($eNeg, $r, $s)->mul($rInv);
|
||||
}
|
||||
|
||||
public function getKeyRecoveryParam($e, $signature, $Q, $enc = false)
|
||||
{
|
||||
$signature = new Signature($signature, $enc);
|
||||
if( $signature->recoveryParam != null )
|
||||
return $signature->recoveryParam;
|
||||
|
||||
for($i = 0; $i < 4; $i++)
|
||||
{
|
||||
$Qprime = null;
|
||||
try {
|
||||
$Qprime = $this->recoverPubKey($e, $signature, $i);
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( $Qprime->eq($Q))
|
||||
return $i;
|
||||
}
|
||||
throw new \Exception("Unable to find valid recovery factor");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
144
vendor/simplito/elliptic-php/lib/EC/KeyPair.php
vendored
Normal file
144
vendor/simplito/elliptic-php/lib/EC/KeyPair.php
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\EC;
|
||||
|
||||
use BN\BN;
|
||||
|
||||
class KeyPair
|
||||
{
|
||||
public $ec;
|
||||
public $pub;
|
||||
public $priv;
|
||||
|
||||
function __construct($ec, #[\SensitiveParameter]
|
||||
$options)
|
||||
{
|
||||
$this->ec = $ec;
|
||||
|
||||
$this->priv = null;
|
||||
$this->pub = null;
|
||||
|
||||
if( isset($options["priv"]) )
|
||||
$this->_importPrivate($options["priv"], $options["privEnc"]);
|
||||
|
||||
if( isset($options["pub"]) )
|
||||
$this->_importPublic($options["pub"], $options["pubEnc"]);
|
||||
}
|
||||
|
||||
public static function fromPublic($ec, $pub, $enc)
|
||||
{
|
||||
if( $pub instanceof KeyPair )
|
||||
return $pub;
|
||||
|
||||
return new KeyPair($ec, array(
|
||||
"pub" => $pub,
|
||||
"pubEnc" => $enc
|
||||
));
|
||||
}
|
||||
|
||||
public static function fromPrivate($ec, #[\SensitiveParameter]
|
||||
$priv, $enc)
|
||||
{
|
||||
if( $priv instanceof KeyPair )
|
||||
return $priv;
|
||||
|
||||
return new KeyPair($ec, array(
|
||||
"priv" => $priv,
|
||||
"privEnc" => $enc
|
||||
));
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
$pub = $this->getPublic();
|
||||
|
||||
if( $pub->isInfinity() )
|
||||
return array( "result" => false, "reason" => "Invalid public key" );
|
||||
|
||||
if( !$pub->validate() )
|
||||
return array( "result" => false, "reason" => "Public key is not a point" );
|
||||
|
||||
if( !$pub->mul($this->ec->curve->n)->isInfinity() )
|
||||
return array( "result" => false, "reason" => "Public key * N != O" );
|
||||
|
||||
return array( "result" => true, "reason" => null );
|
||||
}
|
||||
|
||||
public function getPublic($compact = false, $enc = "")
|
||||
{
|
||||
//compact is optional argument
|
||||
if( is_string($compact) )
|
||||
{
|
||||
$enc = $compact;
|
||||
$compact = false;
|
||||
}
|
||||
|
||||
if( $this->pub === null )
|
||||
$this->pub = $this->ec->g->mul($this->priv);
|
||||
|
||||
if( !$enc )
|
||||
return $this->pub;
|
||||
|
||||
return $this->pub->encode($enc, $compact);
|
||||
}
|
||||
|
||||
public function getPrivate($enc = false)
|
||||
{
|
||||
if( $enc === "hex" )
|
||||
return $this->priv->toString(16, 2);
|
||||
|
||||
return $this->priv;
|
||||
}
|
||||
|
||||
private function _importPrivate(#[\SensitiveParameter]
|
||||
$key, $enc)
|
||||
{
|
||||
$this->priv = new BN($key, (isset($enc) && $enc) ? $enc : 16);
|
||||
|
||||
// Ensure that the priv won't be bigger than n, otherwise we may fail
|
||||
// in fixed multiplication method
|
||||
$this->priv = $this->priv->umod($this->ec->curve->n);
|
||||
}
|
||||
|
||||
private function _importPublic($key, $enc)
|
||||
{
|
||||
$x = $y = null;
|
||||
if ( is_object($key) ) {
|
||||
$x = $key->x;
|
||||
$y = $key->y;
|
||||
} elseif ( is_array($key) ) {
|
||||
$x = isset($key["x"]) ? $key["x"] : null;
|
||||
$y = isset($key["y"]) ? $key["y"] : null;
|
||||
}
|
||||
|
||||
if( $x != null || $y != null )
|
||||
$this->pub = $this->ec->curve->point($x, $y);
|
||||
else
|
||||
$this->pub = $this->ec->curve->decodePoint($key, $enc);
|
||||
}
|
||||
|
||||
//ECDH
|
||||
public function derive($pub) {
|
||||
return $pub->mul($this->priv)->getX();
|
||||
}
|
||||
|
||||
//ECDSA
|
||||
public function sign($msg, $enc = false, $options = false) {
|
||||
return $this->ec->sign($msg, $this, $enc, $options);
|
||||
}
|
||||
|
||||
public function verify($msg, $signature) {
|
||||
return $this->ec->verify($msg, $signature, $this);
|
||||
}
|
||||
|
||||
public function inspect() {
|
||||
return "<Key priv: " . (isset($this->priv) ? $this->priv->toString(16, 2) : "") .
|
||||
" pub: " . (isset($this->pub) ? $this->pub->inspect() : "") . ">";
|
||||
}
|
||||
|
||||
public function __debugInfo() {
|
||||
return ["priv" => $this->priv, "pub" => $this->pub];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
155
vendor/simplito/elliptic-php/lib/EC/Signature.php
vendored
Normal file
155
vendor/simplito/elliptic-php/lib/EC/Signature.php
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic\EC;
|
||||
|
||||
use Elliptic\Utils;
|
||||
use BN\BN;
|
||||
|
||||
class Signature
|
||||
{
|
||||
public $r;
|
||||
public $s;
|
||||
public $recoveryParam;
|
||||
|
||||
function __construct($options, $enc = false)
|
||||
{
|
||||
if ($options instanceof Signature) {
|
||||
$this->r = $options->r;
|
||||
$this->s = $options->s;
|
||||
$this->recoveryParam = $options->recoveryParam;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($options['r'])) {
|
||||
assert(isset($options["r"]) && isset($options["s"])); //, "Signature without r or s");
|
||||
$this->r = new BN($options["r"], 16);
|
||||
$this->s = new BN($options["s"], 16);
|
||||
|
||||
if( isset($options["recoveryParam"]) )
|
||||
$this->recoveryParam = $options["recoveryParam"];
|
||||
else
|
||||
$this->recoveryParam = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->_importDER($options, $enc))
|
||||
throw new \Exception('Unknown signature format');
|
||||
|
||||
}
|
||||
|
||||
private static function getLength($buf, &$pos)
|
||||
{
|
||||
$initial = $buf[$pos++];
|
||||
if( !($initial & 0x80) )
|
||||
return $initial;
|
||||
|
||||
$octetLen = $initial & 0xf;
|
||||
$val = 0;
|
||||
for($i = 0; $i < $octetLen; $i++)
|
||||
{
|
||||
$val = $val << 8;
|
||||
$val = $val | $buf[$pos];
|
||||
$pos++;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
private static function rmPadding(&$buf)
|
||||
{
|
||||
$i = 0;
|
||||
$len = count($buf) - 1;
|
||||
while($i < $len && !$buf[$i] && !($buf[$i+1] & 0x80) )
|
||||
$i++;
|
||||
|
||||
if( $i === 0 )
|
||||
return $buf;
|
||||
|
||||
return array_slice($buf, $i);
|
||||
}
|
||||
|
||||
private function _importDER($data, $enc)
|
||||
{
|
||||
$data = Utils::toArray($data, $enc);
|
||||
$dataLen = count($data);
|
||||
$place = 0;
|
||||
|
||||
if( $data[$place++] !== 0x30)
|
||||
return false;
|
||||
|
||||
$len = self::getLength($data, $place);
|
||||
if( ($len + $place) !== $dataLen )
|
||||
return false;
|
||||
|
||||
if( $data[$place++] !== 0x02 )
|
||||
return false;
|
||||
|
||||
$rlen = self::getLength($data, $place);
|
||||
$r = array_slice($data, $place, $rlen);
|
||||
$place += $rlen;
|
||||
|
||||
if( $data[$place++] !== 0x02 )
|
||||
return false;
|
||||
|
||||
$slen = self::getLength($data, $place);
|
||||
if( $dataLen !== $slen + $place )
|
||||
return false;
|
||||
$s = array_slice($data, $place, $slen);
|
||||
|
||||
if( $r[0] === 0 && ($r[1] & 0x80 ) )
|
||||
$r = array_slice($r, 1);
|
||||
if( $s[0] === 0 && ($s[1] & 0x80 ) )
|
||||
$s = array_slice($s, 1);
|
||||
|
||||
$this->r = new BN($r);
|
||||
$this->s = new BN($s);
|
||||
$this->recoveryParam = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function constructLength(&$arr, $len)
|
||||
{
|
||||
if( $len < 0x80 )
|
||||
{
|
||||
array_push($arr, $len);
|
||||
return;
|
||||
}
|
||||
|
||||
$octets = 1 + (log($len) / M_LN2 >> 3);
|
||||
array_push($arr, $octets | 0x80);
|
||||
while(--$octets)
|
||||
array_push($arr, ($len >> ($octets << 3)) & 0xff);
|
||||
array_push($arr, $len);
|
||||
}
|
||||
|
||||
public function toDER($enc = false)
|
||||
{
|
||||
$r = $this->r->toArray();
|
||||
$s = $this->s->toArray();
|
||||
|
||||
//Pad values
|
||||
if( $r[0] & 0x80 )
|
||||
array_unshift($r, 0);
|
||||
if( $s[0] & 0x80 )
|
||||
array_unshift($s, 0);
|
||||
|
||||
$r = self::rmPadding($r);
|
||||
$s = self::rmPadding($s);
|
||||
|
||||
while(!$s[0] && !($s[1] & 0x80))
|
||||
array_slice($s, 1);
|
||||
|
||||
$arr = array(0x02);
|
||||
self::constructLength($arr, count($r));
|
||||
$arr = array_merge($arr, $r, array(0x02));
|
||||
self::constructLength($arr, count($s));
|
||||
$backHalf = array_merge($arr, $s);
|
||||
$res = array(0x30);
|
||||
self::constructLength($res, count($backHalf));
|
||||
$res = array_merge($res, $backHalf);
|
||||
|
||||
return Utils::encode($res, $enc);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
124
vendor/simplito/elliptic-php/lib/EdDSA.php
vendored
Normal file
124
vendor/simplito/elliptic-php/lib/EdDSA.php
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
namespace Elliptic;
|
||||
|
||||
use Elliptic\EdDSA\KeyPair;
|
||||
use Elliptic\EdDSA\Signature;
|
||||
|
||||
class EdDSA {
|
||||
|
||||
public $curve;
|
||||
public $g;
|
||||
public $pointClass;
|
||||
public $encodingLength;
|
||||
public $hash;
|
||||
|
||||
function __construct($curve) {
|
||||
assert($curve == "ed25519"); //, 'only tested with ed25519 so far');
|
||||
|
||||
$curve = \Elliptic\Curves::getCurve($curve)->curve;
|
||||
$this->curve = $curve;
|
||||
$this->g = $curve->g;
|
||||
$this->g->precompute($curve->n->bitLength() + 1);
|
||||
|
||||
$this->pointClass = get_class($curve->point());
|
||||
$this->encodingLength = intval(ceil($curve->n->bitLength() / 8));
|
||||
// TODO: !!!
|
||||
$this->hash = [ "algo" => "sha512" ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array|String} message - message bytes
|
||||
* @param {Array|String|KeyPair} secret - secret bytes or a keypair
|
||||
* @returns {Signature} - signature
|
||||
*/
|
||||
public function sign($message, #[\SensitiveParameter]
|
||||
$secret) {
|
||||
$message = Utils::parseBytes($message);
|
||||
$key = $this->keyFromSecret($secret);
|
||||
$r = $this->hashInt($key->messagePrefix(), $message);
|
||||
$R = $this->g->mul($r);
|
||||
$Rencoded = $this->encodePoint($R);
|
||||
$s_ = $this->hashInt($Rencoded, $key->pubBytes(), $message)
|
||||
->mul($key->priv());
|
||||
$S = $r->add($s_)->umod($this->curve->n);
|
||||
return $this->makeSignature([ "R" => $R, "S" => $S, "Rencoded" => $Rencoded ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} message - message bytes
|
||||
* @param {Array|String|Signature} sig - sig bytes
|
||||
* @param {Array|String|Point|KeyPair} pub - public key
|
||||
* @returns {Boolean} - true if public key matches sig of message
|
||||
*/
|
||||
public function verify($message, $sig, $pub) {
|
||||
$message = Utils::parseBytes($message);
|
||||
$sig = $this->makeSignature($sig);
|
||||
$key = $this->keyFromPublic($pub);
|
||||
$h = $this->hashInt($sig->Rencoded(), $key->pubBytes(), $message);
|
||||
$SG = $this->g->mul($sig->S());
|
||||
$RplusAh = $sig->R()->add($key->pub()->mul($h));
|
||||
return $RplusAh->eq($SG);
|
||||
}
|
||||
|
||||
public function hashInt() {
|
||||
$arguments = func_get_args();
|
||||
// TODO: refactor when hash-php is ready
|
||||
$hash = hash_init($this->hash["algo"]);
|
||||
for ($i = 0; $i < count($arguments); $i++)
|
||||
hash_update($hash, Utils::toBin($arguments[$i]));
|
||||
return Utils::intFromLE(hash_final($hash))->umod($this->curve->n);
|
||||
}
|
||||
|
||||
public function keyFromPublic($pub) {
|
||||
return KeyPair::fromPublic($this, $pub);
|
||||
}
|
||||
|
||||
public function keyFromSecret(#[\SensitiveParameter]
|
||||
$secret) {
|
||||
return KeyPair::fromSecret($this, $secret);
|
||||
}
|
||||
|
||||
public function makeSignature($sig) {
|
||||
if ($sig instanceof Signature)
|
||||
return $sig;
|
||||
return new Signature($this, $sig);
|
||||
}
|
||||
|
||||
/**
|
||||
* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
|
||||
*
|
||||
* EdDSA defines methods for encoding and decoding points and integers. These are
|
||||
* helper convenience methods, that pass along to utility functions implied
|
||||
* parameters.
|
||||
*
|
||||
*/
|
||||
public function encodePoint($point) {
|
||||
$enc = $point->getY()->toArray('le', $this->encodingLength);
|
||||
$enc[$this->encodingLength - 1] |= $point->getX()->isOdd() ? 0x80 : 0;
|
||||
return $enc;
|
||||
}
|
||||
|
||||
public function decodePoint($bytes) {
|
||||
$bytes = Utils::parseBytes($bytes);
|
||||
|
||||
$lastIx = count($bytes) - 1;
|
||||
$normed = $bytes;
|
||||
$normed[$lastIx] = $bytes[$lastIx] & ~0x80;
|
||||
$xIsOdd = ($bytes[$lastIx] & 0x80) !== 0;
|
||||
|
||||
$y = Utils::intFromLE($normed);
|
||||
return $this->curve->pointFromY($y, $xIsOdd);
|
||||
}
|
||||
|
||||
public function encodeInt($num) {
|
||||
return $num->toArray('le', $this->encodingLength);
|
||||
}
|
||||
|
||||
public function decodeInt($bytes) {
|
||||
return Utils::intFromLE($bytes);
|
||||
}
|
||||
|
||||
public function isPoint($val) {
|
||||
return is_a($val, $this->pointClass);
|
||||
}
|
||||
}
|
||||
128
vendor/simplito/elliptic-php/lib/EdDSA/KeyPair.php
vendored
Normal file
128
vendor/simplito/elliptic-php/lib/EdDSA/KeyPair.php
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
namespace Elliptic\EdDSA;
|
||||
|
||||
use Elliptic\Utils;
|
||||
|
||||
class KeyPair {
|
||||
public $eddsa;
|
||||
public $_pubBytes;
|
||||
/**
|
||||
* @param {\Elliptic\EdDSA} eddsa - instance
|
||||
* @param {Object} params - public/private key parameters
|
||||
*
|
||||
* @param {Array<Byte>} [params.secret] - secret seed bytes
|
||||
* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
|
||||
* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
|
||||
*
|
||||
*/
|
||||
function __construct($eddsa, #[\SensitiveParameter]
|
||||
$params) {
|
||||
$this->eddsa = $eddsa;
|
||||
$this->_secret = isset($params["secret"]) ? Utils::parseBytes($params["secret"]) : null;
|
||||
if (!isset($params["pub"])) {
|
||||
$this->_pub = null;
|
||||
$this->_pubBytes = null;
|
||||
return;
|
||||
}
|
||||
if ($eddsa->isPoint($params["pub"]))
|
||||
$this->_pub = $params["pub"];
|
||||
else
|
||||
$this->_pubBytes = Utils::parseBytes($params["pub"]);
|
||||
}
|
||||
|
||||
public static function fromPublic($eddsa, $pub) {
|
||||
if ($pub instanceof KeyPair)
|
||||
return $pub;
|
||||
return new KeyPair($eddsa, [ "pub" => $pub ]);
|
||||
}
|
||||
|
||||
public static function fromSecret($eddsa, #[\SensitiveParameter]
|
||||
$secret) {
|
||||
if ($secret instanceof KeyPair)
|
||||
return $secret;
|
||||
return new KeyPair($eddsa, [ "secret" => $secret ]);
|
||||
}
|
||||
|
||||
private $_secret;
|
||||
public function secret() {
|
||||
return $this->_secret;
|
||||
}
|
||||
|
||||
public function pubBytes() {
|
||||
if (!$this->_pubBytes)
|
||||
$this->_pubBytes = $this->eddsa->encodePoint($this->pub());
|
||||
return $this->_pubBytes;
|
||||
}
|
||||
|
||||
private $_pub;
|
||||
public function pub() {
|
||||
if (!$this->_pub) {
|
||||
if ($this->_pubBytes)
|
||||
$this->_pub = $this->eddsa->decodePoint($this->_pubBytes);
|
||||
else
|
||||
$this->_pub = $this->eddsa->g->mul($this->priv());
|
||||
}
|
||||
return $this->_pub;
|
||||
}
|
||||
|
||||
private $_privBytes;
|
||||
public function privBytes() {
|
||||
if (!$this->_privBytes) {
|
||||
$eddsa = $this->eddsa;
|
||||
$hash = $this->hash();
|
||||
$lastIx = $eddsa->encodingLength - 1;
|
||||
|
||||
$a = array_slice($hash, 0, $eddsa->encodingLength);
|
||||
$a[0] &= 248;
|
||||
$a[$lastIx] &= 127;
|
||||
$a[$lastIx] |= 64;
|
||||
$this->_privBytes = $a;
|
||||
}
|
||||
return $this->_privBytes;
|
||||
}
|
||||
|
||||
private $_priv;
|
||||
public function priv() {
|
||||
if (!$this->_priv) {
|
||||
$this->_priv = $this->eddsa->decodeInt($this->privBytes());
|
||||
}
|
||||
return $this->_priv;
|
||||
}
|
||||
|
||||
private $_hash;
|
||||
public function hash() {
|
||||
if (!$this->_hash) {
|
||||
// TODO: !!!
|
||||
$hash = hash_init('sha512');
|
||||
hash_update($hash, Utils::toBin($this->secret()));
|
||||
$this->_hash = Utils::toArray( hash_final($hash), 'hex' );
|
||||
}
|
||||
return $this->_hash;
|
||||
}
|
||||
|
||||
private $_messagePrefix;
|
||||
public function messagePrefix() {
|
||||
if (!$this->_messagePrefix) {
|
||||
$this->_messagePrefix = array_slice($this->hash(), $this->eddsa->encodingLength);
|
||||
}
|
||||
return $this->_messagePrefix;
|
||||
}
|
||||
|
||||
public function sign($message) {
|
||||
assert($this->_secret); //, 'KeyPair can only verify');
|
||||
return $this->eddsa->sign($message, $this);
|
||||
}
|
||||
|
||||
public function verify($message, $sig) {
|
||||
return $this->eddsa->verify($message, $sig, $this);
|
||||
}
|
||||
|
||||
public function getSecret($enc = false) {
|
||||
assert($this->_secret); //, 'KeyPair is public only');
|
||||
return Utils::encode($this->secret(), $enc);
|
||||
}
|
||||
|
||||
public function getPublic($enc = false) {
|
||||
return Utils::encode($this->pubBytes(), $enc);
|
||||
}
|
||||
}
|
||||
82
vendor/simplito/elliptic-php/lib/EdDSA/Signature.php
vendored
Normal file
82
vendor/simplito/elliptic-php/lib/EdDSA/Signature.php
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace Elliptic\EdDSA;
|
||||
|
||||
use Elliptic\Utils;
|
||||
use BN\BN;
|
||||
|
||||
class Signature {
|
||||
|
||||
public $eddsa;
|
||||
|
||||
/**
|
||||
* @param {EdDSA} eddsa - eddsa instance
|
||||
* @param {Array<Bytes>|Object} sig -
|
||||
* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
|
||||
* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
|
||||
* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
|
||||
* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
|
||||
*/
|
||||
function __construct($eddsa, $sig) {
|
||||
$this->eddsa = $eddsa;
|
||||
|
||||
if (is_string($sig))
|
||||
$sig = Utils::parseBytes($sig);
|
||||
|
||||
if (is_array($sig) && !isset($sig["R"])) {
|
||||
$sig = [
|
||||
"R" => array_slice($sig, 0, $eddsa->encodingLength),
|
||||
"S" => array_slice($sig, $eddsa->encodingLength)
|
||||
];
|
||||
}
|
||||
|
||||
assert($sig["R"] && $sig["S"]); //, 'Signature without R or S');
|
||||
|
||||
if ($eddsa->isPoint($sig["R"]))
|
||||
$this->_R = $sig["R"];
|
||||
if ($sig["S"] instanceof BN)
|
||||
$this->_S = $sig["S"];
|
||||
|
||||
$this->_Rencoded = is_array($sig["R"]) ? $sig["R"] : (isset($sig["Rencoded"]) ?$sig["Rencoded"] : null);
|
||||
$this->_Sencoded = is_array($sig["S"]) ? $sig["S"] : (isset($sig["Sencoded"]) ?$sig["Sencoded"] : null);
|
||||
}
|
||||
|
||||
private $_S;
|
||||
public function S() {
|
||||
if (!$this->_S) {
|
||||
$this->_S = $this->eddsa->decodeInt($this->Sencoded());
|
||||
}
|
||||
return $this->_S;
|
||||
}
|
||||
|
||||
private $_R;
|
||||
public function R() {
|
||||
if (!$this->_R) {
|
||||
$this->_R = $this->eddsa->decodePoint($this->Rencoded());
|
||||
}
|
||||
return $this->_R;
|
||||
}
|
||||
|
||||
private $_Rencoded;
|
||||
public function Rencoded() {
|
||||
if (!$this->_Rencoded) {
|
||||
$this->_Rencoded = $this->eddsa->encodePoint($this->R());
|
||||
}
|
||||
return $this->_Rencoded;
|
||||
}
|
||||
|
||||
private $_Sencoded;
|
||||
public function Sencoded() {
|
||||
if (!$this->_Sencoded) {
|
||||
$this->_Sencoded = $this->eddsa->encodeInt($this->S());
|
||||
}
|
||||
return $this->_Sencoded;
|
||||
}
|
||||
|
||||
public function toBytes() {
|
||||
return array_merge($this->Rencoded(), $this->Sencoded());
|
||||
}
|
||||
|
||||
public function toHex() {
|
||||
return strtoupper(Utils::encode($this->toBytes(), 'hex'));
|
||||
}
|
||||
}
|
||||
135
vendor/simplito/elliptic-php/lib/HmacDRBG.php
vendored
Normal file
135
vendor/simplito/elliptic-php/lib/HmacDRBG.php
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic;
|
||||
|
||||
class HmacDRBG
|
||||
{
|
||||
private $hash;
|
||||
private $predResist;
|
||||
private $outLen;
|
||||
private $minEntropy;
|
||||
private $reseed;
|
||||
private $reseedInterval;
|
||||
private $K;
|
||||
private $V;
|
||||
|
||||
function __construct($options)
|
||||
{
|
||||
Utils::optionAssert($options, "predResist");
|
||||
Utils::optionAssert($options, "hash", null, true);
|
||||
Utils::optionAssert($options["hash"], "outSize", null, true);
|
||||
Utils::optionAssert($options["hash"], "hmacStrength", null, true);
|
||||
Utils::optionAssert($options["hash"], "algo", null, true);
|
||||
Utils::optionAssert($options, "minEntropy");
|
||||
Utils::optionAssert($options, "entropy", null, true);
|
||||
Utils::optionAssert($options, "entropyEnc");
|
||||
Utils::optionAssert($options, "nonce", "");
|
||||
Utils::optionAssert($options, "nonceEnc");
|
||||
Utils::optionAssert($options, "pers", "");
|
||||
Utils::optionAssert($options, "persEnc");
|
||||
|
||||
$this->hash = $options["hash"];
|
||||
$this->predResist = $options["predResist"];
|
||||
|
||||
$this->outLen = $this->hash["outSize"];
|
||||
$this->minEntropy = $options["minEntropy"] ?: $this->hash["hmacStrength"];
|
||||
|
||||
$this->reseed = null;
|
||||
$this->reseedInterval = null;
|
||||
$this->K = null;
|
||||
$this->V = null;
|
||||
|
||||
$entropy = Utils::toBin($options["entropy"], $options["entropyEnc"]);
|
||||
$nonce = Utils::toBin($options["nonce"], $options["nonceEnc"]);
|
||||
$pers = Utils::toBin($options["pers"], $options["persEnc"]);
|
||||
|
||||
if (Utils::$ASSERT_ENABLED) {
|
||||
assert(strlen($entropy) >= ($this->minEntropy / 8));
|
||||
}
|
||||
$this->_init($entropy, $nonce, $pers);
|
||||
}
|
||||
|
||||
private function _init($entropy, $nonce, $pers)
|
||||
{
|
||||
$seed = $entropy . $nonce . $pers;
|
||||
|
||||
$this->K = str_repeat(chr(0x00), $this->outLen / 8);
|
||||
$this->V = str_repeat(chr(0x01), $this->outLen / 8);
|
||||
|
||||
$this->_update($seed);
|
||||
$this->reseed = 1;
|
||||
$this->reseedInterval = 0x1000000000000; // 2^48
|
||||
}
|
||||
|
||||
private function _hmac()
|
||||
{
|
||||
return hash_init($this->hash["algo"], HASH_HMAC, $this->K);
|
||||
}
|
||||
|
||||
private function _update($seed = false)
|
||||
{
|
||||
$kmac = $this->_hmac();
|
||||
hash_update($kmac, $this->V);
|
||||
hash_update($kmac, chr(0x00));
|
||||
|
||||
if( $seed )
|
||||
hash_update($kmac, $seed);
|
||||
$this->K = hash_final($kmac, true);
|
||||
|
||||
$kmac = $this->_hmac();
|
||||
hash_update($kmac, $this->V);
|
||||
$this->V = hash_final($kmac, true);
|
||||
|
||||
if(!$seed)
|
||||
return;
|
||||
|
||||
$kmac = $this->_hmac();
|
||||
hash_update($kmac, $this->V);
|
||||
hash_update($kmac, chr(0x01));
|
||||
hash_update($kmac, $seed);
|
||||
$this->K = hash_final($kmac, true);
|
||||
|
||||
$kmac = $this->_hmac();
|
||||
hash_update($kmac, $this->V);
|
||||
$this->V = hash_final($kmac, true);
|
||||
}
|
||||
|
||||
// TODO: reseed()
|
||||
|
||||
public function generate($len, $enc = null, $add = null, $addEnc = null)
|
||||
{
|
||||
if ($this->reseed > $this->reseedInterval)
|
||||
throw new \Exception("Reseed is required");
|
||||
|
||||
// Optional encoding
|
||||
if( !is_string($enc) )
|
||||
{
|
||||
$addEnc = $enc;
|
||||
$add = $enc;
|
||||
$enc = null;
|
||||
}
|
||||
|
||||
// Optional additional data
|
||||
if( $add != null ) {
|
||||
$add = Utils::toBin($add, $addEnc);
|
||||
$this->_update($add);
|
||||
}
|
||||
|
||||
$temp = "";
|
||||
while( strlen($temp) < $len )
|
||||
{
|
||||
$hmac = $this->_hmac();
|
||||
hash_update($hmac, $this->V);
|
||||
$this->V = hash_final($hmac, true);
|
||||
$temp .= $this->V;
|
||||
}
|
||||
|
||||
$res = substr($temp, 0, $len);
|
||||
$this->_update($add);
|
||||
$this->reseed++;
|
||||
|
||||
return Utils::encode(Utils::toArray($res), $enc);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
176
vendor/simplito/elliptic-php/lib/Utils.php
vendored
Normal file
176
vendor/simplito/elliptic-php/lib/Utils.php
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Elliptic;
|
||||
|
||||
use \Exception;
|
||||
use BN\BN;
|
||||
|
||||
if (!function_exists("random_int")) {
|
||||
function random_int($a, $b) {
|
||||
return rand($a, $b);
|
||||
}
|
||||
}
|
||||
|
||||
class Utils
|
||||
{
|
||||
public static $ASSERT_ENABLED;
|
||||
|
||||
public static function toArray($msg, $enc = false)
|
||||
{
|
||||
if( is_array($msg) )
|
||||
return array_slice($msg, 0);
|
||||
|
||||
if( !$msg )
|
||||
return array();
|
||||
|
||||
if( !is_string($msg) )
|
||||
throw new Exception("Not implemented");
|
||||
|
||||
if( !$enc )
|
||||
return array_slice(unpack("C*", $msg), 0);
|
||||
|
||||
if( $enc === "hex" )
|
||||
return array_slice(unpack("C*", hex2bin($msg)), 0);
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
public static function toHex($msg)
|
||||
{
|
||||
if( is_string($msg) )
|
||||
return bin2hex($msg);
|
||||
|
||||
if( !is_array($msg) )
|
||||
throw new Exception("Not implemented");
|
||||
|
||||
$binary = call_user_func_array("pack", array_merge(["C*"], $msg));
|
||||
return bin2hex($binary);
|
||||
}
|
||||
|
||||
public static function toBin($msg, $enc = false)
|
||||
{
|
||||
if( is_array($msg) )
|
||||
return call_user_func_array("pack", array_merge(["C*"], $msg));
|
||||
|
||||
if( $enc === "hex" )
|
||||
return hex2bin($msg);
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
public static function encode($arr, $enc)
|
||||
{
|
||||
if( $enc === "hex" )
|
||||
return self::toHex($arr);
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// Represent num in a w-NAF form
|
||||
public static function getNAF($num, $w)
|
||||
{
|
||||
$naf = array();
|
||||
$ws = 1 << ($w + 1);
|
||||
$k = clone($num);
|
||||
|
||||
while( $k->cmpn(1) >= 0 )
|
||||
{
|
||||
if( !$k->isOdd() )
|
||||
array_push($naf, 0);
|
||||
else
|
||||
{
|
||||
$mod = $k->andln($ws - 1);
|
||||
$z = $mod;
|
||||
if( $mod > (($ws >> 1) - 1))
|
||||
$z = ($ws >> 1) - $mod;
|
||||
$k->isubn($z);
|
||||
array_push($naf, $z);
|
||||
}
|
||||
|
||||
// Optimization, shift by word if possible
|
||||
$shift = (!$k->isZero() && $k->andln($ws - 1) === 0) ? ($w + 1) : 1;
|
||||
for($i = 1; $i < $shift; $i++)
|
||||
array_push($naf, 0);
|
||||
$k->iushrn($shift);
|
||||
}
|
||||
|
||||
return $naf;
|
||||
}
|
||||
|
||||
// Represent k1, k2 in a Joint Sparse Form
|
||||
public static function getJSF($k1, $k2)
|
||||
{
|
||||
$jsf = array( array(), array() );
|
||||
$k1 = $k1->_clone();
|
||||
$k2 = $k2->_clone();
|
||||
$d1 = 0;
|
||||
$d2 = 0;
|
||||
|
||||
while( $k1->cmpn(-$d1) > 0 || $k2->cmpn(-$d2) > 0 )
|
||||
{
|
||||
// First phase
|
||||
$m14 = ($k1->andln(3) + $d1) & 3;
|
||||
$m24 = ($k2->andln(3) + $d2) & 3;
|
||||
if( $m14 === 3 )
|
||||
$m14 = -1;
|
||||
if( $m24 === 3 )
|
||||
$m24 = -1;
|
||||
|
||||
$u1 = 0;
|
||||
if( ($m14 & 1) !== 0 )
|
||||
{
|
||||
$m8 = ($k1->andln(7) + $d1) & 7;
|
||||
$u1 = ( ($m8 === 3 || $m8 === 5) && $m24 === 2 ) ? -$m14 : $m14;
|
||||
}
|
||||
array_push($jsf[0], $u1);
|
||||
|
||||
$u2 = 0;
|
||||
if( ($m24 & 1) !== 0 )
|
||||
{
|
||||
$m8 = ($k2->andln(7) + $d2) & 7;
|
||||
$u2 = ( ($m8 === 3 || $m8 === 5) && $m14 === 2 ) ? -$m24 : $m24;
|
||||
}
|
||||
array_push($jsf[1], $u2);
|
||||
|
||||
// Second phase
|
||||
if( (2 * $d1) === ($u1 + 1) )
|
||||
$d1 = 1 - $d1;
|
||||
if( (2 * $d2) === ($u2 + 1) )
|
||||
$d2 = 1 - $d2;
|
||||
$k1->iushrn(1);
|
||||
$k2->iushrn(1);
|
||||
}
|
||||
|
||||
return $jsf;
|
||||
}
|
||||
|
||||
public static function intFromLE($bytes) {
|
||||
return new BN($bytes, 'hex', 'le');
|
||||
}
|
||||
|
||||
public static function parseBytes($bytes) {
|
||||
if (is_string($bytes))
|
||||
return self::toArray($bytes, 'hex');
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
public static function randBytes($count)
|
||||
{
|
||||
$res = "";
|
||||
for($i = 0; $i < $count; $i++)
|
||||
$res .= chr(random_int(0, 255));
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function optionAssert(&$array, $key, $value = false, $required = false)
|
||||
{
|
||||
if( isset($array[$key]) )
|
||||
return;
|
||||
if( $required )
|
||||
throw new Exception("Missing option " . $key);
|
||||
$array[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
Utils::$ASSERT_ENABLED = ini_get("zend.assertions") === "1";
|
||||
|
||||
?>
|
||||
10
vendor/simplito/elliptic-php/phpbench.json
vendored
Normal file
10
vendor/simplito/elliptic-php/phpbench.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"bootstrap": "vendor/autoload.php",
|
||||
"path": "benchmarks",
|
||||
"reports": {
|
||||
"simple": {
|
||||
"generator": "table",
|
||||
"cols": ["subject", "mode", "rstdev", "its", "revs"]
|
||||
}
|
||||
}
|
||||
}
|
||||
21
vendor/simplito/elliptic-php/phpunit.xml.dist
vendored
Normal file
21
vendor/simplito/elliptic-php/phpunit.xml.dist
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
stopOnFailure="false"
|
||||
verbose="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="AllTests">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<coverage>
|
||||
<exclude>
|
||||
<directory suffix=".php">lib/</directory>
|
||||
</exclude>
|
||||
</coverage>
|
||||
</phpunit>
|
||||
17
vendor/simplito/elliptic-php/tests/ApiTest.php
vendored
Normal file
17
vendor/simplito/elliptic-php/tests/ApiTest.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
require_once __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
class ApiTest extends \PHPUnit\Framework\TestCase {
|
||||
public function test_should_instatiate_with_valid_curve_secp256k1() {
|
||||
$ec = new \Elliptic\EC('secp256k1');
|
||||
|
||||
$this->assertNotNull($ec);
|
||||
$this->assertInstanceOf(\Elliptic\EC::class, $ec);
|
||||
}
|
||||
|
||||
|
||||
public function test_should_throw_error_with_invalid_curve() {
|
||||
$this->expectException(\Exception::class);
|
||||
$ec = new \Elliptic\EC('nonexistent-curve');
|
||||
}
|
||||
}
|
||||
165
vendor/simplito/elliptic-php/tests/CurveTest.php
vendored
Normal file
165
vendor/simplito/elliptic-php/tests/CurveTest.php
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
require_once __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
use BN\BN;
|
||||
|
||||
class CurveTest extends \PHPUnit\Framework\TestCase {
|
||||
public function test_should_work_with_example_curve() {
|
||||
$curve = new \Elliptic\Curve\ShortCurve(array(
|
||||
"p" => '1d',
|
||||
"a" => '4',
|
||||
"b" => '14'
|
||||
));
|
||||
|
||||
$p = $curve->point('18', '16');
|
||||
$this->assertTrue($p->validate());
|
||||
$this->assertTrue($p->dbl()->validate());
|
||||
$this->assertTrue($p->dbl()->add($p)->validate());
|
||||
$this->assertTrue($p->dbl()->add($p->dbl())->validate());
|
||||
$this->assertTrue($p->dbl()->add($p->dbl())->eq($p->add($p)->add($p)->add($p)));
|
||||
}
|
||||
|
||||
public function test_should_work_with_secp112k1() {
|
||||
$curve = new \Elliptic\Curve\ShortCurve(array(
|
||||
"p" => 'db7c 2abf62e3 5e668076 bead208b',
|
||||
"a" => 'db7c 2abf62e3 5e668076 bead2088',
|
||||
"b" => '659e f8ba0439 16eede89 11702b22'
|
||||
));
|
||||
|
||||
$p = $curve->point(
|
||||
'0948 7239995a 5ee76b55 f9c2f098',
|
||||
'a89c e5af8724 c0a23e0e 0ff77500');
|
||||
$this->assertTrue($p->validate());
|
||||
$this->assertTrue($p->dbl()->validate());
|
||||
}
|
||||
|
||||
public function test_should_work_with_secp256k1() {
|
||||
$curve = new \Elliptic\Curve\ShortCurve(array(
|
||||
"p" => 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ' .
|
||||
'fffffc2f',
|
||||
"a" => '0',
|
||||
"b" => '7',
|
||||
"n" => 'ffffffff ffffffff ffffffff fffffffe ' .
|
||||
'baaedce6 af48a03b bfd25e8c d0364141',
|
||||
"g" => [
|
||||
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
|
||||
'483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'
|
||||
]
|
||||
));
|
||||
|
||||
$p = $curve->point(
|
||||
'79be667e f9dcbbac 55a06295 ce870b07 029bfcdb 2dce28d9 59f2815b 16f81798',
|
||||
'483ada77 26a3c465 5da4fbfc 0e1108a8 fd17b448 a6855419 9c47d08f fb10d4b8'
|
||||
);
|
||||
$this->assertTrue($p->validate());
|
||||
$this->assertTrue($p->dbl()->validate());
|
||||
$this->assertTrue($p->toJ()->dbl()->toP()->validate());
|
||||
$this->assertTrue($p->mul(new BN('79be667e f9dcbbac 55a06295 ce870b07', 16))->validate());
|
||||
|
||||
$j = $p->toJ();
|
||||
$this->assertTrue($j->trpl()->eq($j->dbl()->add($j)));
|
||||
|
||||
// Endomorphism test
|
||||
$this->assertNotNull($curve->endo);
|
||||
$this->assertEquals(
|
||||
$curve->endo["beta"]->fromRed()->toString(16),
|
||||
'7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee');
|
||||
$this->assertEquals(
|
||||
$curve->endo["lambda"]->toString(16),
|
||||
'5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72');
|
||||
|
||||
$k = new BN('1234567890123456789012345678901234', 16);
|
||||
$split = $curve->_endoSplit($k);
|
||||
|
||||
$testK = $split["k1"]->add($split["k2"]->mul($curve->endo["lambda"]))->umod($curve->n);
|
||||
$this->assertEquals($testK->toString(16), $k->toString(16));
|
||||
}
|
||||
|
||||
public function test_should_compute_this_problematic_secp256k1_multiplication() {
|
||||
$curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
|
||||
$g1 = $curve->g; // precomputed g
|
||||
$this->assertNotNull($g1->precomputed);
|
||||
$g2 = $curve->point($g1->getX(), $g1->getY()); // not precomputed g
|
||||
$this->assertNull($g2->precomputed);
|
||||
$a = new BN(
|
||||
'6d1229a6b24c2e775c062870ad26bc261051e0198c67203167273c7c62538846', 16);
|
||||
$p1 = $g1->mul($a);
|
||||
$p2 = $g2->mul($a);
|
||||
$this->assertTrue($p1->eq($p2));
|
||||
}
|
||||
|
||||
public function test_should_not_use_fixed_NAF_when_k_is_too_large() {
|
||||
$curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
|
||||
$g1 = $curve->g; // precomputed g
|
||||
$this->assertNotNull($g1->precomputed);
|
||||
$g2 = $curve->point($g1->getX(), $g1->getY()); // not precomputed g
|
||||
$this->assertNull($g2->precomputed);
|
||||
|
||||
$a = new BN(
|
||||
'6d1229a6b24c2e775c062870ad26bc26' .
|
||||
'1051e0198c67203167273c7c6253884612345678',
|
||||
16);
|
||||
$p1 = $g1->mul($a);
|
||||
$p2 = $g2->mul($a);
|
||||
$this->assertTrue($p1->eq($p2));
|
||||
}
|
||||
|
||||
public function test_should_not_fail_on_secp256k1_regression() {
|
||||
$curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
|
||||
$k1 = new BN(
|
||||
'32efeba414cd0c830aed727749e816a01c471831536fd2fce28c56b54f5a3bb1', 16);
|
||||
$k2 = new BN(
|
||||
'5f2e49b5d64e53f9811545434706cde4de528af97bfd49fde1f6cf792ee37a8c', 16);
|
||||
|
||||
$p1 = $curve->g->mul($k1);
|
||||
$p2 = $curve->g->mul($k2);
|
||||
|
||||
// 2 + 2 + 1 = 2 + 1 + 2
|
||||
$two = $p2->dbl();
|
||||
$five = $two->dbl()->add($p2);
|
||||
$three = $two->add($p2);
|
||||
$maybeFive = $three->add($two);
|
||||
|
||||
$this->assertTrue($maybeFive->eq($five));
|
||||
|
||||
$p1 = $p1->mul($k2);
|
||||
$p2 = $p2->mul($k1);
|
||||
|
||||
$this->assertTrue($p1->validate());
|
||||
$this->assertTrue($p2->validate());
|
||||
$this->assertTrue($p1->eq($p2));
|
||||
}
|
||||
|
||||
public function test_should_correctly_double_the_affine_point_on_secp256k1() {
|
||||
$bad = new ArrayObject(array(
|
||||
"x" => '026a2073b1ef6fab47ace18e60e728a05180a82755bbcec9a0abc08ad9f7a3d4',
|
||||
"y" => '9cd8cb48c3281596139f147c1364a3ede88d3f310fdb0eb98c924e599ca1b3c9',
|
||||
"z" => 'd78587ad45e4102f48b54b5d85598296e069ce6085002e169c6bad78ddc6d9bd'
|
||||
), ArrayObject::ARRAY_AS_PROPS);
|
||||
|
||||
$good = new ArrayObject(array(
|
||||
"x" => 'e7789226739ac2eb3c7ccb2a9a910066beeed86cdb4e0f8a7fee8eeb29dc7016',
|
||||
"y" => '4b76b191fd6d47d07828ea965e275b76d0e3e0196cd5056d38384fbb819f9fcb',
|
||||
"z" => 'cbf8d99056618ba132d6145b904eee1ce566e0feedb9595139c45f84e90cfa7d'
|
||||
), ArrayObject::ARRAY_AS_PROPS);
|
||||
|
||||
$curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
|
||||
$bad = $curve->jpoint($bad->x, $bad->y, $bad->z);
|
||||
$good = $curve->jpoint($good->x, $good->y, $good->z);
|
||||
|
||||
// They are the same points
|
||||
$this->assertTrue($bad->add($good->neg())->isInfinity());
|
||||
|
||||
// But doubling borks them out
|
||||
$this->assertTrue($bad->dbl()->add($good->dbl()->neg())->isInfinity());
|
||||
}
|
||||
|
||||
public function test_should_store_precomputed_values_correctly_on_negation() {
|
||||
$curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
|
||||
$p = $curve->g->mul('2');
|
||||
$p->precompute();
|
||||
$neg = $p->neg(true);
|
||||
$neg2 = $neg->neg(true);
|
||||
$this->assertTrue($p->eq($neg2));
|
||||
}
|
||||
}
|
||||
36
vendor/simplito/elliptic-php/tests/ECDHTest.php
vendored
Normal file
36
vendor/simplito/elliptic-php/tests/ECDHTest.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
require_once __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
class ECDHTest extends \PHPUnit\Framework\TestCase {
|
||||
public function test_should_work_with_secp256k1_curve() {
|
||||
$this->doTest('secp256k1');
|
||||
}
|
||||
|
||||
public function test_should_work_with_p256_curve() {
|
||||
$this->doTest('p256');
|
||||
}
|
||||
|
||||
public function test_should_work_with_curve25519_curve() {
|
||||
$this->doTest('curve25519');
|
||||
}
|
||||
|
||||
public function test_should_work_with_ed25519_curve() {
|
||||
$this->doTest('ed25519');
|
||||
}
|
||||
|
||||
function doTest($name) {
|
||||
$ecdh = new \Elliptic\EC($name);
|
||||
$s1 = $ecdh->genKeyPair();
|
||||
$s2 = $ecdh->genKeyPair();
|
||||
$sh1 = $s1->derive($s2->getPublic());
|
||||
$sh2 = $s2->derive($s1->getPublic());
|
||||
|
||||
$this->assertEquals($sh1->toString(16), $sh2->toString(16));
|
||||
|
||||
$sh1 = $s1->derive($ecdh->keyFromPublic($s2->getPublic('hex'), 'hex')
|
||||
->getPublic());
|
||||
$sh2 = $s2->derive($ecdh->keyFromPublic($s1->getPublic('hex'), 'hex')
|
||||
->getPublic());
|
||||
$this->assertEquals($sh1->toString(16), $sh2->toString(16));
|
||||
}
|
||||
}
|
||||
321
vendor/simplito/elliptic-php/tests/ECDSATest.php
vendored
Normal file
321
vendor/simplito/elliptic-php/tests/ECDSATest.php
vendored
Normal file
@ -0,0 +1,321 @@
|
||||
<?php
|
||||
require_once __DIR__ . "/../vendor/autoload.php";
|
||||
use BN\BN;
|
||||
|
||||
class ECDSATest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
function ECDSACurveNames() {
|
||||
return [
|
||||
['secp256k1']
|
||||
, ['ed25519']
|
||||
, ['p256']
|
||||
, ['p384']
|
||||
, ['p521']
|
||||
];
|
||||
}
|
||||
|
||||
static $entropy = [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 25
|
||||
];
|
||||
|
||||
static $msg = 'deadbeef';
|
||||
|
||||
protected $curve;
|
||||
protected $ecdsa;
|
||||
protected $keys;
|
||||
|
||||
public function prepare($name) {
|
||||
$this->curve = \Elliptic\Curves::getCurve($name);
|
||||
$this->assertNotNull($this->curve);
|
||||
|
||||
$this->ecdsa = new \Elliptic\EC($this->curve);
|
||||
$this->keys = $this->ecdsa->genKeyPair([ "entropy" => self::$entropy ]);
|
||||
return [$this->curve, $this->ecdsa, $this->keys];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_generate_proper_key_pair($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$keylen = 64;
|
||||
if ($name == 'p384') {
|
||||
$keylen = 96;
|
||||
} else if ($name == 'p521') {
|
||||
$keylen = 132;
|
||||
}
|
||||
// Get keys out of pair
|
||||
$this->assertTrue( $keys->getPublic()->x && $keys->getPublic()->y );
|
||||
$this->assertTrue( $keys->getPrivate()->byteLength() > 0);
|
||||
$this->assertEquals( strlen($keys->getPrivate('hex')), $keylen);
|
||||
$this->assertTrue( strlen($keys->getPublic('hex')) > 0);
|
||||
$this->assertTrue( strlen($keys->getPrivate('hex')) > 0);
|
||||
$this->assertTrue( $keys->validate()["result"], 'key validate' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_sign_and_verify($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$signature = $ecdsa->sign(self::$msg, $keys);
|
||||
$this->assertTrue($ecdsa->verify(self::$msg, $signature, $keys), 'Normal verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_sign_and_verify_using_keys_methods($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$signature = $keys->sign(self::$msg);
|
||||
$this->assertTrue($keys->verify(self::$msg, $signature), 'On-key verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_load_private_key_from_the_hex_value($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$copy = $ecdsa->keyFromPrivate($keys->getPrivate('hex'), 'hex');
|
||||
$signature = $ecdsa->sign(self::$msg, $copy);
|
||||
$this->assertTrue($ecdsa->verify(self::$msg, $signature, $copy), 'hex-private verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_have_signature_s_leq_keys_ec_nh($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
// key.sign(msg, options)
|
||||
$sign = $keys->sign('deadbeef', [ "canonical" => true ]);
|
||||
$this->assertTrue($sign->s->cmp($keys->ec->nh) <= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_support_options_k($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$sign = $keys->sign(self::$msg, [
|
||||
"k" => function($iter) {
|
||||
$this->assertTrue($iter >= 0);
|
||||
return new BN(1358);
|
||||
}
|
||||
]);
|
||||
$this->assertTrue($ecdsa->verify(self::$msg, $sign, $keys), 'custom-k verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_have_another_signature_with_pers($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$sign1 = $keys->sign(self::$msg);
|
||||
$sign2 = $keys->sign(self::$msg, [ "pers" => '1234', "persEnc" => 'hex' ]);
|
||||
$this->assertNotEquals($sign1->r->toString('hex') . $sign1->s->toString('hex'),
|
||||
$sign2->r->toString('hex') . $sign2->s->toString('hex'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_load_public_key_from_compact_hex_value($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$pub = $keys->getPublic(true, 'hex');
|
||||
$copy = $ecdsa->keyFromPublic($pub, 'hex');
|
||||
$this->assertEquals($copy->getPublic(true, 'hex'), $pub);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_load_public_key_from_hex_value($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$pub = $keys->getPublic('hex');
|
||||
$copy = $ecdsa->keyFromPublic($pub, 'hex');
|
||||
$this->assertEquals($copy->getPublic('hex'), $pub);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_support_hex_DER_encoding_of_signatures($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$signature = $ecdsa->sign(self::$msg, $keys);
|
||||
$dsign = $signature->toDER('hex');
|
||||
$this->assertTrue($ecdsa->verify(self::$msg, $dsign, $keys), 'hex-DER encoded verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_support_DER_encoding_of_signatures($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$signature = $ecdsa->sign(self::$msg, $keys);
|
||||
$dsign = $signature->toDER();
|
||||
$this->assertTrue($ecdsa->verify(self::$msg, $dsign, $keys), 'DER encoded verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_not_verify_signature_with_wrong_public_key($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$signature = $ecdsa->sign(self::$msg, $keys);
|
||||
|
||||
$wrong = $ecdsa->genKeyPair();
|
||||
$this->assertNotTrue($ecdsa->verify(self::$msg, $signature, $wrong), 'Wrong key verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ECDSACurveNames
|
||||
*/
|
||||
public function test_should_not_verify_signature_with_wrong_private_key($name) {
|
||||
list($curve, $ecdsa, $keys) = $this->prepare($name);
|
||||
$signature = $ecdsa->sign(self::$msg, $keys);
|
||||
|
||||
$wrong = $ecdsa->keyFromPrivate($keys->getPrivate('hex') .
|
||||
$keys->getPrivate('hex'), 'hex');
|
||||
$this->assertNotTrue($ecdsa->verify(self::$msg, $signature, $wrong), 'Wrong key verify');
|
||||
}
|
||||
|
||||
|
||||
// TODO: Implement RFC6979 vectors test
|
||||
|
||||
|
||||
function MaxwellsTrickVector() {
|
||||
$p256 = \Elliptic\Curves::getCurve("p256");
|
||||
$p384 = \Elliptic\Curves::getCurve("p384");
|
||||
$msg = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
|
||||
return [
|
||||
[[
|
||||
"curve" => $p256,
|
||||
"pub" => '041548fc88953e06cd34d4b300804c5322cb48c24aaaa4d0' .
|
||||
'7a541b0f0ccfeedeb0ae4991b90519ea405588bdf699f5e6' .
|
||||
'd0c6b2d5217a5c16e8371062737aa1dae1',
|
||||
"message" => $msg,
|
||||
"sig" => '3006020106020104',
|
||||
"result" => true
|
||||
]],
|
||||
[[
|
||||
"curve" => $p256,
|
||||
"pub" => '04ad8f60e4ec1ebdb6a260b559cb55b1e9d2c5ddd43a41a2' .
|
||||
'd11b0741ef2567d84e166737664104ebbc337af3d861d352' .
|
||||
'4cfbc761c12edae974a0759750c8324f9a',
|
||||
"message" => $msg,
|
||||
"sig" => '3006020106020104',
|
||||
"result" => true
|
||||
]],
|
||||
[[
|
||||
"curve" => $p256,
|
||||
"pub" => '0445bd879143a64af5746e2e82aa65fd2ea07bba4e355940' .
|
||||
'95a981b59984dacb219d59697387ac721b1f1eccf4b11f43' .
|
||||
'ddc39e8367147abab3084142ed3ea170e4',
|
||||
"message" => $msg,
|
||||
"sig" => '301502104319055358e8617b0c46353d039cdaae020104',
|
||||
"result" => true
|
||||
]],
|
||||
[[
|
||||
"curve" => $p256,
|
||||
"pub" => '040feb5df4cc78b35ec9c180cc0de5842f75f088b4845697' .
|
||||
'8ffa98e716d94883e1e6500b2a1f6c1d9d493428d7ae7d9a' .
|
||||
'8a560fff30a3d14aa160be0c5e7edcd887',
|
||||
"message" => $msg,
|
||||
"sig" => '301502104319055358e8617b0c46353d039cdaae020104',
|
||||
"result" => false
|
||||
]],
|
||||
[[
|
||||
"curve" => $p384,
|
||||
"pub" => '0425e299eea9927b39fa92417705391bf17e8110b4615e9e' .
|
||||
'b5da471b57be0c30e7d89dbdc3e5da4eae029b300344d385' .
|
||||
'1548b59ed8be668813905105e673319d59d32f574e180568' .
|
||||
'463c6186864888f6c0b67b304441f82aab031279e48f047c31',
|
||||
"message" => $msg,
|
||||
"sig" => '3006020103020104',
|
||||
"result" => true
|
||||
]],
|
||||
[[
|
||||
"curve" => $p384,
|
||||
"pub" => '04a328f65c22307188b4af65779c1d2ec821c6748c6bd8dc' .
|
||||
'0e6a008135f048f832df501f7f3f79966b03d5bef2f187ec' .
|
||||
'34d85f6a934af465656fb4eea8dd9176ab80fbb4a27a649f' .
|
||||
'526a7dfe616091b78d293552bc093dfde9b31cae69d51d3afb',
|
||||
"message" => $msg,
|
||||
"sig" => '3006020103020104',
|
||||
"result" => true
|
||||
]],
|
||||
[[
|
||||
"curve" => $p384,
|
||||
"pub" => '04242e8585eaa7a28cc6062cab4c9c5fd536f46b17be1728' .
|
||||
'288a2cda5951df4941aed1d712defda023d10aca1c5ee014' .
|
||||
'43e8beacd821f7efa27847418ab95ce2c514b2b6b395ee73' .
|
||||
'417c83dbcad631421f360d84d64658c98a62d685b220f5aad4',
|
||||
"message" => $msg,
|
||||
"sig" => '301d0218389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68e020104',
|
||||
"result" => true
|
||||
]],
|
||||
[[
|
||||
"curve" => $p384,
|
||||
"pub" => '04cdf865dd743fe1c23757ec5e65fd5e4038b472ded2af26' .
|
||||
'1e3d8343c595c8b69147df46379c7ca40e60e80170d34a11' .
|
||||
'88dbb2b6f7d3934c23d2f78cfb0db3f3219959fad63c9b61' .
|
||||
'2ef2f20d679777b84192ce86e781c14b1bbb77eacd6e0520e2',
|
||||
"message" => $msg,
|
||||
"sig" => '301d0218389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68e020104',
|
||||
"result" => false
|
||||
]]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider MaxwellsTrickVector
|
||||
*/
|
||||
public function test_should_pass_on_Maxwells_trick_vectors($vector) {
|
||||
$ecdsa = new \Elliptic\EC($vector["curve"]);
|
||||
$key = $ecdsa->keyFromPublic($vector["pub"], 'hex');
|
||||
$msg = $vector["message"];
|
||||
$sig = $vector["sig"];
|
||||
|
||||
$actual = $ecdsa->verify($msg, $sig, $key);
|
||||
$this->assertEquals($actual, $vector["result"]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function test_should_deterministically_generate_private_key() {
|
||||
$curve = \Elliptic\Curves::getCurve("secp256k1");
|
||||
$this->assertNotNull($curve);
|
||||
|
||||
$ecdsa = new \Elliptic\EC($curve);
|
||||
$keys = $ecdsa->genKeyPair(array(
|
||||
"pers" => 'my.pers.string',
|
||||
"entropy" => hash('sha256', 'hello world', true)
|
||||
));
|
||||
$this->assertEquals(
|
||||
$keys->getPrivate('hex'),
|
||||
'6160edb2b218b7f1394b9ca8eb65a72831032a1f2f3dc2d99291c2f7950ed887');
|
||||
}
|
||||
|
||||
public function test_should_recover_the_public_key_from_a_signature() {
|
||||
$ec = new \Elliptic\EC('secp256k1');
|
||||
$key = $ec->genKeyPair();
|
||||
$msg = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
|
||||
$signature = $key->sign($msg);
|
||||
$recid = $ec->getKeyRecoveryParam($msg, $signature, $key->getPublic());
|
||||
$r = $ec->recoverPubKey($msg, $signature, $recid);
|
||||
$this->assertTrue($key->getPublic()->eq($r), 'the keys should match');
|
||||
}
|
||||
|
||||
public function test_should_fail_to_recover_key_when_no_quadratic_residue_available() {
|
||||
$ec = new \Elliptic\EC('secp256k1');
|
||||
$message =
|
||||
'f75c6b18a72fabc0f0b888c3da58e004f0af1fe14f7ca5d8c897fe164925d5e9';
|
||||
|
||||
$this->expectException(\Exception::class);
|
||||
$ec->recoverPubKey($message, [
|
||||
"r" => 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140',
|
||||
"s" => '8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3'
|
||||
], 0);
|
||||
}
|
||||
}
|
||||
110
vendor/simplito/elliptic-php/tests/ED25519Test.php
vendored
Normal file
110
vendor/simplito/elliptic-php/tests/ED25519Test.php
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
require_once __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
use \Elliptic\EdDSA;
|
||||
use \Elliptic\Utils;
|
||||
|
||||
function toHex($arg) { return strtoupper(Utils::toHex($arg)); }
|
||||
|
||||
class ED25519Test extends \PHPUnit\Framework\TestCase {
|
||||
public function derivations() {
|
||||
$data = json_decode( file_get_contents(__DIR__ . "/fixtures/derivation-fixtures"), true);
|
||||
$data = array_slice($data, 0, 50);
|
||||
return array_map(function($set) { return [$set]; }, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider derivations
|
||||
*/
|
||||
public function test_derivations_can_compute_correct_a_and_A_from_secret($test) {
|
||||
$ed25519 = new EdDSA("ed25519");
|
||||
$secret = Utils::toArray($test["secret_hex"], 'hex');
|
||||
$key = $ed25519->keyFromSecret($secret);
|
||||
$this->assertEquals( toHex($key->privBytes()), $test["a_hex"] );
|
||||
$xRecovered = toHex( $ed25519->encodeInt(
|
||||
$ed25519->decodePoint( $key->pubBytes() )->getX()) );
|
||||
$this->assertEquals( $xRecovered, $test["A_P"]["x"] );
|
||||
$this->assertEquals( toHex( $key->pubBytes() ), $test["A_hex"] );
|
||||
}
|
||||
|
||||
public function signLines() {
|
||||
$data = file_get_contents(__DIR__ . "/fixtures/sign.input");
|
||||
$lines = array_filter( explode("\n", $data), function($line) { return strlen($line) > 0; });
|
||||
$lines = array_slice($lines, 0, 50);
|
||||
return array_map(function($line) { return [$line]; }, $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider signLines
|
||||
*/
|
||||
public function test_sign_input_test_vectors($line) {
|
||||
$split = explode(':', strtoupper($line));
|
||||
$ed25519 = new EdDSA("ed25519");
|
||||
$key = $ed25519->keyFromSecret(substr($split[0], 0, 64));
|
||||
$expectedPk = substr($split[0], 64);
|
||||
$this->assertEquals( toHex($key->pubBytes()), $expectedPk);
|
||||
|
||||
$msg = Utils::toArray($split[2], 'hex');
|
||||
$sig = $key->sign($msg)->toHex();
|
||||
$sigR = substr($sig, 0, 64);
|
||||
$sigS = substr($sig, 64);
|
||||
|
||||
$this->assertEquals($sigR, substr($split[3], 0, 64));
|
||||
$this->assertEquals($sigS, substr($split[3], 64, 64));
|
||||
$this->assertTrue($key->verify($msg, $sig));
|
||||
|
||||
if (count($msg) == 0) {
|
||||
$forged = [ 0x78 ] /* ord('x') */;
|
||||
} else {
|
||||
$forged = $msg;
|
||||
$forged[count($msg) - 1] = ($msg[count($msg) - 1] + 1) % 256;
|
||||
}
|
||||
|
||||
$this->assertNotTrue($key->verify($forged, $sig));
|
||||
}
|
||||
|
||||
public function test_eddsa_has_encodingLength_of_32() {
|
||||
$ed25519 = new EdDSA("ed25519");
|
||||
$this->assertEquals(32, $ed25519->encodingLength);
|
||||
}
|
||||
|
||||
public function test_eddsa_can_sign_and_verify_messages() {
|
||||
$ed25519 = new EdDSA("ed25519");
|
||||
$secret = array_fill(0, 32, 0);
|
||||
$msg = [ 0xB, 0xE, 0xE, 0xF ];
|
||||
$key = $ed25519->keyFromSecret($secret);
|
||||
$sig = $key->sign($msg)->toHex();
|
||||
|
||||
$R = '8F1B9A7FDB22BCD2C15D4695B1CE2B063CBFAEC9B00BE360427BAC9533943F6C';
|
||||
$S = '5F0B380FD7F2E43B70AB2FA29F6C6E3FFC1012710E174786814012324BF19B0C';
|
||||
|
||||
$this->assertEquals(substr($sig, 0, 64), $R);
|
||||
$this->assertEquals(substr($sig, 64), $S);
|
||||
|
||||
$this->assertTrue($key->verify($msg, $sig));
|
||||
}
|
||||
|
||||
static $secret = '0000000000000000000000000000000000000000000000000000000000000000';
|
||||
public function test_eddsa_keypair_can_be_created_with_keyFromSecret_or_keyFromPublic() {
|
||||
$ed25519 = new EdDSA("ed25519");
|
||||
$pair = $ed25519->keyFromSecret(self::$secret);
|
||||
$pubKey = $ed25519->keyFromPublic( toHex($pair->pubBytes()) );
|
||||
$this->assertTrue( is_a($pubKey->pub(), $ed25519->pointClass) );
|
||||
$this->assertTrue( $pubKey->pub()->eq($pair->pub()));
|
||||
}
|
||||
|
||||
public function test_eddsa_keypair_getSecret_returns_bytes_with_optional_encoding() {
|
||||
$ed25519 = new EdDSA("ed25519");
|
||||
$pair = $ed25519->keyFromSecret(self::$secret);
|
||||
$this->assertTrue( is_array($pair->getSecret()) );
|
||||
$this->assertTrue( $pair->getSecret('hex') == self::$secret);
|
||||
}
|
||||
|
||||
public function test_eddsa_keypair_getPub_returns_bytes_with_optional_encoding() {
|
||||
$ed25519 = new EdDSA("ed25519");
|
||||
$pair = $ed25519->keyFromSecret(self::$secret);
|
||||
$this->assertTrue( is_array($pair->getPublic()) );
|
||||
$this->assertEquals( $pair->getPublic('hex'),
|
||||
'3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29');
|
||||
}
|
||||
}
|
||||
68
vendor/simplito/elliptic-php/tests/HmacDRBGTest.php
vendored
Normal file
68
vendor/simplito/elliptic-php/tests/HmacDRBGTest.php
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
require_once __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
class HmacDRBGTest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
public function test_should_support_hmac_drbg_sha256() {
|
||||
function doDrbg($opt) {
|
||||
$drbg = new \Elliptic\HmacDRBG([
|
||||
"hash" => ["algo" => 'sha256', 'outSize' => 256, 'hmacStrength' => 192],//hash.sha256,
|
||||
"entropy" => $opt["entropy"],
|
||||
"nonce" => $opt["nonce"],
|
||||
"pers" => $opt["pers"]
|
||||
]);
|
||||
return $drbg->generate($opt["size"], 'hex');
|
||||
}
|
||||
|
||||
$test = [
|
||||
[
|
||||
"entropy" => 'totally random0123456789',
|
||||
"nonce" => 'secret nonce',
|
||||
"pers" => 'my drbg',
|
||||
"size" => 32,
|
||||
"res" => '018ec5f8e08c41e5ac974eb129ac297c5388ee1864324fa13d9b15cf98d9a157'
|
||||
],
|
||||
[
|
||||
"entropy" => 'totally random0123456789',
|
||||
"nonce" => 'secret nonce',
|
||||
"pers" => null,
|
||||
"size" => 32,
|
||||
"res" => 'ed5d61ecf0ef38258e62f03bbb49f19f2cd07ba5145a840d83b134d5963b3633'
|
||||
]
|
||||
];
|
||||
for ($i = 0; $i < count($test); $i++)
|
||||
$this->assertEquals(doDrbg($test[$i]), $test[$i]["res"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider NISTVector
|
||||
*/
|
||||
public function test_should_not_fail_at_NIST_vector($opt) {
|
||||
$drbg = new \Elliptic\HmacDRBG([
|
||||
"hash" => ["algo" => 'sha256', 'outSize' => 256, 'hmacStrength' => 192],//hash.sha256,
|
||||
"entropy" => $opt["entropy"],
|
||||
"entropyEnc" => 'hex',
|
||||
"nonce" => $opt["nonce"],
|
||||
"nonceEnc" => 'hex',
|
||||
"pers" => $opt["pers"],
|
||||
"persEnc" => 'hex'
|
||||
]);
|
||||
|
||||
for ($i = 0; $i < count($opt["add"]); $i++) {
|
||||
$last = $drbg->generate(strlen($opt["expected"]) / 2,
|
||||
'hex',
|
||||
$opt["add"][$i],
|
||||
'hex');
|
||||
}
|
||||
$this->assertEquals($last, $opt["expected"]);
|
||||
}
|
||||
|
||||
function NISTVector() {
|
||||
$data = json_decode(file_get_contents(__DIR__."/fixtures/hmac-drbg-nist.json"), true);
|
||||
$cases = array();
|
||||
for($i = 0; $i < count($data); ++$i) {
|
||||
$cases[ $data[$i]["name"] ] = [ $data[$i] ];
|
||||
}
|
||||
return $cases;
|
||||
}
|
||||
}
|
||||
104
vendor/simplito/elliptic-php/tests/PointCodecTest.php
vendored
Normal file
104
vendor/simplito/elliptic-php/tests/PointCodecTest.php
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
require_once __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
class PointCodecTest extends \PHPUnit\Framework\TestCase {
|
||||
function makeShortTest($definition) {
|
||||
$curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
|
||||
|
||||
return function() use($curve, $definition) {
|
||||
$co = $definition["coordinates"];
|
||||
$p = $curve->point($co["x"], $co["y"]);
|
||||
|
||||
// Encodes as expected
|
||||
$this->assertEquals($p->encode('hex'), $definition["encoded"]);
|
||||
$this->assertEquals($p->encodeCompressed('hex'), $definition["compactEncoded"]);
|
||||
|
||||
// Decodes as expected
|
||||
$this->assertTrue($curve->decodePoint($definition["encoded"], 'hex')->eq($p));
|
||||
$this->assertTrue($curve->decodePoint($definition["compactEncoded"], 'hex')->eq($p));
|
||||
$this->assertTrue($curve->decodePoint($definition["hybrid"], 'hex')->eq($p));
|
||||
};
|
||||
}
|
||||
|
||||
function makeMontTest($definition) {
|
||||
$curve = \Elliptic\Curves::getCurve("curve25519")->curve;
|
||||
return function() use ($definition, $curve) {
|
||||
$co = $definition["coordinates"];
|
||||
$p = $curve->point($co["x"], $co["z"]);
|
||||
$encoded = $p->encode('hex');
|
||||
$decoded = $curve->decodePoint($encoded, 'hex');
|
||||
$this->assertTrue($decoded->eq($p));
|
||||
$this->assertEquals($encoded, $definition["encoded"]);
|
||||
};
|
||||
}
|
||||
|
||||
static $shortPointEvenY;
|
||||
static $shortPointOddY;
|
||||
|
||||
public function test_should_throw_when_trying_to_decode_random_bytes() {
|
||||
$this->expectException(\Exception::class);
|
||||
\Elliptic\Curves::getCurve("secp256k1")->curve->decodePoint(
|
||||
'05' .
|
||||
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798');
|
||||
}
|
||||
|
||||
public function test_should_be_able_to_encode_and_decode_a_short_curve_point_with_even_Y() {
|
||||
$f = $this->makeShortTest(self::$shortPointEvenY);
|
||||
$f();
|
||||
}
|
||||
|
||||
public function test_should_be_able_to_encode_and_decode_a_short_curve_point_with_odd_Y() {
|
||||
$f = $this->makeShortTest(self::$shortPointOddY);
|
||||
$f();
|
||||
}
|
||||
|
||||
public function test_should_be_able_to_encode_and_decode_a_mont_curve_point() {
|
||||
$f = $this->makeMontTest([
|
||||
"coordinates" => [
|
||||
// curve25519.curve.g.mul(new BN('6')).getX().toString(16, 2)
|
||||
"x" => '26954ccdc99ebf34f8f1dde5e6bb080685fec73640494c28f9fe0bfa8c794531',
|
||||
"z" => '1'
|
||||
],
|
||||
"encoded" =>
|
||||
'26954ccdc99ebf34f8f1dde5e6bb080685fec73640494c28f9fe0bfa8c794531'
|
||||
]);
|
||||
$f();
|
||||
}
|
||||
}
|
||||
|
||||
PointCodecTest::$shortPointEvenY = [
|
||||
"coordinates" => [
|
||||
"x" => '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
|
||||
"y" => '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'
|
||||
],
|
||||
"compactEncoded" =>
|
||||
'02' .
|
||||
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
|
||||
"encoded" =>
|
||||
'04' .
|
||||
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798' .
|
||||
'483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
|
||||
"hybrid" =>
|
||||
'06' .
|
||||
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798' .
|
||||
'483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'
|
||||
];
|
||||
|
||||
|
||||
PointCodecTest::$shortPointOddY = [
|
||||
"coordinates" => [
|
||||
"x" => 'fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556',
|
||||
"y" => 'ae12777aacfbb620f3be96017f45c560de80f0f6518fe4a03c870c36b075f297'
|
||||
],
|
||||
"compactEncoded" =>
|
||||
'03' .
|
||||
'fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556',
|
||||
"encoded" =>
|
||||
'04' .
|
||||
'fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556' .
|
||||
'ae12777aacfbb620f3be96017f45c560de80f0f6518fe4a03c870c36b075f297',
|
||||
"hybrid" =>
|
||||
'07' .
|
||||
'fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556' .
|
||||
'ae12777aacfbb620f3be96017f45c560de80f0f6518fe4a03c870c36b075f297'
|
||||
];
|
||||
3842
vendor/simplito/elliptic-php/tests/fixtures/derivation-fixtures
vendored
Normal file
3842
vendor/simplito/elliptic-php/tests/fixtures/derivation-fixtures
vendored
Normal file
File diff suppressed because it is too large
Load Diff
332
vendor/simplito/elliptic-php/tests/fixtures/hmac-drbg-nist.json
vendored
Normal file
332
vendor/simplito/elliptic-php/tests/fixtures/hmac-drbg-nist.json
vendored
Normal file
@ -0,0 +1,332 @@
|
||||
[
|
||||
{
|
||||
"name": "0",
|
||||
"entropy": "ca851911349384bffe89de1cbdc46e6831e44d34a4fb935ee285dd14b71a7488",
|
||||
"nonce": "659ba96c601dc69fc902940805ec0ca8",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "e528e9abf2dece54d47c7e75e5fe302149f817ea9fb4bee6f4199697d04d5b89d54fbb978a15b5c443c9ec21036d2460b6f73ebad0dc2aba6e624abf07745bc107694bb7547bb0995f70de25d6b29e2d3011bb19d27676c07162c8b5ccde0668961df86803482cb37ed6d5c0bb8d50cf1f50d476aa0458bdaba806f48be9dcb8"
|
||||
},
|
||||
{
|
||||
"name": "1",
|
||||
"entropy": "79737479ba4e7642a221fcfd1b820b134e9e3540a35bb48ffae29c20f5418ea3",
|
||||
"nonce": "3593259c092bef4129bc2c6c9e19f343",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "cf5ad5984f9e43917aa9087380dac46e410ddc8a7731859c84e9d0f31bd43655b924159413e2293b17610f211e09f770f172b8fb693a35b85d3b9e5e63b1dc252ac0e115002e9bedfb4b5b6fd43f33b8e0eafb2d072e1a6fee1f159df9b51e6c8da737e60d5032dd30544ec51558c6f080bdbdab1de8a939e961e06b5f1aca37"
|
||||
},
|
||||
{
|
||||
"name": "2",
|
||||
"entropy": "b340907445b97a8b589264de4a17c0bea11bb53ad72f9f33297f05d2879d898d",
|
||||
"nonce": "65cb27735d83c0708f72684ea58f7ee5",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "75183aaaf3574bc68003352ad655d0e9ce9dd17552723b47fab0e84ef903694a32987eeddbdc48efd24195dbdac8a46ba2d972f5808f23a869e71343140361f58b243e62722088fe10a98e43372d252b144e00c89c215a76a121734bdc485486f65c0b16b8963524a3a70e6f38f169c12f6cbdd169dd48fe4421a235847a23ff"
|
||||
},
|
||||
{
|
||||
"name": "3",
|
||||
"entropy": "8e159f60060a7d6a7e6fe7c9f769c30b98acb1240b25e7ee33f1da834c0858e7",
|
||||
"nonce": "c39d35052201bdcce4e127a04f04d644",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "62910a77213967ea93d6457e255af51fc79d49629af2fccd81840cdfbb4910991f50a477cbd29edd8a47c4fec9d141f50dfde7c4d8fcab473eff3cc2ee9e7cc90871f180777a97841597b0dd7e779eff9784b9cc33689fd7d48c0dcd341515ac8fecf5c55a6327aea8d58f97220b7462373e84e3b7417a57e80ce946d6120db5"
|
||||
},
|
||||
{
|
||||
"name": "4",
|
||||
"entropy": "74755f196305f7fb6689b2fe6835dc1d81484fc481a6b8087f649a1952f4df6a",
|
||||
"nonce": "c36387a544a5f2b78007651a7b74b749",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "b2896f3af4375dab67e8062d82c1a005ef4ed119d13a9f18371b1b873774418684805fd659bfd69964f83a5cfe08667ddad672cafd16befffa9faed49865214f703951b443e6dca22edb636f3308380144b9333de4bcb0735710e4d9266786342fc53babe7bdbe3c01a3addb7f23c63ce2834729fabbd419b47beceb4a460236"
|
||||
},
|
||||
{
|
||||
"name": "5",
|
||||
"entropy": "4b222718f56a3260b3c2625a4cf80950b7d6c1250f170bd5c28b118abdf23b2f",
|
||||
"nonce": "7aed52d0016fcaef0b6492bc40bbe0e9",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "a6da029b3665cd39fd50a54c553f99fed3626f4902ffe322dc51f0670dfe8742ed48415cf04bbad5ed3b23b18b7892d170a7dcf3ef8052d5717cb0c1a8b3010d9a9ea5de70ae5356249c0e098946030c46d9d3d209864539444374d8fbcae068e1d6548fa59e6562e6b2d1acbda8da0318c23752ebc9be0c1c1c5b3cf66dd967"
|
||||
},
|
||||
{
|
||||
"name": "6",
|
||||
"entropy": "b512633f27fb182a076917e39888ba3ff35d23c3742eb8f3c635a044163768e0",
|
||||
"nonce": "e2c39b84629a3de5c301db5643af1c21",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "fb931d0d0194a97b48d5d4c231fdad5c61aedf1c3a55ac24983ecbf38487b1c93396c6b86ff3920cfa8c77e0146de835ea5809676e702dee6a78100da9aa43d8ec0bf5720befa71f82193205ac2ea403e8d7e0e6270b366dc4200be26afd9f63b7e79286a35c688c57cbff55ac747d4c28bb80a2b2097b3b62ea439950d75dff"
|
||||
},
|
||||
{
|
||||
"name": "7",
|
||||
"entropy": "aae3ffc8605a975befefcea0a7a286642bc3b95fb37bd0eb0585a4cabf8b3d1e",
|
||||
"nonce": "9504c3c0c4310c1c0746a036c91d9034",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "2819bd3b0d216dad59ddd6c354c4518153a2b04374b07c49e64a8e4d055575dfbc9a8fcde68bd257ff1ba5c6000564b46d6dd7ecd9c5d684fd757df62d85211575d3562d7814008ab5c8bc00e7b5a649eae2318665b55d762de36eba00c2906c0e0ec8706edb493e51ca5eb4b9f015dc932f262f52a86b11c41e9a6d5b3bd431"
|
||||
},
|
||||
{
|
||||
"name": "8",
|
||||
"entropy": "b9475210b79b87180e746df704b3cbc7bf8424750e416a7fbb5ce3ef25a82cc6",
|
||||
"nonce": "24baf03599c10df6ef44065d715a93f7",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "ae12d784f796183c50db5a1a283aa35ed9a2b685dacea97c596ff8c294906d1b1305ba1f80254eb062b874a8dfffa3378c809ab2869aa51a4e6a489692284a25038908a347342175c38401193b8afc498077e10522bec5c70882b7f760ea5946870bd9fc72961eedbe8bff4fd58c7cc1589bb4f369ed0d3bf26c5bbc62e0b2b2"
|
||||
},
|
||||
{
|
||||
"name": "9",
|
||||
"entropy": "27838eb44ceccb4e36210703ebf38f659bc39dd3277cd76b7a9bcd6bc964b628",
|
||||
"nonce": "39cfe0210db2e7b0eb52a387476e7ea1",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "e5e72a53605d2aaa67832f97536445ab774dd9bff7f13a0d11fd27bf6593bfb52309f2d4f09d147192199ea584503181de87002f4ee085c7dc18bf32ce5315647a3708e6f404d6588c92b2dda599c131aa350d18c747b33dc8eda15cf40e95263d1231e1b4b68f8d829f86054d49cfdb1b8d96ab0465110569c8583a424a099a"
|
||||
},
|
||||
{
|
||||
"name": "10",
|
||||
"entropy": "d7129e4f47008ad60c9b5d081ff4ca8eb821a6e4deb91608bf4e2647835373a5",
|
||||
"nonce": "a72882773f78c2fc4878295840a53012",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "0cbf48585c5de9183b7ff76557f8fc9ebcfdfde07e588a8641156f61b7952725bbee954f87e9b937513b16bba0f2e523d095114658e00f0f3772175acfcb3240a01de631c19c5a834c94cc58d04a6837f0d2782fa53d2f9f65178ee9c837222494c799e64c60406069bd319549b889fa00a0032dd7ba5b1cc9edbf58de82bfcd"
|
||||
},
|
||||
{
|
||||
"name": "11",
|
||||
"entropy": "67fe5e300c513371976c80de4b20d4473889c9f1214bce718bc32d1da3ab7532",
|
||||
"nonce": "e256d88497738a33923aa003a8d7845c",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "b44660d64ef7bcebc7a1ab71f8407a02285c7592d755ae6766059e894f694373ed9c776c0cfc8594413eefb400ed427e158d687e28da3ecc205e0f7370fb089676bbb0fa591ec8d916c3d5f18a3eb4a417120705f3e2198154cd60648dbfcfc901242e15711cacd501b2c2826abe870ba32da785ed6f1fdc68f203d1ab43a64f"
|
||||
},
|
||||
{
|
||||
"name": "12",
|
||||
"entropy": "de8142541255c46d66efc6173b0fe3ffaf5936c897a3ce2e9d5835616aafa2cb",
|
||||
"nonce": "d01f9002c407127bc3297a561d89b81d",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "64d1020929d74716446d8a4e17205d0756b5264867811aa24d0d0da8644db25d5cde474143c57d12482f6bf0f31d10af9d1da4eb6d701bdd605a8db74fb4e77f79aaa9e450afda50b18d19fae68f03db1d7b5f1738d2fdce9ad3ee9461b58ee242daf7a1d72c45c9213eca34e14810a9fca5208d5c56d8066bab1586f1513de7"
|
||||
},
|
||||
{
|
||||
"name": "13",
|
||||
"entropy": "4a8e0bd90bdb12f7748ad5f147b115d7385bb1b06aee7d8b76136a25d779bcb7",
|
||||
"nonce": "7f3cce4af8c8ce3c45bdf23c6b181a00",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "320c7ca4bbeb7af977bc054f604b5086a3f237aa5501658112f3e7a33d2231f5536d2c85c1dad9d9b0bf7f619c81be4854661626839c8c10ae7fdc0c0b571be34b58d66da553676167b00e7d8e49f416aacb2926c6eb2c66ec98bffae20864cf92496db15e3b09e530b7b9648be8d3916b3c20a3a779bec7d66da63396849aaf"
|
||||
},
|
||||
{
|
||||
"name": "14",
|
||||
"entropy": "451ed024bc4b95f1025b14ec3616f5e42e80824541dc795a2f07500f92adc665",
|
||||
"nonce": "2f28e6ee8de5879db1eccd58c994e5f0",
|
||||
"pers": null,
|
||||
"add": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"expected": "3fb637085ab75f4e95655faae95885166a5fbb423bb03dbf0543be063bcd48799c4f05d4e522634d9275fe02e1edd920e26d9accd43709cb0d8f6e50aa54a5f3bdd618be23cf73ef736ed0ef7524b0d14d5bef8c8aec1cf1ed3e1c38a808b35e61a44078127c7cb3a8fd7addfa50fcf3ff3bc6d6bc355d5436fe9b71eb44f7fd"
|
||||
},
|
||||
{
|
||||
"name": "0 with additional data",
|
||||
"entropy": "d3cc4d1acf3dde0c4bd2290d262337042dc632948223d3a2eaab87da44295fbd",
|
||||
"nonce": "0109b0e729f457328aa18569a9224921",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"3c311848183c9a212a26f27f8c6647e40375e466a0857cc39c4e47575d53f1f6",
|
||||
"fcb9abd19ccfbccef88c9c39bfb3dd7b1c12266c9808992e305bc3cff566e4e4"
|
||||
],
|
||||
"expected": "9c7b758b212cd0fcecd5daa489821712e3cdea4467b560ef5ddc24ab47749a1f1ffdbbb118f4e62fcfca3371b8fbfc5b0646b83e06bfbbab5fac30ea09ea2bc76f1ea568c9be0444b2cc90517b20ca825f2d0eccd88e7175538b85d90ab390183ca6395535d34473af6b5a5b88f5a59ee7561573337ea819da0dcc3573a22974"
|
||||
},
|
||||
{
|
||||
"name": "1 with additional data",
|
||||
"entropy": "f97a3cfd91faa046b9e61b9493d436c4931f604b22f1081521b3419151e8ff06",
|
||||
"nonce": "11f3a7d43595357d58120bd1e2dd8aed",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"517289afe444a0fe5ed1a41dbbb5eb17150079bdd31e29cf2ff30034d8268e3b",
|
||||
"88028d29ef80b4e6f0fe12f91d7449fe75062682e89c571440c0c9b52c42a6e0"
|
||||
],
|
||||
"expected": "c6871cff0824fe55ea7689a52229886730450e5d362da5bf590dcf9acd67fed4cb32107df5d03969a66b1f6494fdf5d63d5b4d0d34ea7399a07d0116126d0d518c7c55ba46e12f62efc8fe28a51c9d428e6d371d7397ab319fc73ded4722e5b4f30004032a6128df5e7497ecf82ca7b0a50e867ef6728a4f509a8c859087039c"
|
||||
},
|
||||
{
|
||||
"name": "2 with additional data",
|
||||
"entropy": "0f2f23d64f481cabec7abb01db3aabf125c3173a044b9bf26844300b69dcac8b",
|
||||
"nonce": "9a5ae13232b43aa19cfe8d7958b4b590",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"ec4c7a62acab73385f567da10e892ff395a0929f959231a5628188ce0c26e818",
|
||||
"6b97b8c6b6bb8935e676c410c17caa8042aa3145f856d0a32b641e4ae5298648"
|
||||
],
|
||||
"expected": "7480a361058bd9afa3db82c9d7586e42269102013f6ec5c269b6d05f17987847748684766b44918fd4b65e1648622fc0e0954178b0279dfc9fa99b66c6f53e51c4860131e9e0644287a4afe4ca8e480417e070db68008a97c3397e4b320b5d1a1d7e1d18a95cfedd7d1e74997052bf649d132deb9ec53aae7dafdab55e6dae93"
|
||||
},
|
||||
{
|
||||
"name": "3 with additional data",
|
||||
"entropy": "53c56660c78481be9c63284e005fcc14fbc7fb27732c9bf1366d01a426765a31",
|
||||
"nonce": "dc7a14d0eb5b0b3534e717a0b3c64614",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"3aa848706ecb877f5bedf4ffc332d57c22e08747a47e75cff6f0fd1316861c95",
|
||||
"9a401afa739b8f752fddacd291e0b854f5eff4a55b515e20cb319852189d3722"
|
||||
],
|
||||
"expected": "5c0eb420e0bf41ce9323e815310e4e8303cd677a8a8b023f31f0d79f0ca15aeb636099a369fd074d69889865eac1b72ab3cbfebdb8cf460b00072802e2ec648b1349a5303be4ccaadd729f1a9ea17482fd026aaeb93f1602bc1404b9853adde40d6c34b844cf148bc088941ecfc1642c8c0b9778e45f3b07e06e21ee2c9e0300"
|
||||
},
|
||||
{
|
||||
"name": "4 with additional data",
|
||||
"entropy": "f63c804404902db334c54bb298fc271a21d7acd9f770278e089775710bf4fdd7",
|
||||
"nonce": "3e45009ea9cb2a36ba1aa4bf39178200",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"d165a13dc8cc43f3f0952c3f5d3de4136954d983683d4a3e6d2dc4c89bf23423",
|
||||
"75106bc86d0336df85097f6af8e80e2da59046a03fa65b06706b8bbc7ffc6785"
|
||||
],
|
||||
"expected": "6363139bba32c22a0f5cd23ca6d437b5669b7d432f786b8af445471bee0b2d24c9d5f2f93717cbe00d1f010cc3b9c515fc9f7336d53d4d26ba5c0d76a90186663c8582eb739c7b6578a3328bf68dc2cec2cd89b3a90201f6993adcc854df0f5c6974d0f5570765a15fe03dbce28942dd2fd16ba2027e68abac83926969349af8"
|
||||
},
|
||||
{
|
||||
"name": "5 with additional data",
|
||||
"entropy": "2aaca9147da66c176615726b69e3e851cc3537f5f279fe7344233d8e44cfc99d",
|
||||
"nonce": "4e171f080af9a6081bee9f183ac9e340",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"d75a2a6eb66c3833e50f5ec3d2e434cf791448d618026d0c360806d120ded669",
|
||||
"b643b74c15b37612e6577ed7ca2a4c67a78d560af9eb50a4108fca742e87b8d6"
|
||||
],
|
||||
"expected": "501dcdc977f4ba856f24eaa4968b374bebb3166b280334cb510232c31ebffde10fa47b7840ef3fe3b77725c2272d3a1d4219baf23e0290c622271edcced58838cf428f0517425d2e19e0d8c89377eecfc378245f283236fafa466c914b99672ceafab369e8889a0c866d8bd639db9fb797254262c6fd44cfa9045ad6340a60ef"
|
||||
},
|
||||
{
|
||||
"name": "6 with additional data",
|
||||
"entropy": "a2e4cd48a5cf918d6f55942d95fcb4e8465cdc4f77b7c52b6fae5b16a25ca306",
|
||||
"nonce": "bef036716440db6e6d333d9d760b7ca8",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"bfa591c7287f3f931168f95e38869441d1f9a11035ad8ea625bb61b9ea17591c",
|
||||
"c00c735463bca215adc372cb892b05e939bf669583341c06d4e31d0e5b363a37"
|
||||
],
|
||||
"expected": "e7d136af69926a5421d4266ee0420fd729f2a4f7c295d3c966bdfa05268180b508b8a2852d1b3a06fd2ab3e13c54005123ef319f42d0c6d3a575e6e7e1496cb28aacadbcf83740fba8f35fcee04bb2ed8a51db3d3362b01094a62fb57e33c99a432f29fce6676cffbbcc05107e794e75e44a02d5e6d9d748c5fbff00a0178d65"
|
||||
},
|
||||
{
|
||||
"name": "7 with additional data",
|
||||
"entropy": "95a67771cba69011a79776e713145d309edae56fad5fd6d41d83eaff89df6e5e",
|
||||
"nonce": "be5b5164e31ecc51ba6f7c3c5199eb33",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"065f693b229a7c4fd373cd15b3807552dd9bf98c5485cef361949d4e7d774b53",
|
||||
"9afb62406f0e812c4f156d58b19a656c904813c1b4a45a0029ae7f50731f8014"
|
||||
],
|
||||
"expected": "f61b61a6e79a41183e8ed6647899d2dc85cdaf5c3abf5c7f3bf37685946dc28f4923dc842f2d4326bd6ce0d50a84cb3ba869d72a36e246910eba6512ba36cd7ed3a5437c9245b00a344308c792b668b458d3c3e16dee2fbec41867da31084d46d8ec168de2148ef64fc5b72069abf5a6ada1ead2b7146bb793ff1c9c3690fa56"
|
||||
},
|
||||
{
|
||||
"name": "8 with additional data",
|
||||
"entropy": "a459e1815cbca4514ec8094d5ab2414a557ba6fe10e613c345338d0521e4bf90",
|
||||
"nonce": "62221392e2552e76cd0d36df6e6068eb",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"0a3642b02b23b3ef62c701a63401124022f5b896de86dab6e6c7451497aa1dcc",
|
||||
"c80514865901371c45ba92d9f95d50bb7c9dd1768cb3dfbc45b968da94965c6e"
|
||||
],
|
||||
"expected": "464e6977b8adaef307c9623e41c357013249c9ffd77f405f3925cebb69f151ce8fbb6a277164002aee7858fc224f6499042aa1e6322deee9a5d133c31d640e12a7487c731ba03ad866a24675badb1d79220c40be689f79c2a0be93cb4dada3e0eac4ab140cb91998b6f11953e68f2319b050c40f71c34de9905ae41b2de1c2f6"
|
||||
},
|
||||
{
|
||||
"name": "9 with additional data",
|
||||
"entropy": "252c2cad613e002478162861880979ee4e323025eebb6fb2e0aa9f200e28e0a1",
|
||||
"nonce": "d001bc9a8f2c8c242e4369df0c191989",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"9bcfc61cb2bc000034bb3db980eb47c76fb5ecdd40553eff113368d639b947fd",
|
||||
"8b0565c767c2610ee0014582e9fbecb96e173005b60e9581503a6dca5637a26e"
|
||||
],
|
||||
"expected": "e96c15fe8a60692b0a7d67171e0195ff6e1c87aab844221e71700d1bbee75feea695f6a740c9760bbe0e812ecf4061d8f0955bc0195e18c4fd1516ebca50ba6a6db86881737dbab8321707675479b87611db6af2c97ea361a5484555ead454defb1a64335de964fc803d40f3a6f057893d2afc25725754f4f00abc51920743dc"
|
||||
},
|
||||
{
|
||||
"name": "10 with additional data",
|
||||
"entropy": "8be0ca6adc8b3870c9d69d6021bc1f1d8eb9e649073d35ee6c5aa0b7e56ad8a5",
|
||||
"nonce": "9d1265f7d51fdb65377f1e6edd6ae0e4",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"da86167ac997c406bb7979f423986a84ec6614d6caa7afc10aff0699a9b2cf7f",
|
||||
"e4baa3c555950b53e2bfdba480cb4c94b59381bac1e33947e0c22e838a9534cf"
|
||||
],
|
||||
"expected": "64384ecc4ea6b458efc227ca697eac5510092265520c0a0d8a0ccf9ed3ca9d58074671188c6a7ad16d0b050cdc072c125d7298d3a31d9f044a9ee40da0089a84fea28cc7f05f1716db952fad29a0e779635cb7a912a959be67be2f0a4170aace2981802e2ff6467e5b46f0ffbff3b42ba5935fd553c82482ac266acf1cd247d7"
|
||||
},
|
||||
{
|
||||
"name": "11 with additional data",
|
||||
"entropy": "d43a75b6adf26d60322284cb12ac38327792442aa8f040f60a2f331b33ac4a8f",
|
||||
"nonce": "0682f8b091f811afacaacaec9b04d279",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"7fd3b8f512940da7de5d80199d9a7b42670c04a945775a3dba869546cbb9bc65",
|
||||
"2575db20bc7aafc2a90a5dabab760db851d754777bc9f05616af1858b24ff3da"
|
||||
],
|
||||
"expected": "0da7a8dc73c163014bf0841913d3067806456bbca6d5de92b85534c6545467313648d71ef17c923d090dc92cff8d4d1a9a2bb63e001dc2e8ab1a597999be3d6cf70ff63fee9985801395fbd4f4990430c4259fcae4fa1fcd73dc3187ccc102d04af7c07532885e5a226fc42809c48f22eecf4f6ab996ae4fcb144786957d9f41"
|
||||
},
|
||||
{
|
||||
"name": "12 with additional data",
|
||||
"entropy": "64352f236af5d32067a529a8fd05ba00a338c9de306371a0b00c36e610a48d18",
|
||||
"nonce": "df99ed2c7608c870624b962a5dc68acd",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"da416335e7aaf60cf3d06fb438735ce796aad09034f8969c8f8c3f81e32fef24",
|
||||
"a28c07c21a2297311adf172c19e83ca0a87731bdffb80548978d2d1cd82cf8a3"
|
||||
],
|
||||
"expected": "132b9f25868729e3853d3c51f99a3b5fae6d4204bea70890daf62e042b776a526c8fb831b80a6d5d3f153237df1fd39b6fd9137963f5516d9cdd4e3f9195c46e9972c15d3edc6606e3368bde1594977fb88d0ca6e6f5f3d057ccadc7d7dab77dfc42658a1e972aa446b20d418286386a52dfc1c714d2ac548713268b0b709729"
|
||||
},
|
||||
{
|
||||
"name": "13 with additional data",
|
||||
"entropy": "282f4d2e05a2cd30e9087f5633089389449f04bac11df718c90bb351cd3653a5",
|
||||
"nonce": "90a7daf3c0de9ea286081efc4a684dfb",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"2630b4ccc7271cc379cb580b0aaede3d3aa8c1c7ba002cf791f0752c3d739007",
|
||||
"c31d69de499f1017be44e3d4fa77ecebc6a9b9934749fcf136f267b29115d2cc"
|
||||
],
|
||||
"expected": "c899094520e0197c37b91dd50778e20a5b950decfb308d39f1db709447ae48f6101d9abe63a783fbb830eec1d359a5f61a2013728966d349213ee96382614aa4135058a967627183810c6622a2158cababe3b8ab99169c89e362108bf5955b4ffc47440f87e4bad0d36bc738e737e072e64d8842e7619f1be0af1141f05afe2d"
|
||||
},
|
||||
{
|
||||
"name": "14 with additional data",
|
||||
"entropy": "13c752b9e745ce77bbc7c0dbda982313d3fe66f903e83ebd8dbe4ff0c11380e9",
|
||||
"nonce": "f1a533095d6174164bd7c82532464ae7",
|
||||
"pers": null,
|
||||
"add": [
|
||||
"4f53db89b9ba7fc00767bc751fb8f3c103fe0f76acd6d5c7891ab15b2b7cf67c",
|
||||
"582c2a7d34679088cca6bd28723c99aac07db46c332dc0153d1673256903b446"
|
||||
],
|
||||
"expected": "6311f4c0c4cd1f86bd48349abb9eb930d4f63df5e5f7217d1d1b91a71d8a6938b0ad2b3e897bd7e3d8703db125fab30e03464fad41e5ddf5bf9aeeb5161b244468cfb26a9d956931a5412c97d64188b0da1bd907819c686f39af82e91cfeef0cbffb5d1e229e383bed26d06412988640706815a6e820796876f416653e464961"
|
||||
}
|
||||
]
|
||||
1024
vendor/simplito/elliptic-php/tests/fixtures/sign.input
vendored
Normal file
1024
vendor/simplito/elliptic-php/tests/fixtures/sign.input
vendored
Normal file
File diff suppressed because it is too large
Load Diff
19
vendor/symfony/polyfill-mbstring/LICENSE
vendored
Normal file
19
vendor/symfony/polyfill-mbstring/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015-present Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
1045
vendor/symfony/polyfill-mbstring/Mbstring.php
vendored
Normal file
1045
vendor/symfony/polyfill-mbstring/Mbstring.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
13
vendor/symfony/polyfill-mbstring/README.md
vendored
Normal file
13
vendor/symfony/polyfill-mbstring/README.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
Symfony Polyfill / Mbstring
|
||||
===========================
|
||||
|
||||
This component provides a partial, native PHP implementation for the
|
||||
[Mbstring](https://php.net/mbstring) extension.
|
||||
|
||||
More information can be found in the
|
||||
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
This library is released under the [MIT license](LICENSE).
|
||||
119
vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php
vendored
Normal file
119
vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'İ' => 'i̇',
|
||||
'µ' => 'μ',
|
||||
'ſ' => 's',
|
||||
'ͅ' => 'ι',
|
||||
'ς' => 'σ',
|
||||
'ϐ' => 'β',
|
||||
'ϑ' => 'θ',
|
||||
'ϕ' => 'φ',
|
||||
'ϖ' => 'π',
|
||||
'ϰ' => 'κ',
|
||||
'ϱ' => 'ρ',
|
||||
'ϵ' => 'ε',
|
||||
'ẛ' => 'ṡ',
|
||||
'ι' => 'ι',
|
||||
'ß' => 'ss',
|
||||
'ʼn' => 'ʼn',
|
||||
'ǰ' => 'ǰ',
|
||||
'ΐ' => 'ΐ',
|
||||
'ΰ' => 'ΰ',
|
||||
'և' => 'եւ',
|
||||
'ẖ' => 'ẖ',
|
||||
'ẗ' => 'ẗ',
|
||||
'ẘ' => 'ẘ',
|
||||
'ẙ' => 'ẙ',
|
||||
'ẚ' => 'aʾ',
|
||||
'ẞ' => 'ss',
|
||||
'ὐ' => 'ὐ',
|
||||
'ὒ' => 'ὒ',
|
||||
'ὔ' => 'ὔ',
|
||||
'ὖ' => 'ὖ',
|
||||
'ᾀ' => 'ἀι',
|
||||
'ᾁ' => 'ἁι',
|
||||
'ᾂ' => 'ἂι',
|
||||
'ᾃ' => 'ἃι',
|
||||
'ᾄ' => 'ἄι',
|
||||
'ᾅ' => 'ἅι',
|
||||
'ᾆ' => 'ἆι',
|
||||
'ᾇ' => 'ἇι',
|
||||
'ᾈ' => 'ἀι',
|
||||
'ᾉ' => 'ἁι',
|
||||
'ᾊ' => 'ἂι',
|
||||
'ᾋ' => 'ἃι',
|
||||
'ᾌ' => 'ἄι',
|
||||
'ᾍ' => 'ἅι',
|
||||
'ᾎ' => 'ἆι',
|
||||
'ᾏ' => 'ἇι',
|
||||
'ᾐ' => 'ἠι',
|
||||
'ᾑ' => 'ἡι',
|
||||
'ᾒ' => 'ἢι',
|
||||
'ᾓ' => 'ἣι',
|
||||
'ᾔ' => 'ἤι',
|
||||
'ᾕ' => 'ἥι',
|
||||
'ᾖ' => 'ἦι',
|
||||
'ᾗ' => 'ἧι',
|
||||
'ᾘ' => 'ἠι',
|
||||
'ᾙ' => 'ἡι',
|
||||
'ᾚ' => 'ἢι',
|
||||
'ᾛ' => 'ἣι',
|
||||
'ᾜ' => 'ἤι',
|
||||
'ᾝ' => 'ἥι',
|
||||
'ᾞ' => 'ἦι',
|
||||
'ᾟ' => 'ἧι',
|
||||
'ᾠ' => 'ὠι',
|
||||
'ᾡ' => 'ὡι',
|
||||
'ᾢ' => 'ὢι',
|
||||
'ᾣ' => 'ὣι',
|
||||
'ᾤ' => 'ὤι',
|
||||
'ᾥ' => 'ὥι',
|
||||
'ᾦ' => 'ὦι',
|
||||
'ᾧ' => 'ὧι',
|
||||
'ᾨ' => 'ὠι',
|
||||
'ᾩ' => 'ὡι',
|
||||
'ᾪ' => 'ὢι',
|
||||
'ᾫ' => 'ὣι',
|
||||
'ᾬ' => 'ὤι',
|
||||
'ᾭ' => 'ὥι',
|
||||
'ᾮ' => 'ὦι',
|
||||
'ᾯ' => 'ὧι',
|
||||
'ᾲ' => 'ὰι',
|
||||
'ᾳ' => 'αι',
|
||||
'ᾴ' => 'άι',
|
||||
'ᾶ' => 'ᾶ',
|
||||
'ᾷ' => 'ᾶι',
|
||||
'ᾼ' => 'αι',
|
||||
'ῂ' => 'ὴι',
|
||||
'ῃ' => 'ηι',
|
||||
'ῄ' => 'ήι',
|
||||
'ῆ' => 'ῆ',
|
||||
'ῇ' => 'ῆι',
|
||||
'ῌ' => 'ηι',
|
||||
'ῒ' => 'ῒ',
|
||||
'ῖ' => 'ῖ',
|
||||
'ῗ' => 'ῗ',
|
||||
'ῢ' => 'ῢ',
|
||||
'ῤ' => 'ῤ',
|
||||
'ῦ' => 'ῦ',
|
||||
'ῧ' => 'ῧ',
|
||||
'ῲ' => 'ὼι',
|
||||
'ῳ' => 'ωι',
|
||||
'ῴ' => 'ώι',
|
||||
'ῶ' => 'ῶ',
|
||||
'ῷ' => 'ῶι',
|
||||
'ῼ' => 'ωι',
|
||||
'ff' => 'ff',
|
||||
'fi' => 'fi',
|
||||
'fl' => 'fl',
|
||||
'ffi' => 'ffi',
|
||||
'ffl' => 'ffl',
|
||||
'ſt' => 'st',
|
||||
'st' => 'st',
|
||||
'ﬓ' => 'մն',
|
||||
'ﬔ' => 'մե',
|
||||
'ﬕ' => 'մի',
|
||||
'ﬖ' => 'վն',
|
||||
'ﬗ' => 'մխ',
|
||||
];
|
||||
1397
vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
vendored
Normal file
1397
vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
vendored
Normal file
5
vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
vendored
Normal file
File diff suppressed because one or more lines are too long
1489
vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php
vendored
Normal file
1489
vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
172
vendor/symfony/polyfill-mbstring/bootstrap.php
vendored
Normal file
172
vendor/symfony/polyfill-mbstring/bootstrap.php
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Polyfill\Mbstring as p;
|
||||
|
||||
if (\PHP_VERSION_ID >= 80000) {
|
||||
return require __DIR__.'/bootstrap80.php';
|
||||
}
|
||||
|
||||
if (!function_exists('mb_convert_encoding')) {
|
||||
function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); }
|
||||
}
|
||||
if (!function_exists('mb_decode_mimeheader')) {
|
||||
function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); }
|
||||
}
|
||||
if (!function_exists('mb_encode_mimeheader')) {
|
||||
function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); }
|
||||
}
|
||||
if (!function_exists('mb_decode_numericentity')) {
|
||||
function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_encode_numericentity')) {
|
||||
function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); }
|
||||
}
|
||||
if (!function_exists('mb_convert_case')) {
|
||||
function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_internal_encoding')) {
|
||||
function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); }
|
||||
}
|
||||
if (!function_exists('mb_language')) {
|
||||
function mb_language($language = null) { return p\Mbstring::mb_language($language); }
|
||||
}
|
||||
if (!function_exists('mb_list_encodings')) {
|
||||
function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
|
||||
}
|
||||
if (!function_exists('mb_encoding_aliases')) {
|
||||
function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
|
||||
}
|
||||
if (!function_exists('mb_check_encoding')) {
|
||||
function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_detect_encoding')) {
|
||||
function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); }
|
||||
}
|
||||
if (!function_exists('mb_detect_order')) {
|
||||
function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); }
|
||||
}
|
||||
if (!function_exists('mb_parse_str')) {
|
||||
function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; }
|
||||
}
|
||||
if (!function_exists('mb_strlen')) {
|
||||
function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strpos')) {
|
||||
function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strtolower')) {
|
||||
function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strtoupper')) {
|
||||
function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_substitute_character')) {
|
||||
function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); }
|
||||
}
|
||||
if (!function_exists('mb_substr')) {
|
||||
function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_stripos')) {
|
||||
function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_stristr')) {
|
||||
function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strrchr')) {
|
||||
function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strrichr')) {
|
||||
function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strripos')) {
|
||||
function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strrpos')) {
|
||||
function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strstr')) {
|
||||
function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_get_info')) {
|
||||
function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
|
||||
}
|
||||
if (!function_exists('mb_http_output')) {
|
||||
function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strwidth')) {
|
||||
function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_substr_count')) {
|
||||
function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_output_handler')) {
|
||||
function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); }
|
||||
}
|
||||
if (!function_exists('mb_http_input')) {
|
||||
function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_convert_variables')) {
|
||||
function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ord')) {
|
||||
function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_chr')) {
|
||||
function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_scrub')) {
|
||||
function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_str_split')) {
|
||||
function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_str_pad')) {
|
||||
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ucfirst')) {
|
||||
function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_lcfirst')) {
|
||||
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_trim')) {
|
||||
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ltrim')) {
|
||||
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_rtrim')) {
|
||||
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); }
|
||||
}
|
||||
|
||||
|
||||
if (extension_loaded('mbstring')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined('MB_CASE_UPPER')) {
|
||||
define('MB_CASE_UPPER', 0);
|
||||
}
|
||||
if (!defined('MB_CASE_LOWER')) {
|
||||
define('MB_CASE_LOWER', 1);
|
||||
}
|
||||
if (!defined('MB_CASE_TITLE')) {
|
||||
define('MB_CASE_TITLE', 2);
|
||||
}
|
||||
167
vendor/symfony/polyfill-mbstring/bootstrap80.php
vendored
Normal file
167
vendor/symfony/polyfill-mbstring/bootstrap80.php
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Polyfill\Mbstring as p;
|
||||
|
||||
if (!function_exists('mb_convert_encoding')) {
|
||||
function mb_convert_encoding(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null): array|string|false { return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); }
|
||||
}
|
||||
if (!function_exists('mb_decode_mimeheader')) {
|
||||
function mb_decode_mimeheader(?string $string): string { return p\Mbstring::mb_decode_mimeheader((string) $string); }
|
||||
}
|
||||
if (!function_exists('mb_encode_mimeheader')) {
|
||||
function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); }
|
||||
}
|
||||
if (!function_exists('mb_decode_numericentity')) {
|
||||
function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null): string { return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_encode_numericentity')) {
|
||||
function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = false): string { return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); }
|
||||
}
|
||||
if (!function_exists('mb_convert_case')) {
|
||||
function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null): string { return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_internal_encoding')) {
|
||||
function mb_internal_encoding(?string $encoding = null): string|bool { return p\Mbstring::mb_internal_encoding($encoding); }
|
||||
}
|
||||
if (!function_exists('mb_language')) {
|
||||
function mb_language(?string $language = null): string|bool { return p\Mbstring::mb_language($language); }
|
||||
}
|
||||
if (!function_exists('mb_list_encodings')) {
|
||||
function mb_list_encodings(): array { return p\Mbstring::mb_list_encodings(); }
|
||||
}
|
||||
if (!function_exists('mb_encoding_aliases')) {
|
||||
function mb_encoding_aliases(?string $encoding): array { return p\Mbstring::mb_encoding_aliases((string) $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_check_encoding')) {
|
||||
function mb_check_encoding(array|string|null $value = null, ?string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_detect_encoding')) {
|
||||
function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); }
|
||||
}
|
||||
if (!function_exists('mb_detect_order')) {
|
||||
function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order($encoding); }
|
||||
}
|
||||
if (!function_exists('mb_parse_str')) {
|
||||
function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); return (bool) $result; }
|
||||
}
|
||||
if (!function_exists('mb_strlen')) {
|
||||
function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strpos')) {
|
||||
function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strtolower')) {
|
||||
function mb_strtolower(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtolower((string) $string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strtoupper')) {
|
||||
function mb_strtoupper(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtoupper((string) $string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_substitute_character')) {
|
||||
function mb_substitute_character(string|int|null $substitute_character = null): string|int|bool { return p\Mbstring::mb_substitute_character($substitute_character); }
|
||||
}
|
||||
if (!function_exists('mb_substr')) {
|
||||
function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null): string { return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_stripos')) {
|
||||
function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_stristr')) {
|
||||
function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strrchr')) {
|
||||
function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strrichr')) {
|
||||
function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strripos')) {
|
||||
function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strrpos')) {
|
||||
function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strstr')) {
|
||||
function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_get_info')) {
|
||||
function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); }
|
||||
}
|
||||
if (!function_exists('mb_http_output')) {
|
||||
function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); }
|
||||
}
|
||||
if (!function_exists('mb_strwidth')) {
|
||||
function mb_strwidth(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strwidth((string) $string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_substr_count')) {
|
||||
function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null): int { return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_output_handler')) {
|
||||
function mb_output_handler(?string $string, ?int $status): string { return p\Mbstring::mb_output_handler((string) $string, (int) $status); }
|
||||
}
|
||||
if (!function_exists('mb_http_input')) {
|
||||
function mb_http_input(?string $type = null): array|string|false { return p\Mbstring::mb_http_input($type); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_convert_variables')) {
|
||||
function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars): string|false { return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ord')) {
|
||||
function mb_ord(?string $string, ?string $encoding = null): int|false { return p\Mbstring::mb_ord((string) $string, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_chr')) {
|
||||
function mb_chr(?int $codepoint, ?string $encoding = null): string|false { return p\Mbstring::mb_chr((int) $codepoint, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_scrub')) {
|
||||
function mb_scrub(?string $string, ?string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); }
|
||||
}
|
||||
if (!function_exists('mb_str_split')) {
|
||||
function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_str_pad')) {
|
||||
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ucfirst')) {
|
||||
function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_lcfirst')) {
|
||||
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_trim')) {
|
||||
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ltrim')) {
|
||||
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_rtrim')) {
|
||||
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); }
|
||||
}
|
||||
|
||||
if (extension_loaded('mbstring')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined('MB_CASE_UPPER')) {
|
||||
define('MB_CASE_UPPER', 0);
|
||||
}
|
||||
if (!defined('MB_CASE_LOWER')) {
|
||||
define('MB_CASE_LOWER', 1);
|
||||
}
|
||||
if (!defined('MB_CASE_TITLE')) {
|
||||
define('MB_CASE_TITLE', 2);
|
||||
}
|
||||
39
vendor/symfony/polyfill-mbstring/composer.json
vendored
Normal file
39
vendor/symfony/polyfill-mbstring/composer.json
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"type": "library",
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-iconv": "*"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" },
|
||||
"files": [ "bootstrap.php" ]
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
}
|
||||
}
|
||||
30
vendor/workerman/globaldata/README.md
vendored
Normal file
30
vendor/workerman/globaldata/README.md
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
# GlobalData
|
||||
进程间数据共享组件,用于分布式数据共享。服务端基于[Workerman](https://github.com/walkor/Workerman)。客户端可用于任何PHP项目。
|
||||
|
||||
# 服务端
|
||||
```php
|
||||
use Workerman\Worker;
|
||||
require_once __DIR__ . '/../../Workerman/Autoloader.php';
|
||||
require_once __DIR__ . '/../src/Server.php';
|
||||
|
||||
$worker = new GlobalData\Server('127.0.0.1', 2207);
|
||||
|
||||
Worker::runAll();
|
||||
```
|
||||
|
||||
# 客户端
|
||||
```php
|
||||
require_once __DIR__ . '/../src/Client.php';
|
||||
|
||||
$global = new GlobalData\Client('127.0.0.1:2207');
|
||||
|
||||
var_export(isset($global->abc));
|
||||
$global->abc = array(1,2,3);
|
||||
var_export($global->abc);
|
||||
unset($global->abc);
|
||||
var_export($global->abc);
|
||||
$global->abc = array(1,2,3);
|
||||
var_export($global->abc);
|
||||
var_export($global->cas('abc', array(1,2,3), array(5,6,7)));
|
||||
var_export($global->abc);
|
||||
```
|
||||
12
vendor/workerman/globaldata/composer.json
vendored
Normal file
12
vendor/workerman/globaldata/composer.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name" : "workerman/globaldata",
|
||||
"type" : "library",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"license" : "MIT",
|
||||
"require": {
|
||||
"workerman/workerman" : ">=3.3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {"GlobalData\\": "./src"}
|
||||
}
|
||||
}
|
||||
251
vendor/workerman/globaldata/src/Client.php
vendored
Normal file
251
vendor/workerman/globaldata/src/Client.php
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
<?php
|
||||
namespace GlobalData;
|
||||
/**
|
||||
* Global data client.
|
||||
* @version 1.0.3
|
||||
*/
|
||||
class Client
|
||||
{
|
||||
/**
|
||||
* Timeout.
|
||||
* @var int
|
||||
*/
|
||||
public $timeout = 5;
|
||||
|
||||
/**
|
||||
* Heartbeat interval.
|
||||
* @var int
|
||||
*/
|
||||
public $pingInterval = 25;
|
||||
|
||||
/**
|
||||
* Global data server address.
|
||||
* @var array
|
||||
*/
|
||||
protected $_globalServers = array();
|
||||
|
||||
/**
|
||||
* Connection to global server.
|
||||
* @var resource
|
||||
*/
|
||||
protected $_globalConnections = null;
|
||||
|
||||
/**
|
||||
* Cache.
|
||||
* @var array
|
||||
*/
|
||||
protected $_cache = array();
|
||||
|
||||
/**
|
||||
* Construct.
|
||||
* @param array | string $servers
|
||||
*/
|
||||
public function __construct($servers)
|
||||
{
|
||||
if(empty($servers))
|
||||
{
|
||||
throw new \Exception('servers empty');
|
||||
}
|
||||
$this->_globalServers = array_values((array)$servers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to global server.
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getConnection($key)
|
||||
{
|
||||
$offset = crc32($key)%count($this->_globalServers);
|
||||
if($offset < 0)
|
||||
{
|
||||
$offset = -$offset;
|
||||
}
|
||||
|
||||
if(!isset($this->_globalConnections[$offset]) || !is_resource($this->_globalConnections[$offset]) || feof($this->_globalConnections[$offset]))
|
||||
{
|
||||
$address = $this->_globalServers[$offset];
|
||||
if(strpos($address,'unix://')!==0){
|
||||
$address = "tcp://{$address}";
|
||||
}
|
||||
|
||||
$connection = stream_socket_client($address, $code, $msg, $this->timeout);
|
||||
if(!$connection)
|
||||
{
|
||||
throw new \Exception($msg);
|
||||
}
|
||||
stream_set_timeout($connection, $this->timeout);
|
||||
if(class_exists('\Workerman\Timer') && php_sapi_name() === 'cli')
|
||||
{
|
||||
$timer_id = \Workerman\Timer::add($this->pingInterval, function($connection)use(&$timer_id)
|
||||
{
|
||||
$buffer = pack('N', 8)."ping";
|
||||
if(strlen($buffer) !== @fwrite($connection, $buffer))
|
||||
{
|
||||
@fclose($connection);
|
||||
\Workerman\Timer::del($timer_id);
|
||||
}
|
||||
}, array($connection));
|
||||
}
|
||||
$this->_globalConnections[$offset] = $connection;
|
||||
}
|
||||
return $this->_globalConnections[$offset];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Magic methods __set.
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __set($key, $value)
|
||||
{
|
||||
$connection = $this->getConnection($key);
|
||||
$this->writeToRemote(array(
|
||||
'cmd' => 'set',
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
), $connection);
|
||||
$this->readFromRemote($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic methods __isset.
|
||||
* @param string $key
|
||||
*/
|
||||
public function __isset($key)
|
||||
{
|
||||
return null !== $this->__get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic methods __unset.
|
||||
* @param string $key
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
$connection = $this->getConnection($key);
|
||||
$this->writeToRemote(array(
|
||||
'cmd' => 'delete',
|
||||
'key' => $key
|
||||
), $connection);
|
||||
$this->readFromRemote($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic methods __get.
|
||||
* @param string $key
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
$connection = $this->getConnection($key);
|
||||
$this->writeToRemote(array(
|
||||
'cmd' => 'get',
|
||||
'key' => $key,
|
||||
), $connection);
|
||||
return $this->readFromRemote($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cas.
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function cas($key, $old_value, $new_value)
|
||||
{
|
||||
$connection = $this->getConnection($key);
|
||||
$this->writeToRemote(array(
|
||||
'cmd' => 'cas',
|
||||
'md5' => md5(serialize($old_value)),
|
||||
'key' => $key,
|
||||
'value' => $new_value,
|
||||
),$connection);
|
||||
return $this->readFromRemote($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add.
|
||||
* @param string $key
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function add($key, $value)
|
||||
{
|
||||
$connection = $this->getConnection($key);
|
||||
$this->writeToRemote(array(
|
||||
'cmd' => 'add',
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
), $connection);
|
||||
return $this->readFromRemote($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment.
|
||||
* @param string $key
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function increment($key, $step = 1)
|
||||
{
|
||||
$connection = $this->getConnection($key);
|
||||
$this->writeToRemote(array(
|
||||
'cmd' => 'increment',
|
||||
'key' => $key,
|
||||
'step' => $step,
|
||||
), $connection);
|
||||
return $this->readFromRemote($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to global server.
|
||||
* @param string $buffer
|
||||
*/
|
||||
protected function writeToRemote($data, $connection)
|
||||
{
|
||||
$buffer = serialize($data);
|
||||
$buffer = pack('N',4 + strlen($buffer)) . $buffer;
|
||||
$len = fwrite($connection, $buffer);
|
||||
if($len !== strlen($buffer))
|
||||
{
|
||||
throw new \Exception('writeToRemote fail');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from global server.
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function readFromRemote($connection)
|
||||
{
|
||||
$all_buffer = '';
|
||||
$total_len = 4;
|
||||
$head_read = false;
|
||||
while(1)
|
||||
{
|
||||
$buffer = fread($connection, 8192);
|
||||
if($buffer === '' || $buffer === false)
|
||||
{
|
||||
throw new \Exception('readFromRemote fail');
|
||||
}
|
||||
$all_buffer .= $buffer;
|
||||
$recv_len = strlen($all_buffer);
|
||||
if($recv_len >= $total_len)
|
||||
{
|
||||
if($head_read)
|
||||
{
|
||||
break;
|
||||
}
|
||||
$unpack_data = unpack('Ntotal_length', $all_buffer);
|
||||
$total_len = $unpack_data['total_length'];
|
||||
if($recv_len >= $total_len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
$head_read = true;
|
||||
}
|
||||
}
|
||||
return unserialize(substr($all_buffer, 4));
|
||||
}
|
||||
}
|
||||
114
vendor/workerman/globaldata/src/Server.php
vendored
Normal file
114
vendor/workerman/globaldata/src/Server.php
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
namespace GlobalData;
|
||||
use Workerman\Protocols\Frame;
|
||||
use Workerman\Worker;
|
||||
|
||||
/**
|
||||
* Global data server.
|
||||
*/
|
||||
class Server
|
||||
{
|
||||
/**
|
||||
* Worker instance.
|
||||
* @var worker
|
||||
*/
|
||||
protected $_worker = null;
|
||||
|
||||
/**
|
||||
* All data.
|
||||
* @var array
|
||||
*/
|
||||
protected $_dataArray = array();
|
||||
|
||||
/**
|
||||
* Construct.
|
||||
* @param string $ip
|
||||
* @param int $port
|
||||
*/
|
||||
public function __construct($ip = '0.0.0.0', $port = 2207)
|
||||
{
|
||||
if (strpos($ip, 'unix://') === 0) {
|
||||
$worker = new Worker($ip);
|
||||
$worker->protocol = Frame::class;
|
||||
} else {
|
||||
$worker = new Worker("frame://$ip:$port");
|
||||
}
|
||||
|
||||
$worker->count = 1;
|
||||
$worker->name = 'globalDataServer';
|
||||
$worker->onMessage = array($this, 'onMessage');
|
||||
$worker->reloadable = false;
|
||||
$this->_worker = $worker;
|
||||
}
|
||||
|
||||
/**
|
||||
* onMessage.
|
||||
* @param TcpConnection $connection
|
||||
* @param string $buffer
|
||||
*/
|
||||
public function onMessage($connection, $buffer)
|
||||
{
|
||||
if($buffer === 'ping')
|
||||
{
|
||||
return;
|
||||
}
|
||||
$data = unserialize($buffer);
|
||||
if(!$buffer || !isset($data['cmd']) || !isset($data['key']))
|
||||
{
|
||||
return $connection->close(serialize('bad request'));
|
||||
}
|
||||
$cmd = $data['cmd'];
|
||||
$key = $data['key'];
|
||||
switch($cmd)
|
||||
{
|
||||
case 'get':
|
||||
if(!isset($this->_dataArray[$key]))
|
||||
{
|
||||
return $connection->send('N;');
|
||||
}
|
||||
return $connection->send(serialize($this->_dataArray[$key]));
|
||||
break;
|
||||
case 'set':
|
||||
$this->_dataArray[$key] = $data['value'];
|
||||
$connection->send('b:1;');
|
||||
break;
|
||||
case 'add':
|
||||
if(isset($this->_dataArray[$key]))
|
||||
{
|
||||
return $connection->send('b:0;');
|
||||
}
|
||||
$this->_dataArray[$key] = $data['value'];
|
||||
return $connection->send('b:1;');
|
||||
break;
|
||||
case 'increment':
|
||||
if(!isset($this->_dataArray[$key]))
|
||||
{
|
||||
return $connection->send('b:0;');
|
||||
}
|
||||
if(!is_numeric($this->_dataArray[$key]))
|
||||
{
|
||||
$this->_dataArray[$key] = 0;
|
||||
}
|
||||
$this->_dataArray[$key] = $this->_dataArray[$key]+$data['step'];
|
||||
return $connection->send(serialize($this->_dataArray[$key]));
|
||||
break;
|
||||
case 'cas':
|
||||
$old_value = !isset($this->_dataArray[$key]) ? null : $this->_dataArray[$key];
|
||||
if(md5(serialize($old_value)) === $data['md5'])
|
||||
{
|
||||
$this->_dataArray[$key] = $data['value'];
|
||||
return $connection->send('b:1;');
|
||||
}
|
||||
$connection->send('b:0;');
|
||||
break;
|
||||
case 'delete':
|
||||
unset($this->_dataArray[$key]);
|
||||
$connection->send('b:1;');
|
||||
break;
|
||||
default:
|
||||
$connection->close(serialize('bad cmd '. $cmd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
vendor/workerman/globaldata/test/bench.php
vendored
Normal file
14
vendor/workerman/globaldata/test/bench.php
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
use GlobalData\Client;
|
||||
require_once __DIR__ . '/../src/Client.php';
|
||||
|
||||
$global = new Client('127.0.0.1:2207');
|
||||
|
||||
$i = $j = 10000;
|
||||
$t = microtime(true);
|
||||
while($i--)
|
||||
{
|
||||
$global->a = array(1,3);
|
||||
}
|
||||
|
||||
echo ceil($j/(microtime(true)-$t))."qps\n";
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user