Completed
Push — master ( a22894...37130c )
by thomas
62:03 queued 58:09
created

PrivateKey::tweakAdd()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 14
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 18
ccs 15
cts 15
cp 1
crap 1
rs 9.4285
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
17
class PrivateKey extends Key implements PrivateKeyInterface
18
{
19
    /**
20
     * @var int|string
21
     */
22
    private $secretMultiplier;
23
24
    /**
25
     * @var bool
26
     */
27
    private $compressed;
28
29
    /**
30
     * @var PublicKey
31
     */
32
    private $publicKey;
33
34
    /**
35
     * @var EcAdapter
36
     */
37
    private $ecAdapter;
38
39
    /**
40
     * @param EcAdapter $ecAdapter
41
     * @param $int
42
     * @param bool $compressed
43
     * @throws InvalidPrivateKey
44
     */
45 125
    public function __construct(EcAdapter $ecAdapter, $int, $compressed = false)
46
    {
47 125
        if (false === $ecAdapter->validatePrivateKey(Buffer::int($int, 32, $ecAdapter->getMath()))) {
48 2
            throw new InvalidPrivateKey('Invalid private key - must be less than curve order.');
49
        }
50
51 123
        if (false === is_bool($compressed)) {
52
            throw new \InvalidArgumentException('PrivateKey: Compressed argument must be a boolean');
53
        }
54
        
55 123
        $this->ecAdapter = $ecAdapter;
56 123
        $this->secretMultiplier = $int;
57 123
        $this->compressed = $compressed;
58 123
    }
59
60
    /**
61
     * @return int|string
62
     */
63 112
    public function getSecretMultiplier()
64
    {
65 112
        return $this->secretMultiplier;
66
    }
67
68
    /**
69
     * @param BufferInterface $msg32
70
     * @param RbgInterface|null $rbg
71
     * @return \BitWasp\Bitcoin\Crypto\EcAdapter\Signature\SignatureInterface
72
     */
73
    public function sign(BufferInterface $msg32, RbgInterface $rbg = null)
74
    {
75
        return $this->ecAdapter->sign($msg32, $this, $rbg);
76
    }
77
78
    /**
79
     * @param int|string $tweak
80
     * @return PrivateKeyInterface
81
     */
82 14
    public function tweakAdd($tweak)
83
    {
84 14
        $adapter = $this->ecAdapter;
85 14
        return $adapter->getPrivateKey(
86 7
            gmp_strval($adapter
87 14
                ->getMath()
88 14
                ->getModularArithmetic(
89
                    $adapter
90 14
                        ->getGenerator()
91 14
                        ->getOrder()
92 7
                )
93 14
                ->add(
94 14
                    gmp_init($tweak, 10),
95 14
                    gmp_init($this->getSecretMultiplier(), 10)
96 14
                ), 10),
97 14
            $this->compressed
98 7
        );
99
    }
100
101
    /**
102
     * @param int|string $tweak
103
     * @return PrivateKeyInterface
104
     */
105 2
    public function tweakMul($tweak)
106
    {
107 2
        $adapter = $this->ecAdapter;
108 2
        return $adapter->getPrivateKey(
109 1
            gmp_strval($adapter
110 2
            ->getMath()
111 2
            ->getModularArithmetic(
112
                $adapter
113 2
                    ->getGenerator()
114 2
                    ->getOrder()
115 1
            )
116 2
            ->mul(
117 2
                gmp_init($tweak, 10),
118 2
                gmp_init($this->getSecretMultiplier(), 10)
119 2
            ), 10),
120 2
            $this->compressed
121 1
        );
122
    }
123
124
    /**
125
     * {@inheritDoc}
126
     */
127 66
    public function isCompressed()
128
    {
129 66
        return $this->compressed;
130
    }
131
132
    /**
133
     * Return the public key
134
     *
135
     * @return PublicKey
136
     */
137 129
    public function getPublicKey()
138
    {
139 129
        if (null === $this->publicKey) {
140 105
            $adapter = $this->ecAdapter;
141 105
            $this->publicKey = $adapter->getPublicKey(
142
                $adapter
143 105
                    ->getGenerator()
144 105
                    ->mul(gmp_init($this->secretMultiplier, 10)),
145 105
                $this->compressed
146 53
            );
147 53
        }
148
149 129
        return $this->publicKey;
150
    }
151
152
    /**
153
     * @param NetworkInterface $network
154
     * @return string
155
     */
156 6
    public function toWif(NetworkInterface $network = null)
157
    {
158 6
        $network = $network ?: Bitcoin::getNetwork();
159 6
        $serializer = new WifPrivateKeySerializer(
160 6
            $this->ecAdapter->getMath(),
161 6
            new PrivateKeySerializer($this->ecAdapter)
162 3
        );
163
164 6
        return $serializer->serialize($network, $this);
165
    }
166
167
    /**
168
     * @return \BitWasp\Buffertools\BufferInterface
169
     */
170 66
    public function getBuffer()
171
    {
172 66
        return (new PrivateKeySerializer($this->ecAdapter))->serialize($this);
173
    }
174
}
175