File Coverage

blib/lib/Bitcoin/Crypto/Key/Private.pm
Criterion Covered Total %
statement 48 48 100.0
branch n/a
condition n/a
subroutine 17 17 100.0
pod n/a
total 65 65 100.0


line stmt bran cond sub pod time code
1             package Bitcoin::Crypto::Key::Private;
2             $Bitcoin::Crypto::Key::Private::VERSION = '2.000_01'; # TRIAL
3             $Bitcoin::Crypto::Key::Private::VERSION = '2.00001';
4 13     13   170 use v5.10;
  13         54  
5 13     13   87 use strict;
  13         55  
  13         279  
6 13     13   84 use warnings;
  13         28  
  13         313  
7 13     13   676 use Moo;
  13         7143  
  13         80  
8 13     13   7812 use Crypt::PK::ECC;
  13         15290  
  13         728  
9 13     13   1144 use Bitcoin::BIP39 qw(bip39_mnemonic_to_entropy entropy_to_bip39_mnemonic);
  13         3212  
  13         861  
10 13     13   720 use Type::Params -sigs;
  13         128101  
  13         119  
11              
12 13     13   12491 use Bitcoin::Crypto::Key::Public;
  13         68  
  13         686  
13 13     13   112 use Bitcoin::Crypto::Base58 qw(encode_base58check decode_base58check);
  13         40  
  13         958  
14 13     13   101 use Bitcoin::Crypto::Types qw(Object Str Maybe);
  13         42  
  13         128  
15 13     13   40390 use Bitcoin::Crypto::Constants;
  13         42  
  13         345  
16 13     13   75 use Bitcoin::Crypto::Network;
  13         39  
  13         380  
17 13     13   77 use Bitcoin::Crypto::Util qw(validate_wif);
  13         45  
  13         733  
18 13     13   104 use Bitcoin::Crypto::Helpers qw(ensure_length);
  13         35  
  13         639  
19 13     13   90 use Bitcoin::Crypto::Exception;
  13         48  
  13         358  
20              
21 13     13   93 use namespace::clean;
  13         50  
  13         216  
