File Coverage

blib/lib/Bitcoin/Secp256k1.pm
Criterion Covered Total %
statement 150 154 97.4
branch 33 60 55.0
condition 32 77 41.5
subroutine 37 37 100.0
pod 27 27 100.0
total 279 355 78.5


line stmt bran cond sub pod time code
1             package Bitcoin::Secp256k1;
2             $Bitcoin::Secp256k1::VERSION = '0.011';
3 3     3   595902 use v5.10;
  3         14  
4 3     3   18 use strict;
  3         5  
  3         97  
5 3     3   15 use warnings;
  3         7  
  3         187  
6 3     3   1574 use Digest::SHA qw(sha256);
  3         10311  
  3         302  
7 3     3   23 use Carp;
  3         4  
  3         212  
8              
9             # RANDOMNESS SOURCE
10             # libsecp256k1 needs a source of randomness to randomize context, which
11             # increases its security. Since it is not 100% required for the library to work
12             # properly, we try a couple sources first, and may eventually give up with a
13             # warning.
14              
15 3     3   14 use constant HAS_CRYPTX => eval { require Crypt::PRNG; 1; };
  3         6  
  3         6  
  3         823  
  0         0  
16 3     3   18 use constant HAS_BYTES_RANDOM_SECURE => eval { require Bytes::Random::Secure; 1; };
  3         8  
  3         7  
  3         6223  
  0         0  
