<?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)); 
    } 
} 
 
 |