Completed
Push — master ( 9369e3...7c941d )
by thomas
33:44 queued 16:13
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
    /**
36
     * @param EcAdapter $ecAdapter
37
     * @param PointInterface $point
38
     * @param bool $compressed
39
     */
40 371
    public function __construct(
41
        EcAdapter $ecAdapter,
42
        PointInterface $point,
43
        $compressed = false,
44
        $prefix = null
45
    ) {
46 371
        if (false === is_bool($compressed)) {
47
            throw new \InvalidArgumentException('PublicKey: Compressed must be a boolean');
48
        }
49 371
        $this->ecAdapter = $ecAdapter;
50 371
        $this->point = $point;
51 371
        $this->prefix = $prefix;
52 371
        $this->compressed = $compressed;
53 371
    }
54
55
    /**
56
     * @return \Mdanter\Ecc\Primitives\GeneratorPoint
57
     */
58 163
    public function getGenerator()
59
    {
60 163
        return $this->ecAdapter->getGenerator();
61
    }
62
63
    /**
64
     * @return \Mdanter\Ecc\Primitives\CurveFpInterface
65
     */
66
    public function getCurve()
67
    {
68
        return $this->ecAdapter->getGenerator()->getCurve();
69
    }
70
71
    /**
72
     * @return string
73
     */
74 200
    public function getPrefix()
75
    {
76 200
        return $this->prefix;
77
    }
78
79
    /**
80
     * @return PointInterface
81
     */
82 325
    public function getPoint()
83
    {
84 325
        return $this->point;
85
    }
86
87
    /**
88
     * @param BufferInterface $msg32
89
     * @param SignatureInterface $signature
90
     * @return bool
91
     */
92
    public function verify(BufferInterface $msg32, SignatureInterface $signature)
93
    {
94
        return $this->ecAdapter->verify($msg32, $this, $signature);
95
    }
96
97
    /**
98
     * @param \GMP $tweak
99
     * @return PublicKeyInterface
100
     */
101 4
    public function tweakAdd(\GMP $tweak)
102
    {
103 4
        $offset = $this->ecAdapter->getGenerator()->mul($tweak);
104 4
        $newPoint = $this->point->add($offset);
105 4
        return $this->ecAdapter->getPublicKey($newPoint, $this->compressed);
106
    }
107
108
    /**
109
     * @param \GMP $tweak
110
     * @return PublicKeyInterface
111
     */
112 2
    public function tweakMul(\GMP $tweak)
113
    {
114 2
        $point = $this->point->mul($tweak);
115 2
        return $this->ecAdapter->getPublicKey($point, $this->compressed);
116
    }
117
118
    /**
119
     * @param BufferInterface $publicKey
120
     * @return bool
121
     */
122 68
    public static function isCompressedOrUncompressed(BufferInterface $publicKey)
123
    {
124 68
        $vchPubKey = $publicKey->getBinary();
125 68
        if ($publicKey->getSize() < self::LENGTH_COMPRESSED) {
126 5
            return false;
127
        }
128
129 66
        if ($vchPubKey[0] === self::KEY_UNCOMPRESSED) {
130 30
            if ($publicKey->getSize() !== self::LENGTH_UNCOMPRESSED) {
131
                // Invalid length for uncompressed key
132 14
                return false;
133
            }
134 55
        } elseif (in_array($vchPubKey[0], [
135 39
            self::KEY_COMPRESSED_EVEN,
136 16
            self::KEY_COMPRESSED_ODD
137 23
        ])) {
138 31
            if ($publicKey->getSize() !== self::LENGTH_COMPRESSED) {
139 14
                return false;
140
            }
141 19
        } else {
142 11
            return false;
143
        }
144
145 55
        return true;
146
    }
147
148
    /**
149
     * @return bool
150
     */
151 241
    public function isCompressed()
152
    {
153 241
        return $this->compressed;
154
    }
155
156
    /**
157
     * @return BufferInterface
158
     */
159 200
    public function getBuffer()
160
    {
161 200
        return (new PublicKeySerializer($this->ecAdapter))->serialize($this);
162
    }
163
}
164