Completed
Pull Request — master (#334)
by thomas
81:34 queued 77:32
created

PublicKeySerializer   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 69.77%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 82
ccs 30
cts 43
cp 0.6977
rs 10
wmc 10
lcom 1
cbo 6

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A doSerialize() 0 18 2
A serialize() 0 5 1
A parse() 0 9 2
A getPrefix() 0 13 4
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 91
                    ? PublicKey::KEY_COMPRESSED_EVEN
40 92
                    : 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