ghost
10 months ago
5 changed files with 317 additions and 0 deletions
@ -0,0 +1,12 @@ |
|||||||
|
{ |
||||||
|
"name": "kvazar/crypto", |
||||||
|
"description": "Crypto Tools for PHP 8", |
||||||
|
"type": "library", |
||||||
|
"license": "MIT", |
||||||
|
"autoload": { |
||||||
|
"psr-4": { |
||||||
|
"Kvazar\\Crypto\\": "src/" |
||||||
|
} |
||||||
|
}, |
||||||
|
"require": {} |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Kvazar\Crypto; |
||||||
|
|
||||||
|
use Kvazar\Crypto\Hash; |
||||||
|
use Kvazar\Crypto\Tool; |
||||||
|
|
||||||
|
class Base58 |
||||||
|
{ |
||||||
|
private const AVAILABLE_CHARS = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; |
||||||
|
|
||||||
|
public static function encode( |
||||||
|
string $value, |
||||||
|
?int $prefix = 128, |
||||||
|
?bool $compressed = true |
||||||
|
): string |
||||||
|
{ |
||||||
|
$value = hex2bin( |
||||||
|
$value |
||||||
|
); |
||||||
|
|
||||||
|
if ($prefix) |
||||||
|
{ |
||||||
|
$value = chr( |
||||||
|
$prefix |
||||||
|
) . $value; |
||||||
|
} |
||||||
|
|
||||||
|
if ($compressed) |
||||||
|
{ |
||||||
|
$value .= chr( |
||||||
|
0x01 |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
$value = $value . substr( |
||||||
|
Hash::sha256( |
||||||
|
Hash::sha256( |
||||||
|
$value |
||||||
|
) |
||||||
|
), 0, 4 |
||||||
|
); |
||||||
|
|
||||||
|
$base58 = self::_encode( |
||||||
|
Tool::bin2bc( |
||||||
|
$value |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
for ($i = 0; $i < strlen($value); $i++) |
||||||
|
{ |
||||||
|
|
||||||
|
if ($value[$i] != '\x00') |
||||||
|
{ |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
$base58 = '1' . $base58; |
||||||
|
} |
||||||
|
|
||||||
|
return $base58; |
||||||
|
} |
||||||
|
|
||||||
|
public static function decode( |
||||||
|
string $value, |
||||||
|
?int $removeLeadingBytes = 1, |
||||||
|
?int $removeTrailingBytes = 4, |
||||||
|
?bool $removeCompression = true |
||||||
|
) |
||||||
|
{ |
||||||
|
$value = bin2hex( |
||||||
|
Tool::bc2bin( |
||||||
|
self::_decode( |
||||||
|
$value |
||||||
|
) |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
if ($removeLeadingBytes) |
||||||
|
{ |
||||||
|
$value = substr( |
||||||
|
$value, |
||||||
|
$removeLeadingBytes * 2 |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
if ($removeTrailingBytes) |
||||||
|
{ |
||||||
|
$value = substr( |
||||||
|
$value, 0, -($removeTrailingBytes * 2) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
if ($removeCompression) |
||||||
|
{ |
||||||
|
$value = substr( |
||||||
|
$value, 0, -2 |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
return $value; |
||||||
|
} |
||||||
|
|
||||||
|
private static function _encode($num, $length = 58): string |
||||||
|
{ |
||||||
|
return Tool::dec2base( |
||||||
|
$num, |
||||||
|
$length, |
||||||
|
self::AVAILABLE_CHARS |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
private static function _decode(string $value, int $length = 58): string |
||||||
|
{ |
||||||
|
return Tool::base2dec( |
||||||
|
$value, |
||||||
|
$length, |
||||||
|
self::AVAILABLE_CHARS |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Kvazar\Crypto; |
||||||
|
|
||||||
|
class Hash |
||||||
|
{ |
||||||
|
public static function sha256(string $data, $raw = true): string |
||||||
|
{ |
||||||
|
return hash( |
||||||
|
'sha256', |
||||||
|
$data, |
||||||
|
$raw |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
public static function sha256d(string $data): string |
||||||
|
{ |
||||||
|
return hash( |
||||||
|
'sha256', |
||||||
|
hash( |
||||||
|
'sha256', |
||||||
|
$data, |
||||||
|
true |
||||||
|
), |
||||||
|
true |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
public static function ripemd160(string $data, $raw = true): string |
||||||
|
{ |
||||||
|
return hash( |
||||||
|
'ripemd160', |
||||||
|
$data, |
||||||
|
$raw |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,142 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Kvazar\Crypto; |
||||||
|
|
||||||
|
class Tool |
||||||
|
{ |
||||||
|
public static function bc2bin($num) |
||||||
|
{ |
||||||
|
return self::dec2base( |
||||||
|
$num, |
||||||
|
256 |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
public static function dec2base($dec, $base, $digits = false): ?string |
||||||
|
{ |
||||||
|
if ($base < 2 || $base > 256) |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
bcscale(0); |
||||||
|
|
||||||
|
$value = ''; |
||||||
|
|
||||||
|
if (!$digits) |
||||||
|
{ |
||||||
|
$digits = self::digits( |
||||||
|
$base |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
while ($dec > $base - 1) |
||||||
|
{ |
||||||
|
$rest = bcmod( |
||||||
|
$dec, |
||||||
|
$base |
||||||
|
); |
||||||
|
|
||||||
|
$dec = bcdiv( |
||||||
|
$dec, |
||||||
|
$base |
||||||
|
); |
||||||
|
|
||||||
|
$value = $digits[$rest] . $value; |
||||||
|
} |
||||||
|
|
||||||
|
$value = $digits[intval($dec)] . $value; |
||||||
|
|
||||||
|
return (string) $value; |
||||||
|
} |
||||||
|
|
||||||
|
public static function base2dec($value, $base, $digits = false): ?string |
||||||
|
{ |
||||||
|
if ($base < 2 || $base > 256) |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
bcscale(0); |
||||||
|
|
||||||
|
if ($base < 37) |
||||||
|
{ |
||||||
|
$value = strtolower( |
||||||
|
$value |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
if (!$digits) |
||||||
|
{ |
||||||
|
$digits = self::digits( |
||||||
|
$base |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
$size = strlen( |
||||||
|
$value |
||||||
|
); |
||||||
|
|
||||||
|
$dec = '0'; |
||||||
|
|
||||||
|
for ($loop = 0; $loop < $size; $loop++) |
||||||
|
{ |
||||||
|
$element = strpos( |
||||||
|
$digits, |
||||||
|
$value[$loop] |
||||||
|
); |
||||||
|
|
||||||
|
$power = bcpow( |
||||||
|
$base, |
||||||
|
$size - $loop - 1 |
||||||
|
); |
||||||
|
|
||||||
|
$dec = bcadd( |
||||||
|
$dec, |
||||||
|
bcmul( |
||||||
|
$element, |
||||||
|
$power |
||||||
|
) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
return (string) $dec; |
||||||
|
} |
||||||
|
|
||||||
|
public static function digits($base): string |
||||||
|
{ |
||||||
|
if ($base > 64) |
||||||
|
{ |
||||||
|
$digits = ''; |
||||||
|
|
||||||
|
for ($loop = 0; $loop < 256; $loop++) |
||||||
|
{ |
||||||
|
$digits .= chr( |
||||||
|
$loop |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
else |
||||||
|
{ |
||||||
|
$digits = '0123456789abcdefghijklmnopqrstuvwxyz'; |
||||||
|
$digits .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ-_'; |
||||||
|
} |
||||||
|
|
||||||
|
$digits = substr( |
||||||
|
$digits, 0, $base |
||||||
|
); |
||||||
|
|
||||||
|
return (string) $digits; |
||||||
|
} |
||||||
|
|
||||||
|
public static function bin2bc($num) |
||||||
|
{ |
||||||
|
return self::base2dec( |
||||||
|
$num, |
||||||
|
256 |
||||||
|
); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue