diff options
Diffstat (limited to 'lib/Crypt')
96 files changed, 18852 insertions, 0 deletions
diff --git a/lib/Crypt/AuthEnc.pm b/lib/Crypt/AuthEnc.pm new file mode 100644 index 00000000..b5960786 --- /dev/null +++ b/lib/Crypt/AuthEnc.pm @@ -0,0 +1,17 @@ +package Crypt::AuthEnc; + +use strict; +use warnings; +our $VERSION = '0.048'; + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +__END__ + +=head1 NAME + +Crypt::AuthEnc - [internal only] + +=cut
\ No newline at end of file diff --git a/lib/Crypt/AuthEnc/CCM.pm b/lib/Crypt/AuthEnc/CCM.pm new file mode 100644 index 00000000..0ba3e398 --- /dev/null +++ b/lib/Crypt/AuthEnc/CCM.pm @@ -0,0 +1,100 @@ +package Crypt::AuthEnc::CCM; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( ccm_encrypt_authenticate ccm_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +### the following functions are implemented in XS: +# - _memory_encrypt +# - _memory_decrypt + +sub ccm_encrypt_authenticate { + my $cipher_name = shift; + my $key = shift; + my $nonce = shift; + my $adata = shift; + my $tag_len = shift; + my $plaintext = shift; + return _memory_encrypt(Crypt::Cipher::_trans_cipher_name($cipher_name), $key, $nonce, $adata, $tag_len, $plaintext); +} + +sub ccm_decrypt_verify { + my $cipher_name = shift; + my $key = shift; + my $nonce = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + return _memory_decrypt(Crypt::Cipher::_trans_cipher_name($cipher_name), $key, $nonce, $adata, $ciphertext, $tag); +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::CCM - Authenticated encryption in CCM mode + +=head1 SYNOPSIS + + ### functional interface + use Crypt::AuthEnc::CCM qw(ccm_encrypt_authenticate ccm_decrypt_verify); + + my ($ciphertext, $tag) = ccm_encrypt_authenticate('AES', $key, $nonce, $adata, $tag_len, $plaintext); + my $plaintext = ccm_decrypt_verify('AES', $key, $nonce, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +CCM is a encrypt+authenticate mode that is centered around using AES (or any 16-byte cipher) as aprimitive. +Unlike EAX and OCB mode, it is only meant for packet mode where the length of the input is known in advance. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::CCM qw(ccm_encrypt_authenticate ccm_decrypt_verify); + +=head1 FUNCTIONS + +=head2 ccm_encrypt_authenticate + + my ($ciphertext, $tag) = ccm_encrypt_authenticate($cipher, $key, $nonce, $adata, $tag_len, $plaintext); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... key of proper length (e.g. 128/192/256bits for AES) + # $nonce ... unique nonce/salt (no need to keep it secret) + # $adata ... additional authenticated data + # $tag_len . required length of output tag + +CCM parameters should follow L<http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38c.pdf> + + # tag length: 4, 6, 8, 10, 12, 14, 16 (reasonable minimum is 8) + # nonce length: 7, 8, 9, 10, 11, 12, 13 (if you are not sure, use 11) + # BEWARE nonce length determines max. enc/dec data size: max_data_size = 2^(8*(15-nonce_len)) + +=head2 ccm_decrypt_verify + + my $plaintext = ccm_decrypt_verify($cipher, $key, $nonce, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::AuthEnc::EAX|Crypt::AuthEnc::EAX>, L<Crypt::AuthEnc::GCM|Crypt::AuthEnc::GCM>, L<Crypt::AuthEnc::OCB|Crypt::AuthEnc::OCB> + +=item * L<https://en.wikipedia.org/wiki/CCM_mode|https://en.wikipedia.org/wiki/CCM_mode> + +=back diff --git a/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm b/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm new file mode 100644 index 00000000..c134a545 --- /dev/null +++ b/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm @@ -0,0 +1,164 @@ +package Crypt::AuthEnc::ChaCha20Poly1305; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; + +sub new { my $class = shift; _new(@_) } + +sub chacha20poly1305_encrypt_authenticate { + my $key = shift; + my $iv = shift; + my $adata = shift; + my $plaintext = shift; + + my $m = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string + my $ct = $m->encrypt_add($plaintext); + my $tag = $m->encrypt_done; + return ($ct, $tag); +} + +sub chacha20poly1305_decrypt_verify { + my $key = shift; + my $iv = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + + my $m = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string + my $ct = $m->decrypt_add($ciphertext); + return $m->decrypt_done($tag) ? $ct : undef; +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::ChaCha20Poly1305 - Authenticated encryption in ChaCha20Poly1305 mode + +=head1 SYNOPSIS + + ### OO interface + use Crypt::AuthEnc::ChaCha20Poly1305; + + # encrypt and authenticate + my $ae = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $ct = $ae->encrypt_add('data1'); + $ct = $ae->encrypt_add('data2'); + $ct = $ae->encrypt_add('data3'); + $tag = $ae->encrypt_done(); + + # decrypt and verify + my $ae = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $pt = $ae->decrypt_add('ciphertext1'); + $pt = $ae->decrypt_add('ciphertext2'); + $pt = $ae->decrypt_add('ciphertext3'); + $tag = $ae->decrypt_done(); + die "decrypt failed" unless $tag eq $expected_tag; + + #or + my $result = $ae->decrypt_done($expected_tag) die "decrypt failed"; + + ### functional interface + use Crypt::AuthEnc::ChaCha20Poly1305 qw(chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify); + + my ($ciphertext, $tag) = chacha20poly1305_encrypt_authenticate($key, $iv, $adata, $plaintext); + my $plaintext = chacha20poly1305_decrypt_verify($key, $iv, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +Provides encryption and authentication based on ChaCha20 + Poly1305 as defined in RFC 7539 - L<https://tools.ietf.org/html/rfc7539> + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::ChaCha20Poly1305 qw(chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify); + +=head1 FUNCTIONS + +=head2 chacha20poly1305_encrypt_authenticate + + my ($ciphertext, $tag) = chacha20poly1305_encrypt_authenticate($key, $iv, $adata, $plaintext); + + # $key ..... key of proper length (128 or 256 bits / 16 or 32 bytes) + # $iv ...... initialization vector (64 or 96 bits / 8 or 12 bytes) + # $adata ... additional authenticated data (optional) + +=head2 chacha20poly1305_decrypt_verify + + my $plaintext = chacha20poly1305_decrypt_verify($key, $iv, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 METHODS + +=head2 new + + my $ae = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + + # $key ..... encryption key of proper length (128 or 256 bits / 16 or 32 bytes) + # $iv ...... initialization vector (64 or 96 bits / 8 or 12 bytes) + +=head2 aad_add + +Can be called before the first C<encrypt_add> or C<decrypt_add>; + + $ae->aad_add($aad_data); #can be called multiple times + +=head2 encrypt_add + + $ciphertext = $ae->encrypt_add($data); #can be called multiple times + +=head2 encrypt_done + + $tag = $ae->encrypt_done(); + +=head2 decrypt_add + + $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times + +=head2 decrypt_done + + my $result = $ae->decrypt_done($tag); # returns 1 (success) or 0 (failure) + #or + my $tag = $ae->decrypt_done; # returns $tag value + +=head2 clone + + my $ae_new = $ae->clone; + +=head2 set_iv + + $ae->set_iv($iv); + +=head2 set_iv_rfc7905 + + $ae->set_iv_rfc7905($iv, $seqnum); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::AuthEnc::GCM|Crypt::AuthEnc::GCM>, L<Crypt::AuthEnc::CCM|Crypt::AuthEnc::CCM>, L<Crypt::AuthEnc::EAX|Crypt::AuthEnc::EAX>, L<Crypt::AuthEnc::OCB|Crypt::AuthEnc::OCB> + +=item * L<https://tools.ietf.org/html/rfc7539> + +=back diff --git a/lib/Crypt/AuthEnc/EAX.pm b/lib/Crypt/AuthEnc/EAX.pm new file mode 100644 index 00000000..e5e7095d --- /dev/null +++ b/lib/Crypt/AuthEnc/EAX.pm @@ -0,0 +1,179 @@ +package Crypt::AuthEnc::EAX; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( eax_encrypt_authenticate eax_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +### the following methods/functions are implemented in XS: +# - _new +# - DESTROY +# - clone +# - encrypt_add +# - encrypt_done +# - decrypt_add +# - decrypt_done +# - aad_add + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +sub eax_encrypt_authenticate { + my $cipher_name = shift; + my $key = shift; + my $iv = shift; + my $adata = shift; + my $plaintext = shift; + + my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $iv); + $m->aad_add($adata) if defined $adata; + my $ct = $m->encrypt_add($plaintext); + my $tag = $m->encrypt_done; + return ($ct, $tag); +} + +sub eax_decrypt_verify { + my $cipher_name = shift; + my $key = shift; + my $iv = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + + my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $iv); + $m->aad_add($adata) if defined $adata; + my $ct = $m->decrypt_add($ciphertext); + return $m->decrypt_done($tag) ? $ct : undef; +} + +sub header_add { + # obsolete, only for backwards compatibility + shift->aad_add(@_); +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::EAX - Authenticated encryption in EAX mode + +=head1 SYNOPSIS + + ### OO interface + use Crypt::AuthEnc::EAX; + + # encrypt and authenticate + my $ae = Crypt::AuthEnc::EAX->new("AES", $key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $ct = $ae->encrypt_add('data1'); + $ct = $ae->encrypt_add('data2'); + $ct = $ae->encrypt_add('data3'); + $tag = $ae->encrypt_done(); + + # decrypt and verify + my $ae = Crypt::AuthEnc::EAX->new("AES", $key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $pt = $ae->decrypt_add('ciphertext1'); + $pt = $ae->decrypt_add('ciphertext2'); + $pt = $ae->decrypt_add('ciphertext3'); + $tag = $ae->decrypt_done(); + die "decrypt failed" unless $tag eq $expected_tag; + + #or + my $result = $ae->decrypt_done($expected_tag) die "decrypt failed"; + + ### functional interface + use Crypt::AuthEnc::EAX qw(eax_encrypt_authenticate eax_decrypt_verify); + + my ($ciphertext, $tag) = eax_encrypt_authenticate('AES', $key, $iv, $adata, $plaintext); + my $plaintext = eax_decrypt_verify('AES', $key, $iv, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +EAX is a mode that requires a cipher, CTR and OMAC support and provides encryption and authentication. +It is initialized with a random IV that can be shared publicly, additional authenticated data which can +be fixed and public, and a random secret symmetric key. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::EAX qw(eax_encrypt_authenticate eax_decrypt_verify); + +=head1 FUNCTIONS + +=head2 eax_encrypt_authenticate + + my ($ciphertext, $tag) = eax_encrypt_authenticate($cipher, $key, $iv, $adata, $plaintext); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $iv ...... unique initialization vector (no need to keep it secret) + # $adata ... additional authenticated data + +=head2 eax_decrypt_verify + + my $plaintext = eax_decrypt_verify($cipher, $key, $iv, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 METHODS + +=head2 new + + my $ae = Crypt::AuthEnc::EAX->new($cipher, $key, $iv); + #or + my $ae = Crypt::AuthEnc::EAX->new($cipher, $key, $iv, $adata); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $iv ...... unique initialization vector (no need to keep it secret) + # $adata ... additional authenticated data (optional) + +=head2 aad_add + + $ae->aad_add($adata); #can be called multiple times + +=head2 encrypt_add + + $ciphertext = $ae->encrypt_add($data); #can be called multiple times + +=head2 encrypt_done + + $tag = $ae->encrypt_done(); + +=head2 decrypt_add + + $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times + +=head2 decrypt_done + + my $result = $ae->decrypt_done($tag); # returns 1 (success) or 0 (failure) + #or + my $tag = $ae->decrypt_done; # returns $tag value + +=head2 clone + + my $ae_new = $ae->clone; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::AuthEnc::CCM|Crypt::AuthEnc::CCM>, L<Crypt::AuthEnc::GCM|Crypt::AuthEnc::GCM>, L<Crypt::AuthEnc::OCB|Crypt::AuthEnc::OCB> + +=item * L<https://en.wikipedia.org/wiki/EAX_mode|https://en.wikipedia.org/wiki/EAX_mode> + +=back diff --git a/lib/Crypt/AuthEnc/GCM.pm b/lib/Crypt/AuthEnc/GCM.pm new file mode 100644 index 00000000..4d9b98f6 --- /dev/null +++ b/lib/Crypt/AuthEnc/GCM.pm @@ -0,0 +1,179 @@ +package Crypt::AuthEnc::GCM; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( gcm_encrypt_authenticate gcm_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { + my ($class, $cipher, $key, $iv) = @_; + my $self = _new(Crypt::Cipher::_trans_cipher_name($cipher), $key); + # for backwards compatibility the $iv is optional + $self->iv_add($iv) if defined $iv; + return $self; +} + +sub gcm_encrypt_authenticate { + my $cipher_name = shift; + my $key = shift; + my $iv = shift; + my $adata = shift; + my $plaintext = shift; + + my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); + $m->iv_add($iv); + $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string + my $ct = $m->encrypt_add($plaintext); + my $tag = $m->encrypt_done; + return ($ct, $tag); +} + +sub gcm_decrypt_verify { + my $cipher_name = shift; + my $key = shift; + my $iv = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + + my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); + $m->iv_add($iv); + $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string + my $ct = $m->decrypt_add($ciphertext); + return $m->decrypt_done($tag) ? $ct : undef; +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::GCM - Authenticated encryption in GCM mode + +=head1 SYNOPSIS + + ### OO interface + use Crypt::AuthEnc::GCM; + + # encrypt and authenticate + my $ae = Crypt::AuthEnc::GCM->new("AES", $key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $ct = $ae->encrypt_add('data1'); + $ct = $ae->encrypt_add('data2'); + $ct = $ae->encrypt_add('data3'); + $tag = $ae->encrypt_done(); + + # decrypt and verify + my $ae = Crypt::AuthEnc::GCM->new("AES", $key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $pt = $ae->decrypt_add('ciphertext1'); + $pt = $ae->decrypt_add('ciphertext2'); + $pt = $ae->decrypt_add('ciphertext3'); + $tag = $ae->decrypt_done(); + die "decrypt failed" unless $tag eq $expected_tag; + + #or + my $result = $ae->decrypt_done($expected_tag) die "decrypt failed"; + + ### functional interface + use Crypt::AuthEnc::GCM qw(gcm_encrypt_authenticate gcm_decrypt_verify); + + my ($ciphertext, $tag) = gcm_encrypt_authenticate('AES', $key, $iv, $adata, $plaintext); + my $plaintext = gcm_decrypt_verify('AES', $key, $iv, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +Galois/Counter Mode (GCM) - provides encryption and authentication. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::GCM qw(gcm_encrypt_authenticate gcm_decrypt_verify); + +=head1 FUNCTIONS + +=head2 gcm_encrypt_authenticate + + my ($ciphertext, $tag) = gcm_encrypt_authenticate($cipher, $key, $iv, $adata, $plaintext); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $iv ...... initialization vector + # $adata ... additional authenticated data + +=head2 gcm_decrypt_verify + + my $plaintext = gcm_decrypt_verify($cipher, $key, $iv, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 METHODS + +=head2 new + + my $ae = Crypt::AuthEnc::GCM->new($cipher, $key); + #or + my $ae = Crypt::AuthEnc::GCM->new($cipher, $key, $iv); + + # $cipher .. 'AES' or name of any other cipher + # $key ..... encryption key of proper length + # $iv ...... initialization vector (optional, you can set it later via iv_add method) + +=head2 iv_add + + $ae->iv_add($iv_data); #can be called multiple times + +=head2 aad_add + +Can be called B<after> all C<iv_add> calls but before the first C<encrypt_add> or C<decrypt_add>; + + $ae->aad_add($aad_data); #can be called multiple times + +=head2 encrypt_add + + $ciphertext = $ae->encrypt_add($data); #can be called multiple times + +=head2 encrypt_done + + $tag = $ae->encrypt_done(); + +=head2 decrypt_add + + $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times + +=head2 decrypt_done + + my $result = $ae->decrypt_done($tag); # returns 1 (success) or 0 (failure) + #or + my $tag = $ae->decrypt_done; # returns $tag value + +=head2 reset + + $ae->reset; + +=head2 clone + + my $ae_new = $ae->clone; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::AuthEnc::CCM|Crypt::AuthEnc::CCM>, L<Crypt::AuthEnc::EAX|Crypt::AuthEnc::EAX>, L<Crypt::AuthEnc::OCB|Crypt::AuthEnc::OCB> + +=item * L<https://en.wikipedia.org/wiki/Galois/Counter_Mode> + +=back diff --git a/lib/Crypt/AuthEnc/OCB.pm b/lib/Crypt/AuthEnc/OCB.pm new file mode 100644 index 00000000..aabab364 --- /dev/null +++ b/lib/Crypt/AuthEnc/OCB.pm @@ -0,0 +1,174 @@ +package Crypt::AuthEnc::OCB; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( ocb_encrypt_authenticate ocb_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +sub ocb_encrypt_authenticate { + my $cipher_name = shift; + my $key = shift; + my $nonce = shift; + my $adata = shift; + my $plaintext = shift; + + my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce); + $m->aad_add($adata) if defined $adata; + my $ct = $m->encrypt_last($plaintext); + my $tag = $m->encrypt_done; + return ($ct, $tag); +} + +sub ocb_decrypt_verify { + my $cipher_name = shift; + my $key = shift; + my $nonce = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + + my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce); + $m->aad_add($adata) if defined $adata; + my $ct = $m->decrypt_last($ciphertext); + return $m->decrypt_done($tag) ? $ct : undef; +} + +sub adata_add { + # obsolete, only for backwards compatibility + shift->aad_add(@_); +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::OCB - Authenticated encryption in OCBv3 mode + +=head1 SYNOPSIS + + ### OO interface + use Crypt::AuthEnc::OCB; + + # encrypt and authenticate + my $ae = Crypt::AuthEnc::OCB->new("AES", $key, $nonce); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $ct = $ae->encrypt_add('data1'); + $ct = $ae->encrypt_add('data2'); + $ct = $ae->encrypt_add('data3'); + $ct = $ae->encrypt_last('rest of data'); + ($ct,$tag) = $ae->encrypt_done(); + + # decrypt and verify + my $ae = Crypt::AuthEnc::OCB->new("AES", $key, $nonce); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $pt = $ae->decrypt_add('ciphertext1'); + $pt = $ae->decrypt_add('ciphertext2'); + $pt = $ae->decrypt_add('ciphertext3'); + $pt = $ae->decrypt_last('rest of data'); + ($pt,$tag) = $ae->decrypt_done(); + + ### functional interface + use Crypt::AuthEnc::OCB qw(ocb_encrypt_authenticate ocb_decrypt_verify); + + my ($ciphertext, $tag) = ocb_encrypt_authenticate('AES', $key, $nonce, $adata, $plaintext); + my $plaintext = ocb_decrypt_verify('AES', $key, $nonce, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +This module implements OCB version 3 according http://datatracker.ietf.org/doc/draft-irtf-cfrg-ocb/ + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::OCB qw(ocb_encrypt_authenticate ocb_decrypt_verify); + +=head1 FUNCTIONS + +=head2 ocb_encrypt_authenticate + + my ($ciphertext, $tag) = ocb_encrypt_authenticate($cipher, $key, $nonce, $adata, $plaintext); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $nonce ... unique nonce/salt (no need to keep it secret) + # $adata ... additional authenticated data + +=head2 ocb_decrypt_verify + + my $plaintext = ocb_decrypt_verify($cipher, $key, $nonce, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 METHODS + +=head2 new + + my $ae = Crypt::AuthEnc::OCB->new($cipher, $key, $nonce); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $nonce ... unique nonce/salt (no need to keep it secret) + +=head2 aad_add + + $ae->aad_add($adata); #can be called multiple times + +=head2 encrypt_add + + $ciphertext = $ae->encrypt_add($data); #can be called multiple times + + #BEWARE: size of $data has to be multiple of blocklen (16 for AES) + +=head2 encrypt_last + + $ciphertext = $ae->encrypt_last($data); + +=head2 encrypt_done + + $tag = $ae->encrypt_done(); + +=head2 decrypt_add + + $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times + + #BEWARE: size of $ciphertext has to be multiple of blocklen (16 for AES) + +=head2 encrypt_last + + $plaintext = $ae->decrypt_last($data); + +=head2 decrypt_done + + my $result = $ae->decrypt_done($tag); # returns 1 (success) or 0 (failure) + #or + my $tag = $ae->decrypt_done; # returns $tag value + +=head2 clone + + my $ae_new = $ae->clone; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::AuthEnc::CCM|Crypt::AuthEnc::CCM>, L<Crypt::AuthEnc::GCM|Crypt::AuthEnc::GCM>, L<Crypt::AuthEnc::EAX|Crypt::AuthEnc::EAX> + +=item * L<https://en.wikipedia.org/wiki/OCB_mode|https://en.wikipedia.org/wiki/OCB_mode> + +=back
\ No newline at end of file diff --git a/lib/Crypt/Checksum.pm b/lib/Crypt/Checksum.pm new file mode 100644 index 00000000..23d23519 --- /dev/null +++ b/lib/Crypt/Checksum.pm @@ -0,0 +1,197 @@ +package Crypt::Checksum; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw/ + adler32_data adler32_data_hex adler32_data_int adler32_file adler32_file_hex adler32_file_int + crc32_data crc32_data_hex crc32_data_int crc32_file crc32_file_hex crc32_file_int + /] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use Crypt::Checksum::Adler32; +use Crypt::Checksum::CRC32; + +sub adler32_data { Crypt::Checksum::Adler32->new->add(@_)->digest } +sub adler32_data_hex { Crypt::Checksum::Adler32->new->add(@_)->hexdigest } +sub adler32_data_int { unpack("N", Crypt::Checksum::Adler32->new->add(@_)->digest) } +sub adler32_file { Crypt::Checksum::Adler32->new->addfile(@_)->digest } +sub adler32_file_hex { Crypt::Checksum::Adler32->new->addfile(@_)->hexdigest } +sub adler32_file_int { unpack("N", Crypt::Checksum::Adler32->new->addfile(@_)->digest) } +sub crc32_data { Crypt::Checksum::CRC32->new->add(@_)->digest } +sub crc32_data_hex { Crypt::Checksum::CRC32->new->add(@_)->hexdigest } +sub crc32_data_int { unpack("N", Crypt::Checksum::CRC32->new->add(@_)->digest) } +sub crc32_file { Crypt::Checksum::CRC32->new->addfile(@_)->digest } +sub crc32_file_hex { Crypt::Checksum::CRC32->new->addfile(@_)->hexdigest } +sub crc32_file_int { unpack("N", Crypt::Checksum::CRC32->new->addfile(@_)->digest) } + +1; + +=pod + +=head1 NAME + +Crypt::Checksum - functional interface to CRC32 and Adler32 checksums + +=head1 SYNOPSIS + + use Crypt::Checksum ':all'; + + # calculate Adler32 checksum from string/buffer + $checksum_raw = adler32_data($data); + $checksum_hex = adler32_data_hex($data); + + # calculate Adler32 checksum from file + $checksum_raw = adler32_file('filename.dat'); + $checksum_hex = adler32_file_hex('filename.dat'); + + # calculate Adler32 checksum from filehandle + $checksum_raw = adler32_file(*FILEHANDLE); + $checksum_hex = adler32_file_hex(*FILEHANDLE); + + # calculate CRC32 checksum from string/buffer + $checksum_raw = crc32_data($data); + $checksum_hex = crc32_data_hex($data); + + # calculate CRC32 checksum from file + $checksum_raw = crc32_file('filename.dat'); + $checksum_hex = crc32_file_hex('filename.dat'); + + # calculate CRC32 checksum from filehandle + $checksum_raw = crc32_file(*FILEHANDLE); + $checksum_hex = crc32_file_hex(*FILEHANDLE); + +=head1 DESCRIPTION + +Calculating CRC32 and Adler32 checksums (functional interface); + +I<Since: CryptX-0.032> + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Checksum qw( adler32_data adler32_data_hex adler32_file adler32_file_hex + crc32_data crc32_data_hex crc32_file crc32_file_hex ); + +Or all of them at once: + + use Crypt::Checksum ':all'; + +=head1 FUNCTIONS + +=head2 adler32_data + +Returns checksum as raw octects. + + $checksum_raw = adler32_data('data string'); + #or + $checksum_raw = adler32_data('any data', 'more data', 'even more data'); + +=head2 adler32_data_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = adler32_data_hex('data string'); + #or + $checksum_hex = adler32_data_hex('any data', 'more data', 'even more data'); + +=head2 adler32_data_int + +Returns checksum as unsingned 32bit integer. + + $checksum_hex = adler32_data_int('data string'); + #or + $checksum_hex = adler32_data_int('any data', 'more data', 'even more data'); + +=head2 adler32_file + +Returns checksum as raw octects. + + $checksum_raw = adler32_file('filename.dat'); + #or + $checksum_raw = adler32_file(*FILEHANDLE); + +=head2 adler32_file_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = adler32_file_hex('filename.dat'); + #or + $checksum_hex = adler32_file_hex(*FILEHANDLE); + +=head2 adler32_file_int + +Returns checksum as unsingned 32bit integer. + + $checksum_hex = adler32_file_int('data string'); + #or + $checksum_hex = adler32_file_int('any data', 'more data', 'even more data'); + +=head2 crc32_data + +Returns checksum as raw octects. + + $checksum_raw = crc32_data('data string'); + #or + $checksum_raw = crc32_data('any data', 'more data', 'even more data'); + +=head2 crc32_data_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = crc32_data_hex('data string'); + #or + $checksum_hex = crc32_data_hex('any data', 'more data', 'even more data'); + +=head2 crc32_data_int + +Returns checksum as unsingned 32bit integer. + + $checksum_hex = crc32_data_int('data string'); + #or + $checksum_hex = crc32_data_int('any data', 'more data', 'even more data'); + +=head2 crc32_file + +Returns checksum as raw octects. + + $checksum_raw = crc32_file('filename.dat'); + #or + $checksum_raw = crc32_file(*FILEHANDLE); + +=head2 crc32_file_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = crc32_file_hex('filename.dat'); + #or + $checksum_hex = crc32_file_hex(*FILEHANDLE); + +=head2 crc32_file_int + +Returns checksum as unsingned 32bit integer. + + $checksum_hex = crc32_file_int('data string'); + #or + $checksum_hex = crc32_file_int('any data', 'more data', 'even more data'); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Checksum::Adler32>, L<Crypt::Checksum::CRC32> + +=item * L<https://en.wikipedia.org/wiki/Adler-32> + +=item * L<https://en.wikipedia.org/wiki/Cyclic_redundancy_check> + +=back + +=cut
\ No newline at end of file diff --git a/lib/Crypt/Checksum/Adler32.pm b/lib/Crypt/Checksum/Adler32.pm new file mode 100644 index 00000000..5691805f --- /dev/null +++ b/lib/Crypt/Checksum/Adler32.pm @@ -0,0 +1,121 @@ +package Crypt::Checksum::Adler32; + +use strict; +use warnings; +our $VERSION = '0.048'; +use Carp; +use CryptX; + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::Checksum::Adler32 - Compute Adler32 checksum + +=head1 SYNOPSIS + + use Crypt::Checksum::Adler32; + + $d = Crypt::Checksum::Adler32->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $checksum_raw = $d->digest; # raw bytes + $checksum_hex = $d->hexdigest; # hexadecimal form + +=head1 DESCRIPTION + +Calculating Adler32 checksums (OO interface); + +I<Since: CryptX-0.032> + +=head1 METHODS + +=head2 new + +Constructor, returns a reference to the checksum object. + + $d = Crypt::Checksum::Adler32->new; + +=head2 clone + +Creates a copy of the checksum object state and returns a reference to the copy. + + $d->clone(); + +=head2 reset + +Reinitialize the checksum object state and returns a reference to the checksum object. + + $d->reset(); + +=head2 add + +All arguments are appended to the message we calculate checksum for. +The return value is the checksum object itself. + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + +The content of the file (or filehandle) is appended to the message we calculate checksum for. +The return value is the checksum object itself. + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 digest + +Returns the binary checksum (raw bytes). + + $result_raw = $d->digest(); + +=head2 hexdigest + +Returns the checksum encoded as a hexadecimal string. + + $result_hex = $d->hexdigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Checksum> + +=item * L<https://en.wikipedia.org/wiki/Adler-32> + +=back + +=cut
\ No newline at end of file diff --git a/lib/Crypt/Checksum/CRC32.pm b/lib/Crypt/Checksum/CRC32.pm new file mode 100644 index 00000000..72cd6624 --- /dev/null +++ b/lib/Crypt/Checksum/CRC32.pm @@ -0,0 +1,121 @@ +package Crypt::Checksum::CRC32; + +use strict; +use warnings; +our $VERSION = '0.048'; +use Carp; +use CryptX; + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::Checksum::CRC32 - Compute CRC32 checksum + +=head1 SYNOPSIS + + use Crypt::Checksum::CRC32; + + $d = Crypt::Checksum::CRC32->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $checksum_raw = $d->digest; # raw bytes + $checksum_hex = $d->hexdigest; # hexadecimal form + +=head1 DESCRIPTION + +Calculating CRC32 checksums (OO interface); + +I<Since: CryptX-0.032> + +=head1 METHODS + +=head2 new + +Constructor, returns a reference to the checksum object. + + $d = Crypt::Checksum::CRC32->new; + +=head2 clone + +Creates a copy of the checksum object state and returns a reference to the copy. + + $d->clone(); + +=head2 reset + +Reinitialize the checksum object state and returns a reference to the checksum object. + + $d->reset(); + +=head2 add + +All arguments are appended to the message we calculate checksum for. +The return value is the checksum object itself. + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + +The content of the file (or filehandle) is appended to the message we calculate checksum for. +The return value is the checksum object itself. + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 digest + +Returns the binary checksum (raw bytes). + + $result_raw = $d->digest(); + +=head2 hexdigest + +Returns the checksum encoded as a hexadecimal string. + + $result_hex = $d->hexdigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Checksum> + +=item * L<https://en.wikipedia.org/wiki/Cyclic_redundancy_check> + +=back + +=cut
\ No newline at end of file diff --git a/lib/Crypt/Cipher.pm b/lib/Crypt/Cipher.pm new file mode 100644 index 00000000..686780f8 --- /dev/null +++ b/lib/Crypt/Cipher.pm @@ -0,0 +1,217 @@ +package Crypt::Cipher; + +use strict; +use warnings; +our $VERSION = '0.048'; +use CryptX; + +### the following methods/functions are implemented in XS: +# - _new +# - DESTROY +# - _keysize +# - _max_keysize +# - _min_keysize +# - _blocksize +# - _default_rounds +# - encrypt +# - decrypt +#functions, not methods: +# - _block_length_by_name +# - _min_key_length_by_name +# - _max_key_length_by_name +# - _default_rounds_by_name + +sub _trans_cipher_name { + my $name = shift; + my %trans = ( + DES_EDE => '3des', + SAFERP => 'safer+', + SAFER_K128 => 'safer-k128', + SAFER_K64 => 'safer-k64', + SAFER_SK128 => 'safer-sk128', + SAFER_SK64 => 'safer-sk64', + ); + $name =~ s/^Crypt::Cipher:://; + return $trans{uc($name)} if defined $trans{uc($name)}; + return lc($name); +} + +### METHODS + +sub new { + my $pkg = shift; + my $cipher_name = $pkg eq __PACKAGE__ ? _trans_cipher_name(shift) : _trans_cipher_name($pkg); + return _new($cipher_name, @_); +} + +sub blocksize { + my $self = shift; + return $self->_blocksize if ref($self); + $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; + return _block_length_by_name(_trans_cipher_name($self)); +} + +sub keysize { + max_keysize(@_); +} + +sub max_keysize +{ + my $self = shift; + return unless defined $self; + return $self->_max_keysize if ref($self); + $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; + return _max_key_length_by_name(_trans_cipher_name($self)); +} + +sub min_keysize { + my $self = shift; + return unless defined $self; + return $self->_min_keysize if ref($self); + $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; + return _min_key_length_by_name(_trans_cipher_name($self)); +} + +sub default_rounds { + my $self = shift; + return unless defined $self; + return $self->_default_rounds if ref($self); + $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; + return _default_rounds_by_name(_trans_cipher_name($self)); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::Cipher - Generic interface to cipher functions + +=head1 SYNOPSIS + + #### example 1 (encrypting single block) + use Crypt::Cipher; + + my $key = '...'; # length has to be valid key size for this cipher + my $c = Crypt::Cipher->new('AES', $key); + my $blocksize = $c->blocksize; + my $ciphertext = $c->encrypt('plain text block'); #encrypt 1 block + my $plaintext = $c->decrypt($ciphertext); #decrypt 1 block + + ### example 2 (using CBC mode) + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('AES'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + #### example 3 (compatibility with Crypt::CBC) + use Crypt::CBC; + use Crypt::Cipher; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cipher = Crypt::Cipher('AES', $key); + my $cbc = Crypt::CBC->new( -cipher=>$cipher, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +Provides an interface to various symetric cipher algorithms. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + +Constructor, returns a reference to the cipher object. + + ## basic scenario + $d = Crypt::Cipher->new($name, $key); + # $name = one of 'AES', 'Anubis', 'Blowfish', 'CAST5', 'Camellia', 'DES', 'DES_EDE', + # 'KASUMI', 'Khazad', 'MULTI2', 'Noekeon', 'RC2', 'RC5', 'RC6', + # 'SAFERP', 'SAFER_K128', 'SAFER_K64', 'SAFER_SK128', 'SAFER_SK64', + # 'SEED', 'Skipjack', 'Twofish', 'XTEA' + # simply any <CNAME> for which there exists Crypt::Cipher::<NAME> + # $key = binary key (keysize should comply with selected cipher requirements) + + ## some of the ciphers (e.g. MULTI2, RC5, SAFER) allows to set number of rounds + $d = Crypt::Cipher->new('MULTI2', $key, $rounds); + # $rounds = positive integer (should comply with selected cipher requirements) + +=head2 encrypt + +Encrypts $plaintext and returns the $ciphertext where $plaintext and $ciphertext should be of B<blocksize> bytes. + + $ciphertext = $d->encrypt($plaintext); + +=head2 decrypt + +Decrypts $ciphertext and returns the $plaintext where $plaintext and $ciphertext should be of B<blocksize> bytes. + + $plaintext = $d->encrypt($ciphertext); + +=head2 keysize + +Just an alias for B<max_keysize> (needed for L<Crypt::CBC|Crypt::CBC> compatibility). + +=head2 max_keysize + +Returns the maximal allowed key size (in bytes) for given cipher. + + $d->max_keysize; + #or + Crypt::Cipher->max_keysize('AES'); + #or + Crypt::Cipher::max_keysize('AES'); + +=head2 min_keysize + +Returns the minimal allowed key size (in bytes) for given cipher. + + $d->min_keysize; + #or + Crypt::Cipher->min_keysize('AES'); + #or + Crypt::Cipher::min_keysize('AES'); + +=head2 blocksize + +Returns block size (in bytes) for given cipher. + + $d->blocksize; + #or + Crypt::Cipher->blocksize('AES'); + #or + Crypt::Cipher::blocksize('AES'); + +=head2 default_rounds + +Returns default number of rounds for given cipher. NOTE: only some cipher (e.g. MULTI2, RC5, SAFER) allows to set number of rounds via new(). + + $d->default_rounds; + #or + Crypt::Cipher->default_rounds('AES'); + #or + Crypt::Cipher::default_rounds('AES'); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * Check subclasses like L<Crypt::Cipher::AES|Crypt::Cipher::AES>, L<Crypt::Cipher::Blowfish|Crypt::Cipher::Blowfish>, ... + +=back + +=cut + +__END__ diff --git a/lib/Crypt/Cipher/AES.pm b/lib/Crypt/Cipher/AES.pm new file mode 100644 index 00000000..1d4e97dc --- /dev/null +++ b/lib/Crypt/Cipher/AES.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::AES; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::AES - Symetric cipher AES (aka Rijndael), key size: 128/192/256 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('AES'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::AES; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::AES', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the AES cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::AES->new($key); + #or + $c = Crypt::Cipher::AES->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::AES->keysize; + #or + Crypt::Cipher::AES::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::AES->blocksize; + #or + Crypt::Cipher::AES::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::AES->max_keysize; + #or + Crypt::Cipher::AES::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::AES->min_keysize; + #or + Crypt::Cipher::AES::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::AES->default_rounds; + #or + Crypt::Cipher::AES::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/Advanced_Encryption_Standard|http://en.wikipedia.org/wiki/Advanced_Encryption_Standard> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/Anubis.pm b/lib/Crypt/Cipher/Anubis.pm new file mode 100644 index 00000000..e06b5cd1 --- /dev/null +++ b/lib/Crypt/Cipher/Anubis.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Anubis; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Anubis - Symetric cipher Anubis, key size: 128-320 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Anubis'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Anubis; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Anubis', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Anubis cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Anubis->new($key); + #or + $c = Crypt::Cipher::Anubis->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Anubis->keysize; + #or + Crypt::Cipher::Anubis::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Anubis->blocksize; + #or + Crypt::Cipher::Anubis::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Anubis->max_keysize; + #or + Crypt::Cipher::Anubis::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Anubis->min_keysize; + #or + Crypt::Cipher::Anubis::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Anubis->default_rounds; + #or + Crypt::Cipher::Anubis::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/Anubis_(cipher)|http://en.wikipedia.org/wiki/Anubis_(cipher)> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/Blowfish.pm b/lib/Crypt/Cipher/Blowfish.pm new file mode 100644 index 00000000..0e98a2cd --- /dev/null +++ b/lib/Crypt/Cipher/Blowfish.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Blowfish; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Blowfish - Symetric cipher Blowfish, key size: 64-448 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Blowfish'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Blowfish; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Blowfish', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Blowfish cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Blowfish->new($key); + #or + $c = Crypt::Cipher::Blowfish->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Blowfish->keysize; + #or + Crypt::Cipher::Blowfish::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Blowfish->blocksize; + #or + Crypt::Cipher::Blowfish::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Blowfish->max_keysize; + #or + Crypt::Cipher::Blowfish::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Blowfish->min_keysize; + #or + Crypt::Cipher::Blowfish::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Blowfish->default_rounds; + #or + Crypt::Cipher::Blowfish::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/Blowfish_(cipher)|http://en.wikipedia.org/wiki/Blowfish_(cipher)> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/CAST5.pm b/lib/Crypt/Cipher/CAST5.pm new file mode 100644 index 00000000..fbfd240c --- /dev/null +++ b/lib/Crypt/Cipher/CAST5.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::CAST5; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::CAST5 - Symetric cipher CAST5 (aka CAST-128), key size: 40-128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('CAST5'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::CAST5; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::CAST5', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the CAST5 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::CAST5->new($key); + #or + $c = Crypt::Cipher::CAST5->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::CAST5->keysize; + #or + Crypt::Cipher::CAST5::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::CAST5->blocksize; + #or + Crypt::Cipher::CAST5::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::CAST5->max_keysize; + #or + Crypt::Cipher::CAST5::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::CAST5->min_keysize; + #or + Crypt::Cipher::CAST5::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::CAST5->default_rounds; + #or + Crypt::Cipher::CAST5::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/CAST-128|http://en.wikipedia.org/wiki/CAST-128> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/Camellia.pm b/lib/Crypt/Cipher/Camellia.pm new file mode 100644 index 00000000..0415ef26 --- /dev/null +++ b/lib/Crypt/Cipher/Camellia.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Camellia; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Camellia - Symetric cipher Camellia, key size: 128/192/256 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Camellia'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Camellia; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Camellia', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Camellia cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Camellia->new($key); + #or + $c = Crypt::Cipher::Camellia->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Camellia->keysize; + #or + Crypt::Cipher::Camellia::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Camellia->blocksize; + #or + Crypt::Cipher::Camellia::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Camellia->max_keysize; + #or + Crypt::Cipher::Camellia::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Camellia->min_keysize; + #or + Crypt::Cipher::Camellia::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Camellia->default_rounds; + #or + Crypt::Cipher::Camellia::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/Camellia_(cipher)|http://en.wikipedia.org/wiki/Camellia_(cipher)> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/DES.pm b/lib/Crypt/Cipher/DES.pm new file mode 100644 index 00000000..486cae84 --- /dev/null +++ b/lib/Crypt/Cipher/DES.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::DES; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::DES - Symetric cipher DES, key size: 64[56] bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('DES'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::DES; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::DES', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the DES cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::DES->new($key); + #or + $c = Crypt::Cipher::DES->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::DES->keysize; + #or + Crypt::Cipher::DES::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::DES->blocksize; + #or + Crypt::Cipher::DES::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::DES->max_keysize; + #or + Crypt::Cipher::DES::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::DES->min_keysize; + #or + Crypt::Cipher::DES::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::DES->default_rounds; + #or + Crypt::Cipher::DES::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/Data_Encryption_Standard|http://en.wikipedia.org/wiki/Data_Encryption_Standard> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/DES_EDE.pm b/lib/Crypt/Cipher/DES_EDE.pm new file mode 100644 index 00000000..ea4b31d9 --- /dev/null +++ b/lib/Crypt/Cipher/DES_EDE.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::DES_EDE; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::DES_EDE - Symetric cipher DES_EDE (aka Tripple-DES, 3DES), key size: 192[168] bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('DES_EDE'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::DES_EDE; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::DES_EDE', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the DES_EDE cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::DES_EDE->new($key); + #or + $c = Crypt::Cipher::DES_EDE->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::DES_EDE->keysize; + #or + Crypt::Cipher::DES_EDE::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::DES_EDE->blocksize; + #or + Crypt::Cipher::DES_EDE::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::DES_EDE->max_keysize; + #or + Crypt::Cipher::DES_EDE::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::DES_EDE->min_keysize; + #or + Crypt::Cipher::DES_EDE::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::DES_EDE->default_rounds; + #or + Crypt::Cipher::DES_EDE::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/Triple_DES|http://en.wikipedia.org/wiki/Triple_DES> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/KASUMI.pm b/lib/Crypt/Cipher/KASUMI.pm new file mode 100644 index 00000000..f1dc727e --- /dev/null +++ b/lib/Crypt/Cipher/KASUMI.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::KASUMI; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::KASUMI - Symetric cipher KASUMI, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('KASUMI'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::KASUMI; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::KASUMI', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the KASUMI cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::KASUMI->new($key); + #or + $c = Crypt::Cipher::KASUMI->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::KASUMI->keysize; + #or + Crypt::Cipher::KASUMI::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::KASUMI->blocksize; + #or + Crypt::Cipher::KASUMI::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::KASUMI->max_keysize; + #or + Crypt::Cipher::KASUMI::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::KASUMI->min_keysize; + #or + Crypt::Cipher::KASUMI::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::KASUMI->default_rounds; + #or + Crypt::Cipher::KASUMI::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/KASUMI_(block_cipher)|http://en.wikipedia.org/wiki/KASUMI_(block_cipher)> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/Khazad.pm b/lib/Crypt/Cipher/Khazad.pm new file mode 100644 index 00000000..bc6217f0 --- /dev/null +++ b/lib/Crypt/Cipher/Khazad.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Khazad; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Khazad - Symetric cipher Khazad, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Khazad'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Khazad; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Khazad', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Khazad cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Khazad->new($key); + #or + $c = Crypt::Cipher::Khazad->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Khazad->keysize; + #or + Crypt::Cipher::Khazad::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Khazad->blocksize; + #or + Crypt::Cipher::Khazad::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Khazad->max_keysize; + #or + Crypt::Cipher::Khazad::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Khazad->min_keysize; + #or + Crypt::Cipher::Khazad::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Khazad->default_rounds; + #or + Crypt::Cipher::Khazad::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/KHAZAD|http://en.wikipedia.org/wiki/KHAZAD> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/MULTI2.pm b/lib/Crypt/Cipher/MULTI2.pm new file mode 100644 index 00000000..895b2420 --- /dev/null +++ b/lib/Crypt/Cipher/MULTI2.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::MULTI2; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::MULTI2 - Symetric cipher MULTI2, key size: 320 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('MULTI2'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::MULTI2; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::MULTI2', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the MULTI2 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::MULTI2->new($key); + #or + $c = Crypt::Cipher::MULTI2->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::MULTI2->keysize; + #or + Crypt::Cipher::MULTI2::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::MULTI2->blocksize; + #or + Crypt::Cipher::MULTI2::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::MULTI2->max_keysize; + #or + Crypt::Cipher::MULTI2::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::MULTI2->min_keysize; + #or + Crypt::Cipher::MULTI2::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::MULTI2->default_rounds; + #or + Crypt::Cipher::MULTI2::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/MULTI2|http://en.wikipedia.org/wiki/MULTI2> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/Noekeon.pm b/lib/Crypt/Cipher/Noekeon.pm new file mode 100644 index 00000000..4a73159e --- /dev/null +++ b/lib/Crypt/Cipher/Noekeon.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Noekeon; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Noekeon - Symetric cipher Noekeon, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Noekeon'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Noekeon; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Noekeon', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Noekeon cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Noekeon->new($key); + #or + $c = Crypt::Cipher::Noekeon->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Noekeon->keysize; + #or + Crypt::Cipher::Noekeon::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Noekeon->blocksize; + #or + Crypt::Cipher::Noekeon::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Noekeon->max_keysize; + #or + Crypt::Cipher::Noekeon::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Noekeon->min_keysize; + #or + Crypt::Cipher::Noekeon::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Noekeon->default_rounds; + #or + Crypt::Cipher::Noekeon::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/NOEKEON|http://en.wikipedia.org/wiki/NOEKEON> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/RC2.pm b/lib/Crypt/Cipher/RC2.pm new file mode 100644 index 00000000..8529a4b6 --- /dev/null +++ b/lib/Crypt/Cipher/RC2.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::RC2; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::RC2 - Symetric cipher RC2, key size: 64-1024 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('RC2'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::RC2; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC2', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the RC2 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::RC2->new($key); + #or + $c = Crypt::Cipher::RC2->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::RC2->keysize; + #or + Crypt::Cipher::RC2::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::RC2->blocksize; + #or + Crypt::Cipher::RC2::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::RC2->max_keysize; + #or + Crypt::Cipher::RC2::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::RC2->min_keysize; + #or + Crypt::Cipher::RC2::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::RC2->default_rounds; + #or + Crypt::Cipher::RC2::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/RC2|http://en.wikipedia.org/wiki/RC2> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/RC5.pm b/lib/Crypt/Cipher/RC5.pm new file mode 100644 index 00000000..f358c25a --- /dev/null +++ b/lib/Crypt/Cipher/RC5.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::RC5; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::RC5 - Symetric cipher RC5, key size: 64-1024 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('RC5'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::RC5; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC5', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the RC5 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::RC5->new($key); + #or + $c = Crypt::Cipher::RC5->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::RC5->keysize; + #or + Crypt::Cipher::RC5::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::RC5->blocksize; + #or + Crypt::Cipher::RC5::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::RC5->max_keysize; + #or + Crypt::Cipher::RC5::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::RC5->min_keysize; + #or + Crypt::Cipher::RC5::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::RC5->default_rounds; + #or + Crypt::Cipher::RC5::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/RC5|http://en.wikipedia.org/wiki/RC5> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/RC6.pm b/lib/Crypt/Cipher/RC6.pm new file mode 100644 index 00000000..f185f3b9 --- /dev/null +++ b/lib/Crypt/Cipher/RC6.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::RC6; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::RC6 - Symetric cipher RC6, key size: 64-1024 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('RC6'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::RC6; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC6', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the RC6 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::RC6->new($key); + #or + $c = Crypt::Cipher::RC6->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::RC6->keysize; + #or + Crypt::Cipher::RC6::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::RC6->blocksize; + #or + Crypt::Cipher::RC6::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::RC6->max_keysize; + #or + Crypt::Cipher::RC6::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::RC6->min_keysize; + #or + Crypt::Cipher::RC6::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::RC6->default_rounds; + #or + Crypt::Cipher::RC6::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/RC6|http://en.wikipedia.org/wiki/RC6> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFERP.pm b/lib/Crypt/Cipher/SAFERP.pm new file mode 100644 index 00000000..05f989f5 --- /dev/null +++ b/lib/Crypt/Cipher/SAFERP.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFERP; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFERP - Symetric cipher SAFER+, key size: 128/192/256 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFERP'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFERP; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFERP', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFERP cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFERP->new($key); + #or + $c = Crypt::Cipher::SAFERP->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFERP->keysize; + #or + Crypt::Cipher::SAFERP::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFERP->blocksize; + #or + Crypt::Cipher::SAFERP::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFERP->max_keysize; + #or + Crypt::Cipher::SAFERP::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFERP->min_keysize; + #or + Crypt::Cipher::SAFERP::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFERP->default_rounds; + #or + Crypt::Cipher::SAFERP::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/SAFER|http://en.wikipedia.org/wiki/SAFER> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFER_K128.pm b/lib/Crypt/Cipher/SAFER_K128.pm new file mode 100644 index 00000000..c3732607 --- /dev/null +++ b/lib/Crypt/Cipher/SAFER_K128.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFER_K128; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFER_K128 - Symetric cipher SAFER_K128, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFER_K128'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFER_K128; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_K128', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFER_K128 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFER_K128->new($key); + #or + $c = Crypt::Cipher::SAFER_K128->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFER_K128->keysize; + #or + Crypt::Cipher::SAFER_K128::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFER_K128->blocksize; + #or + Crypt::Cipher::SAFER_K128::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFER_K128->max_keysize; + #or + Crypt::Cipher::SAFER_K128::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFER_K128->min_keysize; + #or + Crypt::Cipher::SAFER_K128::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFER_K128->default_rounds; + #or + Crypt::Cipher::SAFER_K128::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/SAFER|http://en.wikipedia.org/wiki/SAFER> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFER_K64.pm b/lib/Crypt/Cipher/SAFER_K64.pm new file mode 100644 index 00000000..52741af6 --- /dev/null +++ b/lib/Crypt/Cipher/SAFER_K64.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFER_K64; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFER_K64 - Symetric cipher SAFER_K64, key size: 64 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFER_K64'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFER_K64; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_K64', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFER_K64 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFER_K64->new($key); + #or + $c = Crypt::Cipher::SAFER_K64->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFER_K64->keysize; + #or + Crypt::Cipher::SAFER_K64::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFER_K64->blocksize; + #or + Crypt::Cipher::SAFER_K64::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFER_K64->max_keysize; + #or + Crypt::Cipher::SAFER_K64::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFER_K64->min_keysize; + #or + Crypt::Cipher::SAFER_K64::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFER_K64->default_rounds; + #or + Crypt::Cipher::SAFER_K64::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/SAFER|http://en.wikipedia.org/wiki/SAFER> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFER_SK128.pm b/lib/Crypt/Cipher/SAFER_SK128.pm new file mode 100644 index 00000000..32193ff1 --- /dev/null +++ b/lib/Crypt/Cipher/SAFER_SK128.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFER_SK128; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFER_SK128 - Symetric cipher SAFER_SK128, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFER_SK128'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFER_SK128; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_SK128', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFER_SK128 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFER_SK128->new($key); + #or + $c = Crypt::Cipher::SAFER_SK128->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFER_SK128->keysize; + #or + Crypt::Cipher::SAFER_SK128::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFER_SK128->blocksize; + #or + Crypt::Cipher::SAFER_SK128::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFER_SK128->max_keysize; + #or + Crypt::Cipher::SAFER_SK128::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFER_SK128->min_keysize; + #or + Crypt::Cipher::SAFER_SK128::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFER_SK128->default_rounds; + #or + Crypt::Cipher::SAFER_SK128::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/SAFER|http://en.wikipedia.org/wiki/SAFER> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFER_SK64.pm b/lib/Crypt/Cipher/SAFER_SK64.pm new file mode 100644 index 00000000..73ac3715 --- /dev/null +++ b/lib/Crypt/Cipher/SAFER_SK64.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFER_SK64; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFER_SK64 - Symetric cipher SAFER_SK64, key size: 64 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFER_SK64'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFER_SK64; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_SK64', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFER_SK64 cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFER_SK64->new($key); + #or + $c = Crypt::Cipher::SAFER_SK64->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFER_SK64->keysize; + #or + Crypt::Cipher::SAFER_SK64::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFER_SK64->blocksize; + #or + Crypt::Cipher::SAFER_SK64::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFER_SK64->max_keysize; + #or + Crypt::Cipher::SAFER_SK64::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFER_SK64->min_keysize; + #or + Crypt::Cipher::SAFER_SK64::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFER_SK64->default_rounds; + #or + Crypt::Cipher::SAFER_SK64::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/SAFER|http://en.wikipedia.org/wiki/SAFER> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/SEED.pm b/lib/Crypt/Cipher/SEED.pm new file mode 100644 index 00000000..c81553b0 --- /dev/null +++ b/lib/Crypt/Cipher/SEED.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SEED; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SEED - Symetric cipher SEED, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SEED'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SEED; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SEED', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SEED cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SEED->new($key); + #or + $c = Crypt::Cipher::SEED->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SEED->keysize; + #or + Crypt::Cipher::SEED::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SEED->blocksize; + #or + Crypt::Cipher::SEED::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SEED->max_keysize; + #or + Crypt::Cipher::SEED::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SEED->min_keysize; + #or + Crypt::Cipher::SEED::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SEED->default_rounds; + #or + Crypt::Cipher::SEED::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/SEED|http://en.wikipedia.org/wiki/SEED> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/Skipjack.pm b/lib/Crypt/Cipher/Skipjack.pm new file mode 100644 index 00000000..41f6f2cb --- /dev/null +++ b/lib/Crypt/Cipher/Skipjack.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Skipjack; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Skipjack - Symetric cipher Skipjack, key size: 80 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Skipjack'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Skipjack; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Skipjack', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Skipjack cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Skipjack->new($key); + #or + $c = Crypt::Cipher::Skipjack->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Skipjack->keysize; + #or + Crypt::Cipher::Skipjack::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Skipjack->blocksize; + #or + Crypt::Cipher::Skipjack::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Skipjack->max_keysize; + #or + Crypt::Cipher::Skipjack::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Skipjack->min_keysize; + #or + Crypt::Cipher::Skipjack::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Skipjack->default_rounds; + #or + Crypt::Cipher::Skipjack::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/Skipjack_(cipher)|http://en.wikipedia.org/wiki/Skipjack_(cipher)> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/Twofish.pm b/lib/Crypt/Cipher/Twofish.pm new file mode 100644 index 00000000..85a20d2a --- /dev/null +++ b/lib/Crypt/Cipher/Twofish.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Twofish; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Twofish - Symetric cipher Twofish, key size: 128/192/256 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Twofish'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Twofish; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Twofish', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Twofish cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Twofish->new($key); + #or + $c = Crypt::Cipher::Twofish->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Twofish->keysize; + #or + Crypt::Cipher::Twofish::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Twofish->blocksize; + #or + Crypt::Cipher::Twofish::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Twofish->max_keysize; + #or + Crypt::Cipher::Twofish::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Twofish->min_keysize; + #or + Crypt::Cipher::Twofish::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Twofish->default_rounds; + #or + Crypt::Cipher::Twofish::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/Twofish|http://en.wikipedia.org/wiki/Twofish> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Cipher/XTEA.pm b/lib/Crypt/Cipher/XTEA.pm new file mode 100644 index 00000000..ce325ba3 --- /dev/null +++ b/lib/Crypt/Cipher/XTEA.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::XTEA; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::XTEA - Symetric cipher XTEA, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('XTEA'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::XTEA; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::XTEA', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the XTEA cipher. Provided interface is compliant with L<Crypt::CBC|Crypt::CBC> module. + +B<BEWARE:> This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L<Crypt::Mode::CBC|Crypt::Mode::CBC>, L<Crypt::Mode::CTR|Crypt::Mode::CTR> or L<Crypt::CBC|Crypt::CBC> (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::XTEA->new($key); + #or + $c = Crypt::Cipher::XTEA->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::XTEA->keysize; + #or + Crypt::Cipher::XTEA::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::XTEA->blocksize; + #or + Crypt::Cipher::XTEA::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::XTEA->max_keysize; + #or + Crypt::Cipher::XTEA::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::XTEA->min_keysize; + #or + Crypt::Cipher::XTEA::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::XTEA->default_rounds; + #or + Crypt::Cipher::XTEA::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<http://en.wikipedia.org/wiki/XTEA|http://en.wikipedia.org/wiki/XTEA> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest.pm b/lib/Crypt/Digest.pm new file mode 100644 index 00000000..a1ec914c --- /dev/null +++ b/lib/Crypt/Digest.pm @@ -0,0 +1,382 @@ +package Crypt::Digest; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +### the following methods/functions are implemented in XS: +# - _new +# - _hashsize +# - _hashsize_by_name (function, not method) +# - clone +# - reset +# - digest +# - hexdigest +# - b64digest +# - add +# - DESTROY + +sub _trans_digest_name { + my $name = shift; + my %trans = ( + CHAES => 'chc_hash', + RIPEMD128 => 'rmd128', + RIPEMD160 => 'rmd160', + RIPEMD256 => 'rmd256', + RIPEMD320 => 'rmd320', + TIGER192 => 'tiger', + SHA512_224 => 'sha512-224', + SHA512_256 => 'sha512-256', + SHA3_224 => 'sha3-224', + SHA3_256 => 'sha3-256', + SHA3_384 => 'sha3-384', + SHA3_512 => 'sha3-512', + BLAKE2B_160 => 'blake2b-160', + BLAKE2B_256 => 'blake2b-256', + BLAKE2B_384 => 'blake2b-384', + BLAKE2B_512 => 'blake2b-512', + BLAKE2S_128 => 'blake2s-128', + BLAKE2S_160 => 'blake2s-160', + BLAKE2S_224 => 'blake2s-224', + BLAKE2S_256 => 'blake2s-256', + ); + $name =~ s/^Crypt::Digest:://i; + return $trans{uc($name)} if defined $trans{uc($name)}; + return lc($name); +} + +### METHODS + +sub new { + my $pkg = shift; + unshift @_, ($pkg eq 'Crypt::Digest' ? _trans_digest_name(shift) : _trans_digest_name($pkg)); + ###return _new(@_); + goto \&_new; # keep the real caller for croak() +} + +sub hashsize { + return unless defined $_[0]; + + if (ref $_[0]) { + ###return _hashsize(@_); + goto \&_hashsize if ref $_[0]; # keep the real caller for croak() + } + else { + my $pkg = shift; + unshift @_, ($pkg eq 'Crypt::Digest' ? _trans_digest_name(shift) : _trans_digest_name($pkg)); + ###return _hashsize_by_name(@_); + goto \&_hashsize_by_name; # keep the real caller for croak() + } +} + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +### FUNCTIONS + +sub digest_data { my $rv = eval {Crypt::Digest->new(shift)->add(@_)->digest}; _croak($@); $rv } +sub digest_data_hex { my $rv = eval {Crypt::Digest->new(shift)->add(@_)->hexdigest}; _croak($@); $rv } +sub digest_data_b64 { my $rv = eval {Crypt::Digest->new(shift)->add(@_)->b64digest}; _croak($@); $rv } +sub digest_data_b64u { my $rv = eval {Crypt::Digest->new(shift)->add(@_)->b64udigest}; _croak($@); $rv } + +sub digest_file { my $rv = eval {Crypt::Digest->new(shift)->addfile(@_)->digest}; _croak($@); $rv } +sub digest_file_hex { my $rv = eval {Crypt::Digest->new(shift)->addfile(@_)->hexdigest}; _croak($@); $rv } +sub digest_file_b64 { my $rv = eval {Crypt::Digest->new(shift)->addfile(@_)->b64digest}; _croak($@); $rv } +sub digest_file_b64u { my $rv = eval {Crypt::Digest->new(shift)->addfile(@_)->b64udigest}; _croak($@); $rv } + +sub _croak { #XXX-FIXME ugly hack for reporting real caller from XS croaks + if ($_[0]) { + $_[0] =~ s/ at .*?\.pm line \d+.[\n\r]*$//g; + croak $_[0]; + } +} + +1; + +=pod + +=head1 NAME + +Crypt::Digest - Generic interface to hash/digest functions + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u + digest_file digest_file_hex digest_file_b64 digest_file_b64u ); + + # calculate digest from string/buffer + $digest_raw = digest_data('SHA1', 'data string'); + $digest_hex = digest_data_hex('SHA1', 'data string'); + $digest_b64 = digest_data_b64('SHA1', 'data string'); + $digest_b64u = digest_data_b64u('SHA1', 'data string'); + # calculate digest from file + $digest_raw = digest_file('SHA1', 'filename.dat'); + $digest_hex = digest_file_hex('SHA1', 'filename.dat'); + $digest_b64 = digest_file_b64('SHA1', 'filename.dat'); + $digest_b64u = digest_file_b64u('SHA1', 'filename.dat'); + # calculate digest from filehandle + $digest_raw = digest_file('SHA1', *FILEHANDLE); + $digest_hex = digest_file_hex('SHA1', *FILEHANDLE); + $digest_b64 = digest_file_b64('SHA1', *FILEHANDLE); + $digest_b64u = digest_file_b64u('SHA1', *FILEHANDLE); + + ### OO interface: + use Crypt::Digest; + + $d = Crypt::Digest->new('SHA1'); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to various hash/digest algorithms. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u + digest_file digest_file_hex digest_file_b64 digest_file_b64u ); + +Or all of them at once: + + use Crypt::Digest ':all'; + +=head1 FUNCTIONS + +Please note that all functions take as its first argument the algoritm name, supported values are: + + 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', + 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', + 'SHA384', 'SHA512', 'SHA512_224', 'SHA512_256', 'Tiger192', 'Whirlpool', + 'SHA3_224', 'SHA3_256', 'SHA3_384', 'SHA3_512' + + (simply any <FUNCNAME> for which there is Crypt::Digest::<FUNCNAME> module) + +=head2 digest_data + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a binary string. + + $digest_raw = digest_data('SHA1', 'data string'); + #or + $digest_raw = digest_data('SHA1', 'any data', 'more data', 'even more data'); + +=head2 digest_data_hex + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a hexadecimal string. + + $digest_hex = digest_data_hex('SHA1', 'data string'); + #or + $digest_hex = digest_data_hex('SHA1', 'any data', 'more data', 'even more data'); + +=head2 digest_data_b64 + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $digest_b64 = digest_data_b64('SHA1', 'data string'); + #or + $digest_b64 = digest_data_b64('SHA1', 'any data', 'more data', 'even more data'); + +=head2 digest_data_b64u + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $digest_b64url = digest_data_b64u('SHA1', 'data string'); + #or + $digest_b64url = digest_data_b64u('SHA1', 'any data', 'more data', 'even more data'); + +=head2 digest_file + +Reads file (defined by filename or filehandle) content, and returns its digest encoded as a binary string. + + $digest_raw = digest_file('SHA1', 'filename.dat'); + #or + $digest_raw = digest_file('SHA1', *FILEHANDLE); + +=head2 digest_file_hex + +Reads file (defined by filename or filehandle) content, and returns its digest encoded as a hexadecimal string. + + $digest_hex = digest_file_hex('SHA1', 'filename.dat'); + #or + $digest_hex = digest_file_hex('SHA1', *FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 digest_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its digest encoded as a Base64 string, B<with> trailing '=' padding. + + $digest_b64 = digest_file_b64('SHA1', 'filename.dat'); + #or + $digest_b64 = digest_file_b64('SHA1', *FILEHANDLE); + +=head2 digest_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $digest_b64url = digest_file_b64u('SHA1', 'filename.dat'); + #or + $digest_b64url = digest_file_b64u('SHA1', *FILEHANDLE); + +=head1 METHODS + +=head2 new + +Constructor, returns a reference to the digest object. + + $d = Crypt::Digest->new($name); + # $name could be: 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', + # 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', 'SHA384', + # 'SHA512', 'SHA512_224', 'SHA512_256', 'Tiger192', 'Whirlpool' + # + # simply any <FUNCNAME> for which there is Crypt::Digest::<FUNCNAME> module + +=head2 clone + +Creates a copy of the digest object state and returns a reference to the copy. + + $d->clone(); + +=head2 reset + +Reinitialize the digest object state and returns a reference to the digest object. + + $d->reset(); + +=head2 add + +All arguments are appended to the message we calculate digest for. +The return value is the digest object itself. + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +Note that all the following cases are equivalent: + + # case 1 + $d->add('aa', 'bb', 'cc'); + + # case 2 + $d->add('aa'); + $d->add('bb'); + $d->add('cc'); + + # case 3 + $d->add('aabbcc'); + + # case 4 + $d->add('aa')->add('bb')->add('cc'); + +=head2 addfile + +The content of the file (or filehandle) is appended to the message we calculate digest for. +The return value is the digest object itself. + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 add_bits + +This method is available mostly for compatibility with other Digest::SOMETHING modules on CPAN, you are very unlikely to need it. +The return value is the digest object itself. + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +B<BEWARE:> It is not possible to add bits that are not a multiple of 8. + +=head2 hashsize + +Returns the length of calculated digest in bytes (e.g. 32 for SHA-256). + + $d->hashsize; + #or + Crypt::Digest->hashsize('SHA1'); + #or + Crypt::Digest::hashsize('SHA1'); + +=head2 digest + +Returns the binary digest (raw bytes). + + $result_raw = $d->digest(); + +=head2 hexdigest + +Returns the digest encoded as a hexadecimal string. + + $result_hex = $d->hexdigest(); + +=head2 b64digest + +Returns the digest encoded as a Base64 string, B<with> trailing '=' padding (B<BEWARE:> this padding +style might differ from other Digest::SOMETHING modules on CPAN). + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + +Returns the digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<Crypt::Digest|Crypt::Digest> tries to be compatible with L<Digest|Digest> interface. + +=item * Check subclasses like L<Crypt::Digest::SHA1|Crypt::Digest::SHA1>, L<Crypt::Digest::MD5|Crypt::Digest::MD5>, ... + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2b_160.pm b/lib/Crypt/Digest/BLAKE2b_160.pm new file mode 100644 index 00000000..bb829e16 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2b_160.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2b_160; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2b_160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2b_160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2b_160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2b_160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2b_160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2b_160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2b_160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2b_160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2b_160 - Hash function BLAKE2b [size: 160 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2b_160 qw( blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u + blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u ); + + # calculate digest from string/buffer + $blake2b_160_raw = blake2b_160('data string'); + $blake2b_160_hex = blake2b_160_hex('data string'); + $blake2b_160_b64 = blake2b_160_b64('data string'); + $blake2b_160_b64u = blake2b_160_b64u('data string'); + # calculate digest from file + $blake2b_160_raw = blake2b_160_file('filename.dat'); + $blake2b_160_hex = blake2b_160_file_hex('filename.dat'); + $blake2b_160_b64 = blake2b_160_file_b64('filename.dat'); + $blake2b_160_b64u = blake2b_160_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2b_160_raw = blake2b_160_file(*FILEHANDLE); + $blake2b_160_hex = blake2b_160_file_hex(*FILEHANDLE); + $blake2b_160_b64 = blake2b_160_file_b64(*FILEHANDLE); + $blake2b_160_b64u = blake2b_160_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2b_160; + + $d = Crypt::Digest::BLAKE2b_160->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b_160 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2b_160 qw(blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u + blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2b_160 ':all'; + +=head1 FUNCTIONS + +=head2 blake2b_160 + +Logically joins all arguments into a single string, and returns its BLAKE2b_160 digest encoded as a binary string. + + $blake2b_160_raw = blake2b_160('data string'); + #or + $blake2b_160_raw = blake2b_160('any data', 'more data', 'even more data'); + +=head2 blake2b_160_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b_160 digest encoded as a hexadecimal string. + + $blake2b_160_hex = blake2b_160_hex('data string'); + #or + $blake2b_160_hex = blake2b_160_hex('any data', 'more data', 'even more data'); + +=head2 blake2b_160_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b_160 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2b_160_b64 = blake2b_160_b64('data string'); + #or + $blake2b_160_b64 = blake2b_160_b64('any data', 'more data', 'even more data'); + +=head2 blake2b_160_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b_160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_160_b64url = blake2b_160_b64u('data string'); + #or + $blake2b_160_b64url = blake2b_160_b64u('any data', 'more data', 'even more data'); + +=head2 blake2b_160_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_160 digest encoded as a binary string. + + $blake2b_160_raw = blake2b_160_file('filename.dat'); + #or + $blake2b_160_raw = blake2b_160_file(*FILEHANDLE); + +=head2 blake2b_160_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_160 digest encoded as a hexadecimal string. + + $blake2b_160_hex = blake2b_160_file_hex('filename.dat'); + #or + $blake2b_160_hex = blake2b_160_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2b_160_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_160 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2b_160_b64 = blake2b_160_file_b64('filename.dat'); + #or + $blake2b_160_b64 = blake2b_160_file_b64(*FILEHANDLE); + +=head2 blake2b_160_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_160_b64url = blake2b_160_file_b64u('filename.dat'); + #or + $blake2b_160_b64url = blake2b_160_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::BLAKE2b_160->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2b_160->hashsize(); + #or + Crypt::Digest::BLAKE2b_160::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<https://blake2.net/|https://blake2.net/> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2b_256.pm b/lib/Crypt/Digest/BLAKE2b_256.pm new file mode 100644 index 00000000..c9a5a2ae --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2b_256.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2b_256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2b_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2b_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2b_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2b_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2b_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2b_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2b_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2b_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2b_256 - Hash function BLAKE2b [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2b_256 qw( blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u + blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u ); + + # calculate digest from string/buffer + $blake2b_256_raw = blake2b_256('data string'); + $blake2b_256_hex = blake2b_256_hex('data string'); + $blake2b_256_b64 = blake2b_256_b64('data string'); + $blake2b_256_b64u = blake2b_256_b64u('data string'); + # calculate digest from file + $blake2b_256_raw = blake2b_256_file('filename.dat'); + $blake2b_256_hex = blake2b_256_file_hex('filename.dat'); + $blake2b_256_b64 = blake2b_256_file_b64('filename.dat'); + $blake2b_256_b64u = blake2b_256_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2b_256_raw = blake2b_256_file(*FILEHANDLE); + $blake2b_256_hex = blake2b_256_file_hex(*FILEHANDLE); + $blake2b_256_b64 = blake2b_256_file_b64(*FILEHANDLE); + $blake2b_256_b64u = blake2b_256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2b_256; + + $d = Crypt::Digest::BLAKE2b_256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b_256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2b_256 qw(blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u + blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2b_256 ':all'; + +=head1 FUNCTIONS + +=head2 blake2b_256 + +Logically joins all arguments into a single string, and returns its BLAKE2b_256 digest encoded as a binary string. + + $blake2b_256_raw = blake2b_256('data string'); + #or + $blake2b_256_raw = blake2b_256('any data', 'more data', 'even more data'); + +=head2 blake2b_256_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b_256 digest encoded as a hexadecimal string. + + $blake2b_256_hex = blake2b_256_hex('data string'); + #or + $blake2b_256_hex = blake2b_256_hex('any data', 'more data', 'even more data'); + +=head2 blake2b_256_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b_256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2b_256_b64 = blake2b_256_b64('data string'); + #or + $blake2b_256_b64 = blake2b_256_b64('any data', 'more data', 'even more data'); + +=head2 blake2b_256_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_256_b64url = blake2b_256_b64u('data string'); + #or + $blake2b_256_b64url = blake2b_256_b64u('any data', 'more data', 'even more data'); + +=head2 blake2b_256_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_256 digest encoded as a binary string. + + $blake2b_256_raw = blake2b_256_file('filename.dat'); + #or + $blake2b_256_raw = blake2b_256_file(*FILEHANDLE); + +=head2 blake2b_256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_256 digest encoded as a hexadecimal string. + + $blake2b_256_hex = blake2b_256_file_hex('filename.dat'); + #or + $blake2b_256_hex = blake2b_256_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2b_256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2b_256_b64 = blake2b_256_file_b64('filename.dat'); + #or + $blake2b_256_b64 = blake2b_256_file_b64(*FILEHANDLE); + +=head2 blake2b_256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_256_b64url = blake2b_256_file_b64u('filename.dat'); + #or + $blake2b_256_b64url = blake2b_256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::BLAKE2b_256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2b_256->hashsize(); + #or + Crypt::Digest::BLAKE2b_256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<https://blake2.net/|https://blake2.net/> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2b_384.pm b/lib/Crypt/Digest/BLAKE2b_384.pm new file mode 100644 index 00000000..3657a358 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2b_384.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2b_384; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2b_384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2b_384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2b_384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2b_384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2b_384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2b_384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2b_384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2b_384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2b_384 - Hash function BLAKE2b [size: 384 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2b_384 qw( blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u + blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u ); + + # calculate digest from string/buffer + $blake2b_384_raw = blake2b_384('data string'); + $blake2b_384_hex = blake2b_384_hex('data string'); + $blake2b_384_b64 = blake2b_384_b64('data string'); + $blake2b_384_b64u = blake2b_384_b64u('data string'); + # calculate digest from file + $blake2b_384_raw = blake2b_384_file('filename.dat'); + $blake2b_384_hex = blake2b_384_file_hex('filename.dat'); + $blake2b_384_b64 = blake2b_384_file_b64('filename.dat'); + $blake2b_384_b64u = blake2b_384_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2b_384_raw = blake2b_384_file(*FILEHANDLE); + $blake2b_384_hex = blake2b_384_file_hex(*FILEHANDLE); + $blake2b_384_b64 = blake2b_384_file_b64(*FILEHANDLE); + $blake2b_384_b64u = blake2b_384_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2b_384; + + $d = Crypt::Digest::BLAKE2b_384->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b_384 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2b_384 qw(blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u + blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2b_384 ':all'; + +=head1 FUNCTIONS + +=head2 blake2b_384 + +Logically joins all arguments into a single string, and returns its BLAKE2b_384 digest encoded as a binary string. + + $blake2b_384_raw = blake2b_384('data string'); + #or + $blake2b_384_raw = blake2b_384('any data', 'more data', 'even more data'); + +=head2 blake2b_384_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b_384 digest encoded as a hexadecimal string. + + $blake2b_384_hex = blake2b_384_hex('data string'); + #or + $blake2b_384_hex = blake2b_384_hex('any data', 'more data', 'even more data'); + +=head2 blake2b_384_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b_384 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2b_384_b64 = blake2b_384_b64('data string'); + #or + $blake2b_384_b64 = blake2b_384_b64('any data', 'more data', 'even more data'); + +=head2 blake2b_384_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b_384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_384_b64url = blake2b_384_b64u('data string'); + #or + $blake2b_384_b64url = blake2b_384_b64u('any data', 'more data', 'even more data'); + +=head2 blake2b_384_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_384 digest encoded as a binary string. + + $blake2b_384_raw = blake2b_384_file('filename.dat'); + #or + $blake2b_384_raw = blake2b_384_file(*FILEHANDLE); + +=head2 blake2b_384_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_384 digest encoded as a hexadecimal string. + + $blake2b_384_hex = blake2b_384_file_hex('filename.dat'); + #or + $blake2b_384_hex = blake2b_384_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2b_384_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_384 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2b_384_b64 = blake2b_384_file_b64('filename.dat'); + #or + $blake2b_384_b64 = blake2b_384_file_b64(*FILEHANDLE); + +=head2 blake2b_384_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_384_b64url = blake2b_384_file_b64u('filename.dat'); + #or + $blake2b_384_b64url = blake2b_384_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::BLAKE2b_384->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2b_384->hashsize(); + #or + Crypt::Digest::BLAKE2b_384::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<https://blake2.net/|https://blake2.net/> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2b_512.pm b/lib/Crypt/Digest/BLAKE2b_512.pm new file mode 100644 index 00000000..fd067846 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2b_512.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2b_512; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2b_512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2b_512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2b_512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2b_512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2b_512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2b_512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2b_512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2b_512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2b_512 - Hash function BLAKE2b [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2b_512 qw( blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u + blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u ); + + # calculate digest from string/buffer + $blake2b_512_raw = blake2b_512('data string'); + $blake2b_512_hex = blake2b_512_hex('data string'); + $blake2b_512_b64 = blake2b_512_b64('data string'); + $blake2b_512_b64u = blake2b_512_b64u('data string'); + # calculate digest from file + $blake2b_512_raw = blake2b_512_file('filename.dat'); + $blake2b_512_hex = blake2b_512_file_hex('filename.dat'); + $blake2b_512_b64 = blake2b_512_file_b64('filename.dat'); + $blake2b_512_b64u = blake2b_512_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2b_512_raw = blake2b_512_file(*FILEHANDLE); + $blake2b_512_hex = blake2b_512_file_hex(*FILEHANDLE); + $blake2b_512_b64 = blake2b_512_file_b64(*FILEHANDLE); + $blake2b_512_b64u = blake2b_512_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2b_512; + + $d = Crypt::Digest::BLAKE2b_512->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b_512 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2b_512 qw(blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u + blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2b_512 ':all'; + +=head1 FUNCTIONS + +=head2 blake2b_512 + +Logically joins all arguments into a single string, and returns its BLAKE2b_512 digest encoded as a binary string. + + $blake2b_512_raw = blake2b_512('data string'); + #or + $blake2b_512_raw = blake2b_512('any data', 'more data', 'even more data'); + +=head2 blake2b_512_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b_512 digest encoded as a hexadecimal string. + + $blake2b_512_hex = blake2b_512_hex('data string'); + #or + $blake2b_512_hex = blake2b_512_hex('any data', 'more data', 'even more data'); + +=head2 blake2b_512_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b_512 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2b_512_b64 = blake2b_512_b64('data string'); + #or + $blake2b_512_b64 = blake2b_512_b64('any data', 'more data', 'even more data'); + +=head2 blake2b_512_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b_512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_512_b64url = blake2b_512_b64u('data string'); + #or + $blake2b_512_b64url = blake2b_512_b64u('any data', 'more data', 'even more data'); + +=head2 blake2b_512_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_512 digest encoded as a binary string. + + $blake2b_512_raw = blake2b_512_file('filename.dat'); + #or + $blake2b_512_raw = blake2b_512_file(*FILEHANDLE); + +=head2 blake2b_512_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_512 digest encoded as a hexadecimal string. + + $blake2b_512_hex = blake2b_512_file_hex('filename.dat'); + #or + $blake2b_512_hex = blake2b_512_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2b_512_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_512 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2b_512_b64 = blake2b_512_file_b64('filename.dat'); + #or + $blake2b_512_b64 = blake2b_512_file_b64(*FILEHANDLE); + +=head2 blake2b_512_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_512_b64url = blake2b_512_file_b64u('filename.dat'); + #or + $blake2b_512_b64url = blake2b_512_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::BLAKE2b_512->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2b_512->hashsize(); + #or + Crypt::Digest::BLAKE2b_512::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<https://blake2.net/|https://blake2.net/> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2s_128.pm b/lib/Crypt/Digest/BLAKE2s_128.pm new file mode 100644 index 00000000..54b873c5 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2s_128.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2s_128; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2s_128 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2s_128_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2s_128_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2s_128_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2s_128_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2s_128_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2s_128_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2s_128_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2s_128 - Hash function BLAKE2s [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2s_128 qw( blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u + blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u ); + + # calculate digest from string/buffer + $blake2s_128_raw = blake2s_128('data string'); + $blake2s_128_hex = blake2s_128_hex('data string'); + $blake2s_128_b64 = blake2s_128_b64('data string'); + $blake2s_128_b64u = blake2s_128_b64u('data string'); + # calculate digest from file + $blake2s_128_raw = blake2s_128_file('filename.dat'); + $blake2s_128_hex = blake2s_128_file_hex('filename.dat'); + $blake2s_128_b64 = blake2s_128_file_b64('filename.dat'); + $blake2s_128_b64u = blake2s_128_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2s_128_raw = blake2s_128_file(*FILEHANDLE); + $blake2s_128_hex = blake2s_128_file_hex(*FILEHANDLE); + $blake2s_128_b64 = blake2s_128_file_b64(*FILEHANDLE); + $blake2s_128_b64u = blake2s_128_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2s_128; + + $d = Crypt::Digest::BLAKE2s_128->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s_128 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2s_128 qw(blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u + blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2s_128 ':all'; + +=head1 FUNCTIONS + +=head2 blake2s_128 + +Logically joins all arguments into a single string, and returns its BLAKE2s_128 digest encoded as a binary string. + + $blake2s_128_raw = blake2s_128('data string'); + #or + $blake2s_128_raw = blake2s_128('any data', 'more data', 'even more data'); + +=head2 blake2s_128_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s_128 digest encoded as a hexadecimal string. + + $blake2s_128_hex = blake2s_128_hex('data string'); + #or + $blake2s_128_hex = blake2s_128_hex('any data', 'more data', 'even more data'); + +=head2 blake2s_128_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s_128 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2s_128_b64 = blake2s_128_b64('data string'); + #or + $blake2s_128_b64 = blake2s_128_b64('any data', 'more data', 'even more data'); + +=head2 blake2s_128_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s_128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_128_b64url = blake2s_128_b64u('data string'); + #or + $blake2s_128_b64url = blake2s_128_b64u('any data', 'more data', 'even more data'); + +=head2 blake2s_128_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_128 digest encoded as a binary string. + + $blake2s_128_raw = blake2s_128_file('filename.dat'); + #or + $blake2s_128_raw = blake2s_128_file(*FILEHANDLE); + +=head2 blake2s_128_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_128 digest encoded as a hexadecimal string. + + $blake2s_128_hex = blake2s_128_file_hex('filename.dat'); + #or + $blake2s_128_hex = blake2s_128_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2s_128_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_128 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2s_128_b64 = blake2s_128_file_b64('filename.dat'); + #or + $blake2s_128_b64 = blake2s_128_file_b64(*FILEHANDLE); + +=head2 blake2s_128_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_128_b64url = blake2s_128_file_b64u('filename.dat'); + #or + $blake2s_128_b64url = blake2s_128_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::BLAKE2s_128->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2s_128->hashsize(); + #or + Crypt::Digest::BLAKE2s_128::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<https://blake2.net/|https://blake2.net/> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2s_160.pm b/lib/Crypt/Digest/BLAKE2s_160.pm new file mode 100644 index 00000000..97c33b45 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2s_160.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2s_160; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2s_160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2s_160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2s_160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2s_160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2s_160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2s_160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2s_160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2s_160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2s_160 - Hash function BLAKE2s [size: 160 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2s_160 qw( blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u + blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u ); + + # calculate digest from string/buffer + $blake2s_160_raw = blake2s_160('data string'); + $blake2s_160_hex = blake2s_160_hex('data string'); + $blake2s_160_b64 = blake2s_160_b64('data string'); + $blake2s_160_b64u = blake2s_160_b64u('data string'); + # calculate digest from file + $blake2s_160_raw = blake2s_160_file('filename.dat'); + $blake2s_160_hex = blake2s_160_file_hex('filename.dat'); + $blake2s_160_b64 = blake2s_160_file_b64('filename.dat'); + $blake2s_160_b64u = blake2s_160_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2s_160_raw = blake2s_160_file(*FILEHANDLE); + $blake2s_160_hex = blake2s_160_file_hex(*FILEHANDLE); + $blake2s_160_b64 = blake2s_160_file_b64(*FILEHANDLE); + $blake2s_160_b64u = blake2s_160_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2s_160; + + $d = Crypt::Digest::BLAKE2s_160->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s_160 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2s_160 qw(blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u + blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2s_160 ':all'; + +=head1 FUNCTIONS + +=head2 blake2s_160 + +Logically joins all arguments into a single string, and returns its BLAKE2s_160 digest encoded as a binary string. + + $blake2s_160_raw = blake2s_160('data string'); + #or + $blake2s_160_raw = blake2s_160('any data', 'more data', 'even more data'); + +=head2 blake2s_160_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s_160 digest encoded as a hexadecimal string. + + $blake2s_160_hex = blake2s_160_hex('data string'); + #or + $blake2s_160_hex = blake2s_160_hex('any data', 'more data', 'even more data'); + +=head2 blake2s_160_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s_160 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2s_160_b64 = blake2s_160_b64('data string'); + #or + $blake2s_160_b64 = blake2s_160_b64('any data', 'more data', 'even more data'); + +=head2 blake2s_160_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s_160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_160_b64url = blake2s_160_b64u('data string'); + #or + $blake2s_160_b64url = blake2s_160_b64u('any data', 'more data', 'even more data'); + +=head2 blake2s_160_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_160 digest encoded as a binary string. + + $blake2s_160_raw = blake2s_160_file('filename.dat'); + #or + $blake2s_160_raw = blake2s_160_file(*FILEHANDLE); + +=head2 blake2s_160_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_160 digest encoded as a hexadecimal string. + + $blake2s_160_hex = blake2s_160_file_hex('filename.dat'); + #or + $blake2s_160_hex = blake2s_160_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2s_160_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_160 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2s_160_b64 = blake2s_160_file_b64('filename.dat'); + #or + $blake2s_160_b64 = blake2s_160_file_b64(*FILEHANDLE); + +=head2 blake2s_160_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_160_b64url = blake2s_160_file_b64u('filename.dat'); + #or + $blake2s_160_b64url = blake2s_160_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::BLAKE2s_160->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2s_160->hashsize(); + #or + Crypt::Digest::BLAKE2s_160::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<https://blake2.net/|https://blake2.net/> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2s_224.pm b/lib/Crypt/Digest/BLAKE2s_224.pm new file mode 100644 index 00000000..c47e8107 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2s_224.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2s_224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2s_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2s_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2s_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2s_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2s_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2s_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2s_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2s_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2s_224 - Hash function BLAKE2s [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2s_224 qw( blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u + blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u ); + + # calculate digest from string/buffer + $blake2s_224_raw = blake2s_224('data string'); + $blake2s_224_hex = blake2s_224_hex('data string'); + $blake2s_224_b64 = blake2s_224_b64('data string'); + $blake2s_224_b64u = blake2s_224_b64u('data string'); + # calculate digest from file + $blake2s_224_raw = blake2s_224_file('filename.dat'); + $blake2s_224_hex = blake2s_224_file_hex('filename.dat'); + $blake2s_224_b64 = blake2s_224_file_b64('filename.dat'); + $blake2s_224_b64u = blake2s_224_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2s_224_raw = blake2s_224_file(*FILEHANDLE); + $blake2s_224_hex = blake2s_224_file_hex(*FILEHANDLE); + $blake2s_224_b64 = blake2s_224_file_b64(*FILEHANDLE); + $blake2s_224_b64u = blake2s_224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2s_224; + + $d = Crypt::Digest::BLAKE2s_224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s_224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2s_224 qw(blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u + blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2s_224 ':all'; + +=head1 FUNCTIONS + +=head2 blake2s_224 + +Logically joins all arguments into a single string, and returns its BLAKE2s_224 digest encoded as a binary string. + + $blake2s_224_raw = blake2s_224('data string'); + #or + $blake2s_224_raw = blake2s_224('any data', 'more data', 'even more data'); + +=head2 blake2s_224_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s_224 digest encoded as a hexadecimal string. + + $blake2s_224_hex = blake2s_224_hex('data string'); + #or + $blake2s_224_hex = blake2s_224_hex('any data', 'more data', 'even more data'); + +=head2 blake2s_224_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s_224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2s_224_b64 = blake2s_224_b64('data string'); + #or + $blake2s_224_b64 = blake2s_224_b64('any data', 'more data', 'even more data'); + +=head2 blake2s_224_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_224_b64url = blake2s_224_b64u('data string'); + #or + $blake2s_224_b64url = blake2s_224_b64u('any data', 'more data', 'even more data'); + +=head2 blake2s_224_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_224 digest encoded as a binary string. + + $blake2s_224_raw = blake2s_224_file('filename.dat'); + #or + $blake2s_224_raw = blake2s_224_file(*FILEHANDLE); + +=head2 blake2s_224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_224 digest encoded as a hexadecimal string. + + $blake2s_224_hex = blake2s_224_file_hex('filename.dat'); + #or + $blake2s_224_hex = blake2s_224_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2s_224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2s_224_b64 = blake2s_224_file_b64('filename.dat'); + #or + $blake2s_224_b64 = blake2s_224_file_b64(*FILEHANDLE); + +=head2 blake2s_224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_224_b64url = blake2s_224_file_b64u('filename.dat'); + #or + $blake2s_224_b64url = blake2s_224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::BLAKE2s_224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2s_224->hashsize(); + #or + Crypt::Digest::BLAKE2s_224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<https://blake2.net/|https://blake2.net/> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2s_256.pm b/lib/Crypt/Digest/BLAKE2s_256.pm new file mode 100644 index 00000000..5c15cfd7 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2s_256.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2s_256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2s_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2s_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2s_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2s_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2s_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2s_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2s_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2s_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2s_256 - Hash function BLAKE2s [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2s_256 qw( blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u + blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u ); + + # calculate digest from string/buffer + $blake2s_256_raw = blake2s_256('data string'); + $blake2s_256_hex = blake2s_256_hex('data string'); + $blake2s_256_b64 = blake2s_256_b64('data string'); + $blake2s_256_b64u = blake2s_256_b64u('data string'); + # calculate digest from file + $blake2s_256_raw = blake2s_256_file('filename.dat'); + $blake2s_256_hex = blake2s_256_file_hex('filename.dat'); + $blake2s_256_b64 = blake2s_256_file_b64('filename.dat'); + $blake2s_256_b64u = blake2s_256_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2s_256_raw = blake2s_256_file(*FILEHANDLE); + $blake2s_256_hex = blake2s_256_file_hex(*FILEHANDLE); + $blake2s_256_b64 = blake2s_256_file_b64(*FILEHANDLE); + $blake2s_256_b64u = blake2s_256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2s_256; + + $d = Crypt::Digest::BLAKE2s_256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s_256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2s_256 qw(blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u + blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2s_256 ':all'; + +=head1 FUNCTIONS + +=head2 blake2s_256 + +Logically joins all arguments into a single string, and returns its BLAKE2s_256 digest encoded as a binary string. + + $blake2s_256_raw = blake2s_256('data string'); + #or + $blake2s_256_raw = blake2s_256('any data', 'more data', 'even more data'); + +=head2 blake2s_256_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s_256 digest encoded as a hexadecimal string. + + $blake2s_256_hex = blake2s_256_hex('data string'); + #or + $blake2s_256_hex = blake2s_256_hex('any data', 'more data', 'even more data'); + +=head2 blake2s_256_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s_256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2s_256_b64 = blake2s_256_b64('data string'); + #or + $blake2s_256_b64 = blake2s_256_b64('any data', 'more data', 'even more data'); + +=head2 blake2s_256_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_256_b64url = blake2s_256_b64u('data string'); + #or + $blake2s_256_b64url = blake2s_256_b64u('any data', 'more data', 'even more data'); + +=head2 blake2s_256_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_256 digest encoded as a binary string. + + $blake2s_256_raw = blake2s_256_file('filename.dat'); + #or + $blake2s_256_raw = blake2s_256_file(*FILEHANDLE); + +=head2 blake2s_256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_256 digest encoded as a hexadecimal string. + + $blake2s_256_hex = blake2s_256_file_hex('filename.dat'); + #or + $blake2s_256_hex = blake2s_256_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2s_256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $blake2s_256_b64 = blake2s_256_file_b64('filename.dat'); + #or + $blake2s_256_b64 = blake2s_256_file_b64(*FILEHANDLE); + +=head2 blake2s_256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_256_b64url = blake2s_256_file_b64u('filename.dat'); + #or + $blake2s_256_b64url = blake2s_256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::BLAKE2s_256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2s_256->hashsize(); + #or + Crypt::Digest::BLAKE2s_256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<https://blake2.net/|https://blake2.net/> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/CHAES.pm b/lib/Crypt/Digest/CHAES.pm new file mode 100644 index 00000000..7ae167e0 --- /dev/null +++ b/lib/Crypt/Digest/CHAES.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::CHAES; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( chaes chaes_hex chaes_b64 chaes_b64u chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub chaes { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub chaes_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub chaes_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub chaes_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub chaes_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub chaes_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub chaes_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub chaes_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::CHAES - Hash function - CipherHash based on AES [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_b64u + chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u ); + + # calculate digest from string/buffer + $chaes_raw = chaes('data string'); + $chaes_hex = chaes_hex('data string'); + $chaes_b64 = chaes_b64('data string'); + $chaes_b64u = chaes_b64u('data string'); + # calculate digest from file + $chaes_raw = chaes_file('filename.dat'); + $chaes_hex = chaes_file_hex('filename.dat'); + $chaes_b64 = chaes_file_b64('filename.dat'); + $chaes_b64u = chaes_file_b64u('filename.dat'); + # calculate digest from filehandle + $chaes_raw = chaes_file(*FILEHANDLE); + $chaes_hex = chaes_file_hex(*FILEHANDLE); + $chaes_b64 = chaes_file_b64(*FILEHANDLE); + $chaes_b64u = chaes_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::CHAES; + + $d = Crypt::Digest::CHAES->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the CHAES digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::CHAES qw(chaes chaes_hex chaes_b64 chaes_b64u + chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u); + +Or all of them at once: + + use Crypt::Digest::CHAES ':all'; + +=head1 FUNCTIONS + +=head2 chaes + +Logically joins all arguments into a single string, and returns its CHAES digest encoded as a binary string. + + $chaes_raw = chaes('data string'); + #or + $chaes_raw = chaes('any data', 'more data', 'even more data'); + +=head2 chaes_hex + +Logically joins all arguments into a single string, and returns its CHAES digest encoded as a hexadecimal string. + + $chaes_hex = chaes_hex('data string'); + #or + $chaes_hex = chaes_hex('any data', 'more data', 'even more data'); + +=head2 chaes_b64 + +Logically joins all arguments into a single string, and returns its CHAES digest encoded as a Base64 string, B<with> trailing '=' padding. + + $chaes_b64 = chaes_b64('data string'); + #or + $chaes_b64 = chaes_b64('any data', 'more data', 'even more data'); + +=head2 chaes_b64u + +Logically joins all arguments into a single string, and returns its CHAES digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $chaes_b64url = chaes_b64u('data string'); + #or + $chaes_b64url = chaes_b64u('any data', 'more data', 'even more data'); + +=head2 chaes_file + +Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a binary string. + + $chaes_raw = chaes_file('filename.dat'); + #or + $chaes_raw = chaes_file(*FILEHANDLE); + +=head2 chaes_file_hex + +Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a hexadecimal string. + + $chaes_hex = chaes_file_hex('filename.dat'); + #or + $chaes_hex = chaes_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 chaes_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a Base64 string, B<with> trailing '=' padding. + + $chaes_b64 = chaes_file_b64('filename.dat'); + #or + $chaes_b64 = chaes_file_b64(*FILEHANDLE); + +=head2 chaes_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $chaes_b64url = chaes_file_b64u('filename.dat'); + #or + $chaes_b64url = chaes_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::CHAES->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::CHAES->hashsize(); + #or + Crypt::Digest::CHAES::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/Cryptographic_hash_function#Hash_functions_based_on_block_ciphers|http://en.wikipedia.org/wiki/Cryptographic_hash_function#Hash_functions_based_on_block_ciphers> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/MD2.pm b/lib/Crypt/Digest/MD2.pm new file mode 100644 index 00000000..12d3441d --- /dev/null +++ b/lib/Crypt/Digest/MD2.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::MD2; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( md2 md2_hex md2_b64 md2_b64u md2_file md2_file_hex md2_file_b64 md2_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub md2 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub md2_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub md2_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub md2_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub md2_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub md2_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub md2_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub md2_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::MD2 - Hash function MD2 [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_b64u + md2_file md2_file_hex md2_file_b64 md2_file_b64u ); + + # calculate digest from string/buffer + $md2_raw = md2('data string'); + $md2_hex = md2_hex('data string'); + $md2_b64 = md2_b64('data string'); + $md2_b64u = md2_b64u('data string'); + # calculate digest from file + $md2_raw = md2_file('filename.dat'); + $md2_hex = md2_file_hex('filename.dat'); + $md2_b64 = md2_file_b64('filename.dat'); + $md2_b64u = md2_file_b64u('filename.dat'); + # calculate digest from filehandle + $md2_raw = md2_file(*FILEHANDLE); + $md2_hex = md2_file_hex(*FILEHANDLE); + $md2_b64 = md2_file_b64(*FILEHANDLE); + $md2_b64u = md2_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::MD2; + + $d = Crypt::Digest::MD2->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the MD2 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::MD2 qw(md2 md2_hex md2_b64 md2_b64u + md2_file md2_file_hex md2_file_b64 md2_file_b64u); + +Or all of them at once: + + use Crypt::Digest::MD2 ':all'; + +=head1 FUNCTIONS + +=head2 md2 + +Logically joins all arguments into a single string, and returns its MD2 digest encoded as a binary string. + + $md2_raw = md2('data string'); + #or + $md2_raw = md2('any data', 'more data', 'even more data'); + +=head2 md2_hex + +Logically joins all arguments into a single string, and returns its MD2 digest encoded as a hexadecimal string. + + $md2_hex = md2_hex('data string'); + #or + $md2_hex = md2_hex('any data', 'more data', 'even more data'); + +=head2 md2_b64 + +Logically joins all arguments into a single string, and returns its MD2 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $md2_b64 = md2_b64('data string'); + #or + $md2_b64 = md2_b64('any data', 'more data', 'even more data'); + +=head2 md2_b64u + +Logically joins all arguments into a single string, and returns its MD2 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md2_b64url = md2_b64u('data string'); + #or + $md2_b64url = md2_b64u('any data', 'more data', 'even more data'); + +=head2 md2_file + +Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a binary string. + + $md2_raw = md2_file('filename.dat'); + #or + $md2_raw = md2_file(*FILEHANDLE); + +=head2 md2_file_hex + +Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a hexadecimal string. + + $md2_hex = md2_file_hex('filename.dat'); + #or + $md2_hex = md2_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 md2_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $md2_b64 = md2_file_b64('filename.dat'); + #or + $md2_b64 = md2_file_b64(*FILEHANDLE); + +=head2 md2_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md2_b64url = md2_file_b64u('filename.dat'); + #or + $md2_b64url = md2_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::MD2->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::MD2->hashsize(); + #or + Crypt::Digest::MD2::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/MD2_(cryptography)|http://en.wikipedia.org/wiki/MD2_(cryptography)> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/MD4.pm b/lib/Crypt/Digest/MD4.pm new file mode 100644 index 00000000..0725cdef --- /dev/null +++ b/lib/Crypt/Digest/MD4.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::MD4; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( md4 md4_hex md4_b64 md4_b64u md4_file md4_file_hex md4_file_b64 md4_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub md4 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub md4_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub md4_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub md4_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub md4_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub md4_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub md4_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub md4_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::MD4 - Hash function MD4 [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_b64u + md4_file md4_file_hex md4_file_b64 md4_file_b64u ); + + # calculate digest from string/buffer + $md4_raw = md4('data string'); + $md4_hex = md4_hex('data string'); + $md4_b64 = md4_b64('data string'); + $md4_b64u = md4_b64u('data string'); + # calculate digest from file + $md4_raw = md4_file('filename.dat'); + $md4_hex = md4_file_hex('filename.dat'); + $md4_b64 = md4_file_b64('filename.dat'); + $md4_b64u = md4_file_b64u('filename.dat'); + # calculate digest from filehandle + $md4_raw = md4_file(*FILEHANDLE); + $md4_hex = md4_file_hex(*FILEHANDLE); + $md4_b64 = md4_file_b64(*FILEHANDLE); + $md4_b64u = md4_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::MD4; + + $d = Crypt::Digest::MD4->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the MD4 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::MD4 qw(md4 md4_hex md4_b64 md4_b64u + md4_file md4_file_hex md4_file_b64 md4_file_b64u); + +Or all of them at once: + + use Crypt::Digest::MD4 ':all'; + +=head1 FUNCTIONS + +=head2 md4 + +Logically joins all arguments into a single string, and returns its MD4 digest encoded as a binary string. + + $md4_raw = md4('data string'); + #or + $md4_raw = md4('any data', 'more data', 'even more data'); + +=head2 md4_hex + +Logically joins all arguments into a single string, and returns its MD4 digest encoded as a hexadecimal string. + + $md4_hex = md4_hex('data string'); + #or + $md4_hex = md4_hex('any data', 'more data', 'even more data'); + +=head2 md4_b64 + +Logically joins all arguments into a single string, and returns its MD4 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $md4_b64 = md4_b64('data string'); + #or + $md4_b64 = md4_b64('any data', 'more data', 'even more data'); + +=head2 md4_b64u + +Logically joins all arguments into a single string, and returns its MD4 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md4_b64url = md4_b64u('data string'); + #or + $md4_b64url = md4_b64u('any data', 'more data', 'even more data'); + +=head2 md4_file + +Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a binary string. + + $md4_raw = md4_file('filename.dat'); + #or + $md4_raw = md4_file(*FILEHANDLE); + +=head2 md4_file_hex + +Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a hexadecimal string. + + $md4_hex = md4_file_hex('filename.dat'); + #or + $md4_hex = md4_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 md4_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $md4_b64 = md4_file_b64('filename.dat'); + #or + $md4_b64 = md4_file_b64(*FILEHANDLE); + +=head2 md4_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md4_b64url = md4_file_b64u('filename.dat'); + #or + $md4_b64url = md4_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::MD4->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::MD4->hashsize(); + #or + Crypt::Digest::MD4::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/MD4|http://en.wikipedia.org/wiki/MD4> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/MD5.pm b/lib/Crypt/Digest/MD5.pm new file mode 100644 index 00000000..ef82f7af --- /dev/null +++ b/lib/Crypt/Digest/MD5.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::MD5; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( md5 md5_hex md5_b64 md5_b64u md5_file md5_file_hex md5_file_b64 md5_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub md5 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub md5_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub md5_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub md5_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub md5_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub md5_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub md5_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub md5_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::MD5 - Hash function MD5 [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_b64u + md5_file md5_file_hex md5_file_b64 md5_file_b64u ); + + # calculate digest from string/buffer + $md5_raw = md5('data string'); + $md5_hex = md5_hex('data string'); + $md5_b64 = md5_b64('data string'); + $md5_b64u = md5_b64u('data string'); + # calculate digest from file + $md5_raw = md5_file('filename.dat'); + $md5_hex = md5_file_hex('filename.dat'); + $md5_b64 = md5_file_b64('filename.dat'); + $md5_b64u = md5_file_b64u('filename.dat'); + # calculate digest from filehandle + $md5_raw = md5_file(*FILEHANDLE); + $md5_hex = md5_file_hex(*FILEHANDLE); + $md5_b64 = md5_file_b64(*FILEHANDLE); + $md5_b64u = md5_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::MD5; + + $d = Crypt::Digest::MD5->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the MD5 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::MD5 qw(md5 md5_hex md5_b64 md5_b64u + md5_file md5_file_hex md5_file_b64 md5_file_b64u); + +Or all of them at once: + + use Crypt::Digest::MD5 ':all'; + +=head1 FUNCTIONS + +=head2 md5 + +Logically joins all arguments into a single string, and returns its MD5 digest encoded as a binary string. + + $md5_raw = md5('data string'); + #or + $md5_raw = md5('any data', 'more data', 'even more data'); + +=head2 md5_hex + +Logically joins all arguments into a single string, and returns its MD5 digest encoded as a hexadecimal string. + + $md5_hex = md5_hex('data string'); + #or + $md5_hex = md5_hex('any data', 'more data', 'even more data'); + +=head2 md5_b64 + +Logically joins all arguments into a single string, and returns its MD5 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $md5_b64 = md5_b64('data string'); + #or + $md5_b64 = md5_b64('any data', 'more data', 'even more data'); + +=head2 md5_b64u + +Logically joins all arguments into a single string, and returns its MD5 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md5_b64url = md5_b64u('data string'); + #or + $md5_b64url = md5_b64u('any data', 'more data', 'even more data'); + +=head2 md5_file + +Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a binary string. + + $md5_raw = md5_file('filename.dat'); + #or + $md5_raw = md5_file(*FILEHANDLE); + +=head2 md5_file_hex + +Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a hexadecimal string. + + $md5_hex = md5_file_hex('filename.dat'); + #or + $md5_hex = md5_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 md5_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $md5_b64 = md5_file_b64('filename.dat'); + #or + $md5_b64 = md5_file_b64(*FILEHANDLE); + +=head2 md5_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md5_b64url = md5_file_b64u('filename.dat'); + #or + $md5_b64url = md5_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::MD5->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::MD5->hashsize(); + #or + Crypt::Digest::MD5::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/MD5|http://en.wikipedia.org/wiki/MD5> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/RIPEMD128.pm b/lib/Crypt/Digest/RIPEMD128.pm new file mode 100644 index 00000000..ec91f8bd --- /dev/null +++ b/lib/Crypt/Digest/RIPEMD128.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::RIPEMD128; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub ripemd128 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub ripemd128_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub ripemd128_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub ripemd128_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub ripemd128_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub ripemd128_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub ripemd128_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub ripemd128_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::RIPEMD128 - Hash function RIPEMD-128 [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u + ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u ); + + # calculate digest from string/buffer + $ripemd128_raw = ripemd128('data string'); + $ripemd128_hex = ripemd128_hex('data string'); + $ripemd128_b64 = ripemd128_b64('data string'); + $ripemd128_b64u = ripemd128_b64u('data string'); + # calculate digest from file + $ripemd128_raw = ripemd128_file('filename.dat'); + $ripemd128_hex = ripemd128_file_hex('filename.dat'); + $ripemd128_b64 = ripemd128_file_b64('filename.dat'); + $ripemd128_b64u = ripemd128_file_b64u('filename.dat'); + # calculate digest from filehandle + $ripemd128_raw = ripemd128_file(*FILEHANDLE); + $ripemd128_hex = ripemd128_file_hex(*FILEHANDLE); + $ripemd128_b64 = ripemd128_file_b64(*FILEHANDLE); + $ripemd128_b64u = ripemd128_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::RIPEMD128; + + $d = Crypt::Digest::RIPEMD128->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the RIPEMD128 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::RIPEMD128 qw(ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u + ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u); + +Or all of them at once: + + use Crypt::Digest::RIPEMD128 ':all'; + +=head1 FUNCTIONS + +=head2 ripemd128 + +Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a binary string. + + $ripemd128_raw = ripemd128('data string'); + #or + $ripemd128_raw = ripemd128('any data', 'more data', 'even more data'); + +=head2 ripemd128_hex + +Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a hexadecimal string. + + $ripemd128_hex = ripemd128_hex('data string'); + #or + $ripemd128_hex = ripemd128_hex('any data', 'more data', 'even more data'); + +=head2 ripemd128_b64 + +Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $ripemd128_b64 = ripemd128_b64('data string'); + #or + $ripemd128_b64 = ripemd128_b64('any data', 'more data', 'even more data'); + +=head2 ripemd128_b64u + +Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd128_b64url = ripemd128_b64u('data string'); + #or + $ripemd128_b64url = ripemd128_b64u('any data', 'more data', 'even more data'); + +=head2 ripemd128_file + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a binary string. + + $ripemd128_raw = ripemd128_file('filename.dat'); + #or + $ripemd128_raw = ripemd128_file(*FILEHANDLE); + +=head2 ripemd128_file_hex + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a hexadecimal string. + + $ripemd128_hex = ripemd128_file_hex('filename.dat'); + #or + $ripemd128_hex = ripemd128_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 ripemd128_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $ripemd128_b64 = ripemd128_file_b64('filename.dat'); + #or + $ripemd128_b64 = ripemd128_file_b64(*FILEHANDLE); + +=head2 ripemd128_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd128_b64url = ripemd128_file_b64u('filename.dat'); + #or + $ripemd128_b64url = ripemd128_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::RIPEMD128->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::RIPEMD128->hashsize(); + #or + Crypt::Digest::RIPEMD128::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/RIPEMD|http://en.wikipedia.org/wiki/RIPEMD> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/RIPEMD160.pm b/lib/Crypt/Digest/RIPEMD160.pm new file mode 100644 index 00000000..b13d948b --- /dev/null +++ b/lib/Crypt/Digest/RIPEMD160.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::RIPEMD160; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub ripemd160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub ripemd160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub ripemd160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub ripemd160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub ripemd160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub ripemd160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub ripemd160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub ripemd160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::RIPEMD160 - Hash function RIPEMD-160 [size: 160 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u + ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u ); + + # calculate digest from string/buffer + $ripemd160_raw = ripemd160('data string'); + $ripemd160_hex = ripemd160_hex('data string'); + $ripemd160_b64 = ripemd160_b64('data string'); + $ripemd160_b64u = ripemd160_b64u('data string'); + # calculate digest from file + $ripemd160_raw = ripemd160_file('filename.dat'); + $ripemd160_hex = ripemd160_file_hex('filename.dat'); + $ripemd160_b64 = ripemd160_file_b64('filename.dat'); + $ripemd160_b64u = ripemd160_file_b64u('filename.dat'); + # calculate digest from filehandle + $ripemd160_raw = ripemd160_file(*FILEHANDLE); + $ripemd160_hex = ripemd160_file_hex(*FILEHANDLE); + $ripemd160_b64 = ripemd160_file_b64(*FILEHANDLE); + $ripemd160_b64u = ripemd160_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::RIPEMD160; + + $d = Crypt::Digest::RIPEMD160->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the RIPEMD160 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::RIPEMD160 qw(ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u + ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u); + +Or all of them at once: + + use Crypt::Digest::RIPEMD160 ':all'; + +=head1 FUNCTIONS + +=head2 ripemd160 + +Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a binary string. + + $ripemd160_raw = ripemd160('data string'); + #or + $ripemd160_raw = ripemd160('any data', 'more data', 'even more data'); + +=head2 ripemd160_hex + +Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a hexadecimal string. + + $ripemd160_hex = ripemd160_hex('data string'); + #or + $ripemd160_hex = ripemd160_hex('any data', 'more data', 'even more data'); + +=head2 ripemd160_b64 + +Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $ripemd160_b64 = ripemd160_b64('data string'); + #or + $ripemd160_b64 = ripemd160_b64('any data', 'more data', 'even more data'); + +=head2 ripemd160_b64u + +Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd160_b64url = ripemd160_b64u('data string'); + #or + $ripemd160_b64url = ripemd160_b64u('any data', 'more data', 'even more data'); + +=head2 ripemd160_file + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a binary string. + + $ripemd160_raw = ripemd160_file('filename.dat'); + #or + $ripemd160_raw = ripemd160_file(*FILEHANDLE); + +=head2 ripemd160_file_hex + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a hexadecimal string. + + $ripemd160_hex = ripemd160_file_hex('filename.dat'); + #or + $ripemd160_hex = ripemd160_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 ripemd160_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $ripemd160_b64 = ripemd160_file_b64('filename.dat'); + #or + $ripemd160_b64 = ripemd160_file_b64(*FILEHANDLE); + +=head2 ripemd160_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd160_b64url = ripemd160_file_b64u('filename.dat'); + #or + $ripemd160_b64url = ripemd160_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::RIPEMD160->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::RIPEMD160->hashsize(); + #or + Crypt::Digest::RIPEMD160::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/RIPEMD|http://en.wikipedia.org/wiki/RIPEMD> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/RIPEMD256.pm b/lib/Crypt/Digest/RIPEMD256.pm new file mode 100644 index 00000000..d1ed3493 --- /dev/null +++ b/lib/Crypt/Digest/RIPEMD256.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::RIPEMD256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub ripemd256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub ripemd256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub ripemd256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub ripemd256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub ripemd256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub ripemd256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub ripemd256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub ripemd256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::RIPEMD256 - Hash function RIPEMD-256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u + ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u ); + + # calculate digest from string/buffer + $ripemd256_raw = ripemd256('data string'); + $ripemd256_hex = ripemd256_hex('data string'); + $ripemd256_b64 = ripemd256_b64('data string'); + $ripemd256_b64u = ripemd256_b64u('data string'); + # calculate digest from file + $ripemd256_raw = ripemd256_file('filename.dat'); + $ripemd256_hex = ripemd256_file_hex('filename.dat'); + $ripemd256_b64 = ripemd256_file_b64('filename.dat'); + $ripemd256_b64u = ripemd256_file_b64u('filename.dat'); + # calculate digest from filehandle + $ripemd256_raw = ripemd256_file(*FILEHANDLE); + $ripemd256_hex = ripemd256_file_hex(*FILEHANDLE); + $ripemd256_b64 = ripemd256_file_b64(*FILEHANDLE); + $ripemd256_b64u = ripemd256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::RIPEMD256; + + $d = Crypt::Digest::RIPEMD256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the RIPEMD256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::RIPEMD256 qw(ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u + ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::RIPEMD256 ':all'; + +=head1 FUNCTIONS + +=head2 ripemd256 + +Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a binary string. + + $ripemd256_raw = ripemd256('data string'); + #or + $ripemd256_raw = ripemd256('any data', 'more data', 'even more data'); + +=head2 ripemd256_hex + +Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a hexadecimal string. + + $ripemd256_hex = ripemd256_hex('data string'); + #or + $ripemd256_hex = ripemd256_hex('any data', 'more data', 'even more data'); + +=head2 ripemd256_b64 + +Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $ripemd256_b64 = ripemd256_b64('data string'); + #or + $ripemd256_b64 = ripemd256_b64('any data', 'more data', 'even more data'); + +=head2 ripemd256_b64u + +Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd256_b64url = ripemd256_b64u('data string'); + #or + $ripemd256_b64url = ripemd256_b64u('any data', 'more data', 'even more data'); + +=head2 ripemd256_file + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a binary string. + + $ripemd256_raw = ripemd256_file('filename.dat'); + #or + $ripemd256_raw = ripemd256_file(*FILEHANDLE); + +=head2 ripemd256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a hexadecimal string. + + $ripemd256_hex = ripemd256_file_hex('filename.dat'); + #or + $ripemd256_hex = ripemd256_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 ripemd256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $ripemd256_b64 = ripemd256_file_b64('filename.dat'); + #or + $ripemd256_b64 = ripemd256_file_b64(*FILEHANDLE); + +=head2 ripemd256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd256_b64url = ripemd256_file_b64u('filename.dat'); + #or + $ripemd256_b64url = ripemd256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::RIPEMD256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::RIPEMD256->hashsize(); + #or + Crypt::Digest::RIPEMD256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/RIPEMD|http://en.wikipedia.org/wiki/RIPEMD> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/RIPEMD320.pm b/lib/Crypt/Digest/RIPEMD320.pm new file mode 100644 index 00000000..816ad936 --- /dev/null +++ b/lib/Crypt/Digest/RIPEMD320.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::RIPEMD320; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub ripemd320 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub ripemd320_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub ripemd320_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub ripemd320_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub ripemd320_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub ripemd320_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub ripemd320_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub ripemd320_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::RIPEMD320 - Hash function RIPEMD-320 [size: 320 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u + ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u ); + + # calculate digest from string/buffer + $ripemd320_raw = ripemd320('data string'); + $ripemd320_hex = ripemd320_hex('data string'); + $ripemd320_b64 = ripemd320_b64('data string'); + $ripemd320_b64u = ripemd320_b64u('data string'); + # calculate digest from file + $ripemd320_raw = ripemd320_file('filename.dat'); + $ripemd320_hex = ripemd320_file_hex('filename.dat'); + $ripemd320_b64 = ripemd320_file_b64('filename.dat'); + $ripemd320_b64u = ripemd320_file_b64u('filename.dat'); + # calculate digest from filehandle + $ripemd320_raw = ripemd320_file(*FILEHANDLE); + $ripemd320_hex = ripemd320_file_hex(*FILEHANDLE); + $ripemd320_b64 = ripemd320_file_b64(*FILEHANDLE); + $ripemd320_b64u = ripemd320_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::RIPEMD320; + + $d = Crypt::Digest::RIPEMD320->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the RIPEMD320 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::RIPEMD320 qw(ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u + ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u); + +Or all of them at once: + + use Crypt::Digest::RIPEMD320 ':all'; + +=head1 FUNCTIONS + +=head2 ripemd320 + +Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a binary string. + + $ripemd320_raw = ripemd320('data string'); + #or + $ripemd320_raw = ripemd320('any data', 'more data', 'even more data'); + +=head2 ripemd320_hex + +Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a hexadecimal string. + + $ripemd320_hex = ripemd320_hex('data string'); + #or + $ripemd320_hex = ripemd320_hex('any data', 'more data', 'even more data'); + +=head2 ripemd320_b64 + +Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $ripemd320_b64 = ripemd320_b64('data string'); + #or + $ripemd320_b64 = ripemd320_b64('any data', 'more data', 'even more data'); + +=head2 ripemd320_b64u + +Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd320_b64url = ripemd320_b64u('data string'); + #or + $ripemd320_b64url = ripemd320_b64u('any data', 'more data', 'even more data'); + +=head2 ripemd320_file + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a binary string. + + $ripemd320_raw = ripemd320_file('filename.dat'); + #or + $ripemd320_raw = ripemd320_file(*FILEHANDLE); + +=head2 ripemd320_file_hex + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a hexadecimal string. + + $ripemd320_hex = ripemd320_file_hex('filename.dat'); + #or + $ripemd320_hex = ripemd320_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 ripemd320_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $ripemd320_b64 = ripemd320_file_b64('filename.dat'); + #or + $ripemd320_b64 = ripemd320_file_b64(*FILEHANDLE); + +=head2 ripemd320_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd320_b64url = ripemd320_file_b64u('filename.dat'); + #or + $ripemd320_b64url = ripemd320_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::RIPEMD320->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::RIPEMD320->hashsize(); + #or + Crypt::Digest::RIPEMD320::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/RIPEMD|http://en.wikipedia.org/wiki/RIPEMD> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA1.pm b/lib/Crypt/Digest/SHA1.pm new file mode 100644 index 00000000..80e6afa1 --- /dev/null +++ b/lib/Crypt/Digest/SHA1.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA1; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha1 sha1_hex sha1_b64 sha1_b64u sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha1 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha1_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha1_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha1_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha1_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha1_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha1_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha1_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA1 - Hash function SHA-1 [size: 160 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_b64u + sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u ); + + # calculate digest from string/buffer + $sha1_raw = sha1('data string'); + $sha1_hex = sha1_hex('data string'); + $sha1_b64 = sha1_b64('data string'); + $sha1_b64u = sha1_b64u('data string'); + # calculate digest from file + $sha1_raw = sha1_file('filename.dat'); + $sha1_hex = sha1_file_hex('filename.dat'); + $sha1_b64 = sha1_file_b64('filename.dat'); + $sha1_b64u = sha1_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha1_raw = sha1_file(*FILEHANDLE); + $sha1_hex = sha1_file_hex(*FILEHANDLE); + $sha1_b64 = sha1_file_b64(*FILEHANDLE); + $sha1_b64u = sha1_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA1; + + $d = Crypt::Digest::SHA1->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA1 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA1 qw(sha1 sha1_hex sha1_b64 sha1_b64u + sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA1 ':all'; + +=head1 FUNCTIONS + +=head2 sha1 + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a binary string. + + $sha1_raw = sha1('data string'); + #or + $sha1_raw = sha1('any data', 'more data', 'even more data'); + +=head2 sha1_hex + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a hexadecimal string. + + $sha1_hex = sha1_hex('data string'); + #or + $sha1_hex = sha1_hex('any data', 'more data', 'even more data'); + +=head2 sha1_b64 + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha1_b64 = sha1_b64('data string'); + #or + $sha1_b64 = sha1_b64('any data', 'more data', 'even more data'); + +=head2 sha1_b64u + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha1_b64url = sha1_b64u('data string'); + #or + $sha1_b64url = sha1_b64u('any data', 'more data', 'even more data'); + +=head2 sha1_file + +Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a binary string. + + $sha1_raw = sha1_file('filename.dat'); + #or + $sha1_raw = sha1_file(*FILEHANDLE); + +=head2 sha1_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a hexadecimal string. + + $sha1_hex = sha1_file_hex('filename.dat'); + #or + $sha1_hex = sha1_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha1_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha1_b64 = sha1_file_b64('filename.dat'); + #or + $sha1_b64 = sha1_file_b64(*FILEHANDLE); + +=head2 sha1_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha1_b64url = sha1_file_b64u('filename.dat'); + #or + $sha1_b64url = sha1_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA1->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA1->hashsize(); + #or + Crypt::Digest::SHA1::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-1|http://en.wikipedia.org/wiki/SHA-1> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA224.pm b/lib/Crypt/Digest/SHA224.pm new file mode 100644 index 00000000..9d342578 --- /dev/null +++ b/lib/Crypt/Digest/SHA224.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha224 sha224_hex sha224_b64 sha224_b64u sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA224 - Hash function SHA-224 [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_b64u + sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u ); + + # calculate digest from string/buffer + $sha224_raw = sha224('data string'); + $sha224_hex = sha224_hex('data string'); + $sha224_b64 = sha224_b64('data string'); + $sha224_b64u = sha224_b64u('data string'); + # calculate digest from file + $sha224_raw = sha224_file('filename.dat'); + $sha224_hex = sha224_file_hex('filename.dat'); + $sha224_b64 = sha224_file_b64('filename.dat'); + $sha224_b64u = sha224_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha224_raw = sha224_file(*FILEHANDLE); + $sha224_hex = sha224_file_hex(*FILEHANDLE); + $sha224_b64 = sha224_file_b64(*FILEHANDLE); + $sha224_b64u = sha224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA224; + + $d = Crypt::Digest::SHA224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA224 qw(sha224 sha224_hex sha224_b64 sha224_b64u + sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA224 ':all'; + +=head1 FUNCTIONS + +=head2 sha224 + +Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a binary string. + + $sha224_raw = sha224('data string'); + #or + $sha224_raw = sha224('any data', 'more data', 'even more data'); + +=head2 sha224_hex + +Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a hexadecimal string. + + $sha224_hex = sha224_hex('data string'); + #or + $sha224_hex = sha224_hex('any data', 'more data', 'even more data'); + +=head2 sha224_b64 + +Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha224_b64 = sha224_b64('data string'); + #or + $sha224_b64 = sha224_b64('any data', 'more data', 'even more data'); + +=head2 sha224_b64u + +Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha224_b64url = sha224_b64u('data string'); + #or + $sha224_b64url = sha224_b64u('any data', 'more data', 'even more data'); + +=head2 sha224_file + +Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a binary string. + + $sha224_raw = sha224_file('filename.dat'); + #or + $sha224_raw = sha224_file(*FILEHANDLE); + +=head2 sha224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a hexadecimal string. + + $sha224_hex = sha224_file_hex('filename.dat'); + #or + $sha224_hex = sha224_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha224_b64 = sha224_file_b64('filename.dat'); + #or + $sha224_b64 = sha224_file_b64(*FILEHANDLE); + +=head2 sha224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha224_b64url = sha224_file_b64u('filename.dat'); + #or + $sha224_b64url = sha224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA224->hashsize(); + #or + Crypt::Digest::SHA224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-2|http://en.wikipedia.org/wiki/SHA-2> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA256.pm b/lib/Crypt/Digest/SHA256.pm new file mode 100644 index 00000000..4e68b95a --- /dev/null +++ b/lib/Crypt/Digest/SHA256.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha256 sha256_hex sha256_b64 sha256_b64u sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA256 - Hash function SHA-256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_b64u + sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u ); + + # calculate digest from string/buffer + $sha256_raw = sha256('data string'); + $sha256_hex = sha256_hex('data string'); + $sha256_b64 = sha256_b64('data string'); + $sha256_b64u = sha256_b64u('data string'); + # calculate digest from file + $sha256_raw = sha256_file('filename.dat'); + $sha256_hex = sha256_file_hex('filename.dat'); + $sha256_b64 = sha256_file_b64('filename.dat'); + $sha256_b64u = sha256_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha256_raw = sha256_file(*FILEHANDLE); + $sha256_hex = sha256_file_hex(*FILEHANDLE); + $sha256_b64 = sha256_file_b64(*FILEHANDLE); + $sha256_b64u = sha256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA256; + + $d = Crypt::Digest::SHA256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA256 qw(sha256 sha256_hex sha256_b64 sha256_b64u + sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA256 ':all'; + +=head1 FUNCTIONS + +=head2 sha256 + +Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a binary string. + + $sha256_raw = sha256('data string'); + #or + $sha256_raw = sha256('any data', 'more data', 'even more data'); + +=head2 sha256_hex + +Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a hexadecimal string. + + $sha256_hex = sha256_hex('data string'); + #or + $sha256_hex = sha256_hex('any data', 'more data', 'even more data'); + +=head2 sha256_b64 + +Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha256_b64 = sha256_b64('data string'); + #or + $sha256_b64 = sha256_b64('any data', 'more data', 'even more data'); + +=head2 sha256_b64u + +Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha256_b64url = sha256_b64u('data string'); + #or + $sha256_b64url = sha256_b64u('any data', 'more data', 'even more data'); + +=head2 sha256_file + +Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a binary string. + + $sha256_raw = sha256_file('filename.dat'); + #or + $sha256_raw = sha256_file(*FILEHANDLE); + +=head2 sha256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a hexadecimal string. + + $sha256_hex = sha256_file_hex('filename.dat'); + #or + $sha256_hex = sha256_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha256_b64 = sha256_file_b64('filename.dat'); + #or + $sha256_b64 = sha256_file_b64(*FILEHANDLE); + +=head2 sha256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha256_b64url = sha256_file_b64u('filename.dat'); + #or + $sha256_b64url = sha256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA256->hashsize(); + #or + Crypt::Digest::SHA256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-2|http://en.wikipedia.org/wiki/SHA-2> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA384.pm b/lib/Crypt/Digest/SHA384.pm new file mode 100644 index 00000000..f8ddfe26 --- /dev/null +++ b/lib/Crypt/Digest/SHA384.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA384; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha384 sha384_hex sha384_b64 sha384_b64u sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA384 - Hash function SHA-384 [size: 384 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_b64u + sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u ); + + # calculate digest from string/buffer + $sha384_raw = sha384('data string'); + $sha384_hex = sha384_hex('data string'); + $sha384_b64 = sha384_b64('data string'); + $sha384_b64u = sha384_b64u('data string'); + # calculate digest from file + $sha384_raw = sha384_file('filename.dat'); + $sha384_hex = sha384_file_hex('filename.dat'); + $sha384_b64 = sha384_file_b64('filename.dat'); + $sha384_b64u = sha384_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha384_raw = sha384_file(*FILEHANDLE); + $sha384_hex = sha384_file_hex(*FILEHANDLE); + $sha384_b64 = sha384_file_b64(*FILEHANDLE); + $sha384_b64u = sha384_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA384; + + $d = Crypt::Digest::SHA384->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA384 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA384 qw(sha384 sha384_hex sha384_b64 sha384_b64u + sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA384 ':all'; + +=head1 FUNCTIONS + +=head2 sha384 + +Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a binary string. + + $sha384_raw = sha384('data string'); + #or + $sha384_raw = sha384('any data', 'more data', 'even more data'); + +=head2 sha384_hex + +Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a hexadecimal string. + + $sha384_hex = sha384_hex('data string'); + #or + $sha384_hex = sha384_hex('any data', 'more data', 'even more data'); + +=head2 sha384_b64 + +Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha384_b64 = sha384_b64('data string'); + #or + $sha384_b64 = sha384_b64('any data', 'more data', 'even more data'); + +=head2 sha384_b64u + +Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha384_b64url = sha384_b64u('data string'); + #or + $sha384_b64url = sha384_b64u('any data', 'more data', 'even more data'); + +=head2 sha384_file + +Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a binary string. + + $sha384_raw = sha384_file('filename.dat'); + #or + $sha384_raw = sha384_file(*FILEHANDLE); + +=head2 sha384_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a hexadecimal string. + + $sha384_hex = sha384_file_hex('filename.dat'); + #or + $sha384_hex = sha384_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha384_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha384_b64 = sha384_file_b64('filename.dat'); + #or + $sha384_b64 = sha384_file_b64(*FILEHANDLE); + +=head2 sha384_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha384_b64url = sha384_file_b64u('filename.dat'); + #or + $sha384_b64url = sha384_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA384->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA384->hashsize(); + #or + Crypt::Digest::SHA384::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-2|http://en.wikipedia.org/wiki/SHA-2> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA3_224.pm b/lib/Crypt/Digest/SHA3_224.pm new file mode 100644 index 00000000..192c044e --- /dev/null +++ b/lib/Crypt/Digest/SHA3_224.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA3_224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha3_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha3_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha3_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha3_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha3_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha3_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha3_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha3_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA3_224 - Hash function SHA3-224 [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA3_224 qw( sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u + sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u ); + + # calculate digest from string/buffer + $sha3_224_raw = sha3_224('data string'); + $sha3_224_hex = sha3_224_hex('data string'); + $sha3_224_b64 = sha3_224_b64('data string'); + $sha3_224_b64u = sha3_224_b64u('data string'); + # calculate digest from file + $sha3_224_raw = sha3_224_file('filename.dat'); + $sha3_224_hex = sha3_224_file_hex('filename.dat'); + $sha3_224_b64 = sha3_224_file_b64('filename.dat'); + $sha3_224_b64u = sha3_224_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha3_224_raw = sha3_224_file(*FILEHANDLE); + $sha3_224_hex = sha3_224_file_hex(*FILEHANDLE); + $sha3_224_b64 = sha3_224_file_b64(*FILEHANDLE); + $sha3_224_b64u = sha3_224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA3_224; + + $d = Crypt::Digest::SHA3_224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA3_224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA3_224 qw(sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u + sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA3_224 ':all'; + +=head1 FUNCTIONS + +=head2 sha3_224 + +Logically joins all arguments into a single string, and returns its SHA3_224 digest encoded as a binary string. + + $sha3_224_raw = sha3_224('data string'); + #or + $sha3_224_raw = sha3_224('any data', 'more data', 'even more data'); + +=head2 sha3_224_hex + +Logically joins all arguments into a single string, and returns its SHA3_224 digest encoded as a hexadecimal string. + + $sha3_224_hex = sha3_224_hex('data string'); + #or + $sha3_224_hex = sha3_224_hex('any data', 'more data', 'even more data'); + +=head2 sha3_224_b64 + +Logically joins all arguments into a single string, and returns its SHA3_224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha3_224_b64 = sha3_224_b64('data string'); + #or + $sha3_224_b64 = sha3_224_b64('any data', 'more data', 'even more data'); + +=head2 sha3_224_b64u + +Logically joins all arguments into a single string, and returns its SHA3_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_224_b64url = sha3_224_b64u('data string'); + #or + $sha3_224_b64url = sha3_224_b64u('any data', 'more data', 'even more data'); + +=head2 sha3_224_file + +Reads file (defined by filename or filehandle) content, and returns its SHA3_224 digest encoded as a binary string. + + $sha3_224_raw = sha3_224_file('filename.dat'); + #or + $sha3_224_raw = sha3_224_file(*FILEHANDLE); + +=head2 sha3_224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA3_224 digest encoded as a hexadecimal string. + + $sha3_224_hex = sha3_224_file_hex('filename.dat'); + #or + $sha3_224_hex = sha3_224_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha3_224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA3_224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha3_224_b64 = sha3_224_file_b64('filename.dat'); + #or + $sha3_224_b64 = sha3_224_file_b64(*FILEHANDLE); + +=head2 sha3_224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA3_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_224_b64url = sha3_224_file_b64u('filename.dat'); + #or + $sha3_224_b64url = sha3_224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA3_224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA3_224->hashsize(); + #or + Crypt::Digest::SHA3_224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-3|http://en.wikipedia.org/wiki/SHA-3> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA3_256.pm b/lib/Crypt/Digest/SHA3_256.pm new file mode 100644 index 00000000..9a13a52e --- /dev/null +++ b/lib/Crypt/Digest/SHA3_256.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA3_256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha3_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha3_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha3_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha3_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha3_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha3_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha3_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha3_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA3_256 - Hash function SHA3-256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA3_256 qw( sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u + sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u ); + + # calculate digest from string/buffer + $sha3_256_raw = sha3_256('data string'); + $sha3_256_hex = sha3_256_hex('data string'); + $sha3_256_b64 = sha3_256_b64('data string'); + $sha3_256_b64u = sha3_256_b64u('data string'); + # calculate digest from file + $sha3_256_raw = sha3_256_file('filename.dat'); + $sha3_256_hex = sha3_256_file_hex('filename.dat'); + $sha3_256_b64 = sha3_256_file_b64('filename.dat'); + $sha3_256_b64u = sha3_256_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha3_256_raw = sha3_256_file(*FILEHANDLE); + $sha3_256_hex = sha3_256_file_hex(*FILEHANDLE); + $sha3_256_b64 = sha3_256_file_b64(*FILEHANDLE); + $sha3_256_b64u = sha3_256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA3_256; + + $d = Crypt::Digest::SHA3_256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA3_256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA3_256 qw(sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u + sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA3_256 ':all'; + +=head1 FUNCTIONS + +=head2 sha3_256 + +Logically joins all arguments into a single string, and returns its SHA3_256 digest encoded as a binary string. + + $sha3_256_raw = sha3_256('data string'); + #or + $sha3_256_raw = sha3_256('any data', 'more data', 'even more data'); + +=head2 sha3_256_hex + +Logically joins all arguments into a single string, and returns its SHA3_256 digest encoded as a hexadecimal string. + + $sha3_256_hex = sha3_256_hex('data string'); + #or + $sha3_256_hex = sha3_256_hex('any data', 'more data', 'even more data'); + +=head2 sha3_256_b64 + +Logically joins all arguments into a single string, and returns its SHA3_256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha3_256_b64 = sha3_256_b64('data string'); + #or + $sha3_256_b64 = sha3_256_b64('any data', 'more data', 'even more data'); + +=head2 sha3_256_b64u + +Logically joins all arguments into a single string, and returns its SHA3_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_256_b64url = sha3_256_b64u('data string'); + #or + $sha3_256_b64url = sha3_256_b64u('any data', 'more data', 'even more data'); + +=head2 sha3_256_file + +Reads file (defined by filename or filehandle) content, and returns its SHA3_256 digest encoded as a binary string. + + $sha3_256_raw = sha3_256_file('filename.dat'); + #or + $sha3_256_raw = sha3_256_file(*FILEHANDLE); + +=head2 sha3_256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA3_256 digest encoded as a hexadecimal string. + + $sha3_256_hex = sha3_256_file_hex('filename.dat'); + #or + $sha3_256_hex = sha3_256_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha3_256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA3_256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha3_256_b64 = sha3_256_file_b64('filename.dat'); + #or + $sha3_256_b64 = sha3_256_file_b64(*FILEHANDLE); + +=head2 sha3_256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA3_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_256_b64url = sha3_256_file_b64u('filename.dat'); + #or + $sha3_256_b64url = sha3_256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA3_256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA3_256->hashsize(); + #or + Crypt::Digest::SHA3_256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-3|http://en.wikipedia.org/wiki/SHA-3> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA3_384.pm b/lib/Crypt/Digest/SHA3_384.pm new file mode 100644 index 00000000..cf98a9e2 --- /dev/null +++ b/lib/Crypt/Digest/SHA3_384.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA3_384; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha3_384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha3_384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha3_384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha3_384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha3_384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha3_384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha3_384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha3_384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA3_384 - Hash function SHA3-384 [size: 384 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA3_384 qw( sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u + sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u ); + + # calculate digest from string/buffer + $sha3_384_raw = sha3_384('data string'); + $sha3_384_hex = sha3_384_hex('data string'); + $sha3_384_b64 = sha3_384_b64('data string'); + $sha3_384_b64u = sha3_384_b64u('data string'); + # calculate digest from file + $sha3_384_raw = sha3_384_file('filename.dat'); + $sha3_384_hex = sha3_384_file_hex('filename.dat'); + $sha3_384_b64 = sha3_384_file_b64('filename.dat'); + $sha3_384_b64u = sha3_384_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha3_384_raw = sha3_384_file(*FILEHANDLE); + $sha3_384_hex = sha3_384_file_hex(*FILEHANDLE); + $sha3_384_b64 = sha3_384_file_b64(*FILEHANDLE); + $sha3_384_b64u = sha3_384_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA3_384; + + $d = Crypt::Digest::SHA3_384->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA3_384 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA3_384 qw(sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u + sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA3_384 ':all'; + +=head1 FUNCTIONS + +=head2 sha3_384 + +Logically joins all arguments into a single string, and returns its SHA3_384 digest encoded as a binary string. + + $sha3_384_raw = sha3_384('data string'); + #or + $sha3_384_raw = sha3_384('any data', 'more data', 'even more data'); + +=head2 sha3_384_hex + +Logically joins all arguments into a single string, and returns its SHA3_384 digest encoded as a hexadecimal string. + + $sha3_384_hex = sha3_384_hex('data string'); + #or + $sha3_384_hex = sha3_384_hex('any data', 'more data', 'even more data'); + +=head2 sha3_384_b64 + +Logically joins all arguments into a single string, and returns its SHA3_384 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha3_384_b64 = sha3_384_b64('data string'); + #or + $sha3_384_b64 = sha3_384_b64('any data', 'more data', 'even more data'); + +=head2 sha3_384_b64u + +Logically joins all arguments into a single string, and returns its SHA3_384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_384_b64url = sha3_384_b64u('data string'); + #or + $sha3_384_b64url = sha3_384_b64u('any data', 'more data', 'even more data'); + +=head2 sha3_384_file + +Reads file (defined by filename or filehandle) content, and returns its SHA3_384 digest encoded as a binary string. + + $sha3_384_raw = sha3_384_file('filename.dat'); + #or + $sha3_384_raw = sha3_384_file(*FILEHANDLE); + +=head2 sha3_384_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA3_384 digest encoded as a hexadecimal string. + + $sha3_384_hex = sha3_384_file_hex('filename.dat'); + #or + $sha3_384_hex = sha3_384_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha3_384_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA3_384 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha3_384_b64 = sha3_384_file_b64('filename.dat'); + #or + $sha3_384_b64 = sha3_384_file_b64(*FILEHANDLE); + +=head2 sha3_384_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA3_384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_384_b64url = sha3_384_file_b64u('filename.dat'); + #or + $sha3_384_b64url = sha3_384_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA3_384->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA3_384->hashsize(); + #or + Crypt::Digest::SHA3_384::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-3|http://en.wikipedia.org/wiki/SHA-3> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA3_512.pm b/lib/Crypt/Digest/SHA3_512.pm new file mode 100644 index 00000000..3762a6bc --- /dev/null +++ b/lib/Crypt/Digest/SHA3_512.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA3_512; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha3_512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha3_512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha3_512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha3_512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha3_512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha3_512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha3_512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha3_512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA3_512 - Hash function SHA3-512 [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA3_512 qw( sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u + sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u ); + + # calculate digest from string/buffer + $sha3_512_raw = sha3_512('data string'); + $sha3_512_hex = sha3_512_hex('data string'); + $sha3_512_b64 = sha3_512_b64('data string'); + $sha3_512_b64u = sha3_512_b64u('data string'); + # calculate digest from file + $sha3_512_raw = sha3_512_file('filename.dat'); + $sha3_512_hex = sha3_512_file_hex('filename.dat'); + $sha3_512_b64 = sha3_512_file_b64('filename.dat'); + $sha3_512_b64u = sha3_512_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha3_512_raw = sha3_512_file(*FILEHANDLE); + $sha3_512_hex = sha3_512_file_hex(*FILEHANDLE); + $sha3_512_b64 = sha3_512_file_b64(*FILEHANDLE); + $sha3_512_b64u = sha3_512_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA3_512; + + $d = Crypt::Digest::SHA3_512->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA3_512 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA3_512 qw(sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u + sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA3_512 ':all'; + +=head1 FUNCTIONS + +=head2 sha3_512 + +Logically joins all arguments into a single string, and returns its SHA3_512 digest encoded as a binary string. + + $sha3_512_raw = sha3_512('data string'); + #or + $sha3_512_raw = sha3_512('any data', 'more data', 'even more data'); + +=head2 sha3_512_hex + +Logically joins all arguments into a single string, and returns its SHA3_512 digest encoded as a hexadecimal string. + + $sha3_512_hex = sha3_512_hex('data string'); + #or + $sha3_512_hex = sha3_512_hex('any data', 'more data', 'even more data'); + +=head2 sha3_512_b64 + +Logically joins all arguments into a single string, and returns its SHA3_512 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha3_512_b64 = sha3_512_b64('data string'); + #or + $sha3_512_b64 = sha3_512_b64('any data', 'more data', 'even more data'); + +=head2 sha3_512_b64u + +Logically joins all arguments into a single string, and returns its SHA3_512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_512_b64url = sha3_512_b64u('data string'); + #or + $sha3_512_b64url = sha3_512_b64u('any data', 'more data', 'even more data'); + +=head2 sha3_512_file + +Reads file (defined by filename or filehandle) content, and returns its SHA3_512 digest encoded as a binary string. + + $sha3_512_raw = sha3_512_file('filename.dat'); + #or + $sha3_512_raw = sha3_512_file(*FILEHANDLE); + +=head2 sha3_512_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA3_512 digest encoded as a hexadecimal string. + + $sha3_512_hex = sha3_512_file_hex('filename.dat'); + #or + $sha3_512_hex = sha3_512_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha3_512_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA3_512 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha3_512_b64 = sha3_512_file_b64('filename.dat'); + #or + $sha3_512_b64 = sha3_512_file_b64(*FILEHANDLE); + +=head2 sha3_512_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA3_512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_512_b64url = sha3_512_file_b64u('filename.dat'); + #or + $sha3_512_b64url = sha3_512_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA3_512->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA3_512->hashsize(); + #or + Crypt::Digest::SHA3_512::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-3|http://en.wikipedia.org/wiki/SHA-3> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA512.pm b/lib/Crypt/Digest/SHA512.pm new file mode 100644 index 00000000..6b109faf --- /dev/null +++ b/lib/Crypt/Digest/SHA512.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA512; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha512 sha512_hex sha512_b64 sha512_b64u sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA512 - Hash function SHA-512 [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_b64u + sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u ); + + # calculate digest from string/buffer + $sha512_raw = sha512('data string'); + $sha512_hex = sha512_hex('data string'); + $sha512_b64 = sha512_b64('data string'); + $sha512_b64u = sha512_b64u('data string'); + # calculate digest from file + $sha512_raw = sha512_file('filename.dat'); + $sha512_hex = sha512_file_hex('filename.dat'); + $sha512_b64 = sha512_file_b64('filename.dat'); + $sha512_b64u = sha512_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha512_raw = sha512_file(*FILEHANDLE); + $sha512_hex = sha512_file_hex(*FILEHANDLE); + $sha512_b64 = sha512_file_b64(*FILEHANDLE); + $sha512_b64u = sha512_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA512; + + $d = Crypt::Digest::SHA512->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA512 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA512 qw(sha512 sha512_hex sha512_b64 sha512_b64u + sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA512 ':all'; + +=head1 FUNCTIONS + +=head2 sha512 + +Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a binary string. + + $sha512_raw = sha512('data string'); + #or + $sha512_raw = sha512('any data', 'more data', 'even more data'); + +=head2 sha512_hex + +Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a hexadecimal string. + + $sha512_hex = sha512_hex('data string'); + #or + $sha512_hex = sha512_hex('any data', 'more data', 'even more data'); + +=head2 sha512_b64 + +Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha512_b64 = sha512_b64('data string'); + #or + $sha512_b64 = sha512_b64('any data', 'more data', 'even more data'); + +=head2 sha512_b64u + +Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_b64url = sha512_b64u('data string'); + #or + $sha512_b64url = sha512_b64u('any data', 'more data', 'even more data'); + +=head2 sha512_file + +Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a binary string. + + $sha512_raw = sha512_file('filename.dat'); + #or + $sha512_raw = sha512_file(*FILEHANDLE); + +=head2 sha512_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a hexadecimal string. + + $sha512_hex = sha512_file_hex('filename.dat'); + #or + $sha512_hex = sha512_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha512_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha512_b64 = sha512_file_b64('filename.dat'); + #or + $sha512_b64 = sha512_file_b64(*FILEHANDLE); + +=head2 sha512_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_b64url = sha512_file_b64u('filename.dat'); + #or + $sha512_b64url = sha512_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA512->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA512->hashsize(); + #or + Crypt::Digest::SHA512::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-2|http://en.wikipedia.org/wiki/SHA-2> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA512_224.pm b/lib/Crypt/Digest/SHA512_224.pm new file mode 100644 index 00000000..eec53e81 --- /dev/null +++ b/lib/Crypt/Digest/SHA512_224.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA512_224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha512_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha512_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha512_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha512_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha512_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha512_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha512_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha512_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA512_224 - Hash function SHA-512/224 [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA512_224 qw( sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u + sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u ); + + # calculate digest from string/buffer + $sha512_224_raw = sha512_224('data string'); + $sha512_224_hex = sha512_224_hex('data string'); + $sha512_224_b64 = sha512_224_b64('data string'); + $sha512_224_b64u = sha512_224_b64u('data string'); + # calculate digest from file + $sha512_224_raw = sha512_224_file('filename.dat'); + $sha512_224_hex = sha512_224_file_hex('filename.dat'); + $sha512_224_b64 = sha512_224_file_b64('filename.dat'); + $sha512_224_b64u = sha512_224_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha512_224_raw = sha512_224_file(*FILEHANDLE); + $sha512_224_hex = sha512_224_file_hex(*FILEHANDLE); + $sha512_224_b64 = sha512_224_file_b64(*FILEHANDLE); + $sha512_224_b64u = sha512_224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA512_224; + + $d = Crypt::Digest::SHA512_224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA512_224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA512_224 qw(sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u + sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA512_224 ':all'; + +=head1 FUNCTIONS + +=head2 sha512_224 + +Logically joins all arguments into a single string, and returns its SHA512_224 digest encoded as a binary string. + + $sha512_224_raw = sha512_224('data string'); + #or + $sha512_224_raw = sha512_224('any data', 'more data', 'even more data'); + +=head2 sha512_224_hex + +Logically joins all arguments into a single string, and returns its SHA512_224 digest encoded as a hexadecimal string. + + $sha512_224_hex = sha512_224_hex('data string'); + #or + $sha512_224_hex = sha512_224_hex('any data', 'more data', 'even more data'); + +=head2 sha512_224_b64 + +Logically joins all arguments into a single string, and returns its SHA512_224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha512_224_b64 = sha512_224_b64('data string'); + #or + $sha512_224_b64 = sha512_224_b64('any data', 'more data', 'even more data'); + +=head2 sha512_224_b64u + +Logically joins all arguments into a single string, and returns its SHA512_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_224_b64url = sha512_224_b64u('data string'); + #or + $sha512_224_b64url = sha512_224_b64u('any data', 'more data', 'even more data'); + +=head2 sha512_224_file + +Reads file (defined by filename or filehandle) content, and returns its SHA512_224 digest encoded as a binary string. + + $sha512_224_raw = sha512_224_file('filename.dat'); + #or + $sha512_224_raw = sha512_224_file(*FILEHANDLE); + +=head2 sha512_224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA512_224 digest encoded as a hexadecimal string. + + $sha512_224_hex = sha512_224_file_hex('filename.dat'); + #or + $sha512_224_hex = sha512_224_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha512_224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA512_224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha512_224_b64 = sha512_224_file_b64('filename.dat'); + #or + $sha512_224_b64 = sha512_224_file_b64(*FILEHANDLE); + +=head2 sha512_224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA512_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_224_b64url = sha512_224_file_b64u('filename.dat'); + #or + $sha512_224_b64url = sha512_224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA512_224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA512_224->hashsize(); + #or + Crypt::Digest::SHA512_224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-2|http://en.wikipedia.org/wiki/SHA-2> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHA512_256.pm b/lib/Crypt/Digest/SHA512_256.pm new file mode 100644 index 00000000..d02044b7 --- /dev/null +++ b/lib/Crypt/Digest/SHA512_256.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA512_256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha512_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha512_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha512_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha512_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha512_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha512_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha512_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha512_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA512_256 - Hash function SHA-512/256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA512_256 qw( sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u + sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u ); + + # calculate digest from string/buffer + $sha512_256_raw = sha512_256('data string'); + $sha512_256_hex = sha512_256_hex('data string'); + $sha512_256_b64 = sha512_256_b64('data string'); + $sha512_256_b64u = sha512_256_b64u('data string'); + # calculate digest from file + $sha512_256_raw = sha512_256_file('filename.dat'); + $sha512_256_hex = sha512_256_file_hex('filename.dat'); + $sha512_256_b64 = sha512_256_file_b64('filename.dat'); + $sha512_256_b64u = sha512_256_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha512_256_raw = sha512_256_file(*FILEHANDLE); + $sha512_256_hex = sha512_256_file_hex(*FILEHANDLE); + $sha512_256_b64 = sha512_256_file_b64(*FILEHANDLE); + $sha512_256_b64u = sha512_256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA512_256; + + $d = Crypt::Digest::SHA512_256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA512_256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA512_256 qw(sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u + sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA512_256 ':all'; + +=head1 FUNCTIONS + +=head2 sha512_256 + +Logically joins all arguments into a single string, and returns its SHA512_256 digest encoded as a binary string. + + $sha512_256_raw = sha512_256('data string'); + #or + $sha512_256_raw = sha512_256('any data', 'more data', 'even more data'); + +=head2 sha512_256_hex + +Logically joins all arguments into a single string, and returns its SHA512_256 digest encoded as a hexadecimal string. + + $sha512_256_hex = sha512_256_hex('data string'); + #or + $sha512_256_hex = sha512_256_hex('any data', 'more data', 'even more data'); + +=head2 sha512_256_b64 + +Logically joins all arguments into a single string, and returns its SHA512_256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha512_256_b64 = sha512_256_b64('data string'); + #or + $sha512_256_b64 = sha512_256_b64('any data', 'more data', 'even more data'); + +=head2 sha512_256_b64u + +Logically joins all arguments into a single string, and returns its SHA512_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_256_b64url = sha512_256_b64u('data string'); + #or + $sha512_256_b64url = sha512_256_b64u('any data', 'more data', 'even more data'); + +=head2 sha512_256_file + +Reads file (defined by filename or filehandle) content, and returns its SHA512_256 digest encoded as a binary string. + + $sha512_256_raw = sha512_256_file('filename.dat'); + #or + $sha512_256_raw = sha512_256_file(*FILEHANDLE); + +=head2 sha512_256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA512_256 digest encoded as a hexadecimal string. + + $sha512_256_hex = sha512_256_file_hex('filename.dat'); + #or + $sha512_256_hex = sha512_256_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha512_256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA512_256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $sha512_256_b64 = sha512_256_file_b64('filename.dat'); + #or + $sha512_256_b64 = sha512_256_file_b64(*FILEHANDLE); + +=head2 sha512_256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA512_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_256_b64url = sha512_256_file_b64u('filename.dat'); + #or + $sha512_256_b64url = sha512_256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::SHA512_256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA512_256->hashsize(); + #or + Crypt::Digest::SHA512_256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-2|http://en.wikipedia.org/wiki/SHA-2> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/SHAKE.pm b/lib/Crypt/Digest/SHAKE.pm new file mode 100644 index 00000000..efdb0776 --- /dev/null +++ b/lib/Crypt/Digest/SHAKE.pm @@ -0,0 +1,106 @@ +package Crypt::Digest::SHAKE; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub new { my $class = shift; _new(@_) } + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHAKE - Hash functions SHAKE128, SHAKE256 from SHA3 family + +=head1 SYNOPSIS + + use Crypt::Digest::SHAKE + + $d = Crypt::Digest::SHAKE->new(128); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $part1 = $d->done(100); # 100 raw bytes + $part2 = $d->done(100); # another 100 raw bytes + #... + +=head1 DESCRIPTION + +Provides an interface to the SHA3's sponge function SHAKE. + +=head1 METHODS + +=head2 new + + $d = Crypt::Digest::SHA3-SHAKE->new($num); + # $num ... 128 or 256 + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 done + + $result_raw = $d->done($len); + # can be called multiple times + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/SHA-3|http://en.wikipedia.org/wiki/SHA-3> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/Tiger192.pm b/lib/Crypt/Digest/Tiger192.pm new file mode 100644 index 00000000..1e66a4cb --- /dev/null +++ b/lib/Crypt/Digest/Tiger192.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::Tiger192; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub tiger192 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub tiger192_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub tiger192_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub tiger192_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub tiger192_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub tiger192_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub tiger192_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub tiger192_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::Tiger192 - Hash function Tiger-192 [size: 192 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u + tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u ); + + # calculate digest from string/buffer + $tiger192_raw = tiger192('data string'); + $tiger192_hex = tiger192_hex('data string'); + $tiger192_b64 = tiger192_b64('data string'); + $tiger192_b64u = tiger192_b64u('data string'); + # calculate digest from file + $tiger192_raw = tiger192_file('filename.dat'); + $tiger192_hex = tiger192_file_hex('filename.dat'); + $tiger192_b64 = tiger192_file_b64('filename.dat'); + $tiger192_b64u = tiger192_file_b64u('filename.dat'); + # calculate digest from filehandle + $tiger192_raw = tiger192_file(*FILEHANDLE); + $tiger192_hex = tiger192_file_hex(*FILEHANDLE); + $tiger192_b64 = tiger192_file_b64(*FILEHANDLE); + $tiger192_b64u = tiger192_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::Tiger192; + + $d = Crypt::Digest::Tiger192->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Tiger192 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::Tiger192 qw(tiger192 tiger192_hex tiger192_b64 tiger192_b64u + tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u); + +Or all of them at once: + + use Crypt::Digest::Tiger192 ':all'; + +=head1 FUNCTIONS + +=head2 tiger192 + +Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a binary string. + + $tiger192_raw = tiger192('data string'); + #or + $tiger192_raw = tiger192('any data', 'more data', 'even more data'); + +=head2 tiger192_hex + +Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a hexadecimal string. + + $tiger192_hex = tiger192_hex('data string'); + #or + $tiger192_hex = tiger192_hex('any data', 'more data', 'even more data'); + +=head2 tiger192_b64 + +Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $tiger192_b64 = tiger192_b64('data string'); + #or + $tiger192_b64 = tiger192_b64('any data', 'more data', 'even more data'); + +=head2 tiger192_b64u + +Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $tiger192_b64url = tiger192_b64u('data string'); + #or + $tiger192_b64url = tiger192_b64u('any data', 'more data', 'even more data'); + +=head2 tiger192_file + +Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a binary string. + + $tiger192_raw = tiger192_file('filename.dat'); + #or + $tiger192_raw = tiger192_file(*FILEHANDLE); + +=head2 tiger192_file_hex + +Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a hexadecimal string. + + $tiger192_hex = tiger192_file_hex('filename.dat'); + #or + $tiger192_hex = tiger192_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 tiger192_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $tiger192_b64 = tiger192_file_b64('filename.dat'); + #or + $tiger192_b64 = tiger192_file_b64(*FILEHANDLE); + +=head2 tiger192_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $tiger192_b64url = tiger192_file_b64u('filename.dat'); + #or + $tiger192_b64url = tiger192_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::Tiger192->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::Tiger192->hashsize(); + #or + Crypt::Digest::Tiger192::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/Tiger_(cryptography)|http://en.wikipedia.org/wiki/Tiger_(cryptography)> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Digest/Whirlpool.pm b/lib/Crypt/Digest/Whirlpool.pm new file mode 100644 index 00000000..553dc6d0 --- /dev/null +++ b/lib/Crypt/Digest/Whirlpool.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::Whirlpool; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub whirlpool { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub whirlpool_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub whirlpool_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub whirlpool_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub whirlpool_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub whirlpool_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub whirlpool_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub whirlpool_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::Whirlpool - Hash function Whirlpool [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u + whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u ); + + # calculate digest from string/buffer + $whirlpool_raw = whirlpool('data string'); + $whirlpool_hex = whirlpool_hex('data string'); + $whirlpool_b64 = whirlpool_b64('data string'); + $whirlpool_b64u = whirlpool_b64u('data string'); + # calculate digest from file + $whirlpool_raw = whirlpool_file('filename.dat'); + $whirlpool_hex = whirlpool_file_hex('filename.dat'); + $whirlpool_b64 = whirlpool_file_b64('filename.dat'); + $whirlpool_b64u = whirlpool_file_b64u('filename.dat'); + # calculate digest from filehandle + $whirlpool_raw = whirlpool_file(*FILEHANDLE); + $whirlpool_hex = whirlpool_file_hex(*FILEHANDLE); + $whirlpool_b64 = whirlpool_file_b64(*FILEHANDLE); + $whirlpool_b64u = whirlpool_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::Whirlpool; + + $d = Crypt::Digest::Whirlpool->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Whirlpool digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::Whirlpool qw(whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u + whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u); + +Or all of them at once: + + use Crypt::Digest::Whirlpool ':all'; + +=head1 FUNCTIONS + +=head2 whirlpool + +Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a binary string. + + $whirlpool_raw = whirlpool('data string'); + #or + $whirlpool_raw = whirlpool('any data', 'more data', 'even more data'); + +=head2 whirlpool_hex + +Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a hexadecimal string. + + $whirlpool_hex = whirlpool_hex('data string'); + #or + $whirlpool_hex = whirlpool_hex('any data', 'more data', 'even more data'); + +=head2 whirlpool_b64 + +Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a Base64 string, B<with> trailing '=' padding. + + $whirlpool_b64 = whirlpool_b64('data string'); + #or + $whirlpool_b64 = whirlpool_b64('any data', 'more data', 'even more data'); + +=head2 whirlpool_b64u + +Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $whirlpool_b64url = whirlpool_b64u('data string'); + #or + $whirlpool_b64url = whirlpool_b64u('any data', 'more data', 'even more data'); + +=head2 whirlpool_file + +Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a binary string. + + $whirlpool_raw = whirlpool_file('filename.dat'); + #or + $whirlpool_raw = whirlpool_file(*FILEHANDLE); + +=head2 whirlpool_file_hex + +Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a hexadecimal string. + + $whirlpool_hex = whirlpool_file_hex('filename.dat'); + #or + $whirlpool_hex = whirlpool_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 whirlpool_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a Base64 string, B<with> trailing '=' padding. + + $whirlpool_b64 = whirlpool_file_b64('filename.dat'); + #or + $whirlpool_b64 = whirlpool_file_b64(*FILEHANDLE); + +=head2 whirlpool_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $whirlpool_b64url = whirlpool_file_b64u('filename.dat'); + #or + $whirlpool_b64url = whirlpool_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::Whirlpool->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::Whirlpool->hashsize(); + #or + Crypt::Digest::Whirlpool::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest|Crypt::Digest> + +=item * L<http://en.wikipedia.org/wiki/Whirlpool_(cryptography)|http://en.wikipedia.org/wiki/Whirlpool_(cryptography)> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/KeyDerivation.pm b/lib/Crypt/KeyDerivation.pm new file mode 100644 index 00000000..921f4844 --- /dev/null +++ b/lib/Crypt/KeyDerivation.pm @@ -0,0 +1,167 @@ +package Crypt::KeyDerivation; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw(pbkdf1 pbkdf2 hkdf hkdf_expand hkdf_extract)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Digest; + +sub pbkdf1 { + my ($password, $salt, $iteration_count, $hash_name, $len) = @_; + $iteration_count ||= 5000; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + $len ||= 32; + return _pkcs_5_alg1($password, $salt, $iteration_count, $hash_name, $len); +} + +sub pbkdf2 { + my ($password, $salt, $iteration_count, $hash_name, $len) = @_; + $iteration_count ||= 5000; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + $len ||= 32; + return _pkcs_5_alg2($password, $salt, $iteration_count, $hash_name, $len); +} + +sub hkdf_extract { + # RFC: HKDF-Extract(salt, IKM, [Hash]) -> PRK + #my ($hash_name, $salt, $keying_material) = @_; + my ($keying_material, $salt, $hash_name) = @_; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + $salt = pack("H*", "00" x Crypt::Digest->hashsize($hash_name)) unless defined $salt; # according to rfc5869 defaults to HashLen zero octets + return _hkdf_extract($hash_name, $salt, $keying_material); +} + +sub hkdf_expand { + # RFC: HKDF-Expand(PRK, info, L, [Hash]) -> OKM + #my ($hash_name, $info, $keying_material, $len) = @_; + my ($keying_material, $hash_name, $len, $info) = @_; + $len ||= 32; + $info ||= ''; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + return _hkdf_expand($hash_name, $info, $keying_material, $len); +} + +sub hkdf { + #my ($hash_name, $salt, $info, $keying_material, $len) = @_; + my ($keying_material, $salt, $hash_name, $len, $info) = @_; + $len ||= 32; + $info ||= ''; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + $salt = pack("H*", "00" x Crypt::Digest->hashsize($hash_name)) unless defined $salt; # according to rfc5869 defaults to HashLen zero octets + return _hkdf($hash_name, $salt, $info, $keying_material, $len); +} + +1; + +=pod + +=head1 NAME + +Crypt::KeyDerivation - PBKDF1, PBKFD2 and HKDF key derivation functions + +=head1 SYNOPSIS + + ### PBKDF1/2 + $derived_key1 = pbkdf1($password, $salt, $iteration_count, $hash_name, $len); + $derived_key2 = pbkdf2($password, $salt, $iteration_count, $hash_name, $len); + + ### HKDF & co. + $derived_key3 = hkdf($keying_material, $salt, $hash_name, $len, $info); + $prk = hkdf_extract($keying_material, $salt, $hash_name); + $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + +=head1 DESCRIPTION + +Provides an interface to Key derivation functions: + +=over + +=item * PBKFD1 and PBKDF according to PKCS#5 v2.0 L<https://tools.ietf.org/html/rfc2898|https://tools.ietf.org/html/rfc2898> + +=item * HKDF (+ related) according to L<https://tools.ietf.org/html/rfc5869|https://tools.ietf.org/html/rfc5869> + +=back + +=head1 FUNCTIONS + +=head2 pbkdf1 + +B<BEWARE:> if you are not sure, do not use C<pbkdf1> but rather choose C<pbkdf2>. + + $derived_key = pbkdf1($password, $salt, $iteration_count, $hash_name, $len); + #or + $derived_key = pbkdf1($password, $salt, $iteration_count, $hash_name); + #or + $derived_key = pbkdf1($password, $salt, $iteration_count); + #or + $derived_key = pbkdf1($password, $salt); + + # $password ......... input keying material (password) + # $salt ............. salt/nonce (expected length: 8) + # $iteration_count .. optional, DEFAULT: 5000 + # $hash_name ........ optional, DEFAULT: 'SHA256' + # $len .............. optional, derived key len, DEFAULT: 32 + +=head2 pbkdf2 + + $derived_key = pbkdf2($password, $salt, $iteration_count, $hash_name, $len); + #or + $derived_key = pbkdf2($password, $salt, $iteration_count, $hash_name); + #or + $derived_key = pbkdf2($password, $salt, $iteration_count); + #or + $derived_key = pbkdf2($password, $salt); + + # $password ......... input keying material (password) + # $salt ............. salt/nonce + # $iteration_count .. optional, DEFAULT: 5000 + # $hash_name ........ optional, DEFAULT: 'SHA256' + # $len .............. optional, derived key len, DEFAULT: 32 + +=head2 hkdf + + $okm2 = hkdf($password, $salt, $hash_name, $len, $info); + #or + $okm2 = hkdf($password, $salt, $hash_name, $len); + #or + $okm2 = hkdf($password, $salt, $hash_name); + #or + $okm2 = hkdf($password, $salt); + + # $password ... input keying material (password) + # $salt ....... salt/nonce, if undef defaults to HashLen zero octets + # $hash_name .. optional, DEFAULT: 'SHA256' + # $len ........ optional, derived key len, DEFAULT: 32 + # $info ....... optional context and application specific information, DEFAULT: '' + +=head2 hkdf_extract + + $prk = hkdf_extract($password, $salt, $hash_name); + #or + $prk = hkdf_extract($password, $salt, $hash_name); + + # $password ... input keying material (password) + # $salt ....... salt/nonce, if undef defaults to HashLen zero octets + # $hash_name .. optional, DEFAULT: 'SHA256' + + +=head2 hkdf_expand + + $okm = hkdf_expand($pseudokey, $hash_name, $len, $info); + #or + $okm = hkdf_expand($pseudokey, $hash_name, $len); + #or + $okm = hkdf_expand($pseudokey, $hash_name); + #or + $okm = hkdf_expand($pseudokey); + + # $pseudokey .. input keying material + # $hash_name .. optional, DEFAULT: 'SHA256' + # $len ........ optional, derived key len, DEFAULT: 32 + # $info ....... optional context and application specific information, DEFAULT: '' diff --git a/lib/Crypt/Mac.pm b/lib/Crypt/Mac.pm new file mode 100644 index 00000000..a52ae8a0 --- /dev/null +++ b/lib/Crypt/Mac.pm @@ -0,0 +1,53 @@ +package Crypt::Mac; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( mac mac_hex )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +sub add { + my $self = shift; + $self->_add_single($_) for (@_); + return $self; +} + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { + #filename + open($handle, "<", $file) || die "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { + #handle + $handle = $file + } + die "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->_add_single($buf) + } + die "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +__END__ + +=head1 NAME + +Crypt::mode - [internal only] + +=cut
\ No newline at end of file diff --git a/lib/Crypt/Mac/BLAKE2b.pm b/lib/Crypt/Mac/BLAKE2b.pm new file mode 100644 index 00000000..657a94c3 --- /dev/null +++ b/lib/Crypt/Mac/BLAKE2b.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::BLAKE2b; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b blake2b_hex blake2b_b64 blake2b_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +sub new { my $class = shift; _new(@_) } +sub blake2b { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->mac } +sub blake2b_hex { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->hexmac } +sub blake2b_b64 { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->b64mac } +sub blake2b_b64u { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::BLAKE2b - Message authentication code BLAKE2b MAC (RFC 7693) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::BLAKE2b qw( blake2b blake2b_hex ); + + # calculate MAC from string/buffer + $blake2b_raw = blake2b($size, $key, 'data buffer'); + $blake2b_hex = blake2b_hex($size, $key, 'data buffer'); + $blake2b_b64 = blake2b_b64($size, $key, 'data buffer'); + $blake2b_b64u = blake2b_b64u($size, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::BLAKE2b; + + $d = Crypt::Mac::BLAKE2b->new($size, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::BLAKE2b qw(blake2b blake2b_hex ); + +Or all of them at once: + + use Crypt::Mac::BLAKE2b ':all'; + +=head1 FUNCTIONS + +=head2 blake2b + +Logically joins all arguments into a single string, and returns its BLAKE2b message authentication code encoded as a binary string. + + $blake2b_raw = blake2b($size, $key, 'data buffer'); + #or + $blake2b_raw = blake2b($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2b_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b message authentication code encoded as a hexadecimal string. + + $blake2b_hex = blake2b_hex($size, $key, 'data buffer'); + #or + $blake2b_hex = blake2b_hex($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2b_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b message authentication code encoded as a Base64 string. + + $blake2b_b64 = blake2b_b64($size, $key, 'data buffer'); + #or + $blake2b_b64 = blake2b_b64($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2b_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_b64url = blake2b_b64u($size, $key, 'data buffer'); + #or + $blake2b_b64url = blake2b_b64u($size, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::BLAKE2b->new($size, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Mac/BLAKE2s.pm b/lib/Crypt/Mac/BLAKE2s.pm new file mode 100644 index 00000000..c696abc3 --- /dev/null +++ b/lib/Crypt/Mac/BLAKE2s.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::BLAKE2s; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s blake2s_hex blake2s_b64 blake2s_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +sub new { my $class = shift; _new(@_) } +sub blake2s { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->mac } +sub blake2s_hex { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->hexmac } +sub blake2s_b64 { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->b64mac } +sub blake2s_b64u { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::BLAKE2s - Message authentication code BLAKE2s MAC (RFC 7693) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::BLAKE2s qw( blake2s blake2s_hex ); + + # calculate MAC from string/buffer + $blake2s_raw = blake2s($size, $key, 'data buffer'); + $blake2s_hex = blake2s_hex($size, $key, 'data buffer'); + $blake2s_b64 = blake2s_b64($size, $key, 'data buffer'); + $blake2s_b64u = blake2s_b64u($size, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::BLAKE2s; + + $d = Crypt::Mac::BLAKE2s->new($size, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::BLAKE2s qw(blake2s blake2s_hex ); + +Or all of them at once: + + use Crypt::Mac::BLAKE2s ':all'; + +=head1 FUNCTIONS + +=head2 blake2s + +Logically joins all arguments into a single string, and returns its BLAKE2s message authentication code encoded as a binary string. + + $blake2s_raw = blake2s($size, $key, 'data buffer'); + #or + $blake2s_raw = blake2s($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2s_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s message authentication code encoded as a hexadecimal string. + + $blake2s_hex = blake2s_hex($size, $key, 'data buffer'); + #or + $blake2s_hex = blake2s_hex($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2s_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s message authentication code encoded as a Base64 string. + + $blake2s_b64 = blake2s_b64($size, $key, 'data buffer'); + #or + $blake2s_b64 = blake2s_b64($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2s_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_b64url = blake2s_b64u($size, $key, 'data buffer'); + #or + $blake2s_b64url = blake2s_b64u($size, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::BLAKE2s->new($size, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<https://tools.ietf.org/html/rfc7693|https://tools.ietf.org/html/rfc7693> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Mac/F9.pm b/lib/Crypt/Mac/F9.pm new file mode 100644 index 00000000..3caf72c6 --- /dev/null +++ b/lib/Crypt/Mac/F9.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::F9; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( f9 f9_hex f9_b64 f9_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub f9 { Crypt::Mac::F9->new(shift, shift)->add(@_)->mac } +sub f9_hex { Crypt::Mac::F9->new(shift, shift)->add(@_)->hexmac } +sub f9_b64 { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64mac } +sub f9_b64u { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::F9 - Message authentication code F9 + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::F9 qw( f9 f9_hex ); + + # calculate MAC from string/buffer + $f9_raw = f9($cipher_name, $key, 'data buffer'); + $f9_hex = f9_hex($cipher_name, $key, 'data buffer'); + $f9_b64 = f9_b64($cipher_name, $key, 'data buffer'); + $f9_b64u = f9_b64u($cipher_name, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::F9; + + $d = Crypt::Mac::F9->new($cipher_name, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the F9 message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::F9 qw(f9 f9_hex ); + +Or all of them at once: + + use Crypt::Mac::F9 ':all'; + +=head1 FUNCTIONS + +=head2 f9 + +Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a binary string. + + $f9_raw = f9($cipher_name, $key, 'data buffer'); + #or + $f9_raw = f9($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 f9_hex + +Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a hexadecimal string. + + $f9_hex = f9_hex($cipher_name, $key, 'data buffer'); + #or + $f9_hex = f9_hex($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 f9_b64 + +Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a Base64 string. + + $f9_b64 = f9_b64($cipher_name, $key, 'data buffer'); + #or + $f9_b64 = f9_b64($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 f9_b64u + +Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $f9_b64url = f9_b64u($cipher_name, $key, 'data buffer'); + #or + $f9_b64url = f9_b64u($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::F9->new($cipher_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Mac/HMAC.pm b/lib/Crypt/Mac/HMAC.pm new file mode 100644 index 00000000..8a2567f3 --- /dev/null +++ b/lib/Crypt/Mac/HMAC.pm @@ -0,0 +1,160 @@ +package Crypt::Mac::HMAC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( hmac hmac_hex hmac_b64 hmac_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Digest; + +sub new { my $class = shift; _new(Crypt::Digest::_trans_digest_name(shift), @_) } +sub hmac { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->mac } +sub hmac_hex { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->hexmac } +sub hmac_b64 { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64mac } +sub hmac_b64u { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::HMAC - Message authentication code HMAC + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::HMAC qw( hmac hmac_hex ); + + # calculate MAC from string/buffer + $hmac_raw = hmac('SHA256', $key, 'data buffer'); + $hmac_hex = hmac_hex('SHA256', $key, 'data buffer'); + $hmac_b64 = hmac_b64('SHA256', $key, 'data buffer'); + $hmac_b64u = hmac_b64u('SHA256', $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::HMAC; + + $d = Crypt::Mac::HMAC->new('SHA256', $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the HMAC message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::HMAC qw(hmac hmac_hex ); + +Or all of them at once: + + use Crypt::Mac::HMAC ':all'; + +=head1 FUNCTIONS + +=head2 hmac + +Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a binary string. + + $hmac_raw = hmac($hash_name, $key, 'data buffer'); + #or + $hmac_raw = hmac($hash_name, $key, 'any data', 'more data', 'even more data'); + +=head2 hmac_hex + +Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a hexadecimal string. + + $hmac_hex = hmac_hex($hash_name, $key, 'data buffer'); + #or + $hmac_hex = hmac_hex($hash_name, $key, 'any data', 'more data', 'even more data'); + +=head2 hmac_b64 + +Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a Base64 string. + + $hmac_b64 = hmac_b64($hash_name, $key, 'data buffer'); + #or + $hmac_b64 = hmac_b64($hash_name, $key, 'any data', 'more data', 'even more data'); + +=head2 hmac_b64u + +Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $hmac_b64url = hmac_b64u($hash_name, $key, 'data buffer'); + #or + $hmac_b64url = hmac_b64u($hash_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::HMAC->new($hash_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<https://en.wikipedia.org/wiki/Hmac|https://en.wikipedia.org/wiki/Hmac> + +=item * L<https://tools.ietf.org/html/rfc2104|https://tools.ietf.org/html/rfc2104> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Mac/OMAC.pm b/lib/Crypt/Mac/OMAC.pm new file mode 100644 index 00000000..3d752f07 --- /dev/null +++ b/lib/Crypt/Mac/OMAC.pm @@ -0,0 +1,158 @@ +package Crypt::Mac::OMAC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( omac omac_hex omac_b64 omac_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub omac { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->mac } +sub omac_hex { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->hexmac } +sub omac_b64 { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64mac } +sub omac_b64u { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::OMAC - Message authentication code OMAC + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::OMAC qw( omac omac_hex ); + + # calculate MAC from string/buffer + $omac_raw = omac($cipher_name, $key, 'data buffer'); + $omac_hex = omac_hex($cipher_name, $key, 'data buffer'); + $omac_b64 = omac_b64($cipher_name, $key, 'data buffer'); + $omac_b64u = omac_b64u($cipher_name, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::OMAC; + + $d = Crypt::Mac::OMAC->new($cipher_name, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the OMAC message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::OMAC qw(omac omac_hex ); + +Or all of them at once: + + use Crypt::Mac::OMAC ':all'; + +=head1 FUNCTIONS + +=head2 omac + +Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a binary string. + + $omac_raw = omac($cipher_name, $key, 'data buffer'); + #or + $omac_raw = omac($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 omac_hex + +Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a hexadecimal string. + + $omac_hex = omac_hex($cipher_name, $key, 'data buffer'); + #or + $omac_hex = omac_hex($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 omac_b64 + +Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a Base64 string. + + $omac_b64 = omac_b64($cipher_name, $key, 'data buffer'); + #or + $omac_b64 = omac_b64($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 omac_b64u + +Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $omac_b64url = omac_b64u($cipher_name, $key, 'data buffer'); + #or + $omac_b64url = omac_b64u($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::OMAC->new($cipher_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<https://en.wikipedia.org/wiki/OMAC_%28cryptography%29|https://en.wikipedia.org/wiki/OMAC_%28cryptography%29> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Mac/PMAC.pm b/lib/Crypt/Mac/PMAC.pm new file mode 100644 index 00000000..04917ded --- /dev/null +++ b/lib/Crypt/Mac/PMAC.pm @@ -0,0 +1,158 @@ +package Crypt::Mac::PMAC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( pmac pmac_hex pmac_b64 pmac_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub pmac { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->mac } +sub pmac_hex { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->hexmac } +sub pmac_b64 { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64mac } +sub pmac_b64u { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::PMAC - Message authentication code PMAC + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::PMAC qw( pmac pmac_hex ); + + # calculate MAC from string/buffer + $pmac_raw = pmac($cipher_name, $key, 'data buffer'); + $pmac_hex = pmac_hex($cipher_name, $key, 'data buffer'); + $pmac_b64 = pmac_b64($cipher_name, $key, 'data buffer'); + $pmac_b64u = pmac_b64u($cipher_name, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::PMAC; + + $d = Crypt::Mac::PMAC->new($cipher_name, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the PMAC message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::PMAC qw(pmac pmac_hex ); + +Or all of them at once: + + use Crypt::Mac::PMAC ':all'; + +=head1 FUNCTIONS + +=head2 pmac + +Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a binary string. + + $pmac_raw = pmac($cipher_name, $key, 'data buffer'); + #or + $pmac_raw = pmac($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 pmac_hex + +Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a hexadecimal string. + + $pmac_hex = pmac_hex($cipher_name, $key, 'data buffer'); + #or + $pmac_hex = pmac_hex($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 pmac_b64 + +Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a Base64 string. + + $pmac_b64 = pmac_b64($cipher_name, $key, 'data buffer'); + #or + $pmac_b64 = pmac_b64($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 pmac_b64u + +Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $pmac_b64url = pmac_b64u($cipher_name, $key, 'data buffer'); + #or + $pmac_b64url = pmac_b64u($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::PMAC->new($cipher_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<https://en.wikipedia.org/wiki/PMAC_%28cryptography%29|https://en.wikipedia.org/wiki/PMAC_%28cryptography%29> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Mac/Pelican.pm b/lib/Crypt/Mac/Pelican.pm new file mode 100644 index 00000000..374b5c99 --- /dev/null +++ b/lib/Crypt/Mac/Pelican.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::Pelican; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( pelican pelican_hex pelican_b64 pelican_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +sub new { my $class = shift; _new(@_) } +sub pelican { Crypt::Mac::Pelican->new(shift)->add(@_)->mac } +sub pelican_hex { Crypt::Mac::Pelican->new(shift)->add(@_)->hexmac } +sub pelican_b64 { Crypt::Mac::Pelican->new(shift)->add(@_)->b64mac } +sub pelican_b64u { Crypt::Mac::Pelican->new(shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::Pelican - Message authentication code Pelican (AES based MAC) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::Pelican qw( pelican pelican_hex ); + + # calculate MAC from string/buffer + $pelican_raw = pelican($key, 'data buffer'); + $pelican_hex = pelican_hex($key, 'data buffer'); + $pelican_b64 = pelican_b64($key, 'data buffer'); + $pelican_b64u = pelican_b64u($key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::Pelican; + + $d = Crypt::Mac::Pelican->new($key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Pelican message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::Pelican qw(pelican pelican_hex ); + +Or all of them at once: + + use Crypt::Mac::Pelican ':all'; + +=head1 FUNCTIONS + +=head2 pelican + +Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a binary string. + + $pelican_raw = pelican($key, 'data buffer'); + #or + $pelican_raw = pelican($key, 'any data', 'more data', 'even more data'); + +=head2 pelican_hex + +Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a hexadecimal string. + + $pelican_hex = pelican_hex($key, 'data buffer'); + #or + $pelican_hex = pelican_hex($key, 'any data', 'more data', 'even more data'); + +=head2 pelican_b64 + +Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a Base64 string. + + $pelican_b64 = pelican_b64($key, 'data buffer'); + #or + $pelican_b64 = pelican_b64($key, 'any data', 'more data', 'even more data'); + +=head2 pelican_b64u + +Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $pelican_b64url = pelican_b64u($key, 'data buffer'); + #or + $pelican_b64url = pelican_b64u($key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::Pelican->new($key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<http://eprint.iacr.org/2005/088.pdf|http://eprint.iacr.org/2005/088.pdf> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Mac/Poly1305.pm b/lib/Crypt/Mac/Poly1305.pm new file mode 100644 index 00000000..1d9bf08f --- /dev/null +++ b/lib/Crypt/Mac/Poly1305.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::Poly1305; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( poly1305 poly1305_hex poly1305_b64 poly1305_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +sub new { my $class = shift; _new(@_) } +sub poly1305 { Crypt::Mac::Poly1305->new(shift)->add(@_)->mac } +sub poly1305_hex { Crypt::Mac::Poly1305->new(shift)->add(@_)->hexmac } +sub poly1305_b64 { Crypt::Mac::Poly1305->new(shift)->add(@_)->b64mac } +sub poly1305_b64u { Crypt::Mac::Poly1305->new(shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::Poly1305 - Message authentication code Poly1305 (RFC 7539) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::Poly1305 qw( poly1305 poly1305_hex ); + + # calculate MAC from string/buffer + $poly1305_raw = poly1305($key, 'data buffer'); + $poly1305_hex = poly1305_hex($key, 'data buffer'); + $poly1305_b64 = poly1305_b64($key, 'data buffer'); + $poly1305_b64u = poly1305_b64u($key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::Poly1305; + + $d = Crypt::Mac::Poly1305->new($key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Poly1305 message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::Poly1305 qw(poly1305 poly1305_hex ); + +Or all of them at once: + + use Crypt::Mac::Poly1305 ':all'; + +=head1 FUNCTIONS + +=head2 poly1305 + +Logically joins all arguments into a single string, and returns its Poly1305 message authentication code encoded as a binary string. + + $poly1305_raw = poly1305($key, 'data buffer'); + #or + $poly1305_raw = poly1305($key, 'any data', 'more data', 'even more data'); + +=head2 poly1305_hex + +Logically joins all arguments into a single string, and returns its Poly1305 message authentication code encoded as a hexadecimal string. + + $poly1305_hex = poly1305_hex($key, 'data buffer'); + #or + $poly1305_hex = poly1305_hex($key, 'any data', 'more data', 'even more data'); + +=head2 poly1305_b64 + +Logically joins all arguments into a single string, and returns its Poly1305 message authentication code encoded as a Base64 string. + + $poly1305_b64 = poly1305_b64($key, 'data buffer'); + #or + $poly1305_b64 = poly1305_b64($key, 'any data', 'more data', 'even more data'); + +=head2 poly1305_b64u + +Logically joins all arguments into a single string, and returns its Poly1305 message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $poly1305_b64url = poly1305_b64u($key, 'data buffer'); + #or + $poly1305_b64url = poly1305_b64u($key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::Poly1305->new($key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<https://www.ietf.org/rfc/rfc7539.txt|https://www.ietf.org/rfc/rfc7539.txt> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Mac/XCBC.pm b/lib/Crypt/Mac/XCBC.pm new file mode 100644 index 00000000..61da2248 --- /dev/null +++ b/lib/Crypt/Mac/XCBC.pm @@ -0,0 +1,158 @@ +package Crypt::Mac::XCBC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( xcbc xcbc_hex xcbc_b64 xcbc_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub xcbc { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->mac } +sub xcbc_hex { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->hexmac } +sub xcbc_b64 { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64mac } +sub xcbc_b64u { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::XCBC - Message authentication code XCBC (RFC 3566) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::XCBC qw( xcbc xcbc_hex ); + + # calculate MAC from string/buffer + $xcbc_raw = xcbc($cipher_name, $key, 'data buffer'); + $xcbc_hex = xcbc_hex($cipher_name, $key, 'data buffer'); + $xcbc_b64 = xcbc_b64($cipher_name, $key, 'data buffer'); + $xcbc_b64u = xcbc_b64u($cipher_name, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::XCBC; + + $d = Crypt::Mac::XCBC->new($cipher_name, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the XCBC message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::XCBC qw(xcbc xcbc_hex ); + +Or all of them at once: + + use Crypt::Mac::XCBC ':all'; + +=head1 FUNCTIONS + +=head2 xcbc + +Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a binary string. + + $xcbc_raw = xcbc($cipher_name, $key, 'data buffer'); + #or + $xcbc_raw = xcbc($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 xcbc_hex + +Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a hexadecimal string. + + $xcbc_hex = xcbc_hex($cipher_name, $key, 'data buffer'); + #or + $xcbc_hex = xcbc_hex($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 xcbc_b64 + +Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a Base64 string. + + $xcbc_b64 = xcbc_b64($cipher_name, $key, 'data buffer'); + #or + $xcbc_b64 = xcbc_b64($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 xcbc_b64u + +Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $xcbc_b64url = xcbc_b64u($cipher_name, $key, 'data buffer'); + #or + $xcbc_b64url = xcbc_b64u($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::XCBC->new($cipher_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=item * L<https://www.ietf.org/rfc/rfc3566.txt|https://www.ietf.org/rfc/rfc3566.txt> + +=back + +=cut + +__END__
\ No newline at end of file diff --git a/lib/Crypt/Misc.pm b/lib/Crypt/Misc.pm new file mode 100644 index 00000000..74cea07e --- /dev/null +++ b/lib/Crypt/Misc.pm @@ -0,0 +1,363 @@ +package Crypt::Misc; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 5.57 'import'; +use Carp 'croak'; +our %EXPORT_TAGS = ( all => [qw(encode_b64 decode_b64 encode_b64u decode_b64u + pem_to_der der_to_pem + read_rawfile write_rawfile + slow_eq is_v4uuid random_v4uuid + increment_octets_be increment_octets_le + )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp 'carp'; +use CryptX; +use Crypt::Digest 'digest_data'; +use Crypt::Mode::CBC; +use Crypt::Mode::CFB; +use Crypt::Mode::ECB; +use Crypt::Mode::OFB; +use Crypt::Cipher; +use Crypt::PRNG 'random_bytes'; + +sub encode_b64 { + CryptX::_encode_base64(@_); +} + +sub decode_b64 { + CryptX::_decode_base64(@_); +} + +sub encode_b64u { + CryptX::_encode_base64url(@_); +} + +sub decode_b64u { + CryptX::_decode_base64url(@_); +} + +sub increment_octets_be { + CryptX::_increment_octets_be(@_); + #$_[0] = CryptX::_increment_octets_be($_[0]); +} + +sub increment_octets_le { + CryptX::_increment_octets_le(@_); + #$_[0] = CryptX::_increment_octets_le($_[0]); +} + +sub pem_to_der { + my ($data, $password) = @_; + + my ($begin, $obj1, $content, $end, $obj2) = $data =~ m/(----[- ]BEGIN ([^\r\n\-]+KEY)[ -]----)(.*?)(----[- ]END ([^\r\n\-]+)[ -]----)/s; + return undef unless $content; + + $content =~ s/^\s+//sg; + $content =~ s/\s+$//sg; + $content =~ s/\r\n/\n/sg; # CR-LF >> LF + $content =~ s/\r/\n/sg; # CR >> LF + $content =~ s/\\\n//sg; # \ + LF + + my ($headers, undef, $b64) = $content =~ /^(([^:]+:.*?\n)*)(.*)$/s; + return undef unless $b64; + + my $binary = decode_b64($b64); + return undef unless $binary; + + my ($ptype, $cipher_name, $iv_hex); + for my $h (split /\n/, ($headers||'')) { + my ($k, $v) = split /:\s*/, $h, 2; + $ptype = $v if $k eq 'Proc-Type'; + ($cipher_name, $iv_hex) = $v =~ /^\s*(.*?)\s*,\s*([0-9a-fA-F]+)\s*$/ if $k eq 'DEK-Info'; + } + if ($cipher_name && $iv_hex && $ptype && $ptype eq '4,ENCRYPTED') { + croak "FATAL: encrypted PEM but no password provided" unless defined $password; + my $iv = pack("H*", $iv_hex); + my ($mode, $klen) = _name2mode($cipher_name); + my $key = _password2key($password, $klen, $iv, 'MD5'); + return $mode->decrypt($binary, $key, $iv); + } + return $binary; +} + +sub der_to_pem { + my ($data, $header_name, $password, $cipher_name) = @_; + my $content = $data; + my @headers; + + if ($password) { + $cipher_name ||= 'AES-256-CBC'; + my ($mode, $klen, $ilen) = _name2mode($cipher_name); + my $iv = random_bytes($ilen); + my $key = _password2key($password, $klen, $iv, 'MD5'); + $content = $mode->encrypt($data, $key, $iv); + push @headers, 'Proc-Type: 4,ENCRYPTED', "DEK-Info: ".uc($cipher_name).",".unpack("H*", $iv); + } + + my $pem = "-----BEGIN $header_name-----\n"; + if (@headers) { + $pem .= "$_\n" for @headers; + $pem .= "\n"; + } + my @l = encode_b64($content) =~ /.{1,64}/g; + $pem .= join("\n", @l) . "\n"; + $pem .= "-----END $header_name-----\n"; + return $pem; +} + +sub read_rawfile { + my $f = shift; + croak "FATAL: read_rawfile() non-existing file '$f'" unless -f $f; + open my $fh, "<", $f or croak "FATAL: read_rawfile() cannot open file '$f': $!"; + binmode $fh; + return do { local $/; <$fh> }; +} + +sub write_rawfile { + # write_rawfile($filename, $data); + croak "FATAL: write_rawfile() no data" unless defined $_[1]; + open my $fh, ">", $_[0] or croak "FATAL: write_rawfile() cannot open file '$_[0]': $!"; + binmode $fh; + print $fh $_[1] or croak "FATAL: write_rawfile() cannot write to '$_[0]': $!"; + close $fh or croak "FATAL: write_rawfile() cannot close '$_[0]': $!"; + return; +} + +sub slow_eq { + my ($a, $b) = @_; + return unless defined $a && defined $b; + my $diff = length $a ^ length $b; + for(my $i = 0; $i < length $a && $i < length $b; $i++) { + $diff |= ord(substr $a, $i) ^ ord(substr $b, $i); + } + return $diff == 0; +} + +sub random_v4uuid() { + # Version 4 - random - UUID: xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx + # where x is any hexadecimal digit and Y is one of 8, 9, A, B (1000, 1001, 1010, 1011) + # e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479 + my $raw = random_bytes(16); + # xxxxxxxxxxxx4xxxYxxxxxxxxxxxxxxx + $raw &= pack("H*", "FFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFF"); + $raw |= pack("H*", "00000000000040000000000000000000"); + $raw &= pack("H*", "FFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFF"); # 0x3 == 0011b + $raw |= pack("H*", "00000000000000008000000000000000"); # 0x8 == 1000b + my $hex = unpack("H*", $raw); + $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*$/$1-$2-$3-$4-$5/; + return $hex; +} + +sub is_v4uuid($) { + my $uuid = shift; + return 0 if !$uuid; + return 1 if $uuid =~ /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return 0; +} + +### private functions + +sub _name2mode { + my $cipher_name = uc(shift); + my %trans = ( 'DES-EDE3' => 'DES_EDE' ); + + my ($cipher, undef, $klen, $mode) = $cipher_name =~ /^(AES|CAMELLIA|DES|DES-EDE3|SEED)(-(\d+))?-(CBC|CFB|ECB|OFB)$/i; + croak "FATAL: unsupported cipher '$cipher_name'" unless $cipher && $mode; + $cipher = $trans{$cipher} || $cipher; + $klen = $klen ? int($klen/8) : Crypt::Cipher::min_keysize($cipher); + my $ilen = Crypt::Cipher::blocksize($cipher); + croak "FATAL: unsupported cipher '$cipher_name'" unless $klen && $ilen; + + return (Crypt::Mode::CBC->new($cipher), $klen, $ilen) if $mode eq 'CBC'; + return (Crypt::Mode::CFB->new($cipher), $klen, $ilen) if $mode eq 'CFB'; + return (Crypt::Mode::ECB->new($cipher), $klen, $ilen) if $mode eq 'ECB'; + return (Crypt::Mode::OFB->new($cipher), $klen, $ilen) if $mode eq 'OFB'; +} + +sub _password2key { + my ($password, $klen, $iv, $hash) = @_; + my $salt = substr($iv, 0, 8); + my $key = ''; + while (length($key) < $klen) { + $key .= digest_data($hash, $key . $password . $salt); + } + return substr($key, 0, $klen); +} + +1; + +=pod + +=head1 NAME + +Crypt::Misc - miscellaneous functions related to (or used by) CryptX + +=head1 SYNOPSIS + +This module contains a collection of mostly unsorted functions loosely-related to CryptX distribution but not implementing cryptography. + +Most of them are also available in other perl modules but once you utilize CryptX you might avoid dependencies on other modules by using +functions from Crypt::Misc. + +=head1 DESCRIPTION + + use Crypt::Misc ':all'; + + # Base64 and Base64/URL-safe functions + $base64 = encode_b64($rawbytes); + $rawbytes = decode_b64($base64); + $base64url = encode_b64u($encode_b64u); + $rawbytes = decode_b64u($base64url); + + # read/write file + $rawdata = read_rawfile($filename); + write_rawfile($filename, $rawdata); + + # convert PEM/DER + $der_data = pem_to_der($pem_data); + $pem_data = der_to_pem($der_data); + + # others + die "mismatch" unless slow_eq($str1, $str2); + +=head1 FUNCTIONS + +By default, Crypt::Misc doesn't import any function. You can import individual functions like this: + + use Crypt::Misc qw(read_rawfile); + +Or import all available functions: + + use Crypt::Misc ':all'; + +=head2 encode_b64 + +I<Since: CryptX-0.029> + + $base64string = encode_b64($rawdata); + +Encode $rawbytes into Base64 string, no line-endings in the output string. + +=head2 decode_b64 + +I<Since: CryptX-0.029> + + $rawdata = encode_b64($base64string); + +Decode a Base64 string. + +=head2 encode_b64u + +I<Since: CryptX-0.029> + + $base64url_string = encode_b64($rawdata); + +Encode $rawbytes into Base64/URL-Safe string, no line-endings in the output string. + +=head2 decode_b64u + +I<Since: CryptX-0.029> + + $rawdata = encode_b64($base64url_string); + +Decode a Base64/URL-Safe string. + +=head2 read_rawfile + +I<Since: CryptX-0.029> + + $rawdata = read_rawfile($filename); + +Read file C<$filename> into a scalar as a binary data (without decoding/transformation). + +=head2 write_rawfile + +I<Since: CryptX-0.029> + + write_rawfile($filename, $rawdata); + +Write C<$rawdata> to file <$filename> as binary data. + +=head2 slow_eq + +I<Since: CryptX-0.029> + + if (slow_eq($data1, $data2)) { ... } + +Constant time compare (to avoid timing side-channel). + +=head2 pem_to_der + +I<Since: CryptX-0.029> + + $der_data = pem_to_der($pem_data); + #or + $der_data = pem_to_der($pem_data, $password); + +Convert PEM to DER representation. Supports also password protected PEM data. + +=head2 der_to_pem + +I<Since: CryptX-0.029> + + $pem_data = der_to_pem($pem_data, $header_name); + #or + $pem_data = der_to_pem($pem_data, $header_name, $password); + #or + $pem_data = der_to_pem($pem_data, $header_name, $passord, $cipher_name); + + # $header_name e.g. "PUBLIC KEY", "RSA PRIVATE KEY" ... + # $cipher_name e.g. "DES-EDE3-CBC", "AES-256-CBC" (DEFAULT) ... + +Convert DER to PEM representation. Supports also password protected PEM data. + +=head2 random_v4uuid + +I<Since: CryptX-0.031> + + my $uuid = random_v4uuid(); + +Returns cryptographically strong Version 4 random UUID: C<xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx> +where C<x> is any hexadecimal digit and C<Y> is one of 8, 9, A, B (1000, 1001, 1010, 1011) +e.g. C<f47ac10b-58cc-4372-a567-0e02b2c3d479>. + +=head2 is_v4uuid + +I<Since: CryptX-0.031> + + if (is_v4uuid($uuid)) { + ... + } + +Checks the given C<$uuid> string whether it matches V4 UUID format and returns C<0> (mismatch) or C<1> (match). + +=head2 increment_octets_le + +I<Since: CryptX-0.048> + + $octects = increment_octets_le($octets); + +Take input C<$octets> as a little-endian big number and return an increment. + +=head2 increment_octets_be + +I<Since: CryptX-0.048> + + $octects = increment_octets_be($octets); + +Take input C<$octets> as a big-endian big number and return an increment. + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX> + +=back + +=cut diff --git a/lib/Crypt/Mode.pm b/lib/Crypt/Mode.pm new file mode 100644 index 00000000..0db6b5b9 --- /dev/null +++ b/lib/Crypt/Mode.pm @@ -0,0 +1,72 @@ +package Crypt::Mode; + +use strict; +use warnings; +our $VERSION = '0.048'; + +### METHODS + +sub new { die } # overriden in subclass + +sub encrypt { + my ($self, $pt) = (shift, shift); + $self->_start(1, @_); + return $self->add($pt) . $self->finish; +} + +sub decrypt { + my ($self, $ct) = (shift, shift); + $self->_start(-1, @_); + return $self->add($ct) . $self->finish; +} + +sub start_encrypt { + my $self = shift; + $self->_start(1, @_); + return $self; +} + +sub start_decrypt { + my $self = shift; + $self->_start(-1, @_); + return $self; +} + +sub finish { + shift->_finish(@_); +} + +sub add { + my $self = shift; + my $rv = ''; + $rv .= $self->_crypt($_) for (@_); + return $rv; +} + +sub _crypt { + my $self = shift; + my $dir = $self->_get_dir; + return $self->_encrypt(@_) if $dir == 1; + return $self->_decrypt(@_) if $dir == -1; + return; +} + +sub _finish { + my $self = shift; + my $dir = $self->_get_dir; + return $self->_finish_enc(@_) if $dir == 1; + return $self->_finish_dec(@_) if $dir == -1; + return; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +__END__ + +=head1 NAME + +Crypt::Mode - [internal only] + +=cut
\ No newline at end of file diff --git a/lib/Crypt/Mode/CBC.pm b/lib/Crypt/Mode/CBC.pm new file mode 100644 index 00000000..be15194a --- /dev/null +++ b/lib/Crypt/Mode/CBC.pm @@ -0,0 +1,108 @@ +package Crypt::Mode::CBC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::CBC - Block cipher mode CBC [Cipher-block chaining] + +=head1 SYNOPSIS + + use Crypt::Mode::CBC; + my $m = Crypt::Mode::CBC->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + $ciphertext .= $m->finish; + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + $plaintext .= $m->finish; + +=head1 DESCRIPTION + +This module implements CBC cipher mode. B<NOTE:> it works only with ciphers from L<CryptX> (Crypt::Cipher::NNNN). + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::CBC->new('AES'); + #or + my $m = Crypt::Mode::CBC->new('AES', $padding); + #or + my $m = Crypt::Mode::CBC->new('AES', $padding, $cipher_rounds); + + # $padding .... 0 no padding (plaintext size has to be myltiple of block length) + # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT + # 2 Crypt::CBC's "oneandzeroes" + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + +=head2 start_encrypt + +See example below L</finish>. + +=head2 start_decrypt + +See example below L</finish>. + +=head2 add + +See example below L</finish>. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + $ciphertext .= $m->finish; + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + $plaintext .= $m->finish; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<Crypt::Cipher::AES|Crypt::Cipher::AES>, L<Crypt::Cipher::Blowfish|Crypt::Cipher::Blowfish>, ... + +=item * L<https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29|https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29> + +=back diff --git a/lib/Crypt/Mode/CFB.pm b/lib/Crypt/Mode/CFB.pm new file mode 100644 index 00000000..6dc55f47 --- /dev/null +++ b/lib/Crypt/Mode/CFB.pm @@ -0,0 +1,99 @@ +package Crypt::Mode::CFB; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::CFB - Block cipher mode CFB [Cipher feedback] + +=head1 SYNOPSIS + + use Crypt::Mode::CFB; + my $m = Crypt::Mode::CFB->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 DESCRIPTION + +This module implements CFB cipher mode. B<NOTE:> it works only with ciphers from L<CryptX> (Crypt::Cipher::NNNN). + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::CFB->new('AES'); + #or + my $m = Crypt::Mode::CFB->new('AES', $cipher_rounds); + + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + +=head2 start_encrypt + +See example below L</finish>. + +=head2 start_decrypt + +See example below L</finish>. + +=head2 add + +See example below L</finish>. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<Crypt::Cipher::AES|Crypt::Cipher::AES>, L<Crypt::Cipher::Blowfish|Crypt::Cipher::Blowfish>, ... + +=item * L<https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_.28CFB.29|https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_.28CFB.29> + +=back diff --git a/lib/Crypt/Mode/CTR.pm b/lib/Crypt/Mode/CTR.pm new file mode 100644 index 00000000..060e8140 --- /dev/null +++ b/lib/Crypt/Mode/CTR.pm @@ -0,0 +1,106 @@ +package Crypt::Mode::CTR; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::CTR - Block cipher mode CTR [Counter mode] + +=head1 SYNOPSIS + + use Crypt::Mode::CTR; + my $m = Crypt::Mode::CTR->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 DESCRIPTION + +This module implements CTR cipher mode. B<NOTE:> it works only with ciphers from L<CryptX> (Crypt::Cipher::NNNN). + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::CTR->new($cipher_name); + #or + my $m = Crypt::Mode::CTR->new($cipher_name, $ctr_mode, $ctr_width); + #or + my $m = Crypt::Mode::CTR->new($cipher_name, $ctr_mode, $ctr_width, $cipher_rounds); + + # $ctr_mode .... 0 little-endian counter (DEFAULT) + # 1 big-endian counter + # 2 little-endian + RFC3686 incrementing + # 3 big-endian + RFC3686 incrementing + # $ctr_width ... counter width in bytes (DEFAULT = full block width) + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + +=head2 start_encrypt + +See example below L</finish>. + +=head2 start_decrypt + +See example below L</finish>. + +=head2 add + +See example below L</finish>. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<Crypt::Cipher::AES|Crypt::Cipher::AES>, L<Crypt::Cipher::Blowfish|Crypt::Cipher::Blowfish>, ... + +=item * L<https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29|https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29> + +=back diff --git a/lib/Crypt/Mode/ECB.pm b/lib/Crypt/Mode/ECB.pm new file mode 100644 index 00000000..2fa877e7 --- /dev/null +++ b/lib/Crypt/Mode/ECB.pm @@ -0,0 +1,109 @@ +package Crypt::Mode::ECB; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::ECB - Block cipher mode ECB [Electronic codebook] + +=head1 SYNOPSIS + + use Crypt::Mode::ECB; + my $m = Crypt::Mode::ECB->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key); + my $plaintext = $m->decrypt($ciphertext, $key); + + #encrypt more chunks + $m->start_encrypt($key); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + $ciphertext .= $m->finish; + + #decrypt more chunks + $m->start_decrypt($key); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + $plaintext .= $m->finish; + +=head1 DESCRIPTION + +This module implements ECB cipher mode. B<NOTE:> it works only with ciphers from L<CryptX> (Crypt::Cipher::NNNN). +B<BEWARE: ECB is inherently insecure>, if you are not sure go for L<Crypt::Mode::CBC>! + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::ECB->new('AES'); + #or + my $m = Crypt::Mode::ECB->new('AES', $padding); + #or + my $m = Crypt::Mode::ECB->new('AES', $padding, $cipher_rounds); + + # $padding .... 0 no padding (plaintext size has to be myltiple of block length) + # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT + # 2 Crypt::CBC's "oneandzeroes" + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key); + +=head2 start_encrypt + +See example below L</finish>. + +=head2 start_decrypt + +See example below L</finish>. + +=head2 add + +See example below L</finish>. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + $ciphertext .= $m->finish; + + #decrypt more chunks + $m->start_decrypt($key); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + $plaintext .= $m->finish; + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<Crypt::Cipher::AES|Crypt::Cipher::AES>, L<Crypt::Cipher::Blowfish|Crypt::Cipher::Blowfish>, ... + +=item * L<https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29|https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29> + +=back diff --git a/lib/Crypt/Mode/OFB.pm b/lib/Crypt/Mode/OFB.pm new file mode 100644 index 00000000..efd888ed --- /dev/null +++ b/lib/Crypt/Mode/OFB.pm @@ -0,0 +1,99 @@ +package Crypt::Mode::OFB; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::OFB - Block cipher mode OFB [Output feedback] + +=head1 SYNOPSIS + + use Crypt::Mode::OFB; + my $m = Crypt::Mode::OFB->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 DESCRIPTION + +This module implements OFB cipher mode. B<NOTE:> it works only with ciphers from L<CryptX> (Crypt::Cipher::NNNN). + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::OFB->new('AES'); + #or + my $m = Crypt::Mode::OFB->new('AES', $cipher_rounds); + + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + +=head2 start_encrypt + +See example below L</finish>. + +=head2 start_decrypt + +See example below L</finish>. + +=head2 add + +See example below L</finish>. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Cipher|Crypt::Cipher> + +=item * L<Crypt::Cipher::AES|Crypt::Cipher::AES>, L<Crypt::Cipher::Blowfish|Crypt::Cipher::Blowfish>, ... + +=item * L<https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_feedback_.28OFB.29|https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_feedback_.28OFB.29> + +=back diff --git a/lib/Crypt/PK.pm b/lib/Crypt/PK.pm new file mode 100644 index 00000000..c240ab4c --- /dev/null +++ b/lib/Crypt/PK.pm @@ -0,0 +1,33 @@ +package Crypt::PK; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Carp; + +sub _ssh_parse { + my $raw = shift; + return unless defined $raw; + my $len = length($raw); + my @parts = (); + my $i = 0; + while (1) { + last unless $i + 4 <= $len; + my $part_len = unpack("N4", substr($raw, $i, 4)); + last unless $i + 4 + $part_len <= $len; + push @parts, substr($raw, $i + 4, $part_len); + $i += $part_len + 4; + } + return @parts; +} + +1; + +__END__ + +=head1 NAME + +Crypt::PK - [internal only] + +=cut
\ No newline at end of file diff --git a/lib/Crypt/PK/DH.pm b/lib/Crypt/PK/DH.pm new file mode 100644 index 00000000..445aea48 --- /dev/null +++ b/lib/Crypt/PK/DH.pm @@ -0,0 +1,643 @@ +package Crypt::PK::DH; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( dh_encrypt dh_decrypt dh_sign_message dh_verify_message dh_sign_hash dh_verify_hash dh_shared_secret )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use CryptX; +use Crypt::Digest 'digest_data'; +use Crypt::Misc qw(read_rawfile); + +my %DH_PARAMS = ( + ike768 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF' + }, + ike1024 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381'. + 'FFFFFFFFFFFFFFFF' + }, + ike1536 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF' + }, + ike2048 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AACAA68FFFFFFFFFFFFFFFF' + }, + ike3072 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'. + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'. + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'. + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'. + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'. + '43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF' + }, + ike4096 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'. + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'. + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'. + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'. + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'. + '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'. + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'. + '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'. + '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'. + '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'. + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199'. + 'FFFFFFFFFFFFFFFF' + }, + ike6144 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'. + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'. + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'. + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'. + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'. + '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'. + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'. + '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'. + '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'. + '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'. + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492'. + '36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD'. + 'F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831'. + '179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B'. + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF'. + '5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6'. + 'D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3'. + '23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA'. + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328'. + '06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C'. + 'DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE'. + '12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF' + }, + ike8192 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'. + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'. + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'. + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'. + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'. + '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'. + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'. + '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'. + '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'. + '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'. + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492'. + '36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD'. + 'F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831'. + '179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B'. + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF'. + '5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6'. + 'D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3'. + '23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA'. + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328'. + '06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C'. + 'DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE'. + '12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4'. + '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300'. + '741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568'. + '3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9'. + '22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B'. + '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A'. + '062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36'. + '4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1'. + 'B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92'. + '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47'. + '9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71'. + '60C980DD98EDD3DFFFFFFFFFFFFFFFFF' + } +); + +sub new { + my ($class, $f) = @_; + my $self = _new(); + $self->import_key($f) if $f; + return $self; +} + +sub import_key { + my ($self, $key) = @_; + croak "FATAL: undefined key" unless $key; + my $data; + if (ref($key) eq 'SCALAR') { + $data = $$key; + } + elsif (-f $key) { + $data = read_rawfile($key); + } + else { + croak "FATAL: non-existing file '$key'"; + } + croak "FATAL: invalid key format" unless $data; + return $self->_import($data); +} + +sub import_key_raw { + my ($self, $raw_bytes, $type, $param) = @_; + my ($g, $p, $x, $y); + + if (ref $param eq 'HASH') { + $g = $param->{g} or croak "FATAL: 'g' param not specified"; + $p = $param->{p} or croak "FATAL: 'p' param not specified"; + $g =~ s/^0x//; + $p =~ s/^0x//; + } elsif (my $dhparam = $DH_PARAMS{$param}) { + $g = $dhparam->{g}; + $p = $dhparam->{p}; + } else { + croak "FATAL: invalid parameter"; + } + + if ($type eq 'private') { + $type = 1; + } elsif ($type eq 'public') { + $type = 0; + } else { + croak "FATAL: invalid key type '$type'"; + } + my $rv = $self->_import_raw($raw_bytes, $type, $g, $p); + croak "FATAL: invalid public key" unless $self->_is_pubkey_valid; + return $rv; +} + +sub encrypt { + my ($self, $data, $hash_name) = @_; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + return $self->_encrypt($data, $hash_name); +} + +sub decrypt { + my ($self, $data) = @_; + return $self->_decrypt($data); +} + +sub sign_message { + my ($self, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_sign($data_hash); +} + +sub verify_message { + my ($self, $sig, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_verify($sig, $data_hash); +} + +sub sign_hash { + my ($self, $data_hash) = @_; + return $self->_sign($data_hash); +} + +sub verify_hash { + my ($self, $sig, $data_hash) = @_; + return $self->_verify($sig, $data_hash); +} + +sub generate_key { + my ($key,$param) = @_; + + if (!ref $param) { + if (my $dhparam = $DH_PARAMS{$param}) { + $param = $dhparam; + } else { + croak "FATAL: invalid key length" unless ($param >= 96 || $param <= 512); + return $key->_generate_key($param); + } + } + my $g = $param->{g} or croak "FATAL: 'g' param not specified"; + my $p = $param->{p} or croak "FATAL: 'p' param not specified"; + $g =~ s/^0x//; + $p =~ s/^0x//; + return $key->_generate_key_ex($g, $p); +} + +### FUNCTIONS + +sub dh_encrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->encrypt(@_); +} + +sub dh_decrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->decrypt(@_); +} + +sub dh_sign_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_message(@_); +} + +sub dh_verify_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_message(@_); +} + +sub dh_sign_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_hash(@_); +} + +sub dh_verify_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_hash(@_); +} + +sub dh_shared_secret { + my ($privkey, $pubkey) = @_; + $privkey = __PACKAGE__->new($privkey) unless ref $privkey; + $pubkey = __PACKAGE__->new($pubkey) unless ref $pubkey; + carp "FATAL: invalid 'privkey' param" unless ref($privkey) eq __PACKAGE__ && $privkey->is_private; + carp "FATAL: invalid 'pubkey' param" unless ref($pubkey) eq __PACKAGE__; + return $privkey->shared_secret($pubkey); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::PK::DH - Public key cryptography based on Diffie-Hellman + +=head1 SYNOPSIS + + ### OO interface + + #Encryption: Alice + my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key'); + my $ct = $pub->encrypt("secret message"); + # + #Encryption: Bob (received ciphertext $ct) + my $priv = Crypt::PK::DH->new('Bob_priv_dh1.key'); + my $pt = $priv->decrypt($ct); + + #Signature: Alice + my $priv = Crypt::PK::DH->new('Alice_priv_dh1.key'); + my $sig = $priv->sign_message($message); + # + #Signature: Bob (received $message + $sig) + my $pub = Crypt::PK::DH->new('Alice_pub_dh1.key'); + $pub->verify_message($sig, $message) or die "ERROR"; + + #Shared secret + my $priv = Crypt::PK::DH->new('Alice_priv_dh1.key'); + my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key'); + my $shared_secret = $priv->shared_secret($pub); + + #Key generation + my $pk = Crypt::PK::DH->new(); + $pk->generate_key(128); + my $private = $pk->export_key('private'); + my $public = $pk->export_key('public'); + + or + + my $pk = Crypt::PK::DH->new(); + $pk->generate_key('ike2048'); + my $private = $pk->export_key('private'); + my $public = $pk->export_key('public'); + + or + + my $pk = Crypt::PK::DH->new(); + $pk->generate_key({ p => $p, g => $g }); + my $private = $pk->export_key('private'); + my $public = $pk->export_key('public'); + + ### Functional interface + + #Encryption: Alice + my $ct = dh_encrypt('Bob_pub_dh1.key', "secret message"); + #Encryption: Bob (received ciphertext $ct) + my $pt = dh_decrypt('Bob_priv_dh1.key', $ct); + + #Signature: Alice + my $sig = dh_sign_message('Alice_priv_dh1.key', $message); + #Signature: Bob (received $message + $sig) + dh_verify_message('Alice_pub_dh1.key', $sig, $message) or die "ERROR"; + + #Shared secret + my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key'); + +=head1 METHODS + +=head2 new + + my $pk = Crypt::PK::DH->new(); + #or + my $pk = Crypt::PK::DH->new($priv_or_pub_key_filename); + #or + my $pk = Crypt::PK::DH->new(\$buffer_containing_priv_or_pub_key); + +=head2 generate_key + +Uses Yarrow-based cryptographically strong random number generator seeded with +random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32). + + $pk->generate_key($keysize); + ### $keysize (in bytes) corresponds to DH params (p, g) predefined by libtomcrypt + # 96 => DH-768 + # 128 => DH-1024 + # 160 => DH-1280 + # 192 => DH-1536 + # 224 => DH-1792 + # 256 => DH-2048 + # 320 => DH-2560 + # 384 => DH-3072 + # 512 => DH-4096 + +The following variants are available since CryptX-0.032 + + $pk->generate_key($name) + ### $name corresponds to values defined in RFC7296 and RFC3526 + # ike768 => 768-bit MODP (Group 1) + # ike1024 => 1024-bit MODP (Group 2) + # ike1536 => 1536-bit MODP (Group 5) + # ike2048 => 2048-bit MODP (Group 14) + # ike3072 => 3072-bit MODP (Group 15) + # ike4096 => 4096-bit MODP (Group 16) + # ike6144 => 6144-bit MODP (Group 17) + # ike8192 => 8192-bit MODP (Group 18) + + $pk->generate_key($param_hash) + ## $param_hash is { g => $g, p => $p } + ## where $g is the generator (base) in a hex string and $p is the prime in a hex string + +=head2 import_key + +Loads private or public key (exported by L</export_key>). + + $pk->import_key($filename); + #or + $pk->import_key(\$buffer_containing_key); + +=head2 import_key_raw + +I<Since: CryptX-0.032> + + $pk->import_key_raw($raw_bytes, $type, $params) + ### $raw_bytes is a binary string containing the key + ### $type is either 'private' or 'public' + ### $param is either a name ('ike2038') or hash containing the p,g values { g=>$g, p=>$p } + ### in hex strings + +=head2 export_key + + my $private = $pk->export_key('private'); + #or + my $public = $pk->export_key('public'); + +=head2 export_key_raw + +I<Since: CryptX-0.032> + + $raw_bytes = $dh->export_key_raw('public') + #or + $raw_bytes = $dh->export_key_raw('private') + +=head2 encrypt + + my $pk = Crypt::PK::DH->new($pub_key_filename); + my $ct = $pk->encrypt($message); + #or + my $ct = $pk->encrypt($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 decrypt + + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $pt = $pk->decrypt($ciphertext); + +=head2 sign_message + + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $signature = $priv->sign_message($message); + #or + my $signature = $priv->sign_message($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 verify_message + + my $pk = Crypt::PK::DH->new($pub_key_filename); + my $valid = $pub->verify_message($signature, $message) + #or + my $valid = $pub->verify_message($signature, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 sign_hash + + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $signature = $priv->sign_hash($message_hash); + +=head2 verify_hash + + my $pk = Crypt::PK::DH->new($pub_key_filename); + my $valid = $pub->verify_hash($signature, $message_hash); + +=head2 shared_secret + + # Alice having her priv key $pk and Bob's public key $pkb + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $pkb = Crypt::PK::DH->new($pub_key_filename); + my $shared_secret = $pk->shared_secret($pkb); + + # Bob having his priv key $pk and Alice's public key $pka + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $pka = Crypt::PK::DH->new($pub_key_filename); + my $shared_secret = $pk->shared_secret($pka); # same value as computed by Alice + +=head2 is_private + + my $rv = $pk->is_private; + # 1 .. private key loaded + # 0 .. public key loaded + # undef .. no key loaded + +=head2 size + + my $size = $pk->size; + # returns key size in bytes or undef if no key loaded + +=head2 key2hash + + my $hash = $pk->key2hash; + + # returns hash like this (or undef if no key loaded): + { + type => 0, # integer: 1 .. private, 0 .. public + size => 256, # integer: key size in bytes + x => "FBC1062F73B9A17BB8473A2F5A074911FA7F20D28FB...", #private key + y => "AB9AAA40774D3CD476B52F82E7EE2D8A8D40CD88BF4...", #public key + g => "2", # generator/base + p => "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80D...", # prime +} + +=head2 params2hash + +I<Since: CryptX-0.032> + + my $params = $pk->params2hash; + + # returns hash like this (or undef if no key loaded): + { + g => "2", # generator/base + p => "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80D...", # prime +} + +=head1 FUNCTIONS + +=head2 dh_encrypt + +DH based encryption as implemented by libtomcrypt. See method L</encrypt> below. + + my $ct = dh_encrypt($pub_key_filename, $message); + #or + my $ct = dh_encrypt(\$buffer_containing_pub_key, $message); + #or + my $ct = dh_encrypt($pub_key_filename, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +Encryption works similar to the L<Crypt::PK::ECC> encryption whereas shared DH key is computed, and +the hash of the shared key XOR'ed against the plaintext forms the ciphertext. + +=head2 dh_decrypt + +DH based decryption as implemented by libtomcrypt. See method L</decrypt> below. + + my $pt = dh_decrypt($priv_key_filename, $ciphertext); + #or + my $pt = dh_decrypt(\$buffer_containing_priv_key, $ciphertext); + +=head2 dh_sign_message + +Generate DH signature as implemented by libtomcrypt. See method L</sign_message> below. + + my $sig = dh_sign_message($priv_key_filename, $message); + #or + my $sig = dh_sign_message(\$buffer_containing_priv_key, $message); + #or + my $sig = dh_sign_message($priv_key, $message, $hash_name); + +=head2 dh_verify_message + +Verify DH signature as implemented by libtomcrypt. See method L</verify_message> below. + + dh_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; + #or + dh_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; + #or + dh_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR"; + +=head2 dh_sign_hash + +Generate DH signature as implemented by libtomcrypt. See method L</sign_hash> below. + + my $sig = dh_sign_hash($priv_key_filename, $message_hash); + #or + my $sig = dh_sign_hash(\$buffer_containing_priv_key, $message_hash); + +=head2 dh_verify_hash + +Verify DH signature as implemented by libtomcrypt. See method L</verify_hash> below. + + dh_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; + #or + dh_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR"; + +=head2 dh_shared_secret + +DH based shared secret generation. See method L</shared_secret> below. + + #on Alice side + my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key'); + + #on Bob side + my $shared_secret = dh_shared_secret('Bob_priv_dh1.key', 'Alice_pub_dh1.key'); + +=head1 SEE ALSO + +=over + +=item * L<https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange|https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange> + +=back diff --git a/lib/Crypt/PK/DSA.pm b/lib/Crypt/PK/DSA.pm new file mode 100644 index 00000000..79cbcdf4 --- /dev/null +++ b/lib/Crypt/PK/DSA.pm @@ -0,0 +1,617 @@ +package Crypt::PK::DSA; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( dsa_encrypt dsa_decrypt dsa_sign_message dsa_verify_message dsa_sign_hash dsa_verify_hash )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use CryptX qw(_encode_json _decode_json); +use Crypt::Digest 'digest_data'; +use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem); +use Crypt::PK; + +sub new { + my ($class, $f, $p) = @_; + my $self = _new(); + $self->import_key($f, $p) if $f; + return $self; +} + +sub export_key_pem { + my ($self, $type, $password, $cipher) = @_; + my $key = $self->export_key_der($type||''); + return unless $key; + return der_to_pem($key, "DSA PRIVATE KEY", $password, $cipher) if $type eq 'private'; + return der_to_pem($key, "DSA PUBLIC KEY") if $type eq 'public'; + return der_to_pem($key, "PUBLIC KEY") if $type eq 'public_x509'; +} + +sub import_key { + my ($self, $key, $password) = @_; + croak "FATAL: undefined key" unless $key; + + # special case + if (ref($key) eq 'HASH') { + if ($key->{p} && $key->{q} && $key->{g} && $key->{y}) { + # hash exported via key2hash + return $self->_import_hex($key->{p}, $key->{q}, $key->{g}, $key->{x}, $key->{y}); + } + } + + my $data; + if (ref($key) eq 'SCALAR') { + $data = $$key; + } + elsif (-f $key) { + $data = read_rawfile($key); + } + else { + croak "FATAL: non-existing file '$key'"; + } + croak "FATAL: invalid key data" unless $data; + + if ($data =~ /-----BEGIN (DSA PRIVATE|DSA PUBLIC|PRIVATE|PUBLIC) KEY-----(.*?)-----END/sg) { + $data = pem_to_der($data, $password); + return $self->_import($data); + } + elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { + $data = pem_to_der($data); + my ($typ, $p, $q, $g, $y) = Crypt::PK::_ssh_parse($data); + return $self->_import_hex(unpack('H*',$p), unpack('H*',$q), unpack('H*',$g), undef, unpack('H*',$y)) if $typ && $p && $q && $g && $y && $typ eq 'ssh-dss'; + } + elsif ($data =~ /ssh-dss\s+(\S+)/) { + $data = decode_b64("$1"); + my ($typ, $p, $q, $g, $y) = Crypt::PK::_ssh_parse($data); + return $self->_import_hex(unpack('H*',$p), unpack('H*',$q), unpack('H*',$g), undef, unpack('H*',$y)) if $typ && $p && $q && $g && $y && $typ eq 'ssh-dss'; + } + else { + return $self->_import($data); + } + croak "FATAL: invalid or unsupported DSA key format"; +} + +sub encrypt { + my ($self, $data, $hash_name) = @_; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + return $self->_encrypt($data, $hash_name); +} + +sub decrypt { + my ($self, $data) = @_; + return $self->_decrypt($data); +} + +sub _truncate { + my ($self, $hash) = @_; + ### section 4.6 of FIPS 186-4 + # let N be the bit length of q + # z = the leftmost min(N, outlen) bits of Hash(M). + my $q = $self->size_q; # = size in bytes + return $hash if $q >= length($hash); + return substr($hash, 0, $q); +} + +sub sign_message { + my ($self, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_sign($self->_truncate($data_hash)); +} + +sub verify_message { + my ($self, $sig, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_verify($sig, $self->_truncate($data_hash)); +} + +sub sign_hash { + my ($self, $data_hash) = @_; + return $self->_sign($self->_truncate($data_hash)); +} + +sub verify_hash { + my ($self, $sig, $data_hash) = @_; + return $self->_verify($sig, $self->_truncate($data_hash)); +} + +### FUNCTIONS + +sub dsa_encrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->encrypt(@_); +} + +sub dsa_decrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->decrypt(@_); +} + +sub dsa_sign_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_message(@_); +} + +sub dsa_verify_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_message(@_); +} + +sub dsa_sign_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_hash(@_); +} + +sub dsa_verify_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_hash(@_); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::PK::DSA - Public key cryptography based on DSA + +=head1 SYNOPSIS + + ### OO interface + + #Encryption: Alice + my $pub = Crypt::PK::DSA->new('Bob_pub_dsa1.der'); + my $ct = $pub->encrypt("secret message"); + # + #Encryption: Bob (received ciphertext $ct) + my $priv = Crypt::PK::DSA->new('Bob_priv_dsa1.der'); + my $pt = $priv->decrypt($ct); + + #Signature: Alice + my $priv = Crypt::PK::DSA->new('Alice_priv_dsa1.der'); + my $sig = $priv->sign_message($message); + # + #Signature: Bob (received $message + $sig) + my $pub = Crypt::PK::DSA->new('Alice_pub_dsa1.der'); + $pub->verify_message($sig, $message) or die "ERROR"; + + #Key generation + my $pk = Crypt::PK::DSA->new(); + $pk->generate_key(30, 256); + my $private_der = $pk->export_key_der('private'); + my $public_der = $pk->export_key_der('public'); + my $private_pem = $pk->export_key_pem('private'); + my $public_pem = $pk->export_key_pem('public'); + + ### Functional interface + + #Encryption: Alice + my $ct = dsa_encrypt('Bob_pub_dsa1.der', "secret message"); + #Encryption: Bob (received ciphertext $ct) + my $pt = dsa_decrypt('Bob_priv_dsa1.der', $ct); + + #Signature: Alice + my $sig = dsa_sign_message('Alice_priv_dsa1.der', $message); + #Signature: Bob (received $message + $sig) + dsa_verify_message('Alice_pub_dsa1.der', $sig, $message) or die "ERROR"; + +=head1 METHODS + +=head2 new + + my $pk = Crypt::PK::DSA->new(); + #or + my $pk = Crypt::PK::DSA->new($priv_or_pub_key_filename); + #or + my $pk = Crypt::PK::DSA->new(\$buffer_containing_priv_or_pub_key); + +Support for password protected PEM keys + + my $pk = Crypt::PK::DSA->new($priv_pem_key_filename, $password); + #or + my $pk = Crypt::PK::DSA->new(\$buffer_containing_priv_pem_key, $password); + +=head2 generate_key + +Uses Yarrow-based cryptographically strong random number generator seeded with +random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32). + + $pk->generate_key($group_size, $modulus_size); + # $group_size ... in bytes .. 15 < $group_size < 1024 + # $modulus_size .. in bytes .. ($modulus_size - $group_size) < 512 + + ### Bits of Security according to libtomcrypt documentation + # 80 bits => generate_key(20, 128) + # 120 bits => generate_key(30, 256) + # 140 bits => generate_key(35, 384) + # 160 bits => generate_key(40, 512) + + ### Sizes according section 4.2 of FIPS 186-4 + # (L and N are the bit lengths of p and q respectively) + # L = 1024, N = 160 => generate_key(20, 128) + # L = 2048, N = 224 => generate_key(28, 256) + # L = 2048, N = 256 => generate_key(32, 256) + # L = 3072, N = 256 => generate_key(32, 384) + +=head2 import_key + +Loads private or public key in DER or PEM format. + + $pk->import_key($filename); + #or + $pk->import_key(\$buffer_containing_key); + +Support for password protected PEM keys + + $pk->import_key($pem_filename, $password); + #or + $pk->import_key(\$buffer_containing_pem_key, $password); + +Loading private or public keys form perl hash: + + $pk->import_key($hashref); + + # where $hashref is a key exported via key2hash + $pk->import_key({ + p => "AAF839A764E04D80824B79FA1F0496C093...", #prime modulus + q => "D05C4CB45F29D353442F1FEC43A6BE2BE8...", #prime divisor + g => "847E8896D12C9BF18FE283AE7AD58ED7F3...", #generator of a subgroup of order q in GF(p) + x => "6C801901AC74E2DC714D75A9F6969483CF...", #private key, random 0 < x < q + y => "8F7604D77FA62C7539562458A63C7611B7...", #public key, where y = g^x mod p + }); + +Supported key formats: + +=over + +=item * DSA public keys + + -----BEGIN PUBLIC KEY----- + MIIBtjCCASsGByqGSM44BAEwggEeAoGBAJKyu+puNMGLpGIhbD1IatnwlI79ePr4 + YHe2KBhRkheKxWUZRpN1Vd/+usS2IHSJ9op5cSWETiP05d7PMtJaitklw7jhudq3 + GxNvV/GRdCQm3H6d76FHP88dms4vcDYc6ry6wKERGfNEtZ+4BAKrMZK+gDYsF4Aw + U6WVR969kYZhAhUA6w25FgSRmJ8W4XkvC60n8Wv3DpMCgYA4ZFE+3tLOM24PZj9Z + rxuqUzZZdR+kIzrsIYpWN9ustbmdKLKwsqIaUIxc5zxHEhbAjAIf8toPD+VEQIpY + 7vgJgDhXuPq45BgN19iLTzOJwIhAFXPZvnAdIo9D/AnMw688gT6g6U8QCZwX2XYg + ICiVcriYVNcjVKHSFY/X0Oi7CgOBhAACgYB4ZTn4OYT/pjUd6tNhGPtOS3CE1oaj + 5ScbetXg4ZDpceEyQi8VG+/ZTbs8var8X77JdEdeQA686cAxpOaVgW8V4odvcmfA + BfueiGnPXjqGfppiHAyL1Ngyd+EsXKmKVXZYAVFVI0WuJKiZBSVURU7+ByxOfpGa + fZhibr0SggWixQ== + -----END PUBLIC KEY----- + +=item * DSA private keys + + -----BEGIN DSA PRIVATE KEY----- + MIIBuwIBAAKBgQCSsrvqbjTBi6RiIWw9SGrZ8JSO/Xj6+GB3tigYUZIXisVlGUaT + dVXf/rrEtiB0ifaKeXElhE4j9OXezzLSWorZJcO44bnatxsTb1fxkXQkJtx+ne+h + Rz/PHZrOL3A2HOq8usChERnzRLWfuAQCqzGSvoA2LBeAMFOllUfevZGGYQIVAOsN + uRYEkZifFuF5LwutJ/Fr9w6TAoGAOGRRPt7SzjNuD2Y/Wa8bqlM2WXUfpCM67CGK + VjfbrLW5nSiysLKiGlCMXOc8RxIWwIwCH/LaDw/lRECKWO74CYA4V7j6uOQYDdfY + i08zicCIQBVz2b5wHSKPQ/wJzMOvPIE+oOlPEAmcF9l2ICAolXK4mFTXI1Sh0hWP + 19DouwoCgYB4ZTn4OYT/pjUd6tNhGPtOS3CE1oaj5ScbetXg4ZDpceEyQi8VG+/Z + Tbs8var8X77JdEdeQA686cAxpOaVgW8V4odvcmfABfueiGnPXjqGfppiHAyL1Ngy + d+EsXKmKVXZYAVFVI0WuJKiZBSVURU7+ByxOfpGafZhibr0SggWixQIVAL7Sia03 + 8bvANjjL9Sitk8slrM6P + -----END DSA PRIVATE KEY----- + +=item * DSA private keys in password protected PEM format: + + -----BEGIN DSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: DES-CBC,227ADC3AA0299491 + + UISxBYAxPQMl2eK9LMAeHsssF6IxO+4G2ta2Jn8VE+boJrrH3iSTKeMXGjGaXl0z + DwcLGV+KMR70y+cxtTb34rFy+uSpBy10dOQJhxALDbe1XfCDQIUfaXRfMNA3um2I + JdZixUD/zcxBOUzao+MCr0V9XlJDgqBhJ5EEr53XHH07Eo5fhiBfbbR9NzdUPFrQ + p2ASyZtFh7RXoIBUCQgg21oeLddcNWV7gd/Y46kghO9s0JbJ8C+IsuWEPRSq502h + tSoDN6B0sxbVvOUICLLbQaxt7yduTAhRxVIJZ1PWATTVD7CZBVz9uIDZ7LOv+er2 + 1q3vkwb8E9spPsA240+BnfD571XEop4jrawxC0VKQZ+3cPVLc6jhIsxvzzFQUt67 + g66v8GUgt7KF3KhVV7qEtntybQWDWb+K/uTIH9Ra8nP820d3Rnl61pPXDPlluteT + WSLOvEMN2zRmkaxQNv/tLdT0SYpQtdjw74G3A6T7+KnvinKrjtp1a/AXkCF9hNEx + DGbxOYo1UOmk8qdxWCrab34nO+Q8oQc9wjXHG+ZtRYIMoGMKREK8DeL4H1RPNkMf + rwXWk8scd8QFmJAb8De1VQ== + -----END DSA PRIVATE KEY----- + +=item * SSH public DSA keys + + ssh-dss AAAAB3NzaC1kc3MAAACBAKU8/avmk...4XOwuEssAVhmwA== + +=item * SSH public DSA keys (RFC-4716 format) + + ---- BEGIN SSH2 PUBLIC KEY ---- + Comment: "1024-bit DSA, converted from OpenSSH" + AAAAB3NzaC1kc3MAAACBAKU8/avmkFeGnSqwYG7dZnQlG+01QNaxu3F5v0NcL/SRUW7Idp + Uq8t14siK0mA6yjphLhOf5t8gugTEVBllP86ANSbFigH7WN3v6ydJWqm60pNhNHN//50cn + NtIsXbxeq3VtsI64pkH1OJqeZDHLmu73k4T0EKOzsylSfF/wtVBJAAAAFQChpubLHViwPB + +jSvUb8e4THS7PBQAAAIAJD1PMCiTCQa1xyD/NCWOajCufTOIzKAhm6l+nlBVPiKI+262X + pYt127Ke4mPL8XJBizoTjSQN08uHMg/8L6W/cdO2aZ+mhkBnS1xAm83DAwqLrDraR1w/4Q + RFxr5Vbyy8qnejrPjTJobBN1BGsv84wHkjmoCn6pFIfkGYeATlJgAAAIAHYPU1zMVBTDWr + u7SNC4G2UyWGWYYLjLytBVHfQmBa51CmqrSs2kCfGLGA1ynfYENsxcJq9nsXrb4i17H5BH + JFkH0g7BUDpeBeLr8gsK3WgfqWwtZsDkltObw9chUD/siK6q/dk/fSIB2Ho0inev7k68Z5 + ZkNI4XOwuEssAVhmwA== + ---- END SSH2 PUBLIC KEY ---- + +=back + +=head2 export_key_der + + my $private_der = $pk->export_key_der('private'); + #or + my $public_der = $pk->export_key_der('public'); + +=head2 export_key_pem + + my $private_pem = $pk->export_key_pem('private'); + #or + my $public_pem = $pk->export_key_pem('public'); + #or + my $public_pem = $pk->export_key_pem('public_x509'); + +With parameter C<'public'> uses header and footer lines: + + -----BEGIN DSA PUBLIC KEY------ + -----END DSA PUBLIC KEY------ + +With parameter C<'public_x509'> uses header and footer lines: + + -----BEGIN PUBLIC KEY------ + -----END PUBLIC KEY------ + +Support for password protected PEM keys + + my $private_pem = $pk->export_key_pem('private', $password); + #or + my $private_pem = $pk->export_key_pem('private', $password, $cipher); + + # supported ciphers: 'DES-CBC' + # 'DES-EDE3-CBC' + # 'SEED-CBC' + # 'CAMELLIA-128-CBC' + # 'CAMELLIA-192-CBC' + # 'CAMELLIA-256-CBC' + # 'AES-128-CBC' + # 'AES-192-CBC' + # 'AES-256-CBC' (DEFAULT) + +=head2 encrypt + + my $pk = Crypt::PK::DSA->new($pub_key_filename); + my $ct = $pk->encrypt($message); + #or + my $ct = $pk->encrypt($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 decrypt + + my $pk = Crypt::PK::DSA->new($priv_key_filename); + my $pt = $pk->decrypt($ciphertext); + +=head2 sign_message + + my $pk = Crypt::PK::DSA->new($priv_key_filename); + my $signature = $priv->sign_message($message); + #or + my $signature = $priv->sign_message($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 verify_message + + my $pk = Crypt::PK::DSA->new($pub_key_filename); + my $valid = $pub->verify_message($signature, $message) + #or + my $valid = $pub->verify_message($signature, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 sign_hash + + my $pk = Crypt::PK::DSA->new($priv_key_filename); + my $signature = $priv->sign_hash($message_hash); + +=head2 verify_hash + + my $pk = Crypt::PK::DSA->new($pub_key_filename); + my $valid = $pub->verify_hash($signature, $message_hash); + +=head2 is_private + + my $rv = $pk->is_private; + # 1 .. private key loaded + # 0 .. public key loaded + # undef .. no key loaded + +=head2 size + + my $size = $pk->size; + # returns key size in bytes or undef if no key loaded + +=head2 key2hash + + my $hash = $pk->key2hash; + + # returns hash like this (or undef if no key loaded): + { + type => 1, # integer: 1 .. private, 0 .. public + size => 256, # integer: key size in bytes + # all the rest are hex strings + p => "AAF839A764E04D80824B79FA1F0496C093...", #prime modulus + q => "D05C4CB45F29D353442F1FEC43A6BE2BE8...", #prime divisor + g => "847E8896D12C9BF18FE283AE7AD58ED7F3...", #generator of a subgroup of order q in GF(p) + x => "6C801901AC74E2DC714D75A9F6969483CF...", #private key, random 0 < x < q + y => "8F7604D77FA62C7539562458A63C7611B7...", #public key, where y = g^x mod p + } + +=head1 FUNCTIONS + +=head2 dsa_encrypt + +DSA based encryption as implemented by libtomcrypt. See method L</encrypt> below. + + my $ct = dsa_encrypt($pub_key_filename, $message); + #or + my $ct = dsa_encrypt(\$buffer_containing_pub_key, $message); + #or + my $ct = dsa_encrypt($pub_key_filename, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +Encryption works similar to the L<Crypt::PK::ECC> encryption whereas shared DSA key is computed, and +the hash of the shared key XOR'ed against the plaintext forms the ciphertext. + +=head2 dsa_decrypt + +DSA based decryption as implemented by libtomcrypt. See method L</decrypt> below. + + my $pt = dsa_decrypt($priv_key_filename, $ciphertext); + #or + my $pt = dsa_decrypt(\$buffer_containing_priv_key, $ciphertext); + +=head2 dsa_sign_message + +Generate DSA signature. See method L</sign_message> below. + + my $sig = dsa_sign_message($priv_key_filename, $message); + #or + my $sig = dsa_sign_message(\$buffer_containing_priv_key, $message); + #or + my $sig = dsa_sign_message($priv_key, $message, $hash_name); + +=head2 dsa_verify_message + +Verify DSA signature. See method L</verify_message> below. + + dsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; + #or + dsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; + #or + dsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR"; + +=head2 dsa_sign_hash + +Generate DSA signature. See method L</sign_hash> below. + + my $sig = dsa_sign_hash($priv_key_filename, $message_hash); + #or + my $sig = dsa_sign_hash(\$buffer_containing_priv_key, $message_hash); + +=head2 dsa_verify_hash + +Verify DSA signature. See method L</verify_hash> below. + + dsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; + #or + dsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR"; + +=head1 OpenSSL interoperability + + ### let's have: + # DSA private key in PEM format - dsakey.priv.pem + # DSA public key in PEM format - dsakey.pub.pem + # data file to be signed - input.data + +=head2 Sign by OpenSSL, verify by Crypt::PK::DSA + +Create signature (from commandline): + + openssl dgst -sha1 -sign dsakey.priv.pem -out input.sha1-dsa.sig input.data + +Verify signature (Perl code): + + use Crypt::PK::DSA; + use Crypt::Digest 'digest_file'; + use File::Slurp 'read_file'; + + my $pkdsa = Crypt::PK::DSA->new("dsakey.pub.pem"); + my $signature = read_file("input.sha1-dsa.sig", binmode=>':raw'); + my $valid = $pkdsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + print $valid ? "SUCCESS" : "FAILURE"; + +=head2 Sign by Crypt::PK::DSA, verify by OpenSSL + +Create signature (Perl code): + + use Crypt::PK::DSA; + use Crypt::Digest 'digest_file'; + use File::Slurp 'write_file'; + + my $pkdsa = Crypt::PK::DSA->new("dsakey.priv.pem"); + my $signature = $pkdsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + write_file("input.sha1-dsa.sig", {binmode=>':raw'}, $signature); + +Verify signature (from commandline): + + openssl dgst -sha1 -verify dsakey.pub.pem -signature input.sha1-dsa.sig input.data + +=head2 Keys generated by Crypt::PK::DSA + +Generate keys (Perl code): + + use Crypt::PK::DSA; + use File::Slurp 'write_file'; + + my $pkdsa = Crypt::PK::DSA->new; + $pkdsa->generate_key(20, 128); + write_file("dsakey.pub.der", {binmode=>':raw'}, $pkdsa->export_key_der('public')); + write_file("dsakey.priv.der", {binmode=>':raw'}, $pkdsa->export_key_der('private')); + write_file("dsakey.pub.pem", $pkdsa->export_key_pem('public_x509')); + write_file("dsakey.priv.pem", $pkdsa->export_key_pem('private')); + write_file("dsakey-passwd.priv.pem", $pkdsa->export_key_pem('private', 'secret')); + +Use keys by OpenSSL: + + openssl dsa -in dsakey.priv.der -text -inform der + openssl dsa -in dsakey.priv.pem -text + openssl dsa -in dsakey-passwd.priv.pem -text -inform pem -passin pass:secret + openssl dsa -in dsakey.pub.der -pubin -text -inform der + openssl dsa -in dsakey.pub.pem -pubin -text + +=head2 Keys generated by OpenSSL + +Generate keys: + + openssl dsaparam -genkey -out dsakey.priv.pem 1024 + openssl dsa -in dsakey.priv.pem -out dsakey.priv.der -outform der + openssl dsa -in dsakey.priv.pem -out dsakey.pub.pem -pubout + openssl dsa -in dsakey.priv.pem -out dsakey.pub.der -outform der -pubout + openssl dsa -in dsakey.priv.pem -passout pass:secret -des3 -out dsakey-passwd.priv.pem + +Load keys (Perl code): + + use Crypt::PK::DSA; + use File::Slurp 'write_file'; + + my $pkdsa = Crypt::PK::DSA->new; + $pkdsa->import_key("dsakey.pub.der"); + $pkdsa->import_key("dsakey.priv.der"); + $pkdsa->import_key("dsakey.pub.pem"); + $pkdsa->import_key("dsakey.priv.pem"); + $pkdsa->import_key("dsakey-passwd.priv.pem", "secret"); + +=head1 SEE ALSO + +=over + +=item * L<https://en.wikipedia.org/wiki/Digital_Signature_Algorithm|https://en.wikipedia.org/wiki/Digital_Signature_Algorithm> + +=back diff --git a/lib/Crypt/PK/ECC.pm b/lib/Crypt/PK/ECC.pm new file mode 100644 index 00000000..58f1d7a7 --- /dev/null +++ b/lib/Crypt/PK/ECC.pm @@ -0,0 +1,1398 @@ +package Crypt::PK::ECC; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( ecc_encrypt ecc_decrypt ecc_sign_message ecc_verify_message ecc_sign_hash ecc_verify_hash ecc_shared_secret )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use CryptX qw(_encode_json _decode_json); +use Crypt::Digest qw(digest_data digest_data_b64u); +use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem); +use Crypt::PK; + +our %curve = ( + ### http://www.ecc-brainpool.org/download/Domain-parameters.pdf (v1.0 19.10.2005) + brainpoolp160r1 => { + oid => '1.3.36.3.3.2.8.1.1.1', + prime => "E95E4A5F737059DC60DFC7AD95B3D8139515620F", + A => "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", + B => "1E589A8595423412134FAA2DBDEC95C8D8675E58", + Gx => "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", + Gy => "1667CB477A1A8EC338F94741669C976316DA6321", + order => "E95E4A5F737059DC60DF5991D45029409E60FC09", + cofactor => 1, + }, + brainpoolp192r1 => { + oid => '1.3.36.3.3.2.8.1.1.3', + prime => "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", + A => "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", + B => "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", + Gx => "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", + Gy => "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", + order => "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", + cofactor => 1, + }, + brainpoolp224r1 => { + oid => '1.3.36.3.3.2.8.1.1.5', + prime => "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", + A => "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", + B => "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", + Gx => "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", + Gy => "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", + order => "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", + cofactor => 1, + }, + brainpoolp256r1 => { + oid => '1.3.36.3.3.2.8.1.1.7', + prime => "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", + A => "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", + B => "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", + Gx => "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", + Gy => "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", + order => "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", + cofactor => 1, + }, + brainpoolp320r1 => { + oid => '1.3.36.3.3.2.8.1.1.9', + prime => "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", + A => "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", + B => "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", + Gx => "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", + Gy => "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", + order => "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", + cofactor => 1, + }, + brainpoolp384r1 => { + oid => '1.3.36.3.3.2.8.1.1.11', + prime => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", + A => "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", + B => "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", + Gx => "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", + Gy => "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", + order => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", + cofactor => 1, + }, + brainpoolp512r1 => { + oid => '1.3.36.3.3.2.8.1.1.13', + prime => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", + A => "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", + B => "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", + Gx => "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", + Gy => "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", + order => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", + cofactor => 1, + }, + ### http://www.secg.org/collateral/sec2_final.pdf (September 20, 2000 - Version 1.0) + secp112r1 => { + oid => '1.3.132.0.6', + prime => "DB7C2ABF62E35E668076BEAD208B", + A => "DB7C2ABF62E35E668076BEAD2088", + B => "659EF8BA043916EEDE8911702B22", + Gx => "09487239995A5EE76B55F9C2F098", + Gy => "A89CE5AF8724C0A23E0E0FF77500", + order => "DB7C2ABF62E35E7628DFAC6561C5", + cofactor => 1, + }, + secp112r2 => { + oid => '1.3.132.0.7', + prime => "DB7C2ABF62E35E668076BEAD208B", + A => "6127C24C05F38A0AAAF65C0EF02C", + B => "51DEF1815DB5ED74FCC34C85D709", + Gx => "4BA30AB5E892B4E1649DD0928643", + Gy => "ADCD46F5882E3747DEF36E956E97", + order => "36DF0AAFD8B8D7597CA10520D04B", + cofactor => 4, + }, + secp128r1 => { + oid => '1.3.132.0.28', + prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + A => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", + B => "E87579C11079F43DD824993C2CEE5ED3", + Gx => "161FF7528B899B2D0C28607CA52C5B86", + Gy => "CF5AC8395BAFEB13C02DA292DDED7A83", + order => "FFFFFFFE0000000075A30D1B9038A115", + cofactor => 1, + }, + secp128r2 => { + oid => '1.3.132.0.29', + prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + A => "D6031998D1B3BBFEBF59CC9BBFF9AEE1", + B => "5EEEFCA380D02919DC2C6558BB6D8A5D", + Gx => "7B6AA5D85E572983E6FB32A7CDEBC140", + Gy => "27B6916A894D3AEE7106FE805FC34B44", + order => "3FFFFFFF7FFFFFFFBE0024720613B5A3", + cofactor => 4, + }, + secp160k1 => { + oid => '1.3.132.0.9', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + A => "0000000000000000000000000000000000000000", + B => "0000000000000000000000000000000000000007", + Gx => "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", + Gy => "938CF935318FDCED6BC28286531733C3F03C4FEE", + order => "0100000000000000000001B8FA16DFAB9ACA16B6B3", + cofactor => 1, + }, + secp160r1 => { + oid => '1.3.132.0.8', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + Gx => "4A96B5688EF573284664698968C38BB913CBFC82", + Gy => "23A628553168947D59DCC912042351377AC5FB32", + order => "0100000000000000000001F4C8F927AED3CA752257", + cofactor => 1, + }, + secp160r2 => { + oid => '1.3.132.0.30', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", + B => "B4E134D3FB59EB8BAB57274904664D5AF50388BA", + Gx => "52DCB034293A117E1F4FF11B30F7199D3144CE6D", + Gy => "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", + order => "0100000000000000000000351EE786A818F3A1A16B", + cofactor => 1, + }, + secp192k1 => { + oid => '1.3.132.0.31', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", + A => "000000000000000000000000000000000000000000000000", + B => "000000000000000000000000000000000000000000000003", + Gx => "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", + Gy => "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", + order => "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", + cofactor => 1, + }, + secp192r1 => { # == NIST P-192, X9.62 prime192v1 + oid => '1.2.840.10045.3.1.1', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + B => "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", + Gx => "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + Gy => "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + order => "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + cofactor => 1, + }, + secp224k1 => { + oid => '1.3.132.0.32', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", + A => "00000000000000000000000000000000000000000000000000000000", + B => "00000000000000000000000000000000000000000000000000000005", + Gx => "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", + Gy => "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", + order => "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", + cofactor => 1, + }, + secp224r1 => { # == NIST P-224 + oid => '1.3.132.0.33', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", + B => "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + Gx => "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", + Gy => "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", + order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + cofactor => 1, + }, + secp256k1 => { + oid => '1.3.132.0.10', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + A => "0000000000000000000000000000000000000000000000000000000000000000", + B => "0000000000000000000000000000000000000000000000000000000000000007", + Gx => "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + Gy => "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + cofactor => 1, + }, + secp256r1 => { # == NIST P-256, X9.62 prime256v1 + oid => '1.2.840.10045.3.1.7', + prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + A => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + B => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + cofactor => 1, + }, + secp384r1 => { # == NIST P-384 + oid => '1.3.132.0.34', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + B => "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + Gx => "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + Gy => "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + cofactor => 1, + }, + secp521r1 => { # == NIST P-521 + oid => '1.3.132.0.35', + prime => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + A => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", + B => "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + Gx => "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", + Gy => "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", + order => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + cofactor => 1 + }, + ### http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (July 2013) + nistp192 => { # == secp192r1, X9.62 prime192v1 + oid => '1.2.840.10045.3.1.1', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', + Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', + Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', + order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', + cofactor => 1, + }, + nistp224 => { # == secp224r1 + oid => '1.3.132.0.33', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', + B => 'B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', + Gx => 'B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', + Gy => 'BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', + order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', + cofactor => 1, + }, + nistp256 => { # == secp256r1, X9.62 prime256v1 + oid => '1.2.840.10045.3.1.7', + prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', + A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', + B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', + Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', + Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', + order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', + cofactor => 1, + }, + nistp384 => { # == secp384r1 + oid => '1.3.132.0.34', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', + B => 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', + Gx => 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', + Gy => '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', + order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', + cofactor => 1, + }, + nistp521 => { # == secp521r1 + oid => '1.3.132.0.35', + prime => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', + A => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC', + B => '051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00', + Gx => '0C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66', + Gy => '11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650', + order => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409', + cofactor => 1, + }, + ### ANS X9.62 elliptic curves - http://www.flexiprovider.de/CurvesGfpX962.html + prime192v1 => { # == secp192r1, NIST P-192 + oid => '1.2.840.10045.3.1.1', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', + Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', + Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', + order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', + cofactor => 1, + }, + prime192v2 => { + oid => '1.2.840.10045.3.1.2', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => 'CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', + Gx => 'EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', + Gy => '6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', + order => 'FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', + cofactor => 1 + }, + prime192v3 => { + oid => '1.2.840.10045.3.1.3', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => '22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', + Gx => '7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', + Gy => '38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', + order => 'FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', + cofactor => 1, + }, + prime239v1 => { + oid => '1.2.840.10045.3.1.4', + prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', + A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', + B => '6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', + Gx => '0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', + Gy => '7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', + order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', + cofactor => 1, + }, + prime239v2 => { + oid => '1.2.840.10045.3.1.5', + prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', + A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', + B => '617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', + Gx => '38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', + Gy => '5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', + order => '7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', + cofactor => 1, + }, + prime239v3 => { + oid => '1.2.840.10045.3.1.6', + prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', + A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', + B => '255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', + Gx => '6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', + Gy => '1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', + order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', + cofactor => 1, + }, + prime256v1 => { # == secp256r1, NIST P-256 + oid => '1.2.840.10045.3.1.7', + prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', + A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', + B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', + Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', + Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', + order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', + cofactor => 1, + }, +); + +my %jwkcrv = ( + 'P-192' => 'secp192r1', + 'P-224' => 'secp224r1', + 'P-256' => 'secp256r1', + 'P-384' => 'secp384r1', + 'P-521' => 'secp521r1', +); + +sub _import_hex { + my ($self, $x, $y, $k, $crv) = @_; + my $p = $curve{$crv}{prime}; + croak "FATAL: invalid or unknown curve" if !$p; + $p =~ s/^0+//; + my $hex_size = length($p) % 2 ? length($p) + 1 : length($p); + if ($k) { + $k =~ /^0+/; + croak "FATAL: too long private key (k)" if length($k) > $hex_size; + my $priv_hex = "0" x ($hex_size - length($k)) . $k; + return $self->import_key_raw(pack("H*", $priv_hex), $crv); + } + elsif ($x && $y) { + $x =~ /^0+/; + $y =~ /^0+/; + croak "FATAL: too long public key (x)" if length($x) > $hex_size; + croak "FATAL: too long public key (y)" if length($y) > $hex_size; + my $pub_hex = "04" . ("0" x ($hex_size - length($x))) . $x . ("0" x ($hex_size - length($y))) . $y; + return $self->import_key_raw(pack("H*", $pub_hex), $crv); + } +} + +sub _curve_name_lookup { + my ($self, $key) = @_; + + return $key->{curve_name} if $key->{curve_name} && exists $curve{$key->{curve_name}}; + + defined(my $A = $key->{curve_A}) or return; + defined(my $B = $key->{curve_B}) or return; + defined(my $Gx = $key->{curve_Gx}) or return; + defined(my $Gy = $key->{curve_Gy}) or return; + defined(my $order = $key->{curve_order}) or return; + defined(my $prime = $key->{curve_prime}) or return; + defined(my $cofactor = $key->{curve_cofactor}) or return; + $A =~ s/^0+//; + $B =~ s/^0+//; + $Gx =~ s/^0+//; + $Gy =~ s/^0+//; + $order =~ s/^0+//; + $prime =~ s/^0+//; + + for my $k (sort keys %curve) { + (my $c_A = $curve{$k}{A} ) =~ s/^0+//; + (my $c_B = $curve{$k}{B} ) =~ s/^0+//; + (my $c_Gx = $curve{$k}{Gx} ) =~ s/^0+//; + (my $c_Gy = $curve{$k}{Gy} ) =~ s/^0+//; + (my $c_order = $curve{$k}{order} ) =~ s/^0+//; + (my $c_prime = $curve{$k}{prime} ) =~ s/^0+//; + my $c_cofactor = $curve{$k}{cofactor}; + return $k if $A eq $c_A && $B eq $c_B && $Gx eq $c_Gx && $Gy eq $c_Gy && + $order eq $c_order && $prime eq $c_prime && $cofactor == $c_cofactor; + } +} + +sub new { + my ($class, $f, $p) = @_; + my $self = _new(); + $self->import_key($f, $p) if $f; + return $self; +} + +sub export_key_pem { + my ($self, $type, $password, $cipher) = @_; + my $key = $self->export_key_der($type||''); + return unless $key; + return der_to_pem($key, "EC PRIVATE KEY", $password, $cipher) if substr($type, 0, 7) eq 'private'; + return der_to_pem($key, "PUBLIC KEY") if substr($type,0, 6) eq 'public'; +} + +sub export_key_jwk { + my ($self, $type, $wanthash) = @_; + my $kh = $self->key2hash; + my $curve = $self->_curve_name_lookup($kh); + $curve = 'P-192' if $curve =~ /(secp192r1|nistp192|prime192v1)/; + $curve = 'P-224' if $curve =~ /(secp224r1|nistp224)/; + $curve = 'P-256' if $curve =~ /(secp256r1|nistp256|prime256v1)/; + $curve = 'P-384' if $curve =~ /(secp384r1|nistp384)/; + $curve = 'P-521' if $curve =~ /(secp521r1|nistp521)/; + if ($type && $type eq 'private') { + return unless $kh->{pub_x} && $kh->{pub_y} && $kh->{k}; + for (qw/pub_x pub_y k/) { + $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; + } + # NOTE: x + y are not necessary in privkey + # but they are used in https://tools.ietf.org/html/rfc7517#appendix-A.2 + my $hash = { + kty => "EC", crv=>$curve, + x => encode_b64u(pack("H*", $kh->{pub_x})), + y => encode_b64u(pack("H*", $kh->{pub_y})), + d => encode_b64u(pack("H*", $kh->{k})), + }; + return $wanthash ? $hash : _encode_json($hash); + } + elsif ($type && $type eq 'public') { + return unless $kh->{pub_x} && $kh->{pub_y}; + for (qw/pub_x pub_y/) { + $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; + } + my $hash = { + kty => "EC", crv=>$curve, + x => encode_b64u(pack("H*", $kh->{pub_x})), + y => encode_b64u(pack("H*", $kh->{pub_y})), + }; + return $wanthash ? $hash : _encode_json($hash); + } +} + +sub export_key_jwk_thumbprint { + my ($self, $hash_name) = @_; + $hash_name ||= 'SHA256'; + my $h = $self->export_key_jwk('public', 1); + my $json = _encode_json({crv=>$h->{crv}, kty=>$h->{kty}, x=>$h->{x}, y=>$h->{y}}); + return digest_data_b64u($hash_name, $json); +} + +sub import_key { + my ($self, $key, $password) = @_; + croak "FATAL: undefined key" unless $key; + + # special case + if (ref($key) eq 'HASH') { + if (($key->{pub_x} && $key->{pub_y}) || $key->{k}) { + # hash exported via key2hash + my $curve = $self->_curve_name_lookup($key); + croak "FATAL: invalid or unknown curve" if !$curve; + return $self->_import_hex($key->{pub_x}, $key->{pub_y}, $key->{k}, $curve); + } + if ($key->{crv} && $key->{kty} && $key->{kty} eq "EC" && ($key->{d} || ($key->{x} && $key->{y}))) { + # hash with items corresponding to JSON Web Key (JWK) + $key = {%$key}; # make a copy as we will modify it + for (qw/x y d/) { + $key->{$_} = eval { unpack("H*", decode_b64u($key->{$_})) } if exists $key->{$_}; + } + if (my $curve = $jwkcrv{$key->{crv}}) { + return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $curve); + } + # curve is not JWK compliant e.g. P-192 P-224 P-256 P-384 P-521 (we'll try to import anyway) + return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, lc($key->{crv})); + } + croak "FATAL: unexpected ECC key hash"; + } + + my $data; + if (ref($key) eq 'SCALAR') { + $data = $$key; + } + elsif (-f $key) { + $data = read_rawfile($key); + } + else { + croak "FATAL: non-existing file '$key'"; + } + croak "FATAL: invalid key data" unless $data; + + if ($data =~ /-----BEGIN (EC PRIVATE|EC PUBLIC|PUBLIC) KEY-----(.*?)-----END/sg) { + $data = pem_to_der($data, $password); + return $self->_import($data); + } + elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) { + $data = pem_to_der($data, $password); + return $self->_import_pkcs8($data); + } + elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { + # XXX-TODO: pkcs#8 encrypted private key + croak "FATAL: encrypted pkcs8 EC private keys are not supported"; + } + elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { + # JSON Web Key (JWK) - http://tools.ietf.org/html/draft-ietf-jose-json-web-key + my $json = "$1"; + my $h = _decode_json($json); + if ($h && $h->{kty} eq "EC") { + for (qw/x y d/) { + $h->{$_} = eval { unpack("H*", decode_b64u($h->{$_})) } if exists $h->{$_}; + } + if (my $curve = $jwkcrv{$h->{crv}}) { + return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $curve); + } + # curve is not JWK compliant e.g. P-192 P-224 P-256 P-384 P-521 (we'll try to import anyway) + return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, lc($h->{crv})); + } + } + elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { + $data = pem_to_der($data); + my ($typ, $skip, $pubkey) = Crypt::PK::_ssh_parse($data); + return $self->import_key_raw($pubkey, "$2") if $pubkey && $typ =~ /^ecdsa-(.+?)-(.*)$/; + } + elsif ($data =~ /(ecdsa-\S+)\s+(\S+)/) { + $data = decode_b64("$2"); + my ($typ, $skip, $pubkey) = Crypt::PK::_ssh_parse($data); + return $self->import_key_raw($pubkey, "$2") if $pubkey && $typ =~ /^ecdsa-(.+?)-(.*)$/; + } + else { + my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data) }; + return $rv if $rv; + } + croak "FATAL: invalid or unsupported EC key format"; +} + +sub encrypt { + my ($self, $data, $hash_name) = @_; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + return $self->_encrypt($data, $hash_name); +} + +sub decrypt { + my ($self, $data) = @_; + return $self->_decrypt($data); +} + +sub sign_message { + my ($self, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_sign($data_hash); +} + +sub sign_message_rfc7518 { + my ($self, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_sign_rfc7518($data_hash); +} + +sub verify_message { + my ($self, $sig, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_verify($sig, $data_hash); +} + +sub verify_message_rfc7518 { + my ($self, $sig, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_verify_rfc7518($sig, $data_hash); +} + +sub sign_hash { + my ($self, $data_hash) = @_; + return $self->_sign($data_hash); +} + +sub verify_hash { + my ($self, $sig, $data_hash) = @_; + return $self->_verify($sig, $data_hash); +} + +sub curve2hash { + my $self = shift; + my $kh = $self->key2hash; + return { + prime => $kh->{curve_prime}, + A => $kh->{curve_A}, + B => $kh->{curve_B}, + Gx => $kh->{curve_Gx}, + Gy => $kh->{curve_Gy}, + cofactor => $kh->{curve_cofactor}, + order => $kh->{curve_order} + }; +} + +### FUNCTIONS + +sub ecc_encrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->encrypt(@_); +} + +sub ecc_decrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->decrypt(@_); +} + +sub ecc_sign_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_message(@_); +} + +sub ecc_verify_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_message(@_); +} + +sub ecc_sign_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_hash(@_); +} + +sub ecc_verify_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_hash(@_); +} + +sub ecc_shared_secret { + my ($privkey, $pubkey) = @_; + $privkey = __PACKAGE__->new($privkey) unless ref $privkey; + $pubkey = __PACKAGE__->new($pubkey) unless ref $pubkey; + carp "FATAL: invalid 'privkey' param" unless ref($privkey) eq __PACKAGE__ && $privkey->is_private; + carp "FATAL: invalid 'pubkey' param" unless ref($pubkey) eq __PACKAGE__; + return $privkey->shared_secret($pubkey); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::PK::ECC - Public key cryptography based on EC + +=head1 SYNOPSIS + + ### OO interface + + #Encryption: Alice + my $pub = Crypt::PK::ECC->new('Bob_pub_ecc1.der'); + my $ct = $pub->encrypt("secret message"); + # + #Encryption: Bob (received ciphertext $ct) + my $priv = Crypt::PK::ECC->new('Bob_priv_ecc1.der'); + my $pt = $priv->decrypt($ct); + + #Signature: Alice + my $priv = Crypt::PK::ECC->new('Alice_priv_ecc1.der'); + my $sig = $priv->sign_message($message); + # + #Signature: Bob (received $message + $sig) + my $pub = Crypt::PK::ECC->new('Alice_pub_ecc1.der'); + $pub->verify_message($sig, $message) or die "ERROR"; + + #Shared secret + my $priv = Crypt::PK::ECC->new('Alice_priv_ecc1.der'); + my $pub = Crypt::PK::ECC->new('Bob_pub_ecc1.der'); + my $shared_secret = $priv->shared_secret($pub); + + #Key generation + my $pk = Crypt::PK::ECC->new(); + $pk->generate_key('secp160r1'); + my $private_der = $pk->export_key_der('private'); + my $public_der = $pk->export_key_der('public'); + my $private_pem = $pk->export_key_pem('private'); + my $public_pem = $pk->export_key_pem('public'); + my $public_raw = $pk->export_key_raw('public'); + + ### Functional interface + + #Encryption: Alice + my $ct = ecc_encrypt('Bob_pub_ecc1.der', "secret message"); + #Encryption: Bob (received ciphertext $ct) + my $pt = ecc_decrypt('Bob_priv_ecc1.der', $ct); + + #Signature: Alice + my $sig = ecc_sign_message('Alice_priv_ecc1.der', $message); + #Signature: Bob (received $message + $sig) + ecc_verify_message('Alice_pub_ecc1.der', $sig, $message) or die "ERROR"; + + #Shared secret + my $shared_secret = ecc_shared_secret('Alice_priv_ecc1.der', 'Bob_pub_ecc1.der'); + +=head1 DESCRIPTION + +The module provides a set of core ECC functions as well as implementation of ECDSA and ECDH. + +Supports elliptic curves C<y^2 = x^3 + a*x + b> over prime fields C<Fp = Z/pZ> (binary fields not supported). + +=head1 METHODS + +=head2 new + + my $pk = Crypt::PK::ECC->new(); + #or + my $pk = Crypt::PK::ECC->new($priv_or_pub_key_filename); + #or + my $pk = Crypt::PK::ECC->new(\$buffer_containing_priv_or_pub_key); + +Support for password protected PEM keys + + my $pk = Crypt::PK::ECC->new($priv_pem_key_filename, $password); + #or + my $pk = Crypt::PK::ECC->new(\$buffer_containing_priv_pem_key, $password); + +=head2 generate_key + +Uses Yarrow-based cryptographically strong random number generator seeded with +random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32). + + $pk->generate_key($curve_name); + #or + $pk->generate_key($hashref_with_curve_params); + +The following pre-defined C<$curve_name> values are supported: + + # curves from http://www.ecc-brainpool.org/download/Domain-parameters.pdf + 'brainpoolp160r1' + 'brainpoolp192r1' + 'brainpoolp224r1' + 'brainpoolp256r1' + 'brainpoolp320r1' + 'brainpoolp384r1' + 'brainpoolp512r1' + # curves from http://www.secg.org/collateral/sec2_final.pdf + 'secp112r1' + 'secp112r2' + 'secp128r1' + 'secp128r2' + 'secp160k1' + 'secp160r1' + 'secp160r2' + 'secp192k1' + 'secp192r1' ... same as nistp192, prime192v1 + 'secp224k1' + 'secp224r1' ... same as nistp224 + 'secp256k1' ... used by Bitcoin + 'secp256r1' ... same as nistp256, prime256v1 + 'secp384r1' ... same as nistp384 + 'secp521r1' ... same as nistp521 + #curves from http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + 'nistp192' ... same as secp192r1, prime192v1 + 'nistp224' ... same as secp224r1 + 'nistp256' ... same as secp256r1, prime256v1 + 'nistp384' ... same as secp384r1 + 'nistp521' ... same as secp521r1 + # curves from ANS X9.62 + 'prime192v1' ... same as nistp192, secp192r1 + 'prime192v2' + 'prime192v3' + 'prime239v1' + 'prime239v2' + 'prime239v3' + 'prime256v1' ... same as nistp256, secp256r1 + +Using custom curve parameters: + + $pk->generate_key({ prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => '22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', + Gx => '7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', + Gy => '38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', + order => 'FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', + cofactor => 1 }); + +See L<http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf>, L<http://www.secg.org/collateral/sec2_final.pdf>, L<http://www.ecc-brainpool.org/download/Domain-parameters.pdf> + +=head2 import_key + +Loads private or public key in DER or PEM format. + + $pk->import_key($filename); + #or + $pk->import_key(\$buffer_containing_key); + +Support for password protected PEM keys: + + $pk->import_key($filename, $password); + #or + $pk->import_key(\$buffer_containing_key, $password); + +Loading private or public keys form perl hash: + + $pk->import_key($hashref); + + # the $hashref is either a key exported via key2hash + $pk->import_key({ + curve_A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + curve_B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + curve_bits => 160, + curve_bytes => 20, + curve_cofactor => 1, + curve_Gx => "4A96B5688EF573284664698968C38BB913CBFC82", + curve_Gy => "23A628553168947D59DCC912042351377AC5FB32", + curve_order => "0100000000000000000001F4C8F927AED3CA752257", + curve_prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + k => "B0EE84A749FE95DF997E33B8F333E12101E824C3", + pub_x => "5AE1ACE3ED0AEA9707CE5C0BCE014F6A2F15023A", + pub_y => "895D57E992D0A15F88D6680B27B701F615FCDC0F", + }); + + # or with the curve defined just by name + $pk->import_key({ + curve_name => "secp160r1", + k => "B0EE84A749FE95DF997E33B8F333E12101E824C3", + pub_x => "5AE1ACE3ED0AEA9707CE5C0BCE014F6A2F15023A", + pub_y => "895D57E992D0A15F88D6680B27B701F615FCDC0F", + }); + + # or a hash with items corresponding to JWK (JSON Web Key) + $pk->import_key({ + kty => "EC", + crv => "P-256", + x => "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + y => "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + d => "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE", + }); + +Supported key formats: + + # all formats can be loaded from a file + my $pk = Crypt::PK::ECC->new($filename); + + # or from a buffer containing the key + my $pk = Crypt::PK::ECC->new(\$buffer_with_key); + +=over + +=item * EC private keys with with all curve parameters + + -----BEGIN EC PRIVATE KEY----- + MIIB+gIBAQQwCKEAcA6cIt6CGfyLKm57LyXWv2PgTjydrHSbvhDJTOl+7bzUW8DS + rgSdtSPONPq1oIIBWzCCAVcCAQEwPAYHKoZIzj0BAQIxAP////////////////// + ///////////////////////+/////wAAAAAAAAAA/////zB7BDD///////////// + /////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk + mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj + GaJ6HQCJamdzpIJ6zaxzBGEEqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU + KjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0Hb0omhR86doxE7Xw + uMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////////////////x2NN + gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoWQDYgAEeGyHPLmHcszPQ9MIIYnznpzi + QbvuJtYSjCqtIGxDfzgcLcc3nCc5tBxo+qX6OJEzcWdDAC0bwplY+9Z9jHR3ylNy + ovlHoK4ItdWkVO8NH89SLSRyVuOF8N5t3CHIo93B + -----END EC PRIVATE KEY----- + +=item * EC private keys with curve defined by OID (short form) + + -----BEGIN EC PRIVATE KEY----- + MHcCAQEEIBG1c3z52T8XwMsahGVdOZWgKCQJfv+l7djuJjgetdbDoAoGCCqGSM49 + AwEHoUQDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjTCLQeb042TjiMJxG+9DLFmRSM + lBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== + -----END EC PRIVATE KEY----- + +=item * EC private keys in password protected PEM format + + -----BEGIN EC PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: AES-128-CBC,98245C830C9282F7937E13D1D5BA11EC + + 0Y85oZ2+BKXYwrkBjsZdj6gnhOAfS5yDVmEsxFCDug+R3+Kw3QvyIfO4MVo9iWoA + D7wtoRfbt2OlBaLVl553+6QrUoa2DyKf8kLHQs1x1/J7tJOMM4SCXjlrOaToQ0dT + o7fOnjQjHne16pjgBVqGilY/I79Ab85AnE4uw7vgEucBEiU0d3nrhwuS2Opnhzyx + 009q9VLDPwY2+q7tXjTqnk9mCmQgsiaDJqY09wlauSukYPgVuOJFmi1VdkRSDKYZ + rUUsQvz6Q6Q+QirSlfHna+NhUgQ2eyhGszwcP6NU8iqIxI+NCwfFVuAzw539yYwS + 8SICczoC/YRlaclayXuomQ== + -----END EC PRIVATE KEY----- + +=item * EC public keys with all curve parameters + + -----BEGIN PUBLIC KEY----- + MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD///////////////// + ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb + /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh + AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABITjF/nKK3jg + pjmBRXKWAv7ekR1Ko/Nb5FFPHXjH0sDrpS7qRxFALwJHv7ylGnekgfKU3vzcewNs + lvjpBYt0Yg4= + -----END PUBLIC KEY----- + +=item * EC public keys with curve defined by OID (short form) + + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjT + CLQeb042TjiMJxG+9DLFmRSMlBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== + -----END PUBLIC KEY----- + +=item * PKCS#8 private keys with all curve parameters + + -----BEGIN PRIVATE KEY----- + MIIBMAIBADCB0wYHKoZIzj0CATCBxwIBATAkBgcqhkjOPQEBAhkA//////////// + /////////v//////////MEsEGP////////////////////7//////////AQYIhI9 + wjlaBcqnQj2uzMlHYKfUYiVr1WkWAxUAxGloRDXes3jEtlypWR4qV2MFmi4EMQR9 + KXeBAMZaHaF4NxZYjc4ri0rujiKPGJY4qQ8iY3M3M0tJ3LZqbcj5l4rKdkipQ7AC + GQD///////////////96YtAxyD9ClPZA7BMCAQEEVTBTAgEBBBiKolTGIsTgOCtl + 6dpdos0LvuaExCDFyT6hNAMyAAREwaCX0VY1LZxLW3G75tmft4p9uhc0J7/+NGaP + DN3Tr7SXkT9+co2a+8KPJhQy10k= + -----END PRIVATE KEY----- + +=item * PKCS#8 private keys with curve defined by OID (short form) + + -----BEGIN PRIVATE KEY----- + MG8CAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQMEVTBTAgEBBBjFP/caeQV4WO3fnWWS + f917PGzwtypd/t+hNAMyAATSg6pBT7RO6l/p+aKcrFsGuthUdfwJWS5V3NGcVt1b + lEHQYjWya2YnHaPq/iMFa7A= + -----END PRIVATE KEY----- + +=item * PKCS#8 encrypted private keys ARE NOT SUPPORTED YET! + + -----BEGIN ENCRYPTED PRIVATE KEY----- + MIGYMBwGCiqGSIb3DQEMAQMwDgQINApjTa6oFl0CAggABHi+59l4d4e6KtG9yci2 + BSC65LEsQSnrnFAExfKptNU1zMFsDLCRvDeDQDbxc6HlfoxyqFL4SmH1g3RvC/Vv + NfckdL5O2L8MRnM+ljkFtV2Te4fszWcJFdd7KiNOkPpn+7sWLfzQdvhHChLKUzmz + 4INKZyMv/G7VpZ0= + -----END ENCRYPTED PRIVATE KEY----- + +=item * SSH public EC keys + + ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT...T3xYfJIs= + +=item * SSH public EC keys (RFC-4716 format) + + ---- BEGIN SSH2 PUBLIC KEY ---- + Comment: "521-bit ECDSA, converted from OpenSSH" + AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFk35srteP9twCwYK + vU9ovMBi77Dd6lEBPrFaMEb0CZdZ5MC3nSqflGHRWkSbUpjdPdO7cYQNpK9YXHbNSO5hbU + 1gFZgyiGFxwJYYz8NAjedBXMgyH4JWplK5FQm5P5cvaglItC9qkKioUXhCc67YMYBtivXl + Ue0PgIq6kbHTqbX6+5Nw== + ---- END SSH2 PUBLIC KEY ---- + +=item * EC private keys in JSON Web Key (JWK) format + +See L<http://tools.ietf.org/html/draft-ietf-jose-json-web-key> + + { + "kty":"EC", + "crv":"P-256", + "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + "d":"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE", + } + +B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module. + +=item * EC public keys in JSON Web Key (JWK) format + + { + "kty":"EC", + "crv":"P-256", + "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + } + +B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module. + +=back + +=head2 import_key_raw + +Import raw public/private key - can load data exported by L</export_key_raw>. + + $pk->import_key_raw($key, $curve); + # $key .... data exported by export_key_raw() + # $curve .. curve name or hashref with curve parameters - same as by generate_key() + +=head2 export_key_der + + my $private_der = $pk->export_key_der('private'); + #or + my $public_der = $pk->export_key_der('public'); + +Since CryptX-0.36 C<export_key_der> can also export keys in a format +that does not explicitely contain curve parameters but only curve OID. + + my $private_der = $pk->export_key_der('private_short'); + #or + my $public_der = $pk->export_key_der('public_short'); + +=head2 export_key_pem + + my $private_pem = $pk->export_key_pem('private'); + #or + my $public_pem = $pk->export_key_pem('public'); + +Since CryptX-0.36 C<export_key_pem> can also export keys in a format +that does not explicitely contain curve parameters but only curve OID. + + my $private_pem = $pk->export_key_pem('private_short'); + #or + my $public_pem = $pk->export_key_pem('public_short'); + +Support for password protected PEM keys + + my $private_pem = $pk->export_key_pem('private', $password); + #or + my $private_pem = $pk->export_key_pem('private', $password, $cipher); + + # supported ciphers: 'DES-CBC' + # 'DES-EDE3-CBC' + # 'SEED-CBC' + # 'CAMELLIA-128-CBC' + # 'CAMELLIA-192-CBC' + # 'CAMELLIA-256-CBC' + # 'AES-128-CBC' + # 'AES-192-CBC' + # 'AES-256-CBC' (DEFAULT) + +=head2 export_key_jwk + +I<Since: CryptX-0.022> + +Exports public/private keys as a JSON Web Key (JWK). + + my $private_json_text = $pk->export_key_jwk('private'); + #or + my $public_json_text = $pk->export_key_jwk('public'); + +Also exports public/private keys as a perl HASH with JWK structure. + + my $jwk_hash = $pk->export_key_jwk('private', 1); + #or + my $jwk_hash = $pk->export_key_jwk('public', 1); + +B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module. + +=head2 export_key_jwk_thumbprint + +I<Since: CryptX-0.031> + +Exports the key's JSON Web Key Thumbprint as a string. + +If you don't know what this is, see RFC 7638 (C<https://tools.ietf.org/html/rfc7638>). + + my $thumbprint = $pk->export_key_jwk_thumbprint('SHA256'); + +=head2 export_key_raw + +Export raw public/private key. Public key is exported in ANS X9.63 format (compressed or uncompressed), +private key is exported as raw bytes (padded with leading zeros to have the same size as the ECC curve). + + my $pubkey_octets = $pk->export_key_raw('public'); + #or + my $pubckey_octets = $pk->export_key_raw('public_compressed'); + #or + my $privkey_octets = $pk->export_key_raw('private'); + +=head2 encrypt + + my $pk = Crypt::PK::ECC->new($pub_key_filename); + my $ct = $pk->encrypt($message); + #or + my $ct = $pk->encrypt($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 decrypt + + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $pt = $pk->decrypt($ciphertext); + +=head2 sign_message + + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $signature = $priv->sign_message($message); + #or + my $signature = $priv->sign_message($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 sign_message_rfc7518 + +I<Since: CryptX-0.024> + +Same as L<sign_message|/sign_message> only the signature format is as defined by L<https://tools.ietf.org/html/rfc7518> +(JWA - JSON Web Algorithms). + +=head2 verify_message + + my $pk = Crypt::PK::ECC->new($pub_key_filename); + my $valid = $pub->verify_message($signature, $message) + #or + my $valid = $pub->verify_message($signature, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 verify_message_rfc7518 + +I<Since: CryptX-0.024> + +Same as L<verify_message|/verify_message> only the signature format is as defined by L<https://tools.ietf.org/html/rfc7518> +(JWA - JSON Web Algorithms). + +=head2 sign_hash + + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $signature = $priv->sign_hash($message_hash); + +=head2 verify_hash + + my $pk = Crypt::PK::ECC->new($pub_key_filename); + my $valid = $pub->verify_hash($signature, $message_hash); + +=head2 shared_secret + + # Alice having her priv key $pk and Bob's public key $pkb + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $pkb = Crypt::PK::ECC->new($pub_key_filename); + my $shared_secret = $pk->shared_secret($pkb); + + # Bob having his priv key $pk and Alice's public key $pka + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $pka = Crypt::PK::ECC->new($pub_key_filename); + my $shared_secret = $pk->shared_secret($pka); # same value as computed by Alice + +=head2 is_private + + my $rv = $pk->is_private; + # 1 .. private key loaded + # 0 .. public key loaded + # undef .. no key loaded + +=head2 size + + my $size = $pk->size; + # returns key size in bytes or undef if no key loaded + +=head2 key2hash + + my $hash = $pk->key2hash; + + # returns hash like this (or undef if no key loaded): + { + size => 20, # integer: key (curve) size in bytes + type => 1, # integer: 1 .. private, 0 .. public + #curve parameters + curve_A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + curve_B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + curve_bits => 160, + curve_bytes => 20, + curve_cofactor => 1, + curve_Gx => "4A96B5688EF573284664698968C38BB913CBFC82", + curve_Gy => "23A628553168947D59DCC912042351377AC5FB32", + curve_name => "secp160r1", + curve_order => "0100000000000000000001F4C8F927AED3CA752257", + curve_prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + #private key + k => "B0EE84A749FE95DF997E33B8F333E12101E824C3", + #public key point coordinates + pub_x => "5AE1ACE3ED0AEA9707CE5C0BCE014F6A2F15023A", + pub_y => "895D57E992D0A15F88D6680B27B701F615FCDC0F", + } + +=head2 curve2hash + +I<Since: CryptX-0.024> + + my $crv = $pk->curve2hash; + + # returns a hash that can be passed to: $pk->generate_key($crv) + { + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + cofactor => 1, + Gx => "4A96B5688EF573284664698968C38BB913CBFC82", + Gy => "23A628553168947D59DCC912042351377AC5FB32", + order => "0100000000000000000001F4C8F927AED3CA752257", + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + } + +=head1 FUNCTIONS + +=head2 ecc_encrypt + +Elliptic Curve Diffie-Hellman (ECDH) encryption as implemented by libtomcrypt. See method L</encrypt> below. + + my $ct = ecc_encrypt($pub_key_filename, $message); + #or + my $ct = ecc_encrypt(\$buffer_containing_pub_key, $message); + #or + my $ct = ecc_encrypt($pub_key_filename, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +ECCDH Encryption is performed by producing a random key, hashing it, and XOR'ing the digest against the plaintext. + +=head2 ecc_decrypt + +Elliptic Curve Diffie-Hellman (ECDH) decryption as implemented by libtomcrypt. See method L</decrypt> below. + + my $pt = ecc_decrypt($priv_key_filename, $ciphertext); + #or + my $pt = ecc_decrypt(\$buffer_containing_priv_key, $ciphertext); + +=head2 ecc_sign_message + +Elliptic Curve Digital Signature Algorithm (ECDSA) - signature generation. See method L</sign_message> below. + + my $sig = ecc_sign_message($priv_key_filename, $message); + #or + my $sig = ecc_sign_message(\$buffer_containing_priv_key, $message); + #or + my $sig = ecc_sign_message($priv_key, $message, $hash_name); + +=head2 ecc_verify_message + +Elliptic Curve Digital Signature Algorithm (ECDSA) - signature verification. See method L</verify_message> below. + + ecc_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; + #or + ecc_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; + #or + ecc_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR"; + +=head2 ecc_sign_hash + +Elliptic Curve Digital Signature Algorithm (ECDSA) - signature generation. See method L</sign_hash> below. + + my $sig = ecc_sign_hash($priv_key_filename, $message_hash); + #or + my $sig = ecc_sign_hash(\$buffer_containing_priv_key, $message_hash); + +=head2 ecc_verify_hash + +Elliptic Curve Digital Signature Algorithm (ECDSA) - signature verification. See method L</verify_hash> below. + + ecc_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; + #or + ecc_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR"; + +=head2 ecc_shared_secret + +Elliptic curve Diffie-Hellman (ECDH) - construct a Diffie-Hellman shared secret with a private and public ECC key. See method L</shared_secret> below. + + #on Alice side + my $shared_secret = ecc_shared_secret('Alice_priv_ecc1.der', 'Bob_pub_ecc1.der'); + + #on Bob side + my $shared_secret = ecc_shared_secret('Bob_priv_ecc1.der', 'Alice_pub_ecc1.der'); + +=head1 OpenSSL interoperability + + ### let's have: + # ECC private key in PEM format - eckey.priv.pem + # ECC public key in PEM format - eckey.pub.pem + # data file to be signed - input.data + +=head2 Sign by OpenSSL, verify by Crypt::PK::ECC + +Create signature (from commandline): + + openssl dgst -sha1 -sign eckey.priv.pem -out input.sha1-ec.sig input.data + +Verify signature (Perl code): + + use Crypt::PK::ECC; + use Crypt::Digest 'digest_file'; + use File::Slurp 'read_file'; + + my $pkec = Crypt::PK::ECC->new("eckey.pub.pem"); + my $signature = read_file("input.sha1-ec.sig", binmode=>':raw'); + my $valid = $pkec->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + print $valid ? "SUCCESS" : "FAILURE"; + +=head2 Sign by Crypt::PK::ECC, verify by OpenSSL + +Create signature (Perl code): + + use Crypt::PK::ECC; + use Crypt::Digest 'digest_file'; + use File::Slurp 'write_file'; + + my $pkec = Crypt::PK::ECC->new("eckey.priv.pem"); + my $signature = $pkec->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + write_file("input.sha1-ec.sig", {binmode=>':raw'}, $signature); + +Verify signature (from commandline): + + openssl dgst -sha1 -verify eckey.pub.pem -signature input.sha1-ec.sig input.data + +=head2 Keys generated by Crypt::PK::ECC + +Generate keys (Perl code): + + use Crypt::PK::ECC; + use File::Slurp 'write_file'; + + my $pkec = Crypt::PK::ECC->new; + $pkec->generate_key('secp160k1'); + write_file("eckey.pub.der", {binmode=>':raw'}, $pkec->export_key_der('public')); + write_file("eckey.priv.der", {binmode=>':raw'}, $pkec->export_key_der('private')); + write_file("eckey.pub.pem", $pkec->export_key_pem('public')); + write_file("eckey.priv.pem", $pkec->export_key_pem('private')); + write_file("eckey-passwd.priv.pem", $pkec->export_key_pem('private', 'secret')); + +Use keys by OpenSSL: + + openssl ec -in eckey.priv.der -text -inform der + openssl ec -in eckey.priv.pem -text + openssl ec -in eckey-passwd.priv.pem -text -inform pem -passin pass:secret + openssl ec -in eckey.pub.der -pubin -text -inform der + openssl ec -in eckey.pub.pem -pubin -text + +=head2 Keys generated by OpenSSL + +Generate keys: + + openssl ecparam -param_enc explicit -name prime192v3 -genkey -out eckey.priv.pem + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pub.pem -pubout + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.priv.der -outform der + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pub.der -outform der -pubout + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.privc.der -outform der -conv_form compressed + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pubc.der -outform der -pubout -conv_form compressed + openssl ec -param_enc explicit -in eckey.priv.pem -passout pass:secret -des3 -out eckey-passwd.priv.pem + +Load keys (Perl code): + + use Crypt::PK::ECC; + use File::Slurp 'write_file'; + + my $pkec = Crypt::PK::ECC->new; + $pkec->import_key("eckey.pub.der"); + $pkec->import_key("eckey.pubc.der"); + $pkec->import_key("eckey.priv.der"); + $pkec->import_key("eckey.privc.der"); + $pkec->import_key("eckey.pub.pem"); + $pkec->import_key("eckey.priv.pem"); + $pkec->import_key("eckey-passwd.priv.pem", "secret"); + +=head1 SEE ALSO + +=over + +=item * L<https://en.wikipedia.org/wiki/Elliptic_curve_cryptography|https://en.wikipedia.org/wiki/Elliptic_curve_cryptography> + +=item * L<https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman|https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman> + +=item * L<https://en.wikipedia.org/wiki/ECDSA|https://en.wikipedia.org/wiki/ECDSA> + +=back diff --git a/lib/Crypt/PK/RSA.pm b/lib/Crypt/PK/RSA.pm new file mode 100644 index 00000000..2fe541ac --- /dev/null +++ b/lib/Crypt/PK/RSA.pm @@ -0,0 +1,939 @@ +package Crypt::PK::RSA; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw(rsa_encrypt rsa_decrypt rsa_sign_message rsa_verify_message rsa_sign_hash rsa_verify_hash)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use CryptX qw(_encode_json _decode_json); +use Crypt::Digest qw(digest_data digest_data_b64u); +use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem); +use Crypt::PK; + +sub new { + my ($class, $f, $p) = @_; + my $self = _new(); + $self->import_key($f, $p) if $f; + return $self; +} + +sub export_key_pem { + my ($self, $type, $password, $cipher) = @_; + my $key = $self->export_key_der($type||''); + return unless $key; + + # PKCS#1 RSAPrivateKey** (PEM header: BEGIN RSA PRIVATE KEY) + # PKCS#8 PrivateKeyInfo* (PEM header: BEGIN PRIVATE KEY) + # PKCS#8 EncryptedPrivateKeyInfo** (PEM header: BEGIN ENCRYPTED PRIVATE KEY) + return der_to_pem($key, "RSA PRIVATE KEY", $password, $cipher) if $type eq 'private'; + + # PKCS#1 RSAPublicKey* (PEM header: BEGIN RSA PUBLIC KEY) + return der_to_pem($key, "RSA PUBLIC KEY") if $type eq 'public'; + # X.509 SubjectPublicKeyInfo** (PEM header: BEGIN PUBLIC KEY) + return der_to_pem($key, "PUBLIC KEY") if $type eq 'public_x509'; +} + +sub export_key_jwk { + my ($self, $type, $wanthash) = @_; + my $kh = $self->key2hash; + if ($type eq 'private') { + return unless $kh->{N} && $kh->{e} && $kh->{d} && $kh->{p} && $kh->{q} && $kh->{dP} && $kh->{dQ} && $kh->{qP}; + for (qw/N e d p q dP dQ qP/) { + $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; + } + my $hash = { + kty => "RSA", + n => encode_b64u(pack("H*", $kh->{N})), + e => encode_b64u(pack("H*", $kh->{e})), + d => encode_b64u(pack("H*", $kh->{d})), + p => encode_b64u(pack("H*", $kh->{p})), + q => encode_b64u(pack("H*", $kh->{q})), + dp => encode_b64u(pack("H*", $kh->{dP})), + dq => encode_b64u(pack("H*", $kh->{dQ})), + qi => encode_b64u(pack("H*", $kh->{qP})), + }; + return $wanthash ? $hash : _encode_json($hash); + } + elsif ($type eq 'public') { + return unless $kh->{N} && $kh->{e}; + for (qw/N e/) { + $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; + } + my $hash = { + kty => "RSA", + n => encode_b64u(pack("H*", $kh->{N})), + e => encode_b64u(pack("H*", $kh->{e})), + }; + return $wanthash ? $hash : _encode_json($hash); + } +} + +sub export_key_jwk_thumbprint { + my ($self, $hash_name) = @_; + $hash_name ||= 'SHA256'; + my $h = $self->export_key_jwk('public', 1); + my $json = _encode_json({kty=>$h->{kty}, n=>$h->{n}, e=>$h->{e}}); + return digest_data_b64u($hash_name, $json); +} + +sub import_key { + my ($self, $key, $password) = @_; + croak "FATAL: undefined key" unless $key; + + # special case + if (ref($key) eq 'HASH') { + if ($key->{N} && $key->{e}) { + # hash exported via key2hash + return $self->_import_hex($key->{N}, $key->{e}, $key->{d}, $key->{p}, $key->{q}, $key->{dP}, $key->{dQ}, $key->{qP}); + } + if ($key->{n} && $key->{e} && $key->{kty} && $key->{kty} eq "RSA") { + $key = {%$key}; #make a copy so that the modifications below stay local + + # hash with items corresponding to JSON Web Key (JWK) + for (qw/n e d p q dp dq qi/) { + $key->{$_} = eval { unpack("H*", decode_b64u($key->{$_})) } if exists $key->{$_}; + } + return $self->_import_hex($key->{n}, $key->{e}, $key->{d}, $key->{p}, $key->{q}, $key->{dp}, $key->{dq}, $key->{qi}); + } + croak "FATAL: unexpected RSA key hash"; + } + + my $data; + if (ref($key) eq 'SCALAR') { + $data = $$key; + } + elsif (-f $key) { + $data = read_rawfile($key); + } + else { + croak "FATAL: non-existing file '$key'"; + } + croak "FATAL: invalid key data" unless $data; + + if ($data =~ /-----BEGIN (RSA PRIVATE|RSA PUBLIC|PUBLIC) KEY-----(.*?)-----END/sg) { + # PKCS#1 RSAPublicKey (PEM header: BEGIN RSA PUBLIC KEY) + # PKCS#1 RSAPrivateKey (PEM header: BEGIN RSA PRIVATE KEY) + # X.509 SubjectPublicKeyInfo (PEM header: BEGIN PUBLIC KEY) + $data = pem_to_der($data, $password); + return $self->_import($data) if $data; + } + elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) { + # PKCS#8 PrivateKeyInfo (PEM header: BEGIN PRIVATE KEY) + $data = pem_to_der($data, $password); + return $self->_import_pkcs8($data) if $data; + } + elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { + # XXX-TODO: PKCS#8 EncryptedPrivateKeyInfo (PEM header: BEGIN ENCRYPTED PRIVATE KEY) + croak "FATAL: encrypted pkcs8 RSA private keys are not supported"; + } + elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { + # JSON Web Key (JWK) - http://tools.ietf.org/html/draft-ietf-jose-json-web-key + my $json = "$1"; + my $h = _decode_json($json); + if ($h && $h->{kty} eq "RSA") { + for (qw/n e d p q dp dq qi/) { + $h->{$_} = eval { unpack("H*", decode_b64u($h->{$_})) } if exists $h->{$_}; + } + return $self->_import_hex($h->{n}, $h->{e}, $h->{d}, $h->{p}, $h->{q}, $h->{dp}, $h->{dq}, $h->{qi}) if $h->{n} && $h->{e}; + } + } + elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { + $data = pem_to_der($data); + my ($typ, $N, $e) = Crypt::PK::_ssh_parse($data); + return $self->_import_hex(unpack("H*", $e), unpack("H*", $N)) if $typ && $e && $N && $typ eq 'ssh-rsa'; + } + elsif ($data =~ /ssh-rsa\s+(\S+)/) { + $data = decode_b64("$1"); + my ($typ, $N, $e) = Crypt::PK::_ssh_parse($data); + return $self->_import_hex(unpack("H*", $e), unpack("H*", $N)) if $typ && $e && $N && $typ eq 'ssh-rsa'; + } + else { + # DER format + my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data) }; + return $rv if $rv; + } + + croak "FATAL: invalid or unsupported RSA key format"; +} + +sub encrypt { + my ($self, $data, $padding, $hash_name, $lparam) = @_; + $lparam ||= ''; + $padding ||= 'oaep'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_encrypt($data, $padding, $hash_name, $lparam); +} + +sub decrypt { + my ($self, $data, $padding, $hash_name, $lparam) = @_; + $lparam ||= ''; + $padding ||= 'oaep'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_decrypt($data, $padding, $hash_name, $lparam); +} + +sub sign_hash { + my ($self, $data, $hash_name, $padding, $saltlen) = @_; + $saltlen ||= 12; + $padding ||= 'pss'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_sign($data, $padding, $hash_name, $saltlen); +} + +sub sign_message { + my ($self, $data, $hash_name, $padding, $saltlen) = @_; + $saltlen ||= 12; + $padding ||= 'pss'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_sign(digest_data($hash_name, $data), $padding, $hash_name, $saltlen); +} + +sub verify_hash { + my ($self, $sig, $data, $hash_name, $padding, $saltlen) = @_; + $saltlen ||= 12; + $padding ||= 'pss'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_verify($sig, $data, $padding, $hash_name, $saltlen); +} + +sub verify_message { + my ($self, $sig, $data, $hash_name, $padding, $saltlen) = @_; + $saltlen ||= 12; + $padding ||= 'pss'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_verify($sig, digest_data($hash_name, $data), $padding, $hash_name, $saltlen); +} + +### FUNCTIONS + +sub rsa_encrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->encrypt(@_); +} + +sub rsa_decrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->decrypt(@_); +} + +sub rsa_sign_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_hash(@_); +} + +sub rsa_verify_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_hash(@_); +} + +sub rsa_sign_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_message(@_); +} + +sub rsa_verify_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_message(@_); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::PK::RSA - Public key cryptography based on RSA + +=head1 SYNOPSIS + + ### OO interface + + #Encryption: Alice + my $pub = Crypt::PK::RSA->new('Bob_pub_rsa1.der'); + my $ct = $pub->encrypt("secret message"); + # + #Encryption: Bob (received ciphertext $ct) + my $priv = Crypt::PK::RSA->new('Bob_priv_rsa1.der'); + my $pt = $priv->decrypt($ct); + + #Signature: Alice + my $priv = Crypt::PK::RSA->new('Alice_priv_rsa1.der'); + my $sig = $priv->sign_message($message); + # + #Signature: Bob (received $message + $sig) + my $pub = Crypt::PK::RSA->new('Alice_pub_rsa1.der'); + $pub->verify_message($sig, $message) or die "ERROR"; + + #Key generation + my $pk = Crypt::PK::RSA->new(); + $pk->generate_key(256, 65537); + my $private_der = $pk->export_key_der('private'); + my $public_der = $pk->export_key_der('public'); + my $private_pem = $pk->export_key_pem('private'); + my $public_pem = $pk->export_key_pem('public'); + + ### Functional interface + + #Encryption: Alice + my $ct = rsa_encrypt('Bob_pub_rsa1.der', "secret message"); + #Encryption: Bob (received ciphertext $ct) + my $pt = rsa_decrypt('Bob_priv_rsa1.der', $ct); + + #Signature: Alice + my $sig = rsa_sign_message('Alice_priv_rsa1.der', $message); + #Signature: Bob (received $message + $sig) + rsa_verify_message('Alice_pub_rsa1.der', $sig, $message) or die "ERROR"; + +=head1 DESCRIPTION + +The module provides a full featured RSA implementation. + +=head1 METHODS + +=head2 new + + my $pk = Crypt::PK::RSA->new(); + #or + my $pk = Crypt::PK::RSA->new($priv_or_pub_key_filename); + #or + my $pk = Crypt::PK::RSA->new(\$buffer_containing_priv_or_pub_key); + +Support for password protected PEM keys + + my $pk = Crypt::PK::RSA->new($priv_pem_key_filename, $password); + #or + my $pk = Crypt::PK::RSA->new(\$buffer_containing_priv_pem_key, $password); + +=head2 generate_key + +Uses Yarrow-based cryptographically strong random number generator seeded with +random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32). + + $pk->generate_key($size, $e); + # $size .. key size: 128-512 bytes (DEFAULT is 256) + # $e ..... exponent: 3, 17, 257 or 65537 (DEFAULT is 65537) + +=head2 import_key + +Loads private or public key in DER or PEM format. + + $pk->import_key($priv_or_pub_key_filename); + #or + $pk->import_key(\$buffer_containing_priv_or_pub_key); + +Support for password protected PEM keys + + $pk->import_key($pem_filename, $password); + #or + $pk->import_key(\$buffer_containing_pem_key, $password); + +Loading private or public keys form perl hash: + + $pk->import_key($hashref); + + # the $hashref is either a key exported via key2hash + $pk->import_key({ + e => "10001", #public exponent + d => "9ED5C3D3F866E06957CA0E9478A273C39BBDA4EEAC5B...", #private exponent + N => "D0A5CCCAE03DF9C2F5C4C8C0CE840D62CDE279990DC6...", #modulus + p => "D3EF0028FFAB508E2773C659E428A80FB0E9211346B4...", #p factor of N + q => "FC07E46B163CAB6A83B8E467D169534B2077DCDEECAE...", #q factor of N + qP => "88C6D406F833DF73C8B734548E0385261AD51F4187CF...", #1/q mod p CRT param + dP => "486F142FEF0A1F53269AC43D2EE4D263E2841B60DA36...", #d mod (p - 1) CRT param + dQ => "4597284B2968B72C4212DB7E8F24360B987B80514DA9...", #d mod (q - 1) CRT param + }); + + # or a hash with items corresponding to JWK (JSON Web Key) + $pk->import_key({ + { + kty => "RSA", + n => "0vx7agoebGcQSuuPiLJXZpt...eZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", + e => "AQAB", + d => "X4cTteJY_gn4FYPsXB8rdXi...FLN5EEaG6RoVH-HLKD9Mdx5ooGURknhnrRwUkC7h5fJLMWbFAKLWY2v7B6NqSzUvx0_YSf", + p => "83i-7IvMGXoMXCskv73TKr8...Z27zvoj6pbUQyLPBQxtPnwD20-60eTmD2ujMt5PoMrm8RmNhVWtjjMmMjOpSicFHjXOuVI", + q => "3dfOR9cuYq-0S-mkFLzgItg...q3hWeMuG0ouqnb3obLyuqjVZQ1dIrdgTnCdYzBcOW5r37AFXjift_NGiovonzhKpoVVS78", + dp => "G4sPXkc6Ya9y8oJW9_ILj4...zi_H7TkS8x5SdX3oE0oiYwxIiemTAu0UOa5pgFGyJ4c8t2VF40XRugKTP8akhFo5tA77Qe", + dq => "s9lAH9fggBsoFR8Oac2R_E...T2kGOhvIllTE1efA6huUvMfBcpn8lqW6vzzYY5SSF7pMd_agI3G8IbpBUb0JiraRNUfLhc", + qi => "GyM_p6JrXySiz1toFgKbWV...4ypu9bMWx3QJBfm0FoYzUIZEVEcOqwmRN81oDAaaBk0KWGDjJHDdDmFW3AN7I-pux_mHZG", + }); + +Supported key formats: + + # all formats can be loaded from a file + my $pk = Crypt::PK::RSA->new($filename); + + # or from a buffer containing the key + my $pk = Crypt::PK::RSA->new(\$buffer_with_key); + +=over + +=item * RSA public keys + + -----BEGIN PUBLIC KEY----- + MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHlYKg9DeHB3/dY1D9WCyJTnl5 + vEzAXpUOL9tDtdPUl96brIbbdMLooO1hKjsq98kLs1q4vOn/pxvzk0BRwhiu7Vvb + VUjAn/2HHDDL0U1utqqlMJhaffeLI3HEq5o/lSMFY7sSkZU/E4YX1yqAN0SE7xfK + B2uzcNq60sMIfp6siQIDAQAB + -----END PUBLIC KEY----- + +=item * RSA private keys + + -----BEGIN RSA PRIVATE KEY----- + MIICXQIBAAKBgQDHlYKg9DeHB3/dY1D9WCyJTnl5vEzAXpUOL9tDtdPUl96brIbb + dMLooO1hKjsq98kLs1q4vOn/pxvzk0BRwhiu7VvbVUjAn/2HHDDL0U1utqqlMJha + ffeLI3HEq5o/lSMFY7sSkZU/E4YX1yqAN0SE7xfKB2uzcNq60sMIfp6siQIDAQAB + AoGBAI5+GgNcGQDYw9uF+t7FwxZM5sGZRJrbbEPyuvL+sDxKKW6voKCyHi4EJzaF + 9jRZMDqgVJcsmUwjPPuMGBHHJ+MI5Zb3L0jbZkyx8u+U5gf88oy9eZmfGOjmHcMB + oCgzyoLmJETuyADg2onLanuY3jggFb3tq/jimKjO8xM2R6zhAkEA7uXWWyJI9cCN + zrVt5R5v6oosjZ4r5VILGMqBRLrzfTvH+WDMK6Rl/2MHE+YDeLajzunaM8qY2456 + GTYEXQsIdQJBANXfMEtXocSdPtoVj3ME8Do/0r+ApgTdcDPCwXOzkmkEJW/UFMSn + b8CYF5G6sZQN9L5z3s2nvi55PaFV8Q0LMUUCQBh9GvIQm6YFbQPpeTBpZFOIgnSp + 6BoDxPtvlryy5U7LF/6qO4OlwIbjYdBaXbS8FCKbujBg7jZjboSzEtNu1BkCQDGT + w0Yz0jQZn3A+fzpScr2N/fSWheWqz0+wXdfMUKw3YdZCe236wlUK7KvDc1a2xX1A + ru1NbTCoujikC3TSm2ECQQDKQshchJlZJmFv9vCFQlGCA/EX+4406xvOOiixbPYC + pIB4Ee2cmvEdAqSaOjrvgs5zvaCCFBO0MecPStCAxUX6 + -----END RSA PRIVATE KEY----- + +=item * RSA private keys in password protected PEM format + + -----BEGIN RSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: DES-EDE3-CBC,4D697440FF5AEF18 + + C09H49Gn99o8b8O2r4+Hqao4r3udvC+QSSfsk20sXatyuZSEmbhyqKAB+13NRj+3 + KIsRTqnL9VkeibIGgLHuekOFKAqeSVZ0PmR4bGWEFxUPAYUvg9N9pIa6hGtNZG+y + TEpOAfFITb1pbHQhp3j8y7qmKc5kY5LrZSFE8WwA24NTG773E07wJgRxKDkXNGOl + kki6oYArNEps0DdtHFxzgdRg0+yaotXuFJRuC5V4YzKGG/oSRcgYyXKTwCndb3xt + aHgI2WprQAPg+qOpLABzoi7bEjCqbHWrwkvnAngylbim2Uyvw1e1xKnzlgIHU7pv + e/J+s00pTItfqW1IpY2mh4C9nkfkfVKBKaAv7jO0s6aPySATqsdlrzv2kpF6Ub4J + kgaZDOfZ4K3qkyAYVLWcQeDqg4glv9Ah2J05bTm4qrIMmthYnThyQlGvcjUfCMXs + 0t+mEQbsRY7xKt0o6HzzvQlJ+JsFlLORoslAubJX9iLqpEdnlrj1lD9bo6uIClZ5 + 5+aoLcAyz1D4OsauuP5i8VFu+Is+QG4SN/vHVuArjkqi3VpLwSAjNDY+KWbq042l + CqlM2mwm6FIGUZQFxiLHJD7WDmk1xmae++m+XG9CEDTfrUQ5v+l0O6BTrl80XUfU + w3gzAWbSjz3UK0FpKeABVFPE9fjNP9fTcS6qL5YJWBPflwxCAbVgsBOW4bOMpDGK + BJDQTeShWn4BlYCe/vgThI9ERdgZhRz4NcFeDgVA/CqQzVqptvz4PSqH46fqUN2n + 4PtJgKE5cASYUBuAjlD71FecSVVM/OTzL1uxYzXBilzvVn2vSHgo9g== + -----END RSA PRIVATE KEY----- + +=item * PKCS#8 encoded private keys + + -----BEGIN PRIVATE KEY----- + MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANPN17xW4EkH5PXG + 1i/i3rE1EXFcCHyxmz95VRBDs1p3MuYf9mxntbfYAmuzS3KrRWh3IyX/Eh80N/v9 + OXPlwZbVqSTX+L3pCEJtRtsWn0zmswGThjMZiwle0oWuap63L35F1QN8EDaSPSBC + yGELNRr6rwVYq0w5b+LOcaCZ+/H1AgMBAAECgYEApfu3aGpww+rC3HUhX0+ckyTy + cXLdV9LbxidwqRlVEb0+DyfXNucjelp2sy5EHy3na9GJovo8mmWSxhCRGKliRkQ6 + XgrEMZdCSaWI2AazuHAGlUJRFEVkvdla3AuBAn6y0YdDp/3kbg0yahmKyD8Gq74z + nUYbDL3R5JtR2Ad/KlUCQQDvSEICTHbO/BF7hVmlKRYZSNHKEPrv8X/OlppS14Kv + QRwc+CZ5+l6T1Y+l5cHJQUXrXZoWS1K741TXdUhjjUd7AkEA4pod804Ex8sttdWi + pHMfeyj+IbPAk5XnBc91jT7AYIeL8ccjtfl99xhMsGFaxrh3wA/4SGEvwzWkbxcq + H8G5TwJAKNG+0P2SVwURRm0dOdukdXPCtiHnbP9Zujhe4zr4hEUrMpXymmRntfh8 + pORpBpgoAVraams3Fe5WDttnGfSD+QJAOOC6V9HjfUrQhG3FT0XeRwm5EDiQQ/tC + a8DxHqz7mL8tL1ju68ReC+G7jiJBqNOwqzLW/UP3uyYByiikWChGHQJAHUau7jIM + 45ErO096n94Vh95p76ANxOroWszOt39TyvJOykIfoPwFagLrBWV9Jjos2/D54KE+ + fyoy4t3yHT+/nw== + -----END PRIVATE KEY----- + +=item * PKCS#8 encrypted private keys ARE NOT SUPPORTED YET! + + -----BEGIN ENCRYPTED PRIVATE KEY----- + MIICojAcBgoqhkiG9w0BDAEDMA4ECCQk+Rr1yzzcAgIIAASCAoD/mgpUFjxxM/Ty + Yt+NeT0Fo4echgoGksqs6+rYhO16oshG664emZfkuNoFGGzJ38X6GVuqIXhlPnYQ + biKvL37dN/KnoGytFHq9Wnk8dDwjGHPtwajhW5WuIV3NuhW/AO1PF/cRZKFjWrPt + NWY5CrpfH6t6zojoe+5uyXpH29lQy4OqvSRdPIt/12UcB+tzV7XzSWEuXh8HAi8a + sYUu6tuCFnq4GrD2ffM4KWFmL5GqBAwN6m0KkyrNni9XT+RaA6zEhv/lVcwg2esa + 4/EzRs0ixzzZDKaml8oCMl9RHtFAbQmdlfV7Ip4rGK9BwY6UFiDMIVru6HynOVQK + vvZ+j//bgO+3ubrv7psX+vC9Fy/MoH2Tc7MIwDN/QVTciPZlzjWBnBNxMfeFKtEn + d7NFiapgfLuRQIiDTMrW/clcqvO54NphxhrcgUEoxos4twKZARntqPZHtf8nEM2x + 2sEF5kI65aEF/5Yy16qvP0vZAA2B1kcIdXZ8XLZCp4c3olhkIrmgUpo1gyFXdCoC + 7dT5Cz7/YLkq5hkcFrtp4V9BZMR24fSttc4p24N5xuZ+JneGnGkLX6B+nJAtm9vw + bZA6P+23GI0qeMzL3HJXwCOTSsWfm/H9W5+2Zmw851aAmE+pZLni/pk3e3iNSWgs + 946x/doA5O0uCFsU7oxme+WAIp2SjhxGoe808Lf1CCFMPboFi1O/E0NsX8SIEX+i + U+UHi4kxZqVkr3Q5SB/9kiSv8K1bE787yueQOT/dsTYYaMsjAbkEZo0o/47F32T6 + A2ioXHOV/pr5zNHqE5tL+qKEcLYbAUF1O+WvmdqYz+vHQjRQBatAqTmncvLDYr/j + 1HPwZX2d + -----END ENCRYPTED PRIVATE KEY----- + +=item * SSH public RSA keys + + ssh-rsa AAAAB3NzaC1yc2EAAAADAQA...6mdYs5iJNGu/ltUdc= + +=item * SSH public RSA keys (RFC-4716 format) + + ---- BEGIN SSH2 PUBLIC KEY ---- + Comment: "768-bit RSA, converted from OpenSSH" + AAAAB3NzaC1yc2EAAAADAQABAAAAYQDYebeGQFCnlQiNRE7r9UEbjr+DQMTdw1ZHGB2w6x + D/DzKem8761GdCpqsLrGaw2D7aSIoP1B5Sz870YoVWHn6Ao7Hvm17V3Kxfn4B01GNQTM5+ + L26mdYs5iJNGu/ltUdc= + ---- END SSH2 PUBLIC KEY ---- + +=item * RSA private keys in JSON Web Key (JWK) format + +See L<http://tools.ietf.org/html/draft-ietf-jose-json-web-key> + + { + "kty":"RSA", + "n":"0vx7agoebGcQSuuPiLJXZpt...eZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", + "e":"AQAB", + "d":"X4cTteJY_gn4FYPsXB8rdXi...FLN5EEaG6RoVH-HLKD9Mdx5ooGURknhnrRwUkC7h5fJLMWbFAKLWY2v7B6NqSzUvx0_YSf", + "p":"83i-7IvMGXoMXCskv73TKr8...Z27zvoj6pbUQyLPBQxtPnwD20-60eTmD2ujMt5PoMrm8RmNhVWtjjMmMjOpSicFHjXOuVI", + "q":"3dfOR9cuYq-0S-mkFLzgItg...q3hWeMuG0ouqnb3obLyuqjVZQ1dIrdgTnCdYzBcOW5r37AFXjift_NGiovonzhKpoVVS78", + "dp":"G4sPXkc6Ya9y8oJW9_ILj4...zi_H7TkS8x5SdX3oE0oiYwxIiemTAu0UOa5pgFGyJ4c8t2VF40XRugKTP8akhFo5tA77Qe", + "dq":"s9lAH9fggBsoFR8Oac2R_E...T2kGOhvIllTE1efA6huUvMfBcpn8lqW6vzzYY5SSF7pMd_agI3G8IbpBUb0JiraRNUfLhc", + "qi":"GyM_p6JrXySiz1toFgKbWV...4ypu9bMWx3QJBfm0FoYzUIZEVEcOqwmRN81oDAaaBk0KWGDjJHDdDmFW3AN7I-pux_mHZG", + } + +B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module. + +=item * RSA public keys in JSON Web Key (JWK) format + + { + "kty":"RSA", + "n": "0vx7agoebGcQSuuPiLJXZp...tN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECP", + "e":"AQAB", + } + +B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module. + +=back + +=head2 export_key_der + + my $private_der = $pk->export_key_der('private'); + #or + my $public_der = $pk->export_key_der('public'); + +=head2 export_key_pem + + my $private_pem = $pk->export_key_pem('private'); + #or + my $public_pem = $pk->export_key_pem('public'); + #or + my $public_pem = $pk->export_key_pem('public_x509'); + +With parameter C<'public'> uses header and footer lines: + + -----BEGIN RSA PUBLIC KEY------ + -----END RSA PUBLIC KEY------ + +With parameter C<'public_x509'> uses header and footer lines: + + -----BEGIN PUBLIC KEY------ + -----END PUBLIC KEY------ + +Support for password protected PEM keys + + my $private_pem = $pk->export_key_pem('private', $password); + #or + my $private_pem = $pk->export_key_pem('private', $password, $cipher); + + # supported ciphers: 'DES-CBC' + # 'DES-EDE3-CBC' + # 'SEED-CBC' + # 'CAMELLIA-128-CBC' + # 'CAMELLIA-192-CBC' + # 'CAMELLIA-256-CBC' + # 'AES-128-CBC' + # 'AES-192-CBC' + # 'AES-256-CBC' (DEFAULT) + +=head2 export_key_jwk + +I<Since: CryptX-0.022> + +Exports public/private keys as a JSON Web Key (JWK). + + my $private_json_text = $pk->export_key_jwk('private'); + #or + my $public_json_text = $pk->export_key_jwk('public'); + +Also exports public/private keys as a perl HASH with JWK structure. + + my $jwk_hash = $pk->export_key_jwk('private', 1); + #or + my $jwk_hash = $pk->export_key_jwk('public', 1); + +B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module. + +=head2 export_key_jwk_thumbprint + +I<Since: CryptX-0.031> + +Exports the key's JSON Web Key Thumbprint as a string. + +If you don't know what this is, see RFC 7638 (C<https://tools.ietf.org/html/rfc7638>). + + my $thumbprint = $pk->export_key_jwk_thumbprint('SHA256'); + +=head2 encrypt + + my $pk = Crypt::PK::RSA->new($pub_key_filename); + my $ct = $pk->encrypt($message); + #or + my $ct = $pk->encrypt($message, $padding); + #or + my $ct = $pk->encrypt($message, 'oaep', $hash_name, $lparam); + + # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE) + # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $lparam (only for oaep) ..... DEFAULT is empty string + +=head2 decrypt + + my $pk = Crypt::PK::RSA->new($priv_key_filename); + my $pt = $pk->decrypt($ciphertext); + #or + my $pt = $pk->decrypt($ciphertext, $padding); + #or + my $pt = $pk->decrypt($ciphertext, 'oaep', $hash_name, $lparam); + + # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE) + # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $lparam (only for oaep) ..... DEFAULT is empty string + +=head2 sign_message + + my $pk = Crypt::PK::RSA->new($priv_key_filename); + my $signature = $priv->sign_message($message); + #or + my $signature = $priv->sign_message($message, $hash_name); + #or + my $signature = $priv->sign_message($message, $hash_name, $padding); + #or + my $signature = $priv->sign_message($message, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 verify_message + + my $pk = Crypt::PK::RSA->new($pub_key_filename); + my $valid = $pub->verify_message($signature, $message); + #or + my $valid = $pub->verify_message($signature, $message, $hash_name); + #or + my $valid = $pub->verify_message($signature, $message, $hash_name, $padding); + #or + my $valid = $pub->verify_message($signature, $message, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 sign_hash + + my $pk = Crypt::PK::RSA->new($priv_key_filename); + my $signature = $priv->sign_hash($message_hash); + #or + my $signature = $priv->sign_hash($message_hash, $hash_name); + #or + my $signature = $priv->sign_hash($message_hash, $hash_name, $padding); + #or + my $signature = $priv->sign_hash($message_hash, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 verify_hash + + my $pk = Crypt::PK::RSA->new($pub_key_filename); + my $valid = $pub->verify_hash($signature, $message_hash); + #or + my $valid = $pub->verify_hash($signature, $message_hash, $hash_name); + #or + my $valid = $pub->verify_hash($signature, $message_hash, $hash_name, $padding); + #or + my $valid = $pub->verify_hash($signature, $message_hash, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 is_private + + my $rv = $pk->is_private; + # 1 .. private key loaded + # 0 .. public key loaded + # undef .. no key loaded + +=head2 size + + my $size = $pk->size; + # returns key size in bytes or undef if no key loaded + +=head2 key2hash + + my $hash = $pk->key2hash; + + # returns hash like this (or undef if no key loaded): + { + type => 1, # integer: 1 .. private, 0 .. public + size => 256, # integer: key size in bytes + # all the rest are hex strings + e => "10001", #public exponent + d => "9ED5C3D3F866E06957CA0E9478A273C39BBDA4EEAC5B...", #private exponent + N => "D0A5CCCAE03DF9C2F5C4C8C0CE840D62CDE279990DC6...", #modulus + p => "D3EF0028FFAB508E2773C659E428A80FB0E9211346B4...", #p factor of N + q => "FC07E46B163CAB6A83B8E467D169534B2077DCDEECAE...", #q factor of N + qP => "88C6D406F833DF73C8B734548E0385261AD51F4187CF...", #1/q mod p CRT param + dP => "486F142FEF0A1F53269AC43D2EE4D263E2841B60DA36...", #d mod (p - 1) CRT param + dQ => "4597284B2968B72C4212DB7E8F24360B987B80514DA9...", #d mod (q - 1) CRT param + } + +=head1 FUNCTIONS + +=head2 rsa_encrypt + +RSA based encryption. See method L</encrypt> below. + + my $ct = rsa_encrypt($pub_key_filename, $message); + #or + my $ct = rsa_encrypt(\$buffer_containing_pub_key, $message); + #or + my $ct = rsa_encrypt($pub_key, $message, $padding); + #or + my $ct = rsa_encrypt($pub_key, $message, 'oaep', $hash_name, $lparam); + + # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE) + # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $lparam (only for oaep) ..... DEFAULT is empty string + +=head2 rsa_decrypt + +RSA based decryption. See method L</decrypt> below. + + my $pt = rsa_decrypt($priv_key_filename, $ciphertext); + #or + my $pt = rsa_decrypt(\$buffer_containing_priv_key, $ciphertext); + #or + my $pt = rsa_decrypt($priv_key, $ciphertext, $padding); + #or + my $pt = rsa_decrypt($priv_key, $ciphertext, 'oaep', $hash_name, $lparam); + + # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE) + # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $lparam (only for oaep) ..... DEFAULT is empty string + +=head2 rsa_sign_message + +Generate RSA signature. See method L</sign_message> below. + + my $sig = rsa_sign_message($priv_key_filename, $message); + #or + my $sig = rsa_sign_message(\$buffer_containing_priv_key, $message); + #or + my $sig = rsa_sign_message($priv_key, $message, $hash_name); + #or + my $sig = rsa_sign_message($priv_key, $message, $hash_name, $padding); + #or + my $sig = rsa_sign_message($priv_key, $message, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 rsa_verify_message + +Verify RSA signature. See method L</verify_message> below. + + rsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; + #or + rsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; + #or + rsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR"; + #or + rsa_verify_message($pub_key, $signature, $message, $hash_name, $padding) or die "ERROR"; + #or + rsa_verify_message($pub_key, $signature, $message, $hash_name, 'pss', $saltlen) or die "ERROR"; + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 rsa_sign_hash + +Generate RSA signature. See method L</sign_hash> below. + + my $sig = rsa_sign_hash($priv_key_filename, $message_hash); + #or + my $sig = rsa_sign_hash(\$buffer_containing_priv_key, $message_hash); + #or + my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name); + #or + my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, $padding); + #or + my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 rsa_verify_hash + +Verify RSA signature. See method L</verify_hash> below. + + rsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; + #or + rsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR"; + #or + rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name) or die "ERROR"; + #or + rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, $padding) or die "ERROR"; + #or + rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, 'pss', $saltlen) or die "ERROR"; + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head1 OpenSSL interoperability + + ### let's have: + # RSA private key in PEM format - rsakey.priv.pem + # RSA public key in PEM format - rsakey.pub.pem + # data file to be signed or encrypted - input.data + +=head2 Encrypt by OpenSSL, decrypt by Crypt::PK::RSA + +Create encrypted file (from commandline): + + openssl rsautl -encrypt -inkey rsakey.pub.pem -pubin -out input.encrypted.rsa -in input.data + +Decrypt file (Perl code): + + use Crypt::PK::RSA; + use File::Slurp 'read_file'; + + my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem"); + my $encfile = read_file("input.encrypted.rsa", binmode=>':raw'); + my $plaintext = $pkrsa->decrypt($encfile, 'v1.5'); + print $plaintext; + +=head2 Encrypt by Crypt::PK::RSA, decrypt by OpenSSL + +Create encrypted file (Perl code): + + use Crypt::PK::RSA; + use File::Slurp 'write_file'; + + my $plaintext = 'secret message'; + my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem"); + my $encrypted = $pkrsa->encrypt($plaintext, 'v1.5'); + write_file("input.encrypted.rsa", {binmode=>':raw'}, $encrypted); + +Decrypt file (from commandline): + + openssl rsautl -decrypt -inkey rsakey.priv.pem -in input.encrypted.rsa + +=head2 Sign by OpenSSL, verify by Crypt::PK::RSA + +Create signature (from commandline): + + openssl dgst -sha1 -sign rsakey.priv.pem -out input.sha1-rsa.sig input.data + +Verify signature (Perl code): + + use Crypt::PK::RSA; + use Crypt::Digest 'digest_file'; + use File::Slurp 'read_file'; + + my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem"); + my $signature = read_file("input.sha1-rsa.sig", binmode=>':raw'); + my $valid = $pkrsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + print $valid ? "SUCCESS" : "FAILURE"; + +=head2 Sign by Crypt::PK::RSA, verify by OpenSSL + +Create signature (Perl code): + + use Crypt::PK::RSA; + use Crypt::Digest 'digest_file'; + use File::Slurp 'write_file'; + + my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem"); + my $signature = $pkrsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + write_file("input.sha1-rsa.sig", {binmode=>':raw'}, $signature); + +Verify signature (from commandline): + + openssl dgst -sha1 -verify rsakey.pub.pem -signature input.sha1-rsa.sig input.data + +=head2 Keys generated by Crypt::PK::RSA + +Generate keys (Perl code): + + use Crypt::PK::RSA; + use File::Slurp 'write_file'; + + my $pkrsa = Crypt::PK::RSA->new; + $pkrsa->generate_key(256, 65537); + write_file("rsakey.pub.der", {binmode=>':raw'}, $pkrsa->export_key_der('public')); + write_file("rsakey.priv.der", {binmode=>':raw'}, $pkrsa->export_key_der('private')); + write_file("rsakey.pub.pem", $pkrsa->export_key_pem('public_x509')); + write_file("rsakey.priv.pem", $pkrsa->export_key_pem('private')); + write_file("rsakey-passwd.priv.pem", $pkrsa->export_key_pem('private', 'secret')); + +Use keys by OpenSSL: + + openssl rsa -in rsakey.priv.der -text -inform der + openssl rsa -in rsakey.priv.pem -text + openssl rsa -in rsakey-passwd.priv.pem -text -inform pem -passin pass:secret + openssl rsa -in rsakey.pub.der -pubin -text -inform der + openssl rsa -in rsakey.pub.pem -pubin -text + +=head2 Keys generated by OpenSSL + +Generate keys: + + openssl genrsa -out rsakey.priv.pem 1024 + openssl rsa -in rsakey.priv.pem -out rsakey.priv.der -outform der + openssl rsa -in rsakey.priv.pem -out rsakey.pub.pem -pubout + openssl rsa -in rsakey.priv.pem -out rsakey.pub.der -outform der -pubout + openssl rsa -in rsakey.priv.pem -passout pass:secret -des3 -out rsakey-passwd.priv.pem + +Load keys (Perl code): + + use Crypt::PK::RSA; + use File::Slurp 'write_file'; + + my $pkrsa = Crypt::PK::RSA->new; + $pkrsa->import_key("rsakey.pub.der"); + $pkrsa->import_key("rsakey.priv.der"); + $pkrsa->import_key("rsakey.pub.pem"); + $pkrsa->import_key("rsakey.priv.pem"); + $pkrsa->import_key("rsakey-passwd.priv.pem", "secret"); + +=head1 SEE ALSO + +=over + +=item * L<https://en.wikipedia.org/wiki/RSA_%28algorithm%29|https://en.wikipedia.org/wiki/RSA_%28algorithm%29> + +=back diff --git a/lib/Crypt/PRNG.pm b/lib/Crypt/PRNG.pm new file mode 100644 index 00000000..ae14afaf --- /dev/null +++ b/lib/Crypt/PRNG.pm @@ -0,0 +1,283 @@ +package Crypt::PRNG; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +#BEWARE: cannot use Crypt::Misc qw(encode_b64 encode_b64u); +use CryptX; + +sub _trans_prng_name { + my $name = shift; + $name =~ s/^Crypt::PRNG:://; + return lc($name); +} + +### METHODS + +sub new { + my $pkg = shift; + my $prng_name = $pkg eq __PACKAGE__ ? _trans_prng_name(shift||'ChaCha20') : _trans_prng_name($pkg); + return _new($$, $prng_name, @_); +} + +sub bytes { return shift->_bytes($$, shift) } + +sub int32 { return shift->_int32($$) } + +sub double { return shift->_double($$, shift) } + +sub bytes_hex { return unpack("H*", shift->bytes(shift)) } + +sub bytes_b64 { return CryptX::_encode_base64(shift->bytes(shift)) } + +sub bytes_b64u { return CryptX::_encode_base64url(shift->bytes(shift)) } + +sub string { + my ($self, $len) = @_; + return $self->string_from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", $len); +} + +sub string_from { + my ($self, $chars, $len) = @_; + + $len = 20 unless defined $len; + return unless $len > 0; + return unless length($chars) > 0; + + my @ch = split(//, $chars); + my $max_index = $#ch; + return if $max_index > 65535; + + my $mask; + for my $n (1..31) { + $mask = (1<<$n) - 1; + last if $mask >= $max_index; + } + + my $upck = ($max_index > 255) ? "n*" : "C*"; + my $l = $len * 2; + + my $rv = ''; + my @r; + while (length $rv < $len) { + @r = unpack($upck, $self->bytes($l)) if scalar @r == 0; + my $i = (shift @r) & $mask; + next if $i > $max_index; + $rv .= $ch[$i]; + } + return $rv; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +### FUNCTIONS + +{ + ### stolen from Bytes::Random::Secure + # + # Instantiate our random number generator(s) inside of a lexical closure, + # limiting the scope of the RNG object so it can't be tampered with. + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand(;$) { return $fetch_RNG->()->double(@_) } + sub irand() { return $fetch_RNG->()->int32() } + sub random_bytes($) { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex($) { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64($) { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u($) { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from($;$) { return $fetch_RNG->()->string_from(@_) } + sub random_string(;$) { return $fetch_RNG->()->string(@_) } +} + +1; + +=pod + +=head1 NAME + +Crypt::PRNG - Cryptographically secure random number generator + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u + random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG; + + $prng = Crypt::PRNG->new; + #or + $prng = Crypt::PRNG->new("RC4"); + #or + $prng = Crypt::PRNG->new("RC4", "some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = $prng->double; + $floating_point_number_0_to_88 = $prng->double(88); + $unsigned_32bit_int = $prng->int32; + +=head1 DESCRIPTION + +Provides an interface to the ChaCha20 based pseudo random number generator (thread-safe and fork-safe). + +=head1 FUNCTIONS + +=head2 random_bytes + + $octets = random_bytes($length); + +Returns C<$length> random octects. + +=head2 random_bytes_hex + + $hex_string = random_bytes_hex($length); + +Returns C<$length> random octects encoded as hexadecimal string. + +=head2 random_bytes_b64 + + $base64_string = random_bytes_b64($length); + +Returns C<$length> random octects Base64 encoded. + +=head2 random_bytes_b64u + + $base64url_string = random_bytes_b64u($length); + +Returns C<$length> random octects Base64 URL Safe (RFC 4648 section 5) encoded. + +=head2 random_string_from + + $string = random_string_from($range, $length); + #e.g. + $string = random_string_from("ABCD", 10); + +Returns a random string made of C<$length> chars randomly chosen from C<$range> string. + +=head2 random_string + + $alphanumeric_string = random_string($length); + #or + $alphanumeric_string = random_string; # default length = 20 + +Similar to random_string_from, only C<$range> is fixed to C<'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'>. + +=head2 rand + + $n = rand; + #or + $n = rand($limit); + +Returns a random floating point number from range C<[0,1)> (if called without param) or C<[0,$limit)>. + +=head2 irand + + $i = irand; + +Returns a random unsigned 32bit integer - range 0 .. 0xFFFFFFFF. + +=head1 METHODS + +=head2 new + + $prng = Crypt::PRNG->new; + #or + $prng = Crypt::PRNG->new($alg); + #or + $prng = Crypt::PRNG->new($alg, $seed); + + # $alg ... algorithm name 'Frotuna' (DEFAULT), 'RC4', 'Sober128' or 'Yarrow' + # $seed ... will be used as an initial entropy for seeding PRNG + +If C<$seed> is not specified the PRNG is automatically seeded with 32bytes random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32) + +=head2 add_entropy + + $prng->add_entropy($random_data); + #or + $prng->add_entropy(); + +If called without parameter it uses 32bytes random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32). + +B<BEWARE:> you probably do not need this function at all as the module does automatic seeding on initialization as well as reseeding after fork and thread creation. + +=head2 bytes + + $octets = $prng->bytes($length); + +See L<random_bytes|/random_bytes> + +=head2 bytes_hex + + $hex_string = $prng->bytes_hex($length); + +See L<random_bytes_hex|/random_bytes_hex> + +=head2 bytes_b64 + + $base64_string = $prng->bytes_b64($length); + +See L<random_bytes_b64|/random_bytes_b64> + +=head2 bytes_b64u + + $base64url_string = $prng->bytes_b64u($length); + +See L<random_bytes_b64u|/random_bytes_b64u> + +=head2 string + + $alphanumeric_string = $prng->string($length); + #or + $alphanumeric_string = $prng->string; + +See L<random_string|/random_string> + +=head2 string_from + + $string = $prng->string_from($range, $length); + +See L<random_string_from|/random_string_from> + +=head2 double + + $n = $prng->double; + #or + $n = $prng->double($limit); + +See L<rand|/rand> + +=head2 int32 + + $i = $prng->int32; + +See L<irand|/irand> + +=head1 SEE ALSO + +L<Crypt::PRNG::Fortuna>, L<Crypt::PRNG::RC4>, L<Crypt::PRNG::Sober128>, L<Crypt::PRNG::Yarrow>
\ No newline at end of file diff --git a/lib/Crypt/PRNG/ChaCha20.pm b/lib/Crypt/PRNG/ChaCha20.pm new file mode 100644 index 00000000..b9ef7779 --- /dev/null +++ b/lib/Crypt/PRNG/ChaCha20.pm @@ -0,0 +1,159 @@ +package Crypt::PRNG::ChaCha20; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use base 'Crypt::PRNG'; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::ChaCha20->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::ChaCha20 - Cryptographically secure PRNG based on ChaCha20 (stream cipher) algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::ChaCha20 qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::ChaCha20; + + $prng = Crypt::PRNG::ChaCha20->new; + #or + $prng = Crypt::PRNG::ChaCha20->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the ChaCha20 based pseudo random number generator + +All methods and functions are the same as for L<Crypt::PRNG>. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L<Crypt::PRNG/random_bytes>. + +=head2 random_bytes_hex + +See L<Crypt::PRNG/random_bytes_hex>. + +=head2 random_bytes_b64 + +See L<Crypt::PRNG/random_bytes_b64>. + +=head2 random_bytes_b64u + +See L<Crypt::PRNG/random_bytes_b64u>. + +=head2 random_string + +See L<Crypt::PRNG/random_string>. + +=head2 random_string_from + +See L<Crypt::PRNG/random_string_from>. + +=head2 rand + +See L<Crypt::PRNG/rand>. + +=head2 irand + +See L<Crypt::PRNG/irand>. + +=head1 METHODS + +=head2 new + +See L<Crypt::PRNG/new>. + +=head2 bytes + +See L<Crypt::PRNG/bytes>. + +=head2 bytes_hex + +See L<Crypt::PRNG/bytes_hex>. + +=head2 bytes_b64 + +See L<Crypt::PRNG/bytes_b64>. + +=head2 bytes_b64u + +See L<Crypt::PRNG/bytes_b64u>. + +=head2 string + +See L<Crypt::PRNG/string>. + +=head2 string_from + +See L<Crypt::PRNG/string_from>. + +=head2 double + +See L<Crypt::PRNG/double>. + +=head2 int32 + +See L<Crypt::PRNG/int32>. + +=head1 SEE ALSO + +=over + +=item * L<Crypt::PRNG> + +=item * L<https://tools.ietf.org/html/rfc7539> + +=back diff --git a/lib/Crypt/PRNG/Fortuna.pm b/lib/Crypt/PRNG/Fortuna.pm new file mode 100644 index 00000000..5ef50297 --- /dev/null +++ b/lib/Crypt/PRNG/Fortuna.pm @@ -0,0 +1,160 @@ +package Crypt::PRNG::Fortuna; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use base 'Crypt::PRNG'; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::Fortuna->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::Fortuna - Cryptographically secure PRNG based on Fortuna algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::Fortuna qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u + random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::Fortuna; + + $prng = Crypt::PRNG::Fortuna->new; + #or + $prng = Crypt::PRNG::Fortuna->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the Fortuna based pseudo random number generator + +All methods and functions are the same as for L<Crypt::PRNG>. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L<Crypt::PRNG/random_bytes>. + +=head2 random_bytes_hex + +See L<Crypt::PRNG/random_bytes_hex>. + +=head2 random_bytes_b64 + +See L<Crypt::PRNG/random_bytes_b64>. + +=head2 random_bytes_b64u + +See L<Crypt::PRNG/random_bytes_b64u>. + +=head2 random_string + +See L<Crypt::PRNG/random_string>. + +=head2 random_string_from + +See L<Crypt::PRNG/random_string_from>. + +=head2 rand + +See L<Crypt::PRNG/rand>. + +=head2 irand + +See L<Crypt::PRNG/irand>. + +=head1 METHODS + +=head2 new + +See L<Crypt::PRNG/new>. + +=head2 bytes + +See L<Crypt::PRNG/bytes>. + +=head2 bytes_hex + +See L<Crypt::PRNG/bytes_hex>. + +=head2 bytes_b64 + +See L<Crypt::PRNG/bytes_b64>. + +=head2 bytes_b64u + +See L<Crypt::PRNG/bytes_b64u>. + +=head2 string + +See L<Crypt::PRNG/string>. + +=head2 string_from + +See L<Crypt::PRNG/string_from>. + +=head2 double + +See L<Crypt::PRNG/double>. + +=head2 int32 + +See L<Crypt::PRNG/int32>. + +=head1 SEE ALSO + +=over + +=item * L<Crypt::PRNG> + +=item * L<https://en.wikipedia.org/wiki/Fortuna_%28PRNG%29|https://en.wikipedia.org/wiki/Fortuna_%28PRNG%29> + +=back diff --git a/lib/Crypt/PRNG/RC4.pm b/lib/Crypt/PRNG/RC4.pm new file mode 100644 index 00000000..fa5d6223 --- /dev/null +++ b/lib/Crypt/PRNG/RC4.pm @@ -0,0 +1,159 @@ +package Crypt::PRNG::RC4; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use base 'Crypt::PRNG'; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::RC4->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::RC4 - Cryptographically secure PRNG based on RC4 (stream cipher) algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::RC4 qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::RC4; + + $prng = Crypt::PRNG::RC4->new; + #or + $prng = Crypt::PRNG::RC4->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the RC4 based pseudo random number generator + +All methods and functions are the same as for L<Crypt::PRNG>. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L<Crypt::PRNG/random_bytes>. + +=head2 random_bytes_hex + +See L<Crypt::PRNG/random_bytes_hex>. + +=head2 random_bytes_b64 + +See L<Crypt::PRNG/random_bytes_b64>. + +=head2 random_bytes_b64u + +See L<Crypt::PRNG/random_bytes_b64u>. + +=head2 random_string + +See L<Crypt::PRNG/random_string>. + +=head2 random_string_from + +See L<Crypt::PRNG/random_string_from>. + +=head2 rand + +See L<Crypt::PRNG/rand>. + +=head2 irand + +See L<Crypt::PRNG/irand>. + +=head1 METHODS + +=head2 new + +See L<Crypt::PRNG/new>. + +=head2 bytes + +See L<Crypt::PRNG/bytes>. + +=head2 bytes_hex + +See L<Crypt::PRNG/bytes_hex>. + +=head2 bytes_b64 + +See L<Crypt::PRNG/bytes_b64>. + +=head2 bytes_b64u + +See L<Crypt::PRNG/bytes_b64u>. + +=head2 string + +See L<Crypt::PRNG/string>. + +=head2 string_from + +See L<Crypt::PRNG/string_from>. + +=head2 double + +See L<Crypt::PRNG/double>. + +=head2 int32 + +See L<Crypt::PRNG/int32>. + +=head1 SEE ALSO + +=over + +=item * L<Crypt::PRNG> + +=item * L<https://en.wikipedia.org/wiki/RC4_cipher|https://en.wikipedia.org/wiki/RC4_cipher> + +=back diff --git a/lib/Crypt/PRNG/Sober128.pm b/lib/Crypt/PRNG/Sober128.pm new file mode 100644 index 00000000..b27230f7 --- /dev/null +++ b/lib/Crypt/PRNG/Sober128.pm @@ -0,0 +1,159 @@ +package Crypt::PRNG::Sober128; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use base 'Crypt::PRNG'; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::Sober128->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::Sober128 - Cryptographically secure PRNG based on Sober128 (stream cipher) algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::Sober128 qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::Sober128; + + $prng = Crypt::PRNG::Sober128->new; + #or + $prng = Crypt::PRNG::Sober128->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the Sober128 based pseudo random number generator + +All methods and functions are the same as for L<Crypt::PRNG>. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L<Crypt::PRNG/random_bytes>. + +=head2 random_bytes_hex + +See L<Crypt::PRNG/random_bytes_hex>. + +=head2 random_bytes_b64 + +See L<Crypt::PRNG/random_bytes_b64>. + +=head2 random_bytes_b64u + +See L<Crypt::PRNG/random_bytes_b64u>. + +=head2 random_string + +See L<Crypt::PRNG/random_string>. + +=head2 random_string_from + +See L<Crypt::PRNG/random_string_from>. + +=head2 rand + +See L<Crypt::PRNG/rand>. + +=head2 irand + +See L<Crypt::PRNG/irand>. + +=head1 METHODS + +=head2 new + +See L<Crypt::PRNG/new>. + +=head2 bytes + +See L<Crypt::PRNG/bytes>. + +=head2 bytes_hex + +See L<Crypt::PRNG/bytes_hex>. + +=head2 bytes_b64 + +See L<Crypt::PRNG/bytes_b64>. + +=head2 bytes_b64u + +See L<Crypt::PRNG/bytes_b64u>. + +=head2 string + +See L<Crypt::PRNG/string>. + +=head2 string_from + +See L<Crypt::PRNG/string_from>. + +=head2 double + +See L<Crypt::PRNG/double>. + +=head2 int32 + +See L<Crypt::PRNG/int32>. + +=head1 SEE ALSO + +=over + +=item * L<Crypt::PRNG> + +=item * L<https://en.wikipedia.org/wiki/SOBER-128|https://en.wikipedia.org/wiki/SOBER-128> + +=back diff --git a/lib/Crypt/PRNG/Yarrow.pm b/lib/Crypt/PRNG/Yarrow.pm new file mode 100644 index 00000000..3a04befc --- /dev/null +++ b/lib/Crypt/PRNG/Yarrow.pm @@ -0,0 +1,158 @@ +package Crypt::PRNG::Yarrow; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::Yarrow->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::Yarrow - Cryptographically secure PRNG based on Yarrow algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::Yarrow qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::Yarrow; + + $prng = Crypt::PRNG::Yarrow->new; + #or + $prng = Crypt::PRNG::Yarrow->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the Yarrow based pseudo random number generator + +All methods and functions are the same as for L<Crypt::PRNG>. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L<Crypt::PRNG/random_bytes>. + +=head2 random_bytes_hex + +See L<Crypt::PRNG/random_bytes_hex>. + +=head2 random_bytes_b64 + +See L<Crypt::PRNG/random_bytes_b64>. + +=head2 random_bytes_b64u + +See L<Crypt::PRNG/random_bytes_b64u>. + +=head2 random_string + +See L<Crypt::PRNG/random_string>. + +=head2 random_string_from + +See L<Crypt::PRNG/random_string_from>. + +=head2 rand + +See L<Crypt::PRNG/rand>. + +=head2 irand + +See L<Crypt::PRNG/irand>. + +=head1 METHODS + +=head2 new + +See L<Crypt::PRNG/new>. + +=head2 bytes + +See L<Crypt::PRNG/bytes>. + +=head2 bytes_hex + +See L<Crypt::PRNG/bytes_hex>. + +=head2 bytes_b64 + +See L<Crypt::PRNG/bytes_b64>. + +=head2 bytes_b64u + +See L<Crypt::PRNG/bytes_b64u>. + +=head2 string + +See L<Crypt::PRNG/string>. + +=head2 string_from + +See L<Crypt::PRNG/string_from>. + +=head2 double + +See L<Crypt::PRNG/double>. + +=head2 int32 + +See L<Crypt::PRNG/int32>. + +=head1 SEE ALSO + +=over + +=item * L<Crypt::PRNG> + +=item * L<https://en.wikipedia.org/wiki/Yarrow_algorithm|https://en.wikipedia.org/wiki/Yarrow_algorithm> + +=back diff --git a/lib/Crypt/Stream/ChaCha.pm b/lib/Crypt/Stream/ChaCha.pm new file mode 100644 index 00000000..bbdc7dd9 --- /dev/null +++ b/lib/Crypt/Stream/ChaCha.pm @@ -0,0 +1,76 @@ +package Crypt::Stream::ChaCha; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; + +sub new { my $class = shift; _new(@_) } + +1; + +=pod + +=head1 NAME + +Crypt::Stream::ChaCha - Stream cipher ChaCha + +=head1 SYNOPSIS + + use Crypt::Stream::ChaCha; + + # encrypt + $key = "1234567890123456"; + $iv = "123456789012"; + $stream = Crypt::Stream::ChaCha->new($key, $iv); + $ct = $stream->crypt("plain message"); + + # decrypt + $key = "1234567890123456"; + $iv = "123456789012"; + $stream = Crypt::Stream::ChaCha->new($key, $iv); + $pt = $stream->crypt($ct); + +=head1 DESCRIPTION + +Provides an interface to the ChaCha stream cipher. + +=head1 METHODS + +=head2 new + + $stream = Crypt::Stream::ChaCha->new($key, $iv); + #or + $stream = Crypt::Stream::ChaCha->new($key, $iv, $counter, $rounds); + + # $key .. 32 or 16 bytes + # $iv .. 8 or 12 bytes + # $counter .. initial counter value (DEFAULT: 0) + # $rounds .. rounds (DEFAULT: 20) + +=head2 crypt + + $ciphertext = $stream->crypt($plaintext); + #or + $plaintext = $stream->crypt($ciphertext); + +=head2 keystream + + $random_key = $stream->keystream($length); + +=head2 clone + + $stream->clone(); + +=head1 SEE ALSO + +=over + +=item * L<Crypt::Stream::RC4>, L<Crypt::Stream::Sober128> + +=item * L<https://tools.ietf.org/html/rfc7539> + +=back + +=cut diff --git a/lib/Crypt/Stream/RC4.pm b/lib/Crypt/Stream/RC4.pm new file mode 100644 index 00000000..c9156866 --- /dev/null +++ b/lib/Crypt/Stream/RC4.pm @@ -0,0 +1,68 @@ +package Crypt::Stream::RC4; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; + +sub new { my $class = shift; _new(@_) } + +1; + +=pod + +=head1 NAME + +Crypt::Stream::RC4 - Stream cipher RC4 + +=head1 SYNOPSIS + + use Crypt::Stream::RC4; + + # encrypt + $key = "1234567890123456"; + $stream = Crypt::Stream::RC4->new($key); + $ct = $stream->crypt("plain message"); + + # decrypt + $key = "1234567890123456"; + $stream = Crypt::Stream::RC4->new($key); + $pt = $stream->crypt($ct); + +=head1 DESCRIPTION + +Provides an interface to the RC4 stream cipher. + +=head1 METHODS + +=head2 new + + $stream = Crypt::Stream::RC4->new($key); + # $key .. length 5-256 bytes (40 - 2048 bits) + +=head2 crypt + + $ciphertext = $stream->crypt($plaintext); + #or + $plaintext = $stream->crypt($ciphertext); + +=head2 keystream + + $random_key = $stream->keystream($length); + +=head2 clone + + $stream->clone(); + +=head1 SEE ALSO + +=over + +=item * L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Sober128> + +=item * L<https://en.wikipedia.org/wiki/RC4_cipher|https://en.wikipedia.org/wiki/RC4_cipher> + +=back + +=cut diff --git a/lib/Crypt/Stream/Sober128.pm b/lib/Crypt/Stream/Sober128.pm new file mode 100644 index 00000000..55366af4 --- /dev/null +++ b/lib/Crypt/Stream/Sober128.pm @@ -0,0 +1,71 @@ +package Crypt::Stream::Sober128; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; + +sub new { my $class = shift; _new(@_) } + +1; + +=pod + +=head1 NAME + +Crypt::Stream::Sober128 - Stream cipher Sober128 + +=head1 SYNOPSIS + + use Crypt::Stream::Sober128; + + # encrypt + $key = "1234567890123456"; + $iv = "123456789012"; + $stream = Crypt::Stream::Sober128->new($key, $iv); + $ct = $stream->crypt("plain message"); + + # decrypt + $key = "1234567890123456"; + $iv = "123456789012"; + $stream = Crypt::Stream::Sober128->new($key, $iv); + $pt = $stream->crypt($ct); + +=head1 DESCRIPTION + +Provides an interface to the Sober128 stream cipher. + +=head1 METHODS + +=head2 new + + $stream = Crypt::Stream::Sober128->new($key, $iv); + # $key .. keylen must be multiple of 4 bytes + # $iv .. ivlen must be multiple of 4 bytes + +=head2 crypt + + $ciphertext = $stream->crypt($plaintext); + #or + $plaintext = $stream->crypt($ciphertext); + +=head2 keystream + + $random_key = $stream->keystream($length); + +=head2 clone + + $stream->clone(); + +=head1 SEE ALSO + +=over + +=item * L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha> + +=item * L<https://en.wikipedia.org/wiki/SOBER-128|https://en.wikipedia.org/wiki/SOBER-128> + +=back + +=cut |