Completed
Pull Request — master (#317)
by thomas
16:45 queued 06:42
created

PublicKey::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.0116

Importance

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