Completed
Push — master ( a8a46d...6b0176 )
by thomas
23:45
created

HierarchicalKeyFactory::fromEntropy()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 2
dl 0
loc 8
ccs 6
cts 6
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Bitcoin\Key\Factory;
6
7
use BitWasp\Bitcoin\Bitcoin;
8
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
9
use BitWasp\Bitcoin\Crypto\EcAdapter\EcSerializer;
10
use BitWasp\Bitcoin\Crypto\EcAdapter\Serializer\Key\PublicKeySerializerInterface;
11
use BitWasp\Bitcoin\Crypto\Hash;
12
use BitWasp\Bitcoin\Crypto\Random\Random;
13
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey;
14
use BitWasp\Bitcoin\Key\KeyToScript\Factory\P2pkhScriptDataFactory;
15
use BitWasp\Bitcoin\Key\KeyToScript\ScriptDataFactory;
16
use BitWasp\Bitcoin\Network\NetworkInterface;
17
use BitWasp\Bitcoin\Serializer\Key\HierarchicalKey\Base58ExtendedKeySerializer;
18
use BitWasp\Bitcoin\Serializer\Key\HierarchicalKey\ExtendedKeySerializer;
19
use BitWasp\Buffertools\Buffer;
20
use BitWasp\Buffertools\BufferInterface;
21
22
class HierarchicalKeyFactory
23
{
24
    /**
25
     * @var EcAdapterInterface
26
     */
27
    private $adapter;
28
29
    /**
30
     * @var Base58ExtendedKeySerializer
31
     */
32
    private $serializer;
33
34
    /**
35
     * @var PrivateKeyFactory
36
     */
37
    private $privFactory;
38
39
    /**
40
     * HierarchicalKeyFactory constructor.
41
     * @param EcAdapterInterface|null $ecAdapter
42
     * @param Base58ExtendedKeySerializer|null $serializer
43
     * @throws \Exception
44
     */
45 71
    public function __construct(EcAdapterInterface $ecAdapter = null, Base58ExtendedKeySerializer $serializer = null)
46
    {
47 71
        $this->adapter = $ecAdapter ?: Bitcoin::getEcAdapter();
48 71
        $this->privFactory = PrivateKeyFactory::compressed($this->adapter);
49 71
        $this->serializer = $serializer ?: new Base58ExtendedKeySerializer(
50 71
            new ExtendedKeySerializer($this->adapter)
51
        );
52 71
    }
53
54
    /**
55
     * @param Random $random
56
     * @param ScriptDataFactory|null $scriptDataFactory
57
     * @return HierarchicalKey
58
     * @throws \BitWasp\Bitcoin\Exceptions\RandomBytesFailure
59
     * @throws \Exception
60
     */
61 8
    public function generateMasterKey(Random $random, ScriptDataFactory $scriptDataFactory = null): HierarchicalKey
62
    {
63 8
        return $this->fromEntropy(
64 8
            $random->bytes(64),
65 8
            $scriptDataFactory
66
        );
67
    }
68
69
    /**
70
     * @param BufferInterface $entropy
71
     * @param ScriptDataFactory|null $scriptFactory
72
     * @return HierarchicalKey
73
     * @throws \Exception
74
     */
75 37
    public function fromEntropy(BufferInterface $entropy, ScriptDataFactory $scriptFactory = null): HierarchicalKey
76
    {
77 37
        $seed = Hash::hmac('sha512', $entropy, new Buffer('Bitcoin seed'));
78 37
        $privSecret = $seed->slice(0, 32);
79 37
        $chainCode = $seed->slice(32, 32);
80 37
        $scriptFactory = $scriptFactory ?: new P2pkhScriptDataFactory(EcSerializer::getSerializer(PublicKeySerializerInterface::class, true, $this->adapter));
81 37
        return new HierarchicalKey($this->adapter, $scriptFactory, 0, 0, 0, $chainCode, $this->privFactory->fromBuffer($privSecret));
82
    }
83
84
    /**
85
     * @param string $extendedKey
86
     * @param NetworkInterface|null $network
87
     * @return HierarchicalKey
88
     * @throws \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure
89
     * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange
90
     */
91 34
    public function fromExtended(string $extendedKey, NetworkInterface $network = null): HierarchicalKey
92
    {
93 34
        return $this->serializer->parse($network ?: Bitcoin::getNetwork(), $extendedKey);
94
    }
95
}
96