Crypt-HashCash
view release on metacpan or search on metacpan
lib/Crypt/HashCash/Client.pm view on Meta::CPAN
# -*-cperl-*-
#
# Crypt::HashCash::Client - Client for HashCash Digital Cash
# Copyright (c) 2001-2017 Ashish Gulhati <crypt-hashcash at hash.neo.tc>
#
# $Id: lib/Crypt/HashCash/Client.pm v1.130 Sat Dec 22 18:42:25 PST 2018 $
package Crypt::HashCash::Client;
use warnings;
use strict;
use Crypt::Random qw(makerandom);
use Bytes::Random::Secure;
use Crypt::RSA::Blind;
use Crypt::ECDSA::Blind;
use Crypt::HashCash::Coin;
use Crypt::HashCash::CoinRequest;
use Crypt::CBC;
use Persistence::Object::Simple;
use Crypt::EECDH;
use Crypt::HashCash qw (_dec _hex);
use Compress::Zlib;
use vars qw( $VERSION $AUTOLOAD );
our ( $VERSION ) = '$Revision: 1.130 $' =~ /\s+([\d\.]+)/;
sub new {
my $class = shift;
my %arg = @_;
bless { RSAB => new Crypt::RSA::Blind,
ECDSAB => new Crypt::ECDSA::Blind,
SIGSCHEME => 'ECDSA',
VERSION => "Crypt::HashCash::Client v$VERSION",
VAULTCONF => $arg{VaultConfig} || '/tmp/vault.cfg',
DEBUG => $arg{Debug} || 0,
XSIZE => 128
}, $class;
}
sub loadkeys {
my $self = shift;
my %pkey;
my $keydb = new Persistence::Object::Simple ('__Fn' => $self->vaultconf);
$self->keydb($keydb); $self->sigscheme($keydb->{sigscheme});
$self->denoms([sort { $a <=> $b } keys %{$self->keydb->{pub}}]);
my $sigmod = 'Crypt::' . $self->sigscheme . '::Blind';
no strict 'refs';
for (@{$self->denoms}) {
$pkey{$_} = &{$sigmod.'::PubKey::from_hex'}($self->keydb->{pub}->{$_});
}
$self->vaultkey(pack ('H*',$self->keydb->{vaultpub}));
$self->mintkeys(\%pkey);
}
sub request_coin {
my $self = shift; my %arg = @_;
$self->_diag("CLIENT: request_coin()\n");
return unless my $mintkey = $self->mintkeys->{$arg{Denomination}};
my $x = makerandom( Size => $self->xsize, Strength => 1 );
$self->_diag("x: $x\n");
my $signer = $self->sigscheme eq 'RSA' ? $self->rsab : $self->ecdsab;
my $req = $signer->request(Key => $mintkey, Message => $x, Init => $arg{Init});
$self->_diag("req: $req\n");
$self->_request($arg{Init} => $x);
return ( bless { R => $req, D => $arg{Denomination}, Init => $arg{Init} }, 'Crypt::HashCash::CoinRequest' );
}
sub unblind_coin {
my $self = shift;
$self->_diag("CLIENT: unblind_coin()\n");
my $bcoin = shift;
return unless my $mintkey = $self->mintkeys->{$bcoin->{D}};
my $signer = $self->sigscheme eq 'RSA' ? $self->rsab : $self->ecdsab;
my $coin = $signer->unblind(Signature => $bcoin->{C}, Key => $mintkey, Init => $bcoin->{Init});
$self->_diag("coin (bc / b): $coin\n");
my $x = $self->_request($bcoin->{Init});
return ( bless { X => $x, D => $bcoin->{D}, Z => $coin }, 'Crypt::HashCash::Coin' );
}
( run in 0.986 second using v1.01-cache-2.11-cpan-e1769b4cff6 )