File Coverage

blib/lib/Crypt/HashCash.pm
Criterion Covered Total %
statement 18 92 19.5
branch 0 8 0.0
condition n/a
subroutine 6 22 27.2
pod 2 2 100.0
total 26 124 20.9


line stmt bran cond sub pod time code
1             # -*-cperl-*-
2             #
3             # Crypt::HashCash - HashCash Digital Cash
4             # Copyright (c) 2001-2017 Ashish Gulhati
5             #
6             # $Id: lib/Crypt/HashCash.pm v1.126 Sat Jun 24 02:15:17 PDT 2017 $
7              
8             package Crypt::HashCash;
9              
10 1     1   20400 use warnings;
  1         4  
  1         44  
11 1     1   8 use strict;
  1         4  
  1         31  
12 1     1   6 use Exporter;
  1         9  
  1         106  
13 1     1   740 use Compress::Zlib;
  1         60142  
  1         195  
14 1     1   560 use Math::BaseCnv qw (cnv dig diginit);
  1         51090  
  1         149  
15 1     1   14 use vars qw($VERSION @ISA @EXPORT_OK);
  1         3  
  1         1257  
16              
17             @ISA = qw(Exporter);
18             @EXPORT_OK = qw(breakamt changecoin _hex _dec _squish _unsquish _dectob85 _b85todec);
19              
20             our ( $VERSION ) = '$Revision: 1.126 $' =~ /\s+([\d\.]+)/;
21              
22             sub breakamt { # Return denominations of lowest number of coins to make an amount
23 0     0 1   my $amt = shift; my %d;
  0            
24 0           my %break = ( 1 => [ qw( 1 ) ],
25             2 => [ qw( 2 ) ],
26             3 => [ qw( 2 1 ) ],
27             4 => [ qw( 2 2 ) ],
28             5 => [ qw( 5 ) ],
29             6 => [ qw( 5 1 ) ],
30             7 => [ qw( 5 2 ) ],
31             8 => [ qw( 5 2 1 ) ],
32             9 => [ qw( 5 2 2 ) ]
33             );
34 0           my @digits = split //, $amt; my $i=-1; my $count = 0;
  0            
  0            
35 0           for (reverse @digits) {
36 0           $i++;
37 0 0         next unless $_;
38 0           my @denoms = @{$break{$_}};
  0            
39 0           for my $denom (@denoms) {
40 0           $d{$denom*(10**$i)}++;
41 0           $count++;
42             }
43             }
44 0           return (\%d, $count);
45             }
46              
47             sub changecoin { # Return denominations of change for a specific coin
48 0     0 1   my $amt = shift; my %d; my @denoms;
  0            
49 0           my %change = ( 2 => [ qw( 1 1 ) ],
50             5 => [ qw( 2 1 1 1 ) ],
51             10 => [ qw( 5 2 1 1 1 ) ],
52             20 => [ qw( 5 5 2 2 1 1 1 1 1 1 ) ],
53             50 => [ qw( 20 10 5 5 2 2 2 1 1 1 1 ) ],
54             );
55 0 0         if ($amt < 10) {
56 0           @denoms = @{$change{$amt}};
  0            
57             }
58             else {
59 0           $amt =~ /^(..)(0*)$/;
60 0           my $digits = $1; my $zeros = $2;
  0            
61 0           @denoms = map { $_ . $zeros } @{$change{$digits}};
  0            
  0            
62             }
63 0           my $count;
64 0           for my $denom (@denoms) {
65 0           $d{$denom}++;
66 0           $count++;
67             }
68 0           return (\%d, $count);
69             }
70              
71             sub _hex {
72 0     0     my $dec = shift;
73 0     0     local $SIG{'__WARN__'} = sub { };
74 0           my $hex = Math::BaseCnv::heX($dec);
75 0           $hex =~ tr/A-F/a-f/; $hex =~ s/^ff//;
  0            
76 0           $hex;
77             }
78              
79             sub _dec {
80 0     0     my $hex = shift;
81 0           $hex = 'ff' . $hex; # So we don't lose leading 0s
82 0     0     local $SIG{'__WARN__'} = sub { };
83 0           Math::BaseCnv::dec($hex);
84             }
85              
86             sub _squish {
87 0     0     my $str = shift; #print "U: $str\n";
88 0           my $dec = _dec(unpack 'H*', compress($str));
89 0           $dec;
90             }
91              
92             sub _unsquish {
93 0     0     my $str = shift;
94 0 0         return if $str =~ /\D/;
95 0 0         return unless my $hex = _hex($str);
96 0           uncompress(pack 'H*',$hex);
97             }
98              
99             sub _dectob85 {
100 0     0     my $dec = shift;
101 0           dig('b85');
102 0           $dec = '9' . $dec; # So we don't lose leading 0s
103 0     0     local $SIG{'__WARN__'} = sub { };
104 0           cnv ($dec, 10, 85);
105             }
106              
107             sub _b85todec {
108 0     0     my $base85 = shift;
109 0           dig('b85');
110 0     0     local $SIG{'__WARN__'} = sub { };
111 0           my $dec = cnv ($base85, 85, 10);
112 0           $dec =~ s/^9//;
113 0           $dec;
114             }
115              
116             sub _hextob32 {
117 0     0     my $hex = shift;
118 0           dig( [ qw( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 2 3 4 6 7 9 0 1 5 8 ) ] );
119 0           $hex =~ tr/0-9a-f/A-P/;
120 0           $hex = 'ff' . $hex; # So we don't lose leading 0s
121 0           $hex =~ tr/0-9a-f/A-P/;
122 0     0     local $SIG{'__WARN__'} = sub { };
123 0           cnv ($hex, 16, 32);
124             }
125              
126             sub _b32tohex {
127 0     0     my $base32 = shift;
128 0           dig( [ qw( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 2 3 4 6 7 9 0 1 5 8 ) ] );
129 0     0     local $SIG{'__WARN__'} = sub { };
130 0           my $hex = cnv ($base32, 32, 16);
131 0           $hex =~ tr/A-P/0-9a-f/; $hex =~ s/^ff//;
  0            
132 0           return $hex;
133             }
134              
135             1; # End of Crypt::HashCash
136              
137             =head1 NAME
138              
139             Crypt::HashCash - HashCash Digital Cash
140              
141             =head1 VERSION
142              
143             $Revision: 1.126 $
144             $Date: Sat Jun 24 02:15:17 PDT 2017 $
145              
146             =head1 SYNOPSIS
147              
148             HashCash is a digital cash system based on blind signatures, as
149             introduced by David Chaum in [1].
150              
151             HashCash features a number of optimizations for usability and
152             accessibility, including blind ECDSA signatures which make for more
153             compact coins than blind RSA, and a simple protocol that enables the
154             system to work in a permissionless manner, requiring no user accounts
155             or registration.
156              
157             The main components of HashCash are: one or more vaults, which issue
158             and verify HashCash coins; the coins themselves; and wallets, which
159             hold and manage coins owned by users.
160              
161             HashCash coins are blind-signed by a vault and represent specific
162             denominations of some value stored by the vault. They are bearer
163             tokens which can be passed directly from one user to another, and
164             cannot be tracked by the vault.
165              
166             HashCash coins could be backed by any store of value, some
167             possibilities being precious metals, fiat currencies, gift cards,
168             etc. The distribution includes an implementation of a vault for
169             Bitcoin, which issues HashCash coins backed by Bitcoin.
170              
171             All messages between wallets and vaults are encrypted, so there's no
172             need for a secure communications channel between them.
173              
174             =head1 HOW TO USE
175              
176             To begin with, the keys and configuration details of one or more
177             vaults (in the form of vault configuration files) need to be placed in
178             the "~/.hashcash/vaults" directory (or "$HASHCASHDIR/.hashcash/vaults"
179             if the HASHCASHDIR environment variable is set).
180              
181             As there are no live public vaults at this time, and the software is
182             in early beta testing, to try the system you can run a local vault
183             yourself. After installing the HashCash distribution, run the command:
184              
185             vault.pl
186              
187             This will generate vault keys on its first run. Wait for key
188             generation to complete before starting the wallet, so the vault
189             configuration file is in place for the wallet.
190              
191             Once the vault has completed key generation, start the wallet with:
192              
193             hashcash.pl
194              
195             Then you can buy or sell HashCash, export coins from your wallet to
196             give to others, or import coins received from others into your
197             wallet. You can also exchange coins for lower denominations, and
198             verify coins you've imported into the wallet.
199              
200             For more details on testing with a local vault, see the Download page
201             on the website: L. Pre-built
202             executables for popular OSes are also available from that page.
203              
204             HashCash coins can be sent to others over any communications channel -
205             email, web, instant messaging, SMS, directly by scanning a QR
206             code. They could even be printed on paper and used just like normal
207             paper currency, though with a higher level of security and privacy.
208              
209             It's easy to automate the acceptance of HashCash payments on a website
210             (or via email or any other communications channel) using the
211             L module.
212              
213             It's also quite straightforward, from a technical standpoint, to start
214             a HashCash vault, which could be quite a profitable automated business
215             requiring minimal ongoing time investment. For more details on this
216             visit the website: L.
217              
218             =head1 FUNCTIONS
219              
220             The Crypt::HashCash module contains a few helper functions. Most of
221             the actual implementation of the system is in other modules, listed in
222             the SEE ALSO section below.
223              
224             =head2 breakamt
225              
226             Accepts a single parameter which is an amount to break into coins, and
227             returns the denominations of the minimum number of coins that total up
228             to this amount, as well as the total number of coins. The coin
229             denominations are returned as a hash whose keys are the coin
230             denominations and values are the number of coins of the corresponding
231             denomination.
232              
233             =head2 changecoin
234              
235             Accepts a single parameter which is the denomination of a coin to get
236             change for, and returns the denominations of the change coins, as well
237             as the total number of coins. The denominations are returned in a
238             hash, as described above, followed by the total number of coins.
239              
240             =head1 SEE ALSO
241              
242             =head2 L
243              
244             =head2 L
245              
246             =head2 L
247              
248             =head2 L
249              
250             =head2 L
251              
252             =head2 L
253              
254             =head1 REFERENCES
255              
256             1. Blind Signatures For Untraceable Payments, David Chaum.
257             L
258              
259             =head1 AUTHOR
260              
261             Ashish Gulhati, C<< >>
262              
263             =head1 BUGS
264              
265             Please report any bugs or feature requests to C, or through
266             the web interface at L. I will be notified, and then you'll
267             automatically be notified of progress on your bug as I make changes.
268              
269             =head1 SUPPORT
270              
271             You can find documentation for this module with the perldoc command.
272              
273             perldoc Crypt::HashCash
274              
275             You can also look for information at:
276              
277             =over 4
278              
279             =item * RT: CPAN's request tracker
280              
281             L
282              
283             =item * AnnoCPAN: Annotated CPAN documentation
284              
285             L
286              
287             =item * CPAN Ratings
288              
289             L
290              
291             =item * Search CPAN
292              
293             L
294              
295             =back
296              
297             =head1 LICENSE AND COPYRIGHT
298              
299             Copyright (c) 2001-2017 Ashish Gulhati.
300              
301             This program is free software; you can redistribute it and/or modify it
302             under the terms of the Artistic License 2.0.
303              
304             See L for the full
305             license terms.