File Coverage

blib/lib/Blockchain/Ethereum/Keystore/Key.pm
Criterion Covered Total %
statement 42 54 77.7
branch 0 2 0.0
condition n/a
subroutine 15 17 88.2
pod 3 6 50.0
total 60 79 75.9


line stmt bran cond sub pod time code
1 4     4   108432 use v5.26;
  4         34  
2 4     4   650 use Object::Pad;
  4         11680  
  4         29  
3              
4             package Blockchain::Ethereum::Keystore::Key 0.005;
5             class Blockchain::Ethereum::Keystore::Key;
6              
7             =encoding utf8
8              
9             =head1 NAME
10              
11             Blockchain::Ethereum::Keystore::Key - Private key abstraction
12              
13             =head1 SYNOPSIS
14              
15             Private key abstraction
16              
17             If instantiated without a private key, this module uses L<Crypt::PRNG> for the random key generation
18              
19             my $key = Blockchain::Ethereum::Key->new;
20             $key->sign_transaction($transaction);
21             ...
22              
23             =cut
24              
25 4     4   1703 use Carp;
  4         9  
  4         299  
26 4     4   3738 use Crypt::PK::ECC;
  4         67830  
  4         255  
27 4     4   2141 use Crypt::Perl::ECDSA::Parse;
  4         438076  
  4         239  
28 4     4   46 use Crypt::Perl::ECDSA::Utils;
  4         10  
  4         146  
29 4     4   2261 use Crypt::Digest::Keccak256 qw(keccak256);
  4         3209  
  4         337  
30 4     4   37 use Crypt::PRNG qw(random_bytes);
  4         11  
  4         219  
31              
32 4     4   2121 use Blockchain::Ethereum::Keystore::Key::PKUtil;
  4         13  
  4         203  
33 4     4   1960 use Blockchain::Ethereum::Keystore::Address;
  4         25  
  4         4599  
34              
35             field $private_key :reader :writer :param //= undef;
36 9     9 0 22 field $_ecc_handler :reader(_ecc_handler) :writer(set_ecc_handler);
  9     32 0 60  
  32     13 0 84  
  32     0   76046  
  13         504415  
  13         252  
  0         0  
  0         0  
37              
38             ADJUST {
39             # if the private key is not set, generate a new one
40             $self->set_private_key(random_bytes(32)) unless defined $self->private_key;
41              
42             my $importer = Crypt::PK::ECC->new();
43             $importer->import_key_raw($self->private_key, 'secp256k1');
44              
45             # Crypt::PK::ECC does not provide support for deterministic keys
46             $self->set_ecc_handler(bless Crypt::Perl::ECDSA::Parse::private($importer->export_key_der('private')),
47             'Blockchain::Ethereum::Keystore::Key::PKUtil');
48              
49             }
50              
51             =head2 sign_transaction
52              
53             Sign a L<Blockchain::Ethereum::Transaction> object
54              
55             Usage:
56              
57             sign_transaction($transaction) -> $$transaction
58              
59             =over 4
60              
61             =item * C<$transaction> - L<Blockchain::Ethereum::Transaction> subclass
62              
63             =back
64              
65             self
66              
67             =cut
68              
69 0     0 1 0 method sign_transaction ($transaction) {
  0         0  
  0         0  
  0         0  
70              
71 0 0       0 croak "transaction must be a reference from Blockchain::Ethereum::Transaction"
72             unless ref($transaction) =~ /^\QBlockchain::Ethereum::Transaction/;
73              
74             # _sign is overriden by Blockchain::ethereum::Keystore::Key::PKUtil
75             # to include the y_parity as part of the response
76 0         0 my ($r, $s, $y_parity) = $self->_ecc_handler->_sign($transaction->hash);
77              
78 0         0 $transaction->set_r($r->as_hex);
79 0         0 $transaction->set_s($s->as_hex);
80 0         0 $transaction->generate_v($y_parity);
81              
82 0         0 return $transaction;
83             }
84              
85             =head2 address
86              
87             Export the L<Blockchain::Ethereum::Keystore::Address> from the imported/generated private key
88              
89             Usage:
90              
91             address() -> L<Blockchain::Ethereum::Keystore::Address>
92              
93             =over 4
94              
95             =back
96              
97             L<Blockchain::Ethereum::Keystore::Address>
98              
99             =cut
100              
101 9     9 1 66 method address {
102              
103 9         42 my ($x, $y) = Crypt::Perl::ECDSA::Utils::split_G_or_public($self->_ecc_handler->_decompress_public_point);
104              
105             # address is the hash of the concatenated value of x and y
106 9         389 my $address = substr(keccak256($x . $y), -20);
107 9         165 my $hex_address = unpack("H*", $address);
108              
109 9         97 return Blockchain::Ethereum::Keystore::Address->new(address => "0x$hex_address");
110             }
111              
112             =head2 export
113              
114             Export the private key bytes
115              
116             Usage:
117              
118             export() -> private key bytes
119              
120             =over 4
121              
122             =back
123              
124             Private key bytes
125              
126             =cut
127              
128 6     6 1 18 method export {
129              
130 6         25 return $self->private_key;
131             }
132              
133             1;
134              
135             __END__
136              
137             =head1 AUTHOR
138              
139             Reginaldo Costa, C<< <refeco at cpan.org> >>
140              
141             =head1 BUGS
142              
143             Please report any bugs or feature requests to L<https://github.com/refeco/perl-ethereum-keystore>
144              
145             =head1 LICENSE AND COPYRIGHT
146              
147             This software is Copyright (c) 2023 by REFECO.
148              
149             This is free software, licensed under:
150              
151             The MIT License
152              
153             =cut