Completed
Pull Request — master (#333)
by thomas
61:20 queued 57:43
created

PublicKey   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 88.89%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
c 6
b 0
f 0
dl 0
loc 150
ccs 40
cts 45
cp 0.8889
rs 10
wmc 17
lcom 1
cbo 6

11 Methods

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