Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
100 lines (86 sloc) 2.28 KB
<?php
namespace Mdanter\Ecc\Crypto\Signature;
use Mdanter\Ecc\EccFactory;
use Mdanter\Ecc\Math\GmpMathInterface;
use Mdanter\Ecc\Primitives\GeneratorPoint;
use Mdanter\Ecc\Util\BinaryString;
use Mdanter\Ecc\Util\NumberSize;
class SignHasher implements HasherInterface
{
/**
* @var int[]
*/
protected static $sizeMap = [
'sha1' => 20,
'sha224' => 28,
'sha256' => 32,
'sha384' => 48,
'sha512' => 64,
];
/**
* @var GmpMathInterface
*/
private $adapter;
/**
* @var string
*/
private $algorithm;
/**
* SignHasher constructor.
* @param string $algorithm
* @param GmpMathInterface|null $math
*/
public function __construct(string $algorithm, GmpMathInterface $math = null)
{
if (!array_key_exists($algorithm, self::$sizeMap)) {
throw new \InvalidArgumentException("Unsupported hashing algorithm");
}
$this->algorithm = $algorithm;
$this->adapter = $math ?: EccFactory::getAdapter();
}
/**
* @return string
*/
public function getAlgorithm(): string
{
return $this->algorithm;
}
/**
* @return int
*/
public function getLengthInBytes(): int
{
return self::$sizeMap[$this->algorithm];
}
/**
* @param string $data
* @return string
*/
public function makeRawHash(string $data): string
{
return hash($this->algorithm, $data, false);
}
/**
* @param \GMP $hash
* @param GeneratorPoint $G
* @return \GMP
*/
public function truncateForECDSA(\GMP $hash, GeneratorPoint $G)
{
$hashBits = gmp_strval($hash, 2);
if (BinaryString::length($hashBits) < self::$sizeMap[$this->algorithm] * 8) {
$hashBits = str_pad($hashBits, self::$sizeMap[$this->algorithm] * 8, '0', STR_PAD_LEFT);
}
return gmp_init(BinaryString::substring($hashBits, 0, NumberSize::bnNumBits($this->adapter, $G->getOrder())), 2);
}
/**
* @param string $data
* @param GeneratorPoint $G
* @return \GMP
*/
public function makeHash(string $data, GeneratorPoint $G): \GMP
{
$hash = gmp_init($this->makeRawHash($data), 16);
return $this->truncateForECDSA($hash, $G);
}
}