line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Bitcoin::Crypto::Role::Key; |
2
|
|
|
|
|
|
|
$Bitcoin::Crypto::Role::Key::VERSION = '2.000_01'; # TRIAL |
3
|
|
|
|
|
|
|
$Bitcoin::Crypto::Role::Key::VERSION = '2.00001'; |
4
|
16
|
|
|
16
|
|
8283
|
use v5.10; |
|
16
|
|
|
|
|
72
|
|
5
|
16
|
|
|
16
|
|
121
|
use strict; |
|
16
|
|
|
|
|
45
|
|
|
16
|
|
|
|
|
343
|
|
6
|
16
|
|
|
16
|
|
102
|
use warnings; |
|
16
|
|
|
|
|
47
|
|
|
16
|
|
|
|
|
431
|
|
7
|
16
|
|
|
16
|
|
89
|
use Crypt::PK::ECC; |
|
16
|
|
|
|
|
34
|
|
|
16
|
|
|
|
|
803
|
|
8
|
16
|
|
|
16
|
|
108
|
use Scalar::Util qw(blessed); |
|
16
|
|
|
|
|
51
|
|
|
16
|
|
|
|
|
882
|
|
9
|
16
|
|
|
16
|
|
124
|
use Mooish::AttributeBuilder -standard; |
|
16
|
|
|
|
|
48
|
|
|
16
|
|
|
|
|
143
|
|
10
|
16
|
|
|
16
|
|
2157
|
use Type::Params -sigs; |
|
16
|
|
|
|
|
58
|
|
|
16
|
|
|
|
|
107
|
|
11
|
|
|
|
|
|
|
|
12
|
16
|
|
|
16
|
|
7402
|
use Bitcoin::Crypto::Types qw(Object InstanceOf BIP44Purpose Enum); |
|
16
|
|
|
|
|
74
|
|
|
16
|
|
|
|
|
107
|
|
13
|
16
|
|
|
16
|
|
61558
|
use Bitcoin::Crypto::Constants; |
|
16
|
|
|
|
|
51
|
|
|
16
|
|
|
|
|
471
|
|
14
|
16
|
|
|
16
|
|
105
|
use Bitcoin::Crypto::Util qw(get_key_type); |
|
16
|
|
|
|
|
61
|
|
|
16
|
|
|
|
|
745
|
|
15
|
16
|
|
|
16
|
|
104
|
use Bitcoin::Crypto::Helpers qw(ensure_length); # loads Math::BigInt |
|
16
|
|
|
|
|
45
|
|
|
16
|
|
|
|
|
671
|
|
16
|
16
|
|
|
16
|
|
102
|
use Bitcoin::Crypto::Exception; |
|
16
|
|
|
|
|
54
|
|
|
16
|
|
|
|
|
2520
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sub __create_key |
19
|
|
|
|
|
|
|
{ |
20
|
566
|
|
|
566
|
|
133302
|
my ($entropy) = @_; |
21
|
|
|
|
|
|
|
|
22
|
566
|
100
|
66
|
|
|
3657
|
return $entropy |
23
|
|
|
|
|
|
|
if blessed($entropy) && $entropy->isa('Crypt::PK::ECC'); |
24
|
|
|
|
|
|
|
|
25
|
505
|
|
|
|
|
1573
|
my $is_private = get_key_type $entropy; |
26
|
|
|
|
|
|
|
|
27
|
505
|
100
|
|
|
|
1263
|
Bitcoin::Crypto::Exception::KeyCreate->raise( |
28
|
|
|
|
|
|
|
'invalid entropy data passed to key creation method' |
29
|
|
|
|
|
|
|
) unless defined $is_private; |
30
|
|
|
|
|
|
|
|
31
|
504
|
100
|
|
|
|
1695
|
$entropy = ensure_length $entropy, Bitcoin::Crypto::Constants::key_max_length |
32
|
|
|
|
|
|
|
if $is_private; |
33
|
|
|
|
|
|
|
|
34
|
504
|
|
|
|
|
2309
|
my $key = Crypt::PK::ECC->new(); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
Bitcoin::Crypto::Exception::KeyCreate->trap_into( |
37
|
|
|
|
|
|
|
sub { |
38
|
504
|
|
|
504
|
|
2308792
|
$key->import_key_raw($entropy, Bitcoin::Crypto::Constants::curve_name); |
39
|
|
|
|
|
|
|
} |
40
|
504
|
|
|
|
|
34192
|
); |
41
|
|
|
|
|
|
|
|
42
|
503
|
|
|
|
|
14359
|
return $key; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
16
|
|
|
16
|
|
169
|
use Moo::Role; |
|
16
|
|
|
|
|
40
|
|
|
16
|
|
|
|
|
122
|
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
has param 'key_instance' => ( |
48
|
|
|
|
|
|
|
isa => InstanceOf ['Crypt::PK::ECC'], |
49
|
|
|
|
|
|
|
coerce => \&__create_key, |
50
|
|
|
|
|
|
|
); |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
has param 'purpose' => ( |
53
|
|
|
|
|
|
|
isa => BIP44Purpose, |
54
|
|
|
|
|
|
|
writer => 1, |
55
|
|
|
|
|
|
|
clearer => 1, |
56
|
|
|
|
|
|
|
required => 0, |
57
|
|
|
|
|
|
|
); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
with qw(Bitcoin::Crypto::Role::Network); |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
requires qw( |
62
|
|
|
|
|
|
|
_is_private |
63
|
|
|
|
|
|
|
); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub BUILD |
66
|
|
|
|
|
|
|
{ |
67
|
547
|
|
|
547
|
0
|
34965
|
my ($self) = @_; |
68
|
|
|
|
|
|
|
|
69
|
547
|
100
|
|
|
|
4143
|
Bitcoin::Crypto::Exception::KeyCreate->raise( |
70
|
|
|
|
|
|
|
'trying to create key from unknown key data' |
71
|
|
|
|
|
|
|
) unless $self->key_instance->is_private == $self->_is_private; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
signature_for has_purpose => ( |
75
|
|
|
|
|
|
|
method => Object, |
76
|
|
|
|
|
|
|
positional => [BIP44Purpose], |
77
|
|
|
|
|
|
|
); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub has_purpose |
80
|
|
|
|
|
|
|
{ |
81
|
|
|
|
|
|
|
my ($self, $purpose) = @_; |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
return !$self->purpose || $self->purpose == $purpose; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# __create_key for object usage |
87
|
|
|
|
|
|
|
sub _create_key |
88
|
|
|
|
|
|
|
{ |
89
|
17
|
|
|
17
|
|
32
|
shift; |
90
|
17
|
|
|
|
|
78
|
goto \&__create_key; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
signature_for raw_key => ( |
94
|
|
|
|
|
|
|
method => Object, |
95
|
|
|
|
|
|
|
positional => [Enum [qw(private public public_compressed)], {optional => 1}], |
96
|
|
|
|
|
|
|
); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub raw_key |
99
|
|
|
|
|
|
|
{ |
100
|
|
|
|
|
|
|
my ($self, $type) = @_; |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
unless (defined $type) { |
103
|
|
|
|
|
|
|
$type = 'public_compressed'; |
104
|
|
|
|
|
|
|
if ($self->_is_private) { |
105
|
|
|
|
|
|
|
$type = 'private'; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
elsif ($self->does('Bitcoin::Crypto::Role::Compressed') && !$self->compressed) { |
108
|
|
|
|
|
|
|
$type = 'public'; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
return $self->key_instance->export_key_raw($type); |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub curve_order |
115
|
|
|
|
|
|
|
{ |
116
|
206
|
|
|
206
|
0
|
477
|
my ($self) = @_; |
117
|
|
|
|
|
|
|
|
118
|
206
|
|
|
|
|
885
|
return Math::BigInt->from_hex($self->key_instance->curve2hash->{order}); |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
1; |
122
|
|
|
|
|
|
|
|