Completed
Pull Request — master (#333)
by thomas
61:20 queued 57:43
created

PublicKeySerializer::getPrefix()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5.1576

Importance

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