package Crypt::Digest::KangarooTwelve; use strict; use warnings; our $VERSION = '0.090'; use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; sub addfile { my ($self, $file) = @_; my ($handle, $close_handle); if (ref($file) && eval { defined fileno($file) }) { $handle = $file; } elsif (defined($file) && !ref($file)) { open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; binmode($handle); $close_handle = 1; } else { croak "FATAL: invalid handle"; } my $n; my $buf = ""; { local $SIG{__DIE__} = \&CryptX::_croak; while (($n = read($handle, $buf, 32*1024))) { $self->add($buf) } croak "FATAL: read failed: $!" unless defined $n; } close($handle) if $close_handle; return $self; } sub CLONE_SKIP { 1 } # prevent cloning 1; =pod =head1 NAME Crypt::Digest::KangarooTwelve - XOF (extendable output) hash function KangarooTwelve =head1 SYNOPSIS use Crypt::Digest::KangarooTwelve; my $d = Crypt::Digest::KangarooTwelve->new(128); # 128-bit security $d->add('any data'); $d->customization('optional context string'); my $result = $d->done(32); # 32 bytes of output # or absorb input from a file instead my $file_d = Crypt::Digest::KangarooTwelve->new(128); $file_d->addfile('filename.dat'); $file_d->customization('optional context string'); my $file_result = $file_d->done(32); =head1 DESCRIPTION I Provides an interface to KangarooTwelve (K12) as defined in L. KangarooTwelve is a fast cryptographic hash and XOF based on a reduced-round (12-round) Keccak-p permutation. It supports an optional B that binds the output to a specific context. C can be called multiple times to stream arbitrary amounts of output. B: C must be called before C; C must be called before C. After the first C, treat the object as being in output mode: do not call C or C again on that state. Use C or a new object to start hashing a new message. =head1 METHODS Unless noted otherwise, assume C<$d> is an existing KangarooTwelve object created via C, for example: my $d = Crypt::Digest::KangarooTwelve->new(128); =head2 new my $d = Crypt::Digest::KangarooTwelve->new($num); # $num ... [integer] 128 or 256 (security level in bits) =head2 clone my $d2 = $d->clone; =head2 reset $d->reset; =head2 add Appends data to the message. Returns the object itself (for chaining). Each argument is converted to bytes using Perl's usual scalar stringification. Defined scalars, including numbers and string-overloaded objects, are accepted. C is treated as an empty string and may emit Perl's usual "uninitialized value" warning. $d->add('any data'); #or $d->add('chunk1', 'chunk2', ...); =head2 addfile Reads the file content and appends it to the message. Returns the object itself (for chaining). $d->addfile('filename.dat'); #or my $filehandle = ...; # existing binary-mode filehandle $d->addfile($filehandle); =head2 customization $d->customization('context string'); # optional; call after add(), before done() Each argument is converted to bytes using Perl's usual scalar stringification. Defined scalars, including numbers and string-overloaded objects, are accepted. C is treated as an empty string and may emit Perl's usual "uninitialized value" warning. =head2 done Returns C<$len> bytes of output as a binary string. Can be called repeatedly to stream an unlimited amount of output from the same absorbed input. The C<$len> argument is required and must be a positive integer. Single C calls are limited to 1,000,000,000 bytes, but the recommended way to read large output is to call C repeatedly in 10 MB chunks. After the first C call the object is in output mode. Calling C or C in this state croaks; use C or create a new object to hash a different message. my $result_raw = $d->done($len); # can be called multiple times; $len is the number of output bytes to read # after the first done(), add() / customization() croak until you call reset() =head1 SEE ALSO =over =item * L, L, L =item * L =back =cut