Completed
Pull Request — master (#364)
by thomas
21:20 queued 30s
created

PrivateKey::getBuffer()   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\PhpEcc\Key;
4
5
use BitWasp\Bitcoin\Bitcoin;
6
use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Adapter\EcAdapter;
7
use BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Serializer\Key\PrivateKeySerializer;
8
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\Key;
9
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PrivateKeyInterface;
10
use BitWasp\Bitcoin\Crypto\Random\RbgInterface;
11
use BitWasp\Bitcoin\Exceptions\InvalidPrivateKey;
12
use BitWasp\Bitcoin\Network\NetworkInterface;
13
use BitWasp\Bitcoin\Serializer\Key\PrivateKey\WifPrivateKeySerializer;
14
use BitWasp\Buffertools\Buffer;
15
use BitWasp\Buffertools\BufferInterface;
16
use Mdanter\Ecc\Crypto\EcDH\EcDH;
17
18
class PrivateKey extends Key implements PrivateKeyInterface, \Mdanter\Ecc\Crypto\Key\PrivateKeyInterface
19
{
20
    /**
21
     * @var \GMP
22
     */
23
    private $secretMultiplier;
24
25
    /**
26
     * @var bool
27
     */
28
    private $compressed;
29
30
    /**
31
     * @var PublicKey
32
     */
33
    private $publicKey;
34
35
    /**
36
     * @var EcAdapter
37
     */
38
    private $ecAdapter;
39
40
    /**
41
     * @param EcAdapter $ecAdapter
42
     * @param \GMP $int
43
     * @param bool $compressed
44
     * @throws InvalidPrivateKey
45
     */
46 35
    public function __construct(EcAdapter $ecAdapter, \GMP $int, $compressed = false)
47
    {
48 35
        if (false === $ecAdapter->validatePrivateKey(Buffer::int(gmp_strval($int, 10), 32, $ecAdapter->getMath()))) {
49
            throw new InvalidPrivateKey('Invalid private key - must be less than curve order.');
50
        }
51
52 35
        if (false === is_bool($compressed)) {
53
            throw new \InvalidArgumentException('PrivateKey: Compressed argument must be a boolean');
54
        }
55
        
56 35
        $this->ecAdapter = $ecAdapter;
57 35
        $this->secretMultiplier = $int;
58 35
        $this->compressed = $compressed;
59 35
    }
60
61
    /**
62
     * @return \Mdanter\Ecc\Primitives\GeneratorPoint
63
     */
64 28
    public function getPoint()
65
    {
66 28
        return $this->ecAdapter->getGenerator();
67
    }
68
69
    /**
70
     * @return \GMP
71
     */
72 40
    public function getSecret()
73
    {
74 40
        return $this->secretMultiplier;
75
    }
76
77
    /**
78
     * @param \Mdanter\Ecc\Crypto\Key\PublicKeyInterface $recipient
79
     * @return EcDH
80
     */
81
    public function createExchange(\Mdanter\Ecc\Crypto\Key\PublicKeyInterface $recipient)
82
    {
83
        $ecdh = new EcDH($this->ecAdapter->getMath());
84
        $ecdh->setSenderKey($this);
85
        $ecdh->setRecipientKey($recipient);
86
        return $ecdh;
87
    }
88
89
    /**
90
     * @param BufferInterface $msg32
91
     * @param RbgInterface|null $rbg
92
     * @return \BitWasp\Bitcoin\Crypto\EcAdapter\Signature\SignatureInterface
93
     */
94
    public function sign(BufferInterface $msg32, RbgInterface $rbg = null)
95
    {
96
        return $this->ecAdapter->sign($msg32, $this, $rbg);
97
    }
98
99
    /**
100
     * @param \GMP $tweak
101
     * @return PrivateKeyInterface
102
     */
103 6
    public function tweakAdd(\GMP $tweak)
104
    {
105 6
        $adapter = $this->ecAdapter;
106 6
        return $adapter->getPrivateKey(
107
            $adapter
108 6
                ->getMath()
109 6
                ->getModularArithmetic(
110
                    $adapter
111 6
                        ->getGenerator()
112 6
                        ->getOrder()
113 6
                )
114 6
                ->add(
115 6
                    $tweak,
116 6
                    $this->getSecret()
117 6
                ),
118 6
            $this->compressed
119 6
        );
120
    }
121
122
    /**
123
     * @param \GMP $tweak
124
     * @return PrivateKeyInterface
125
     */
126
    public function tweakMul(\GMP $tweak)
127
    {
128
        $adapter = $this->ecAdapter;
129
        return $adapter->getPrivateKey(
130
            $adapter
131
            ->getMath()
132
            ->getModularArithmetic(
133
                $adapter
134
                    ->getGenerator()
135
                    ->getOrder()
136
            )
137
            ->mul(
138
                $tweak,
139
                $this->getSecret()
140
            ),
141
            $this->compressed
142
        );
143
    }
144
145
    /**
146
     * {@inheritDoc}
147
     */
148 18
    public function isCompressed()
149
    {
150 18
        return $this->compressed;
151
    }
152
153
    /**
154
     * Return the public key
155
     *
156
     * @return PublicKey
157
     */
158 57
    public function getPublicKey()
159
    {
160 57
        if (null === $this->publicKey) {
161 33
            $adapter = $this->ecAdapter;
162 33
            $this->publicKey = $adapter->getPublicKey(
163
                $adapter
164 33
                    ->getGenerator()
165 33
                    ->mul($this->secretMultiplier),
166 33
                $this->compressed
167 33
            );
168 33
        }
169
170 57
        return $this->publicKey;
171
    }
172
173
    /**
174
     * @param NetworkInterface $network
175
     * @return string
176
     */
177
    public function toWif(NetworkInterface $network = null)
178
    {
179
        $network = $network ?: Bitcoin::getNetwork();
180
        $serializer = new WifPrivateKeySerializer(
181
            $this->ecAdapter->getMath(),
182
            new PrivateKeySerializer($this->ecAdapter)
183
        );
184
185
        return $serializer->serialize($network, $this);
186
    }
187
188
    /**
189
     * @return \BitWasp\Buffertools\BufferInterface
190
     */
191 32
    public function getBuffer()
192
    {
193 32
        return (new PrivateKeySerializer($this->ecAdapter))->serialize($this);
194
    }
195
}
196