Completed
Push — master ( 26690c...ea008d )
by thomas
177:34 queued 174:51
created

PublicKeySerializer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1.0156

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 4
cp 0.75
crap 1.0156
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Serializer\Key;
4
5
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PublicKeyInterface;
6
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Key\PublicKeySerializerInterface;
7
use BitWasp\Buffertools\Buffer;
8
use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Adapter\EcAdapter;
9
use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Key\PublicKey;
10
use BitWasp\Buffertools\BufferInterface;
11
use BitWasp\Buffertools\Parser;
12
use Mdanter\Ecc\Primitives\PointInterface;
13
14
class PublicKeySerializer implements PublicKeySerializerInterface
15
{
16
    /**
17
     * @var EcAdapter
18
     */
19
    private $ecAdapter;
20
21
    /**
22
     * @param EcAdapter $ecAdapter
23
     */
24 696
    public function __construct(EcAdapter $ecAdapter)
25
    {
26 696
        $this->ecAdapter = $ecAdapter;
27 696
    }
28
29
    /**
30
     * @param PublicKey $publicKey
31
     * @return string
32
     */
33 376
    public function getPrefix(PublicKey $publicKey)
34
    {
35 376
        if (null === $publicKey->getPrefix()) {
36 196
            return $publicKey->isCompressed()
37 164
                ? $this->ecAdapter->getMath()->isEven($publicKey->getPoint()->getY())
38 97
                    ? PublicKey::KEY_COMPRESSED_EVEN
39 95
                    : PublicKey::KEY_COMPRESSED_ODD
40 196
                : PublicKey::KEY_UNCOMPRESSED;
41
        } else {
42 216
            return $publicKey->getPrefix();
43
        }
44
    }
45
46
    /**
47
     * @param PublicKey $publicKey
48
     * @return BufferInterface
49
     */
50 376
    private function doSerialize(PublicKey $publicKey)
51
    {
52 376
        $math = $this->ecAdapter->getMath();
53 376
        $point = $publicKey->getPoint();
54 376
        $compressed = $publicKey->isCompressed();
55
56 376
        $parser = new Parser('', $math);
57 376
        $parser->writeBytes(1, new Buffer($this->getPrefix($publicKey)));
58
59 188
        $compressed
60 188
            ? $parser
61 220
            ->writeBytes(32, Buffer::int(gmp_strval($point->getX(), 10), null, $math))
62 110
            : $parser
63 192
            ->writeBytes(32, Buffer::int(gmp_strval($point->getX(), 10), null, $math))
64 192
            ->writeBytes(32, Buffer::int(gmp_strval($point->getY(), 10), null, $math));
65
66 376
        return $parser->getBuffer();
67
    }
68
69
    /**
70
     * @param PublicKeyInterface $publicKey
71
     * @return BufferInterface
72
     */
73 376
    public function serialize(PublicKeyInterface $publicKey)
74
    {
75
        /** @var PublicKey $publicKey */
76 376
        return $this->doSerialize($publicKey);
77
    }
78
79
    /**
80
     * @param BufferInterface|string $data
81
     * @return PublicKey
82
     * @throws \Exception
83
     */
84 562
    public function parse($data)
85
    {
86 562
        $buffer = (new Parser($data))->getBuffer();
87 562
        if (!in_array($buffer->getSize(), [PublicKey::LENGTH_COMPRESSED, PublicKey::LENGTH_UNCOMPRESSED], true)) {
88 24
            throw new \Exception('Invalid hex string, must match size of compressed or uncompressed public key');
89
        }
90
91 542
        return $this->ecAdapter->publicKeyFromBuffer($buffer);
92
    }
93
}
94