Passed
Push — master ( 02542f...9cd002 )
by thomas
58:57 queued 33:55
created

SignHasher::getAlgorithm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Mdanter\Ecc\Crypto\Signature;
4
5
use Mdanter\Ecc\EccFactory;
6
use Mdanter\Ecc\Math\GmpMathInterface;
7
use Mdanter\Ecc\Primitives\GeneratorPoint;
8
use Mdanter\Ecc\Util\BinaryString;
9
use Mdanter\Ecc\Util\NumberSize;
10
11
class SignHasher implements HasherInterface
12
{
13
    /**
14
     * @var int[]
15
     */
16
    protected static $sizeMap = [
17
        'sha1' => 20,
18
        'sha224' => 28,
19
        'sha256' => 32,
20
        'sha384' => 48,
21
        'sha512' => 64,
22
    ];
23
24
    /**
25
     * @var GmpMathInterface
26
     */
27
    private $adapter;
28
29
    /**
30
     * @var string
31
     */
32
    private $algorithm;
33
34
    /**
35
     * SignHasher constructor.
36
     * @param string $algorithm
37
     * @param GmpMathInterface|null $math
38
     */
39
    public function __construct(string $algorithm, GmpMathInterface $math = null)
40
    {
41
        if (!array_key_exists($algorithm, self::$sizeMap)) {
42
            throw new \InvalidArgumentException("Unsupported hashing algorithm");
43
        }
44
45
        $this->algorithm = $algorithm;
46
        $this->adapter = $math ?: EccFactory::getAdapter();
47
    }
48
49
    /**
50
     * @return string
51
     */
52
    public function getAlgorithm(): string
53
    {
54
        return $this->algorithm;
55
    }
56
57
    /**
58
     * @return int
59
     */
60
    public function getLengthInBytes(): int
61
    {
62
        return self::$sizeMap[$this->algorithm];
63
    }
64
65
    /**
66
     * @param string $data
67
     * @return string
68
     */
69
    public function makeRawHash(string $data): string
70
    {
71
        return hash($this->algorithm, $data, false);
72
    }
73
74
    /**
75
     * @param \GMP $hash
76
     * @param GeneratorPoint $G
77
     * @return \GMP
78
     */
79
    public function truncateForECDSA(\GMP $hash, GeneratorPoint $G)
80
    {
81
        $hashBits = gmp_strval($hash, 2);
82
        if (BinaryString::length($hashBits) < self::$sizeMap[$this->algorithm] * 8) {
83
            $hashBits = str_pad($hashBits, self::$sizeMap[$this->algorithm] * 8, '0', STR_PAD_LEFT);
84
        }
85
86
        return gmp_init(BinaryString::substring($hashBits, 0, NumberSize::bnNumBits($this->adapter, $G->getOrder())), 2);
87
    }
88
89
    /**
90
     * @param string $data
91
     * @param GeneratorPoint $G
92
     * @return \GMP
93
     */
94
    public function makeHash(string $data, GeneratorPoint $G): \GMP
95
    {
96
        $hash = gmp_init($this->makeRawHash($data), 16);
97
        return $this->truncateForECDSA($hash, $G);
98
    }
99
}
100