Completed
Pull Request — master (#318)
by thomas
72:01
created

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