Completed
Push — master ( 57f238...3923b5 )
by thomas
17:59 queued 06:33
created

PublicKey::isCompressed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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