File Coverage

blib/lib/Bitcoin/Crypto/Base58.pm
Criterion Covered Total %
statement 30 30 100.0
branch n/a
condition n/a
subroutine 10 10 100.0
pod 0 1 0.0
total 40 41 97.5


line stmt bran cond sub pod time code
1             package Bitcoin::Crypto::Base58;
2             $Bitcoin::Crypto::Base58::VERSION = '2.000_01'; # TRIAL
3             $Bitcoin::Crypto::Base58::VERSION = '2.00001';
4 30     30   79574 use v5.10;
  30         146  
5 30     30   171 use strict;
  30         58  
  30         713  
6 30     30   174 use warnings;
  30         73  
  30         900  
7 30     30   171 use Exporter qw(import);
  30         74  
  30         1095  
8 30     30   2047 use Crypt::Misc qw(encode_b58b decode_b58b);
  30         32637  
  30         2072  
9 30     30   1522 use Type::Params -sigs;
  30         261829  
  30         271  
10              
11 30     30   19153 use Bitcoin::Crypto::Util qw(hash256);
  30         97  
  30         2035  
12 30     30   291 use Bitcoin::Crypto::Exception;
  30         125  
  30         955  
13 30     30   192 use Bitcoin::Crypto::Types qw(Str ByteStr);
  30         77  
  30         293  
14              
15             our @EXPORT_OK = qw(
16             encode_base58
17             encode_base58check
18             decode_base58
19             decode_base58check
20             );
21              
22             our %EXPORT_TAGS = (all => [@EXPORT_OK]);
23              
24             my $CHECKSUM_SIZE = 4;
25              
26             sub verify_checksum
27             {
28 96     96 0 262 my ($decoded) = @_;
29 96         302 my $encoded_val = substr $decoded, 0, -$CHECKSUM_SIZE;
30 96         470 my $checksum = substr $decoded, -$CHECKSUM_SIZE;
31 96         549 return unpack('a' . $CHECKSUM_SIZE, hash256($encoded_val)) eq $checksum;
32             }
33              
34             signature_for encode_base58 => (
35             positional => [ByteStr],
36             );
37              
38             sub encode_base58
39             {
40             my ($bytes) = @_;
41              
42             return encode_b58b($bytes);
43             }
44              
45             signature_for encode_base58check => (
46             positional => [ByteStr],
47             );
48              
49             sub encode_base58check
50             {
51             my ($bytes) = @_;
52              
53             my $checksum = pack('a' . $CHECKSUM_SIZE, hash256($bytes));
54             return encode_base58($bytes . $checksum);
55             }
56              
57             signature_for decode_base58 => (
58             positional => [Str],
59             );
60              
61             sub decode_base58
62             {
63             my ($base58encoded) = @_;
64              
65             my $decoded = decode_b58b($base58encoded);
66             Bitcoin::Crypto::Exception::Base58InputFormat->raise(
67             'illegal characters in base58 string'
68             ) unless defined $decoded;
69              
70             return $decoded;
71             }
72              
73             signature_for decode_base58check => (
74             positional => [Str],
75             );
76              
77             sub decode_base58check
78             {
79             my ($base58encoded) = @_;
80              
81             my $decoded = decode_base58($base58encoded);
82             Bitcoin::Crypto::Exception::Base58InputChecksum->raise(
83             'incorrect base58check checksum'
84             ) unless verify_checksum($decoded);
85              
86             return substr $decoded, 0, -$CHECKSUM_SIZE;
87             }
88              
89             1;
90              
91             __END__
92              
93             =head1 NAME
94              
95             Bitcoin::Crypto::Base58 - Bitcoin base58 helpers
96              
97             =head1 SYNOPSIS
98              
99             # none exported by default
100             use Bitcoin::Crypto::Base58 qw(
101             encode_base58
102             decode_base58
103             encode_base58check
104             decode_base58check
105             );
106              
107             my $b58str = encode_base58check(pack 'A*', 'hello');
108             my $bytestr = decode_base58check($b58str);
109              
110             =head1 DESCRIPTION
111              
112             Implementation of Base58Check algorithm and alias to CryptX C<encode_b58b> / C<decode_b58b>
113              
114             =head1 FUNCTIONS
115              
116             This module is based on Exporter. None of the functions are exported by
117             default. Use C<:all> tag to import all the functions at once.
118              
119             =head2 encode_base58
120              
121             =head2 decode_base58
122              
123             Basic base58 encoding / decoding.
124              
125             Encoding takes one argument which is byte string.
126              
127             Decoding takes base58-encoded string
128              
129             These two functions are just aliases to L<Crypt::Misc/encode_b58b> and
130             L<Crypt::Misc/decode_b58b> with some error checking.
131              
132             =head2 encode_base58check
133              
134             =head2 decode_base58check
135              
136             Base58 with checksum validation. These functions are used with legacy /
137             compatibility addresses as well as WIF strings and extended key serialization.
138              
139             Arguments are the same as base functions mentioned above.
140              
141             =head1 EXCEPTIONS
142              
143             This module throws an instance of L<Bitcoin::Crypto::Exception> if it
144             encounters an error. It can produce the following error types from the
145             L<Bitcoin::Crypto::Exception> namespace:
146              
147             =over
148              
149             =item * Base58InputFormat - input was not suitable for base58 operations due to invalid format
150              
151             =item * Base58InputChecksum - checksum validation has failed
152              
153             =back
154              
155             =head1 SEE ALSO
156              
157             L<Crypt::Misc>
158              
159             L<Bitcoin::Crypto::Bech32>
160