Completed
Push — master ( a22894...37130c )
by thomas
62:03 queued 58:09
created

PublicKeySerializer::parse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.2109

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 8
cp 0.625
crap 2.2109
rs 9.6666
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 246
    public function __construct(EcAdapter $ecAdapter)
25
    {
26 246
        $this->ecAdapter = $ecAdapter;
27 246
    }
28
29
    /**
30
     * @param bool $compressed
31
     * @param PointInterface $point
32
     * @return string
33
     */
34 200
    public function getPrefix($compressed, PointInterface $point)
35
    {
36 100
        return $compressed
37 161
            ? $this->ecAdapter->getMath()->isEven($point->getY())
38 93
                ? PublicKey::KEY_COMPRESSED_EVEN
39 92
                : PublicKey::KEY_COMPRESSED_ODD
40 200
            : PublicKey::KEY_UNCOMPRESSED;
41
    }
42
43
    /**
44
     * @param PublicKey $publicKey
45
     * @return BufferInterface
46
     */
47 200
    private function doSerialize(PublicKey $publicKey)
48
    {
49 200
        $math = $this->ecAdapter->getMath();
50 200
        $point = $publicKey->getPoint();
51 200
        $compressed = $publicKey->isCompressed();
52
53 200
        $parser = new Parser('', $math);
54 200
        $parser->writeBytes(1, $this->getPrefix($compressed, $point));
55
56 100
        $compressed
57 100
            ? $parser
58 122
            ->writeBytes(32, Buffer::int(gmp_strval($point->getX(), 10), null, $math))
59 61
            : $parser
60 96
            ->writeBytes(32, Buffer::int(gmp_strval($point->getX(), 10), null, $math))
61 96
            ->writeBytes(32, Buffer::int(gmp_strval($point->getY(), 10), null, $math));
62
63 200
        return $parser->getBuffer();
64
    }
65
66
    /**
67
     * @param PublicKeyInterface $publicKey
68
     * @return BufferInterface
69
     */
70 200
    public function serialize(PublicKeyInterface $publicKey)
71
    {
72
        /** @var PublicKey $publicKey */
73 200
        return $this->doSerialize($publicKey);
74
    }
75
76
    /**
77
     * @param BufferInterface|string $data
78
     * @return PublicKey
79
     * @throws \Exception
80
     */
81 160
    public function parse($data)
82
    {
83 160
        $buffer = (new Parser($data))->getBuffer();
84 160
        if (!in_array($buffer->getSize(), [PublicKey::LENGTH_COMPRESSED, PublicKey::LENGTH_UNCOMPRESSED], true)) {
85 4
            throw new \Exception('Invalid hex string, must match size of compressed or uncompressed public key');
86
        }
87
88 158
        return $this->ecAdapter->publicKeyFromBuffer($buffer);
89
    }
90
}
91