Completed
Push — 0.0.35 ( b2fc74...d8d049 )
by thomas
28:12 queued 09:10
created

DerSignatureSerializer::getEcAdapter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace BitWasp\Bitcoin\Crypto\EcAdapter\Impl\Secp256k1\Serializer\Signature;
4
5
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
6
use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\Secp256k1\Adapter\EcAdapter;
7
use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\Secp256k1\Signature\Signature;
8
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Signature\DerSignatureSerializerInterface;
9
use BitWasp\Bitcoin\Crypto\EcAdapter\Signature\SignatureInterface;
10
use BitWasp\Buffertools\Buffer;
11
use BitWasp\Buffertools\Parser;
12
use BitWasp\Buffertools\Template;
13
use BitWasp\Buffertools\TemplateFactory;
14
15
class DerSignatureSerializer implements DerSignatureSerializerInterface
16
{
17
    /**
18
     * @var EcAdapter
19
     */
20
    private $ecAdapter;
21
22
    /**
23
     * @param EcAdapter $ecAdapter
24
     */
25 2402
    public function __construct(EcAdapter $ecAdapter)
26
    {
27 2402
        $this->ecAdapter = $ecAdapter;
28 2402
    }
29
30
    /**
31
     * @return EcAdapterInterface
32
     */
33 213
    public function getEcAdapter()
34
    {
35 213
        return $this->ecAdapter;
36
    }
37
38
    /**
39
     * @param Signature $signature
40
     * @return Buffer
41
     */
42 27
    private function doSerialize(Signature $signature)
43
    {
44 27
        $signatureOut = '';
45 27
        if (!secp256k1_ecdsa_signature_serialize_der($this->ecAdapter->getContext(), $signatureOut, $signature->getResource())) {
46
            throw new \RuntimeException('Secp256k1: serialize der failure');
47
        }
48
49 27
        return new Buffer($signatureOut);
50
    }
51
52
    /**
53
     * @param SignatureInterface $signature
54
     * @return Buffer
55
     */
56 27
    public function serialize(SignatureInterface $signature)
57
    {
58
        /** @var Signature $signature */
59 27
        return $this->doSerialize($signature);
60
    }
61
62
    /**
63
     * @return Template
64
     */
65 162
    private function getInnerTemplate()
66
    {
67 162
        return (new TemplateFactory())
68 162
            ->uint8()
69 162
            ->varstring()
70 162
            ->uint8()
71 162
            ->varstring()
72 162
            ->getTemplate();
73
    }
74
75
    /**
76
     * @return Template
77
     */
78 162
    private function getOuterTemplate()
79
    {
80 162
        return (new TemplateFactory())
81 162
            ->uint8()
82 162
            ->varstring()
83 162
            ->getTemplate();
84
    }
85
86
    /**
87
     * @param string $data
88
     * @return SignatureInterface
89
     */
90 215
    public function parse($data)
91
    {
92 215
        $buffer = (new Parser($data))->getBuffer();
93 215
        $binary = $buffer->getBinary();
94
95 215
        $sig_t = '';
96
        /** @var resource $sig_t */
97 215
        if (!ecdsa_signature_parse_der_lax($this->ecAdapter->getContext(), $sig_t, $binary)) {
98 57
            throw new \RuntimeException('Secp256k1: parse der failure');
99
        }
100
101
        // Unfortunately, we need to use the Parser here to get r and s :/
102 162
        list (, $inner) = $this->getOuterTemplate()->parse(new Parser($buffer));
103 162
        list (, $r, , $s) = $this->getInnerTemplate()->parse(new Parser($inner));
104
        /** @var Buffer $r */
105
        /** @var Buffer $s */
106
107 162
        return new Signature($this->ecAdapter, $r->getGmp(), $s->getGmp(), $sig_t);
108
    }
109
}
110