File Coverage

blib/lib/Bitcoin/Crypto/Role/Key.pm
Criterion Covered Total %
statement 57 57 100.0
branch 14 14 100.0
condition 8 9 88.8
subroutine 18 18 100.0
pod 0 3 0.0
total 97 101 96.0


line stmt bran cond sub pod time code
1             package Bitcoin::Crypto::Role::Key;
2             $Bitcoin::Crypto::Role::Key::VERSION = '1.008_01'; # TRIAL
3             $Bitcoin::Crypto::Role::Key::VERSION = '1.00801';
4 10     10   5300 use v5.10;
  10         38  
5 10     10   63 use strict;
  10         22  
  10         239  
6 10     10   55 use warnings;
  10         25  
  10         334  
7 10     10   66 use Crypt::PK::ECC;
  10         25  
  10         518  
8 10     10   68 use Scalar::Util qw(blessed);
  10         42  
  10         580  
9 10     10   86 use Mooish::AttributeBuilder -standard;
  10         23  
  10         113  
10              
11 10     10   1514 use Bitcoin::Crypto::Types qw(InstanceOf BIP44Purpose);
  10         35  
  10         102  
12 10     10   27424 use Bitcoin::Crypto::Config;
  10         29  
  10         261  
13 10     10   4370 use Bitcoin::Crypto::Util qw(get_key_type);
  10         37  
  10         670  
14 10     10   100 use Bitcoin::Crypto::Helpers qw(ensure_length);
  10         34  
  10         480  
15 10     10   79 use Bitcoin::Crypto::Exception;
  10         34  
  10         1645  
16              
17             sub __create_key
18             {
19 562     562   1589 my ($entropy) = @_;
20              
21 562 100 66     3549 return $entropy
22             if blessed($entropy) && $entropy->isa('Crypt::PK::ECC');
23              
24 502         1472 my $is_private = get_key_type $entropy;
25              
26 502 100       1195 Bitcoin::Crypto::Exception::KeyCreate->raise(
27             'invalid entropy data passed to key creation method'
28             ) unless defined $is_private;
29              
30 501 100       1794 $entropy = ensure_length $entropy, Bitcoin::Crypto::Config::key_max_length
31             if $is_private;
32              
33 501         2078 my $key = Crypt::PK::ECC->new();
34              
35             Bitcoin::Crypto::Exception::KeyCreate->trap_into(
36             sub {
37 501     501   2525663 $key->import_key_raw($entropy, Bitcoin::Crypto::Config::curve_name);
38             }
39 501         30202 );
40              
41 500         15153 return $key;
42             }
43              
44              
45 10     10   82 use Moo::Role;
  10         21  
  10         117  
46              
47             has param 'key_instance' => (
48             isa => InstanceOf ['Crypt::PK::ECC'],
49             coerce => sub { __create_key($_[0]) },
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 545     545 0 35549 my ($self) = @_;
68              
69 545 100       3557 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             sub has_purpose
75             {
76 51     51 0 117 my ($self, $purpose) = @_;
77              
78 51   100     323 return !$self->purpose || $self->purpose == $purpose;
79             }
80              
81             # __create_key for object usage
82             sub _create_key
83             {
84 15     15   34 shift;
85 15         67 goto \&__create_key;
86             }
87              
88             sub raw_key
89             {
90 1139     1139 0 2366 my ($self, $type) = @_;
91              
92 1139 100       2606 unless (defined $type) {
93 570         994 $type = 'public_compressed';
94 570 100 100     1341 if ($self->_is_private) {
    100          
95 443         809 $type = 'private';
96             }
97             elsif ($self->does('Bitcoin::Crypto::Role::Compressed') && !$self->compressed) {
98 7         326 $type = 'public';
99             }
100             }
101 1139         15877 return $self->key_instance->export_key_raw($type);
102             }
103              
104             1;
105