22              
23             with qw(Bitcoin::Crypto::Role::BasicKey);
24              
25 112     112   619 sub _is_private { 1 }
26              
27             signature_for to_wif => (
28             method => Object,
29             positional => [],
30             );
31              
32             sub to_wif
33             {
34             my ($self) = @_;
35             my $bytes = $self->to_serialized();
36              
37             # wif network - 1B
38             my $wifdata = $self->network->wif_byte;
39              
40             # key entropy - 32B
41             $wifdata .= ensure_length $bytes, Bitcoin::Crypto::Constants::key_max_length;
42              
43             # additional byte for compressed key - 1B
44             $wifdata .= Bitcoin::Crypto::Constants::wif_compressed_byte if $self->compressed;
45              
46             return encode_base58check($wifdata);
47             }
48              
49             signature_for from_wif => (
50             method => Str,
51             positional => [Str, Maybe [Str], {optional => 1}],
52             );
53              
54             sub from_wif
55             {
56             my ($class, $wif, $network) = @_;
57              
58             Bitcoin::Crypto::Exception::KeyCreate->raise(
59             'base58 string is not valid WIF'
60             ) unless validate_wif($wif);
61              
62             my $decoded = decode_base58check($wif);
63             my $private = substr $decoded, 1;
64              
65             my $compressed = 0;
66             if (length($private) > Bitcoin::Crypto::Constants::key_max_length) {
67             chop $private;
68             $compressed = 1;
69             }
70              
71             my $wif_network_byte = substr $decoded, 0, 1;
72             my @found_networks =
73             Bitcoin::Crypto::Network->find(sub { shift->wif_byte eq $wif_network_byte });
74             @found_networks = grep { $_ eq $network } @found_networks
75             if defined $network;
76              
77             Bitcoin::Crypto::Exception::KeyCreate->raise(
78             'found multiple networks possible for given WIF'
79             ) if @found_networks > 1;
80              
81             Bitcoin::Crypto::Exception::KeyCreate->raise(
82             "network name $network cannot be used for given WIF"
83             ) if @found_networks == 0 && defined $network;
84              
85             Bitcoin::Crypto::Exception::NetworkConfig->raise(
86             "couldn't find network for WIF byte $wif_network_byte"
87             ) if @found_networks == 0;
88              
89             my $instance = $class->from_serialized($private);
90             $instance->set_compressed($compressed);
91             $instance->set_network(@found_networks);
92             return $instance;
93             }
94              
95             signature_for get_public_key => (
96             method => Object,
97             positional => [],
98             );
99              
100             sub get_public_key
101             {
102             my ($self) = @_;
103              
104             my $public = Bitcoin::Crypto::Key::Public->new(
105             key_instance => $self->raw_key('public'),
106             compressed => $self->compressed,
107             network => $self->network,
108             purpose => $self->purpose,
109             );
110              
111             return $public;
112             }
113              
114             1;
115              
116             __END__
117             =head1 NAME
118              
119             Bitcoin::Crypto::Key::Private - Bitcoin private keys
120              
121             =head1 SYNOPSIS
122              
123             use Bitcoin::Crypto::Key::Private;
124              
125             # get Bitcoin::Crypto::Key::Public instance from private key
126              
127             my $pub = $priv->get_public_key();
128              
129             # automatically sign standard transactions
130              
131             $priv->sign_transaction($tx, signing_index => $n);
132              
133             # create signature for custom message (hash256)
134              
135             my $sig = $priv->sign_message('Hello world');
136              
137             # signature is returned as byte string
138             # use to_format to get the representation you need
139              
140             use Bitcoin::Crypto::Util qw(to_format);
141             my $sig_hex = to_format [hex => $sig];
142              
143             # signature verification
144              
145             $priv->verify_message('Hello world', $sig);
146              
147             =head1 DESCRIPTION
148              
149             This class allows you to create a private key instance.
150              
151             You can use a private key to:
152              
153             =over 2
154              
155             =item * generate public keys
156              
157             =item * sign and verify messages
158              
159             =back
160              
161             Please note that any keys generated are by default compressed.
162              
163             see L<Bitcoin::Crypto::Network> if you want to work with other networks than
164             Bitcoin Mainnet.
165              
166             =head1 METHODS
167              
168             =head2 new
169              
170             Constructor is reserved for internal and advanced use only. Use L</from_serialized>
171             or L</from_wif> instead.
172              
173             =head2 from_serialized
174              
175             $key_object = $class->from_serialized($serialized)
176              
177             This creates a new key from string data. Argument C<$serialized> is a
178             formatable bytestring containing the private key entropy.
179              
180             Returns a new key object instance.
181              
182             =head2 to_serialized
183              
184             $serialized = $key_object->to_serialized()
185              
186             This returns a private key as a sequence of bytes. The result is a bytestring
187             which can be further formated with C<to_format> utility.
188              
189             =head2 from_bytes
190              
191             Deprecated. Use C<< $class->from_serialized($data) >> instead.
192              
193             =head2 to_bytes
194              
195             Deprecated. Use C<< $key->to_serialized($data) >> instead.
196              
197             =head2 from_hex
198              
199             Deprecated. Use C<< $class->from_serialized([hex => $data]) >> instead.
200              
201             =head2 to_hex
202              
203             Deprecated. Use C<< to_format [hex => $key->to_serialized($data)] >> instead.
204              
205             =head2 from_wif
206              
207             $key_object = $class->from_wif($str, $network = undef)
208              
209             Creates a new private key from Wallet Import Format string.
210              
211             Takes an additional optional argument, which is network name. It may be useful
212             if you use many networks and some have the same WIF byte.
213              
214             This method will change compression and network states of the created private
215             key, as this data is included in WIF format.
216              
217             Returns class instance.
218              
219             =head2 to_wif
220              
221             $wif_string = $object->to_wif()
222              
223             Does the opposite of from_wif on a target object
224              
225             =head2 set_compressed
226              
227             $key_object = $object->set_compressed($val)
228              
229             Change key's compression state to C<$val> (1/0). This will change the WIF
230             generated by to_wif() method and also enable creation of uncompressed public
231             keys. If C<$val> is omitted it is set to C<1>.
232              
233             Returns current key instance.
234              
235             =head2 set_network
236              
237             $key_object = $object->set_network($val)
238              
239             Change key's network state to C<$val>. It can be either network name present in
240             Bitcoin::Crypto::Network package or an instance of this class.
241              
242             Returns current key instance.
243              
244             =head2 get_public_key
245              
246             $public_key_object = $object->get_public_key()
247              
248             Returns instance of L<Bitcoin::Crypto::Key::Public> generated from the private
249             key.
250              
251             =head2 sign_message
252              
253             $signature = $object->sign_message($message)
254              
255             Signs a digest of C<$message> (digesting it with double sha256) with a private
256             key.
257              
258             Returns a byte string containing signature.
259              
260             Character encoding note: C<$message> should be encoded in the proper encoding
261             before passing it to this method. Passing Unicode string will cause the
262             function to fail. You can encode like this (for UTF-8):
263              
264             use Encode qw(encode);
265             $message = encode('UTF-8', $message);
266              
267             Caution: libtomcrypt cryptographic package that is generating signatures does
268             not currently offer a deterministic mechanism. For this reason the sign_message
269             method will complain with a warning. You should install an optional
270             L<Crypt::Perl> package, which supports deterministic signatures, which will
271             disable the warning. Non-deterministic signatures can lead to leaking private
272             keys if the random number generator's entropy is insufficient.
273              
274             =head2 sign_transaction
275              
276             $object->sign_transaction($tx, %params)
277              
278             Signs the transaction C<$tx> using this private key. This automatic signing
279             only works for standard script types, if your script is non-standard then you
280             will have to sign manually.
281              
282             Returns nothing - the result of the function is the modification of transaction
283             C<$tx>.
284              
285             C<%params> can contain:
286              
287             =over
288              
289             =item * C<signing_index>
290              
291             This non-negative integer is the index of the input being signed. Required.
292              
293             =item * C<redeem_script>
294              
295             A L<Bitcoin::Crypto::Script> instance or something which can be turned into a
296             script, used for specifying a payout script when redeeming P2SH and P2WSH
297             outputs.
298              
299             =item * C<multisig>
300              
301             An indication of the multisig signing stage. It is an array reference with
302             exactly two elements. The first element is the number (1-based, not the index!)
303             of the currently signed multisig. The second element is the total number of
304             signatures required for the multisig. For example, signing 2-out-of-3 multisig
305             can look like this (taken from C<ex/tx/multisig_redeem.pl> example):
306              
307             # sign using the private key belonging to the first pubkey
308             btc_prv->from_wif('cScAuqNfiNR7mq61QGW3LtokKAwzBzs4rbCz4Uff1NA15ysEij2i')
309             ->sign_transaction($tx, signing_index => 0, redeem_script => $redeem_script, multisig => [1, 2]);
310              
311             # sign using the private key belonging to the third pubkey
312             btc_prv->from_wif('cQsSKWrBLXNY1oSZbLcJf4HF5vnKGgKko533LnkTmqRdS9Fx4SGH')
313             ->sign_transaction($tx, signing_index => 0, redeem_script => $redeem_script, multisig => [2, 2]);
314              
315             =item * C<sighash>
316              
317             The sighash which should be used for the signature. By default C<SIGHASH_ALL>
318             is used.
319              
320             =back
321              
322             =head2 verify_message
323              
324             $signature_valid = $object->verify_message($message, $signature)
325              
326             Verifies C<$signature> against digest of C<$message> (digesting it with double
327             sha256) using private key.
328              
329             Returns boolean.
330              
331             Character encoding note: C<$message> should be encoded in the proper encoding
332             before passing it to this method. Passing Unicode string will cause the
333             function to fail. You can encode like this (for UTF-8):
334              
335             use Encode qw(encode);
336             $message = encode('UTF-8', $message);
337              
338             =head1 EXCEPTIONS
339              
340             This module throws an instance of L<Bitcoin::Crypto::Exception> if it
341             encounters an error. It can produce the following error types from the
342             L<Bitcoin::Crypto::Exception> namespace:
343              
344             =over 2
345              
346             =item * Sign - couldn't sign the message correctly
347              
348             =item * ScriptType - couldn't automatically sign the given script type
349              
350             =item * Verify - couldn't verify the message correctly
351              
352             =item * KeyCreate - key couldn't be created correctly
353              
354             =item * NetworkConfig - incomplete or corrupted network configuration
355              
356             =back
357              
358             =head1 SEE ALSO
359              
360             =over 2
361              
362             =item L<Bitcoin::Crypto::Key::Public>
363              
364             =item L<Bitcoin::Crypto::Network>
365              
366             =back
367              
368             =cut
369