Completed
Push — master ( 508371...265855 )
by thomas
68:00 queued 64:13
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 370
    public function __construct(EcAdapter $ecAdapter)
25
    {
26 370
        $this->ecAdapter = $ecAdapter;
27 370
    }
28
29
    /**
30
     * @param PublicKey $publicKey
31
     * @return string
32
     */
33 200
    public function getPrefix(PublicKey $publicKey)
34
    {
35 200
        if (null === $publicKey->getPrefix()) {
36 116
            return $publicKey->isCompressed()
37 93
                ? $this->ecAdapter->getMath()->isEven($publicKey->getPoint()->getY())
38 53
                    ? PublicKey::KEY_COMPRESSED_EVEN
39 51
                    : PublicKey::KEY_COMPRESSED_ODD
40 116
                : PublicKey::KEY_UNCOMPRESSED;
41
        } else {
42 104
            return $publicKey->getPrefix();
43
        }
44
45
    }
46
47
    /**
48
     * @param PublicKey $publicKey
49
     * @return BufferInterface
50
     */
51 200
    private function doSerialize(PublicKey $publicKey)
52
    {
53 200
        $math = $this->ecAdapter->getMath();
54 200
        $point = $publicKey->getPoint();
55 200
        $compressed = $publicKey->isCompressed();
56
57 200
        $parser = new Parser('', $math);
58 200
        $parser->writeBytes(1, new Buffer($this->getPrefix($publicKey)));
59
60 100
        $compressed
61 100
            ? $parser
62 122
            ->writeBytes(32, Buffer::int(gmp_strval($point->getX(), 10), null, $math))
63 61
            : $parser
64 96
            ->writeBytes(32, Buffer::int(gmp_strval($point->getX(), 10), null, $math))
65 96
            ->writeBytes(32, Buffer::int(gmp_strval($point->getY(), 10), null, $math));
66
67 200
        return $parser->getBuffer();
68
    }
69
70
    /**
71
     * @param PublicKeyInterface $publicKey
72
     * @return BufferInterface
73
     */
74 200
    public function serialize(PublicKeyInterface $publicKey)
75
    {
76
        /** @var PublicKey $publicKey */
77 200
        return $this->doSerialize($publicKey);
78
    }
79
80
    /**
81
     * @param BufferInterface|string $data
82
     * @return PublicKey
83
     * @throws \Exception
84
     */
85 284
    public function parse($data)
86
    {
87 284
        $buffer = (new Parser($data))->getBuffer();
88 284
        if (!in_array($buffer->getSize(), [PublicKey::LENGTH_COMPRESSED, PublicKey::LENGTH_UNCOMPRESSED], true)) {
89 12
            throw new \Exception('Invalid hex string, must match size of compressed or uncompressed public key');
90
        }
91
92 274
        return $this->ecAdapter->publicKeyFromBuffer($buffer);
93
    }
94
}
95