ghost
10 months ago
5 changed files with 317 additions and 0 deletions
@ -0,0 +1,12 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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