File Coverage

lib/Crypt/Perl/ECDSA/EncodedPoint.pm
Criterion Covered Total %
statement 39 40 97.5
branch 9 12 75.0
condition 9 12 75.0
subroutine 9 9 100.0
pod 0 3 0.0
total 66 76 86.8


line stmt bran cond sub pod time code
1             package Crypt::Perl::ECDSA::EncodedPoint;
2              
3 8     8   54 use strict;
  8         20  
  8         317  
4 8     8   51 use warnings;
  8         26  
  8         186  
5              
6 8     8   56 use Try::Tiny;
  8         26  
  8         482  
7              
8 8     8   7368 use Crypt::Perl::ECDSA::Utils ();
  8         23  
  8         159  
9 8     8   52 use Crypt::Perl::X ();
  8         18  
  8         3117  
10              
11             #input can be a string or BigInt,
12             #in any of “hybrid”, “uncompressed”, or “compressed” formats
13             sub new {
14 725     725 0 2553 my ($class, $input) = @_;
15              
16 725         1671 my $bin;
17              
18             my $input_is_obj;
19 725 100   725   7160 if ( try { $input->isa('Crypt::Perl::BigInt') } ) {
  725         27634  
20 549         11173 $bin = $input->as_bytes();
21 549         1669 $input_is_obj = 1;
22             }
23             else {
24 176         2784 $input =~ s<\A\0+><>;
25 176         432 $bin = $input;
26             }
27              
28 725         5452 my $first_octet = ord substr( $bin, 0, 1 );
29              
30 725         2315 my $self = bless {}, $class;
31              
32             #Accommodate “hybrid” points
33 725 100 100     10075 if ($first_octet == 6 || $first_octet == 7) {
    100 66        
    50          
34 201         1387 $self->{'_bin'} = "\x04" . substr( $bin, 1 );
35             }
36             elsif ($first_octet == 4) {
37 320         1360 $self->{'_bin'} = $bin;
38             }
39             elsif ($first_octet == 2 || $first_octet == 3) {
40 204         863 $self->{'_compressed_bin'} = $bin;
41             }
42             else {
43 0         0 die Crypt::Perl::X::create('Generic', sprintf "Invalid leading octet in ECDSA point: %v02x", $bin);
44             }
45              
46 725         4421 return $self;
47             }
48              
49             #returns a string
50             sub get_compressed {
51 7     7 0 20 my ($self) = @_;
52              
53 7   66     40 return $self->{'_compressed_bin'} ||= do {
54 3         22 Crypt::Perl::ECDSA::Utils::compress_point( $self->{'_bin'} );
55             };
56             }
57              
58             #returns a string
59             sub get_uncompressed {
60 1059     1059 0 5164 my ($self, $curve_hr) = @_;
61              
62 1059 50       6128 die "Need curve! (p, a, b)" if !$curve_hr;
63              
64 1059   66     11663 return $self->{'_bin'} ||= do {
65 112 50       1032 die "Need compressed bin!" if !$self->{'_compressed_bin'};
66              
67             Crypt::Perl::ECDSA::Utils::decompress_point(
68             $self->{'_compressed_bin'},
69 112         727 @{$curve_hr}{ qw( p a b ) },
  112         1543  
70             );
71             };
72             }
73              
74             #If there’s ever a demand for “hybrid”:
75             #0x06 and 0x07 take the place of the uncompressed leading 0x04,
76             #analogous to 0x02 and 0x03 in the compressed form.
77              
78             1;