<?php
declare(strict_types=1);
namespace ParagonIE\EasyECC\ECDSA;
use Mdanter\Ecc\Crypto\Signature\Signature as BaseSignature;
use Mdanter\Ecc\Crypto\Signature\SignatureInterface;
use Mdanter\Ecc\Exception\SignatureDecodeException;
use Mdanter\Ecc\Util\BinaryString;
/**
* Class Signature
* @package ParagonIE\EasyECC
*/
class Signature extends BaseSignature
{
/**
* Returns a hexadecimal-encoded signature.
*
* @param int $length
* @return string
*/
public function toString(int $length = 0): string
{
$r = gmp_strval($this->getR(), 16);
$s = gmp_strval($this->getS(), 16);
$len = max(strlen($r), strlen($s), $length >> 1);
return str_pad($r, $len, '0', STR_PAD_LEFT) .
str_pad($s, $len, '0', STR_PAD_LEFT);
}
/**
* Returns a hexadecimal-encoded signature.
*
* @return string
*/
public function __toString()
{
return $this->toString();
}
/**
* Promote an instance of the base signature type to this type.
*
* @param SignatureInterface $sig
* @return self
*/
public static function promote(SignatureInterface $sig): self
{
return new self($sig->getR(), $sig->getS());
}
/**
* Serializes a signature from a hexadecimal string.
*
* @param string $hexString
* @return self
* @throws \SodiumException
*/
public static function fromString(string $hexString): self
{
$binary = sodium_hex2bin($hexString);
$total_length = BinaryString::length($binary);
if (($total_length & 1) !== 0) {
throw new SignatureDecodeException('IEEE-P1363 signatures must be an even length');
}
$piece_len = $total_length >> 1;
$r = bin2hex(BinaryString::substring($binary, 0, $piece_len));
$s = bin2hex(BinaryString::substring($binary, $piece_len, $piece_len));
return new self(gmp_init($r, 16), gmp_init($s, 16));
}
}
|