Completed
Pull Request — master (#446)
by thomas
157:14 queued 87:18
created

PublicKey::doEquals()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 4
nc 7
nop 1
dl 0
loc 6
ccs 1
cts 1
cp 1
crap 5
rs 8.8571
c 0
b 0
f 0
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
    /**
36
     * PublicKey constructor.
37
     * @param EcAdapter $ecAdapter
38
     * @param PointInterface $point
39
     * @param bool $compressed
40
     * @param string $prefix
41
     */
42 384
    public function __construct(
43
        EcAdapter $ecAdapter,
44
        PointInterface $point,
45
        $compressed = false,
46
        $prefix = null
47
    ) {
48 384
        if (false === is_bool($compressed)) {
49
            throw new \InvalidArgumentException('PublicKey: Compressed must be a boolean');
50
        }
51 384
        $this->ecAdapter = $ecAdapter;
52 384
        $this->point = $point;
53 384
        $this->prefix = $prefix;
54 384
        $this->compressed = $compressed;
55 384
    }
56
57
    /**
58
     * @return \Mdanter\Ecc\Primitives\GeneratorPoint
59
     */
60 202
    public function getGenerator()
61
    {
62 202
        return $this->ecAdapter->getGenerator();
63
    }
64
65
    /**
66
     * @return \Mdanter\Ecc\Primitives\CurveFpInterface
67
     */
68
    public function getCurve()
69
    {
70
        return $this->ecAdapter->getGenerator()->getCurve();
71
    }
72
73
    /**
74
     * @return string
75
     */
76 218
    public function getPrefix()
77
    {
78 218
        return $this->prefix;
79
    }
80
81
    /**
82
     * @return PointInterface
83
     */
84 350
    public function getPoint()
85
    {
86 350
        return $this->point;
87
    }
88
89
    /**
90
     * @param BufferInterface $msg32
91
     * @param SignatureInterface $signature
92
     * @return bool
93
     */
94
    public function verify(BufferInterface $msg32, SignatureInterface $signature)
95
    {
96
        return $this->ecAdapter->verify($msg32, $this, $signature);
97
    }
98
99
    /**
100
     * @param \GMP $tweak
101
     * @return PublicKeyInterface
102
     */
103 8
    public function tweakAdd(\GMP $tweak)
104
    {
105 8
        $offset = $this->ecAdapter->getGenerator()->mul($tweak);
106 8
        $newPoint = $this->point->add($offset);
107 8
        return $this->ecAdapter->getPublicKey($newPoint, $this->compressed);
108
    }
109
110
    /**
111
     * @param \GMP $tweak
112
     * @return PublicKeyInterface
113
     */
114 2
    public function tweakMul(\GMP $tweak)
115
    {
116 2
        $point = $this->point->mul($tweak);
117 2
        return $this->ecAdapter->getPublicKey($point, $this->compressed);
118
    }
119
120
    /**
121
     * @param BufferInterface $publicKey
122
     * @return bool
123
     */
124 122
    public static function isCompressedOrUncompressed(BufferInterface $publicKey)
125
    {
126 122
        $vchPubKey = $publicKey->getBinary();
127 122
        if ($publicKey->getSize() < self::LENGTH_COMPRESSED) {
128 8
            return false;
129
        }
130
131 120
        if ($vchPubKey[0] === self::KEY_UNCOMPRESSED) {
132 60
            if ($publicKey->getSize() !== self::LENGTH_UNCOMPRESSED) {
133
                // Invalid length for uncompressed key
134 36
                return false;
135
            }
136 90
        } elseif (in_array($vchPubKey[0], [
137 66
            self::KEY_COMPRESSED_EVEN,
138 33
            self::KEY_COMPRESSED_ODD
139 33
        ])) {
140 58
            if ($publicKey->getSize() !== self::LENGTH_COMPRESSED) {
141 32
                return false;
142
            }
143 29
        } else {
144 14
            return false;
145
        }
146
147 106
        return true;
148
    }
149
150
    /**
151
     * @return bool
152
     */
153 250
    public function isCompressed()
154
    {
155 250
        return $this->compressed;
156
    }
157
158
    /**
159
     * @param PublicKey $other
160
     * @return bool
161 218
     */
162
    private function doEquals(self $other)
163 218
    {
164
        return $this->compressed === $other->compressed
165
            && $this->point->equals($other->point)
166
            && (($this->prefix === null || $this->prefix === null) || ($this->prefix === $other->prefix));
167
    }
168
169
    /**
170
     * @param PublicKeyInterface $other
171
     * @return bool
172
     */
173
    public function equals(PublicKeyInterface $other)
174
    {
175
        /** @var self $other */
176
        return $this->doEquals($other);
0 ignored issues
show
Documentation introduced by
$other is of type object<BitWasp\Bitcoin\C...l\PhpEcc\Key\PublicKey>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
177
    }
178
179
    /**
180
     * @return BufferInterface
181
     */
182
    public function getBuffer()
183
    {
184
        return (new PublicKeySerializer($this->ecAdapter))->serialize($this);
185
    }
186
}
187