Completed
Pull Request — master (#336)
by thomas
04:08
created

PublicKey::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0078

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 11
c 1
b 0
f 0
nc 2
nop 4
dl 0
loc 14
ccs 7
cts 8
cp 0.875
crap 2.0078
rs 9.4285
1
<?php
2
3
namespace BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Key;
4
5
use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Adapter\EcAdapter;
6
use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Serializer\Key\PublicKeySerializer;
7
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\Key;
8
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PublicKeyInterface;
9
use BitWasp\Bitcoin\Crypto\EcAdapter\Signature\SignatureInterface;
10
use BitWasp\Buffertools\BufferInterface;
11
use Mdanter\Ecc\Primitives\PointInterface;
12
13
class PublicKey extends Key implements PublicKeyInterface, \Mdanter\Ecc\Crypto\Key\PublicKeyInterface
14
{
15
    /**
16
     * @var EcAdapter
17
     */
18
    private $ecAdapter;
19
20
    /**
21
     * @var PointInterface
22
     */
23
    private $point;
24
25
    /**
26
     * @var string
27
     */
28
    private $prefix;
29
30
    /**
31
     * @var bool
32
     */
33
    private $compressed;
34
35 255
    /**
36
     * @param EcAdapter $ecAdapter
37
     * @param PointInterface $point
38
     * @param bool $compressed
39
     */
40 255
    public function __construct(
41
        EcAdapter $ecAdapter,
42
        PointInterface $point,
43 255
        $compressed = false,
44 255
        $prefix = null
45 255
    ) {
46 255
        if (false === is_bool($compressed)) {
47
            throw new \InvalidArgumentException('PublicKey: Compressed must be a boolean');
48
        }
49
        $this->ecAdapter = $ecAdapter;
50
        $this->point = $point;
51 47
        $this->prefix = $prefix;
52
        $this->compressed = $compressed;
53 47
    }
54
55
    /**
56
     * @return \Mdanter\Ecc\Primitives\GeneratorPoint
57
     */
58
    public function getGenerator()
59
    {
60
        return $this->ecAdapter->getGenerator();
61
    }
62
63
    /**
64
     * @return \Mdanter\Ecc\Primitives\CurveFpInterface
65
     */
66
    public function getCurve()
67 209
    {
68
        return $this->ecAdapter->getGenerator()->getCurve();
69 209
    }
70
71
    /**
72
     * @return string
73
     */
74
    public function getPrefix()
75
    {
76
        return $this->prefix;
77
    }
78
79
    /**
80
     * @return PointInterface
81
     */
82
    public function getPoint()
83
    {
84
        return $this->point;
85
    }
86 4
87
    /**
88 4
     * @param BufferInterface $msg32
89 4
     * @param SignatureInterface $signature
90 4
     * @return bool
91
     */
92
    public function verify(BufferInterface $msg32, SignatureInterface $signature)
93
    {
94
        return $this->ecAdapter->verify($msg32, $this, $signature);
95
    }
96
97 2
    /**
98
     * @param \GMP $tweak
99 2
     * @return PublicKeyInterface
100 2
     */
101
    public function tweakAdd(\GMP $tweak)
102
    {
103
        $offset = $this->ecAdapter->getGenerator()->mul($tweak);
104
        $newPoint = $this->point->add($offset);
105
        return $this->ecAdapter->getPublicKey($newPoint, $this->compressed);
106
    }
107 48
108
    /**
109 48
     * @param \GMP $tweak
110 48
     * @return PublicKeyInterface
111 3
     */
112
    public function tweakMul(\GMP $tweak)
113
    {
114 48
        $point = $this->point->mul($tweak);
115 30
        return $this->ecAdapter->getPublicKey($point, $this->compressed);
116
    }
117 14
118
    /**
119 37
     * @param BufferInterface $publicKey
120 21
     * @return bool
121 7
     */
122 14
    public static function isCompressedOrUncompressed(BufferInterface $publicKey)
123 21
    {
124 9
        $vchPubKey = $publicKey->getBinary();
125
        if ($publicKey->getSize() < self::LENGTH_COMPRESSED) {
126 14
            return false;
127 3
        }
128
129
        if ($vchPubKey[0] === self::KEY_UNCOMPRESSED) {
130 45
            if ($publicKey->getSize() !== self::LENGTH_UNCOMPRESSED) {
131
                // Invalid length for uncompressed key
132
                return false;
133
            }
134
        } elseif (in_array($vchPubKey[0], [
135
            self::KEY_COMPRESSED_EVEN,
136 241
            self::KEY_COMPRESSED_ODD
137
        ])) {
138 241
            if ($publicKey->getSize() !== self::LENGTH_COMPRESSED) {
139
                return false;
140
            }
141
        } else {
142
            return false;
143
        }
144 200
145
        return true;
146 200
    }
147
148
    /**
149
     * @return bool
150
     */
151
    public function isCompressed()
152
    {
153
        return $this->compressed;
154
    }
155
156
    /**
157
     * @return BufferInterface
158
     */
159
    public function getBuffer()
160
    {
161
        return (new PublicKeySerializer($this->ecAdapter))->serialize($this);
162
    }
163
}
164