17              
18             sub _random_bytes
19             {
20 4     4   648268 my ($count) = @_;
21              
22 4 50       34 if (HAS_CRYPTX) {
23 0         0 return Crypt::PRNG::random_bytes($count);
24             }
25              
26 4 50       16 if (HAS_BYTES_RANDOM_SECURE) {
27 0         0 return Bytes::Random::Secure::random_bytes($count);
28             }
29              
30             carp
31 4         983 'Caution: no supported PRNG module is installed. For extra security, please install CryptX or Bytes::Random::Secure';
32 4         151 return undef;
33             }
34              
35             our $FORCED_SCHNORR_AUX_RAND;
36              
37             sub _schnorr_aux_random
38             {
39 4   66 4   246 return $FORCED_SCHNORR_AUX_RAND // _random_bytes(32);
40             }
41              
42             # LOW LEVEL API
43             # XS defines constructor, destructor and some general utility methods
44             # interacting directly with libsecp256k1. All of these methods are private and
45             # subject to change. They are used internally to deliver high level API below.
46              
47             require XSLoader;
48             XSLoader::load('Bitcoin::Secp256k1', $Bitcoin::Secp256k1::VERSION);
49              
50             # HIGH LEVEL API
51             # These methods are implemented in Perl and deliver more convenient API to
52             # interact with. They are stable and public.
53              
54             sub _croak_usage
55             {
56 5     5   17 my $args_str = join ', ', @_;
57              
58 5         16 my ($package) = caller;
59 5         42 my ($calling_sub) = (caller 1)[3];
60 5         72 $calling_sub =~ s/^${package}:://;
61              
62 5         1172 croak "bad or undefined arguments, usage: \$secp256k1->$calling_sub($args_str)";
63             }
64              
65             sub verify_private_key
66             {
67 3     3 1 5635 my ($self, $private_key) = @_;
68              
69 3 50       9 (defined $private_key)
70             or _croak_usage(qw($private_key));
71              
72 3         28 return $self->_verify_privkey($private_key);
73             }
74              
75             sub verify_public_key
76             {
77 3     3 1 1590 my ($self, $public_key) = @_;
78              
79 3 50       6 (defined $public_key)
80             or _croak_usage(qw($public_key));
81              
82             # scope for local $@
83             {
84 3         4 local $@;
  3         4  
85              
86 3         3 my $success = eval {
87 3         42 $self->_pubkey($public_key);
88 1         2 1;
89             };
90              
91 3         14 return !!$success;
92             }
93             }
94              
95             sub create_public_key
96             {
97 7     7 1 19487 my ($self, $private_key) = @_;
98              
99 7 50       21 (defined $private_key)
100             or _croak_usage(qw($private_key));
101              
102 7         249 $self->_create_pubkey($private_key);
103 3         18 return $self->_pubkey;
104             }
105              
106             sub normalize_signature
107             {
108 2     2 1 1428 my ($self, $signature) = @_;
109              
110 2 50       5 (defined $signature)
111             or _croak_usage(qw($signature));
112              
113 2         13 $self->_signature($signature);
114 2         6 $self->_normalize;
115              
116 2         10 return $self->_signature;
117             }
118              
119             sub compress_public_key
120             {
121 4     4 1 1355 my ($self, $public_key, $compressed) = @_;
122 4   100     17 $compressed //= !!1;
123              
124 4 50       8 (defined $public_key)
125             or _croak_usage(qw($public_key [$compressed]));
126              
127 4         50 return $self->_pubkey($public_key, $compressed);
128             }
129              
130             sub sign_message
131             {
132 1     1 1 1265 my ($self, $private_key, $message) = @_;
133              
134 1 50 33     7 (defined $private_key and defined $message)
135             or _croak_usage(qw($private_key $message));
136              
137 1         15 return $self->sign_digest($private_key, sha256(sha256($message)));
138             }
139              
140             sub sign_message_schnorr
141             {
142 2     2 1 2582 my ($self, $private_key, $message) = @_;
143              
144 2 50 33     20 (defined $private_key and defined $message)
145             or _croak_usage(qw($private_key $message));
146              
147 2         35 return $self->sign_digest_schnorr($private_key, sha256($message));
148             }
149              
150             sub sign_message_recoverable
151             {
152 3     3 1 1791 my ($self, $private_key, $message) = @_;
153              
154 3 50 33     17 (defined $private_key and defined $message)
155             or _croak_usage(qw($private_key $message));
156              
157 3         29 return $self->sign_digest_recoverable($private_key, sha256(sha256($message)));
158             }
159              
160             sub sign_digest
161             {
162 2     2 1 1252 my ($self, $private_key, $digest) = @_;
163              
164 2 50 33     8 (defined $private_key and defined $digest)
165             or _croak_usage(qw($private_key $digest));
166              
167 2         160 $self->_sign($private_key, $digest);
168 2         15 return $self->_signature;
169             }
170              
171             sub sign_digest_schnorr
172             {
173 4     4 1 4520 my ($self, $private_key, $digest) = @_;
174              
175 4 50 33     22 (defined $private_key and defined $digest)
176             or _croak_usage(qw($private_key $digest));
177              
178 4         336 $self->_sign_schnorr($private_key, $digest);
179 4         37 return $self->_signature_schnorr;
180             }
181              
182             sub sign_digest_recoverable
183             {
184 6     6 1 4567 my ($self, $private_key, $digest) = @_;
185              
186 6 50 33     21 (defined $private_key and defined $digest)
187             or _croak_usage(qw($private_key $digest));
188              
189 6         466 $self->_sign_recoverable($private_key, $digest);
190 6         56 return $self->_signature_recoverable;
191             }
192              
193             sub recover_public_key_message
194             {
195 3     3 1 978 my ($self, $recoverable_signature, $message) = @_;
196              
197 3 50 33     12 (defined $recoverable_signature and defined $message)
198             or _croak_usage(qw($signature $message));
199              
200 3         42 return $self->recover_public_key_digest($recoverable_signature, sha256(sha256($message)));
201             }
202              
203             sub recover_public_key_digest
204             {
205 6     6 1 577 my ($self, $recoverable_signature, $digest) = @_;
206              
207 6 50 33     20 (defined $recoverable_signature and defined $digest)
208             or _croak_usage(qw($signature $digest));
209              
210 6         30 $self->_signature_recoverable($recoverable_signature);
211 6         635 $self->_recover_pubkey_recoverable($digest);
212 6         37 return $self->_pubkey;
213             }
214              
215             sub verify_message
216             {
217 7     7 1 3352 my ($self, $public_key, $signature, $message) = @_;
218              
219 7 100 100     56 (defined $public_key and defined $signature and defined $message)
      100        
220             or _croak_usage(qw($public_key $signature $message));
221              
222 4         55 return $self->verify_digest($public_key, $signature, sha256(sha256($message)));
223             }
224              
225             sub verify_message_schnorr
226             {
227 3     3 1 368 my ($self, $public_key, $signature, $message) = @_;
228              
229 3 50 33     16 (defined $public_key and defined $signature and defined $message)
      33        
230             or _croak_usage(qw($public_key $signature $message));
231              
232 3         19 return $self->verify_digest_schnorr($public_key, $signature, sha256($message));
233             }
234              
235             sub verify_message_recoverable
236             {
237 2     2 1 290 my ($self, $public_key, $signature, $message) = @_;
238              
239 2 50 33     11 (defined $public_key and defined $signature and defined $message)
      33        
240             or _croak_usage(qw($public_key $signature $message));
241              
242 2         17 return $self->verify_digest_recoverable($public_key, $signature, sha256(sha256($message)));
243             }
244              
245             sub verify_digest
246             {
247 10     10 1 6674 my ($self, $public_key, $signature, $digest) = @_;
248              
249 10 50 33     76 (defined $public_key and defined $signature and defined $digest)
      33        
250             or _croak_usage(qw($public_key $signature $digest));
251              
252 10         186 $self->_pubkey($public_key);
253 9         56 $self->_signature($signature);
254 8         29 $self->_normalize;
255              
256 8         855 return $self->_verify($digest);
257             }
258              
259             sub verify_digest_schnorr
260             {
261 7     7 1 2169 my ($self, $public_key, $signature, $digest) = @_;
262              
263 7 50 33     38 (defined $public_key and defined $signature and defined $digest)
      33        
264             or _croak_usage(qw($public_key $signature $digest));
265              
266 7         153 $self->_xonly_pubkey($public_key);
267 6         19 $self->_signature_schnorr($signature);
268              
269 6         809 return $self->_verify_schnorr($digest);
270             }
271              
272             sub verify_digest_recoverable
273             {
274 4     4 1 310 my ($self, $public_key, $signature, $digest) = @_;
275              
276 4 50 33     24 (defined $public_key and defined $signature and defined $digest)
      33        
277             or _croak_usage(qw($public_key $signature $digest));
278              
279 4         26 $self->_signature_recoverable($signature);
280 4         390 $self->_recover_pubkey_recoverable($digest);
281 4         25 my $recovered_pubkey = $self->_pubkey;
282              
283 4         20 return $recovered_pubkey eq $public_key;
284             }
285              
286             sub negate_public_key
287             {
288 1     1 1 1158 my ($self, $public_key) = @_;
289              
290 1 50       4 (defined $public_key)
291             or _croak_usage(qw($public_key));
292              
293 1         16 $self->_pubkey($public_key);
294 1         6 $self->_pubkey_negate;
295              
296 1         5 return $self->_pubkey;
297             }
298              
299             sub negate_private_key
300             {
301 2     2 1 2142 my ($self, $private_key) = @_;
302              
303 2 50       38 (defined $private_key)
304             or _croak_usage(qw($private_key));
305              
306 2         18 return $self->_privkey_negate($private_key);
307             }
308              
309             sub xonly_public_key
310             {
311 1     1 1 1178 my ($self, $public_key) = @_;
312              
313 1 50       3 (defined $public_key)
314             or _croak_usage(qw($public_key));
315              
316 1         17 $self->_pubkey($public_key);
317 1         4 $self->_convert_pubkey_xonly;
318              
319 1         6 return $self->_xonly_pubkey;
320             }
321              
322             sub add_public_key
323             {
324 1     1 1 1276 my ($self, $public_key, $tweak) = @_;
325              
326 1 50 33     10 (defined $public_key and defined $tweak)
327             or _croak_usage(qw($public_key $tweak));
328              
329 1         27 $self->_pubkey($public_key);
330 1         110 $self->_pubkey_add($tweak);
331              
332 1         11 return $self->_pubkey;
333             }
334              
335             sub add_private_key
336             {
337 2     2 1 29 my ($self, $private_key, $tweak) = @_;
338              
339 2 50 33     15 (defined $private_key and defined $tweak)
340             or _croak_usage(qw($private_key $tweak));
341              
342 2         23 return $self->_privkey_add($private_key, $tweak);
343             }
344              
345             sub multiply_public_key
346             {
347 2     2 1 3486 my ($self, $public_key, $tweak) = @_;
348              
349 2 50 33     14 (defined $public_key and defined $tweak)
350             or _croak_usage(qw($public_key $tweak));
351              
352 2         82 $self->_pubkey($public_key);
353 2         90 $self->_pubkey_mul($tweak);
354              
355 1         6 return $self->_pubkey;
356             }
357              
358             sub multiply_private_key
359             {
360 1     1 1 3 my ($self, $private_key, $tweak) = @_;
361              
362 1 50 33     5 (defined $private_key and defined $tweak)
363             or _croak_usage(qw($private_key $tweak));
364              
365 1         8 return $self->_privkey_mul($private_key, $tweak);
366             }
367              
368             sub combine_public_keys
369             {
370 5     5 1 8008 my ($self, @public_keys) = @_;
371              
372 5 100       24 (@public_keys > 0)
373             or _croak_usage(qw($public_key [@more_public_keys]));
374              
375 4         27 $self->_clear;
376 4         10 foreach my $pub (@public_keys) {
377              
378 8 100       21 (defined $pub)
379             or _croak_usage(qw($public_key [@more_public_keys]));
380              
381 7         117 $self->_pubkey($pub);
382 6         21 $self->_push_pubkey;
383             }
384              
385 2         21 $self->_pubkey_combine;
386              
387 2         12 return $self->_pubkey;
388             }
389              
390             1;
391              
392             __END__