Completed
Pull Request — master (#332)
by thomas
38:04
created

PublicKey::verify()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
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 null
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 403
    public function __construct(
43
        EcAdapter $ecAdapter,
44
        PointInterface $point,
45
        $compressed = false,
46
        $prefix = null
47
    ) {
48 403
        if (false === is_bool($compressed)) {
49
            throw new \InvalidArgumentException('PublicKey: Compressed must be a boolean');
50
        }
51
52 403
        $this->ecAdapter = $ecAdapter;
53 403
        $this->point = $point;
54 403
        $this->prefix = $prefix;
0 ignored issues
show
Documentation Bug introduced by
It seems like $prefix can also be of type string. However, the property $prefix is declared as type null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
55 403
        $this->compressed = $compressed;
56 403
    }
57
58
    /**
59
     * @return \Mdanter\Ecc\Primitives\GeneratorPoint
60
     */
61 195
    public function getGenerator()
62
    {
63 195
        return $this->ecAdapter->getGenerator();
64
    }
65
66
    /**
67
     * @return \Mdanter\Ecc\Primitives\CurveFpInterface
68
     */
69
    public function getCurve()
70
    {
71
        return $this->ecAdapter->getGenerator()->getCurve();
72
    }
73
74
    /**
75
     * @return null|string
76
     */
77 232
    public function getPrefix()
78
    {
79 232
        return $this->prefix;
80
    }
81
82
    /**
83
     * @return PointInterface
84
     */
85 357
    public function getPoint()
86
    {
87 357
        return $this->point;
88
    }
89
90
    /**
91
     * @param BufferInterface $msg32
92
     * @param SignatureInterface $signature
93
     * @return bool
94
     */
95
    public function verify(BufferInterface $msg32, SignatureInterface $signature)
96
    {
97
        return $this->ecAdapter->verify($msg32, $this, $signature);
98
    }
99
100
    /**
101
     * @param \GMP $tweak
102
     * @return PublicKeyInterface
103
     */
104 4
    public function tweakAdd(\GMP $tweak)
105
    {
106 4
        $offset = $this->ecAdapter->getGenerator()->mul($tweak);
107 4
        $newPoint = $this->point->add($offset);
108 4
        return $this->ecAdapter->getPublicKey($newPoint, $this->compressed);
109
    }
110
111
    /**
112
     * @param \GMP $tweak
113
     * @return PublicKeyInterface
114
     */
115 2
    public function tweakMul(\GMP $tweak)
116
    {
117 2
        $point = $this->point->mul($tweak);
118 2
        return $this->ecAdapter->getPublicKey($point, $this->compressed);
119
    }
120
121
    /**
122
     * @param BufferInterface $publicKey
123
     * @return bool
124
     */
125 90
    public static function isCompressedOrUncompressed(BufferInterface $publicKey)
126
    {
127 90
        $vchPubKey = $publicKey->getBinary();
128 90
        if ($publicKey->getSize() < self::LENGTH_COMPRESSED) {
129 6
            return false;
130
        }
131
132 87
        if ($vchPubKey[0] === self::KEY_UNCOMPRESSED) {
133 30
            if ($publicKey->getSize() !== self::LENGTH_UNCOMPRESSED) {
134
                // Invalid length for uncompressed key
135 14
                return false;
136
            }
137 76
        } elseif (in_array($vchPubKey[0], [
138 60
            self::KEY_COMPRESSED_EVEN,
139 20
            self::KEY_COMPRESSED_ODD
140 40
        ])) {
141 48
            if ($publicKey->getSize() !== self::LENGTH_COMPRESSED) {
142 18
                return false;
143
            }
144 32
        } else {
145 15
            return false;
146
        }
147
148 72
        return true;
149
    }
150
151
    /**
152
     * @return bool
153
     */
154 273
    public function isCompressed()
155
    {
156 273
        return $this->compressed;
157
    }
158
159
    /**
160
     * @return BufferInterface
161
     */
162 232
    public function getBuffer()
163
    {
164 232
        return (new PublicKeySerializer($this->ecAdapter))->serialize($this);
165
    }
166
}
167