@@ -1,5 +1,20 @@
Revision history for Perl module Digest::SHA::PurePerl.
+5.88 Mon Mar 17 08:46:10 MST 2014
+ - changed text file test (-T) to act on filehandles
+ -- ref. addfile portable mode
+ -- improves consistency when reading from STDIN
+ -- still acts on filenames for early Perls (< 5.6)
+ - added -M and -V options to shasum
+ -- undocumented: for development and testing use only
+
+5.87 Mon Feb 17 16:42:02 MST 2014
+ - simplified capture of intermediate SHA states
+ -- can now be done via strings (ref. getstate/putstate)
+
+5.86 Thu Jan 30 08:24:28 MST 2014
+ - changes only to Digest::SHA for version 5.86
+
5.85 Wed Jun 26 04:05:26 MST 2013
- corrected typos in shasum script
-- ref. Bug #85430 (posted at Digest::SHA)
@@ -9,7 +9,6 @@ lib/Digest/SHA/PurePerl.pm
t/allfcns.t
t/base64.t
t/bitbuf.t
-t/dumpload.t
t/fips180-4.t
t/fips198.t
t/gg.t
@@ -27,5 +26,6 @@ t/sha224.t
t/sha256.t
t/sha384.t
t/sha512.t
+t/state.t
t/unicode.t
t/woodbury.t
@@ -1,6 +1,6 @@
--- #YAML:1.0
name: Digest-SHA-PurePerl
-version: 5.85
+version: 5.88
abstract: Perl implementation of SHA-1/224/256/384/512
license: perl
author:
@@ -11,7 +11,7 @@ requires:
provides:
Digest::SHA::PurePerl:
file: lib/Digest/SHA/PurePerl.pm
- version: 5.85
+ version: 5.88
meta-spec:
version: 1.3
url: http://module-build.sourceforge.net/META-spec-v1.3.html
@@ -1,4 +1,4 @@
-Digest::SHA::PurePerl version 5.85
+Digest::SHA::PurePerl version 5.88
==================================
Digest::SHA::PurePerl is a complete implementation of the NIST
@@ -29,7 +29,7 @@ DEPENDENCIES
COPYRIGHT AND LICENSE
-Copyright (C) 2003-2013 Mark Shelor
+Copyright (C) 2003-2014 Mark Shelor
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
@@ -9,7 +9,7 @@ use integer;
use FileHandle;
use Carp qw(croak);
-$VERSION = '5.85';
+$VERSION = '5.88';
require Exporter;
@ISA = qw(Exporter);
@@ -691,83 +691,76 @@ sub _shacpy {
sub _shadup { my($self) = @_; my($copy); _shacpy($copy, $self) }
sub _shadump {
- my $file = shift;
- my $fh = (!defined($file) || $file eq "")
- ? FileHandle->new("> -")
- : FileHandle->new($file, "w") or return;
my $self = shift;
- my $is32bit = $self->{alg} <= 256;
- my $fmt = $is32bit ? ":%08x" : ":%016x";
+ for (qw(alg H block blockcnt lenhh lenhl lenlh lenll)) {
+ return unless defined $self->{$_};
+ }
- printf $fh "alg:%d\n", $self->{alg};
+ my @state = ();
+ my $fmt = ($self->{alg} <= 256 ? "%08x" : "%016x");
- printf $fh "H";
- for (@{$self->{H}}) { printf $fh $fmt, $is32bit ? $_ & $MAX32 : $_ }
+ push(@state, "alg:" . $self->{alg});
+
+ my @H = map { $self->{alg} <= 256 ? $_ & $MAX32 : $_ } @{$self->{H}};
+ push(@state, "H:" . join(":", map { sprintf($fmt, $_) } @H));
- printf $fh "\nblock";
my @c = unpack("C*", $self->{block});
push(@c, 0x00) while scalar(@c) < ($self->{blocksize} >> 3);
- for (@c) { printf $fh ":%02x", $_ }
-
- printf $fh "\nblockcnt:%u\n", $self->{blockcnt};
-
- printf $fh "lenhh:%lu\n", $self->{lenhh} & $MAX32;
- printf $fh "lenhl:%lu\n", $self->{lenhl} & $MAX32;
- printf $fh "lenlh:%lu\n", $self->{lenlh} & $MAX32;
- printf $fh "lenll:%lu\n", $self->{lenll} & $MAX32;
-
- close($fh);
- $self;
+ push(@state, "block:" . join(":", map {sprintf("%02x", $_)} @c));
+ push(@state, "blockcnt:" . $self->{blockcnt});
+
+ push(@state, "lenhh:" . $self->{lenhh});
+ push(@state, "lenhl:" . $self->{lenhl});
+ push(@state, "lenlh:" . $self->{lenlh});
+ push(@state, "lenll:" . $self->{lenll});
+ join("\n", @state) . "\n";
}
-sub _match {
- my($fh, $tag) = @_;
- my @f;
- while (<$fh>) {
+sub _shaload {
+ my $state = shift;
+
+ my %s = ();
+ for (split(/\n/, $state)) {
s/^\s+//;
s/\s+$//;
next if (/^(#|$)/);
- @f = split(/[:\s]+/);
- last;
+ my @f = split(/[:\s]+/);
+ my $tag = shift(@f);
+ $s{$tag} = join('', @f);
}
- shift(@f) eq $tag or return;
- return(@f);
-}
-sub _shaload {
- my $file = shift;
- my $fh = (!defined($file) || $file eq "")
- ? FileHandle->new("< -")
- : FileHandle->new($file, "r") or return;
-
- my @f = _match($fh, "alg") or return;
- my $self = _shaopen(shift(@f)) or return;
-
- @f = _match($fh, "H") or return;
- my $numxdigits = $self->{alg} <= 256 ? 8 : 16;
- for (@f) { $_ = "0" . $_ while length($_) < $numxdigits }
- for (@f) { $_ = substr($_, 1) while length($_) > $numxdigits }
- @{$self->{H}} = map { $self->{alg} <= 256 ? hex($_) :
- ((hex(substr($_, 0, 8)) << 16) << 16) |
- hex(substr($_, 8)) } @f;
-
- @f = _match($fh, "block") or return;
- for (@f) { $self->{block} .= chr(hex($_)) }
-
- @f = _match($fh, "blockcnt") or return;
- $self->{blockcnt} = shift(@f);
+ # H and block may contain arbitrary values, but check everything else
+ grep { $_ == $s{alg} } (1,224,256,384,512,512224,512256) or return;
+ length($s{H}) == ($s{alg} <= 256 ? 64 : 128) or return;
+ length($s{block}) == ($s{alg} <= 256 ? 128 : 256) or return;
+ {
+ no integer;
+ for (qw(blockcnt lenhh lenhl lenlh lenll)) {
+ 0 <= $s{$_} or return;
+ $s{$_} <= 4294967295 or return;
+ }
+ $s{blockcnt} < ($s{alg} <= 256 ? 512 : 1024) or return;
+ }
+
+ my $self = _shaopen($s{alg}) or return;
+
+ my @h = $s{H} =~ /(.{8})/g;
+ for (@{$self->{H}}) {
+ $_ = hex(shift @h);
+ if ($self->{alg} > 256) {
+ $_ = (($_ << 16) << 16) | hex(shift @h);
+ }
+ }
+
+ $self->{blockcnt} = $s{blockcnt};
+ $self->{block} = pack("H*", $s{block});
$self->{block} = substr($self->{block},0,_BYTECNT($self->{blockcnt}));
- @f = _match($fh, "lenhh") or return;
- $self->{lenhh} = shift(@f);
- @f = _match($fh, "lenhl") or return;
- $self->{lenhl} = shift(@f);
- @f = _match($fh, "lenlh") or return;
- $self->{lenlh} = shift(@f);
- @f = _match($fh, "lenll") or return;
- $self->{lenll} = shift(@f);
+ $self->{lenhh} = $s{lenhh};
+ $self->{lenhl} = $s{lenhl};
+ $self->{lenlh} = $s{lenlh};
+ $self->{lenll} = $s{lenll};
- close($fh);
$self;
}
@@ -932,6 +925,20 @@ sub _addfile {
$self;
}
+my $_can_T_filehandle;
+
+sub _istext {
+ local *FH = shift;
+ my $file = shift;
+
+ if (! defined $_can_T_filehandle) {
+ local $^W = 0;
+ eval { -T FH };
+ $_can_T_filehandle = $@ ? 0 : 1;
+ }
+ return $_can_T_filehandle ? -T FH : -T $file;
+}
+
sub _Addfile {
my ($self, $file, $mode) = @_;
@@ -959,55 +966,70 @@ sub _Addfile {
}
binmode(FH) if $binary || $portable;
- unless ($portable && -T $file) {
+ unless ($portable && _istext(*FH, $file)) {
$self->_addfile(*FH);
close(FH);
return($self);
}
- my ($n1, $n2);
- my ($buf1, $buf2) = ("", "");
-
- while (($n1 = read(FH, $buf1, 4096))) {
- while (substr($buf1, -1) eq "\015") {
- $n2 = read(FH, $buf2, 4096);
- _bail("Read failed") unless defined $n2;
- last unless $n2;
- $buf1 .= $buf2;
- }
- $buf1 =~ s/\015?\015\012/\012/g; # DOS/Windows
- $buf1 =~ s/\015/\012/g; # early MacOS
- $self->add($buf1);
+ while (<FH>) {
+ s/\015?\015\012/\012/g; # DOS/Windows
+ s/\015/\012/g; # early MacOS
+ $self->add($_);
}
- _bail("Read failed") unless defined $n1;
close(FH);
$self;
}
-sub dump {
+sub getstate {
my $self = shift;
- my $file = shift;
- $file = "" unless defined $file;
- _shadump($file, $self) or return;
- return($self);
+ return _shadump($self);
}
-sub load {
+sub putstate {
my $class = shift;
- my $file = shift;
+ my $state = shift;
- $file = "" unless defined $file;
if (ref($class)) { # instance method
- my $self = _shaload($file) or return;
+ my $self = _shaload($state) or return;
return(_shacpy($class, $self));
}
- my $self = _shaload($file) or return;
+ my $self = _shaload($state) or return;
bless($self, $class);
return($self);
}
+sub dump {
+ my $self = shift;
+ my $file = shift;
+
+ my $state = $self->getstate or return;
+ $file = "-" if (!defined($file) || $file eq "");
+
+ local *FH;
+ open(FH, "> $file") or return;
+ print FH $state;
+ close(FH);
+
+ return($self);
+}
+
+sub load {
+ my $class = shift;
+ my $file = shift;
+
+ $file = "-" if (!defined($file) || $file eq "");
+
+ local *FH;
+ open(FH, "< $file") or return;
+ my $str = join('', <FH>);
+ close(FH);
+
+ $class->putstate($str);
+}
+
1;
__END__
@@ -1045,9 +1067,9 @@ In programs:
$sha->add_bits($bits);
$sha->add_bits($data, $nbits);
- $sha_copy = $sha->clone; # if needed, make copy of
- $sha->dump($file); # current digest state,
- $sha->load($file); # or save it on disk
+ $sha_copy = $sha->clone; # make copy of digest object
+ $state = $sha->getstate; # save current state to string
+ $sha->putstate($state); # restore previous $state
$digest = $sha->digest; # compute digest
$digest = $sha->hexdigest;
@@ -1123,16 +1145,15 @@ Note that for larger bit-strings, it's more efficient to use the
two-argument version I<add_bits($data, $nbits)>, where I<$data> is
in the customary packed binary format used for Perl strings.
-The module also lets you save intermediate SHA states to disk, or
-display them on standard output. The I<dump()> method generates
-portable, human-readable text describing the current state of
-computation. You can subsequently retrieve the file with I<load()>
-to resume where the calculation left off.
+The module also lets you save intermediate SHA states to a string. The
+I<getstate()> method generates portable, human-readable text describing
+the current state of computation. You can subsequently restore that
+state with I<putstate()> to resume where the calculation left off.
To see what a state description looks like, just run the following:
use Digest::SHA::PurePerl;
- Digest::SHA::PurePerl->new->add("Shaw" x 1962)->dump;
+ print Digest::SHA::PurePerl->new->add("Shaw" x 1962)->getstate;
As an added convenience, the Digest::SHA::PurePerl module offers
routines to calculate keyed hashes using the HMAC-SHA-1/224/256/384/512
@@ -1385,21 +1406,30 @@ a convenient way to calculate the digest values of partial-byte data by
using files, rather than having to write programs using the I<add_bits>
method.
+=item B<getstate>
+
+Returns a string containing a portable, human-readable representation
+of the current SHA state.
+
+=item B<putstate($str)>
+
+Returns a Digest::SHA object representing the SHA state contained
+in I<$str>. The format of I<$str> matches the format of the output
+produced by method I<getstate>. If called as a class method, a new
+object is created; if called as an instance method, the object is reset
+to the state contained in I<$str>.
+
=item B<dump($filename)>
-Provides persistent storage of intermediate SHA states by writing
-a portable, human-readable representation of the current state to
-I<$filename>. If the argument is missing, or equal to the empty
-string, the state information will be written to STDOUT.
+Writes the output of I<getstate> to I<$filename>. If the argument is
+missing, or equal to the empty string, the state information will be
+written to STDOUT.
=item B<load($filename)>
-Returns a Digest::SHA::PurePerl object representing the intermediate
-SHA state that was previously dumped to I<$filename>. If called
-as a class method, a new object is created; if called as an instance
-method, the object is reset to the state contained in I<$filename>.
-If the argument is missing, or equal to the empty string, the state
-information will be read from STDIN.
+Returns a Digest::SHA object that results from calling I<putstate> on
+the contents of I<$filename>. If the argument is missing, or equal to
+the empty string, the state information will be read from STDIN.
=item B<digest>
@@ -1553,7 +1583,7 @@ darkness and moored it in so perfect a calm and in so brilliant a light"
=head1 COPYRIGHT AND LICENSE
-Copyright (C) 2003-2013 Mark Shelor
+Copyright (C) 2003-2014 Mark Shelor
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
@@ -2,10 +2,10 @@
## shasum: filter for computing SHA digests (ref. sha1sum/md5sum)
##
- ## Copyright (C) 2003-2013 Mark Shelor, All Rights Reserved
+ ## Copyright (C) 2003-2014 Mark Shelor, All Rights Reserved
##
- ## Version: 5.85
- ## Wed Jun 26 04:05:26 MST 2013
+ ## Version: 5.88
+ ## Mon Mar 17 08:46:10 MST 2014
## shasum SYNOPSIS adapted from GNU Coreutils sha1sum.
## Add an "-a" option for algorithm selection, a "-p"
@@ -47,10 +47,11 @@ shasum - Print or Check SHA Checksums
shasum -a 512224 -c checksumfile
- The sums are computed as described in FIPS-180-4. When checking, the
- input should be a former output of this program. The default mode is to
- print a line with checksum, a character indicating type (`*' for binary,
- ` ' for text, `?' for portable, `^' for BITS), and name for each FILE.
+ The sums are computed as described in FIPS PUB 180-4. When checking,
+ the input should be a former output of this program. The default
+ mode is to print a line with checksum, a character indicating type
+ (`*' for binary, ` ' for text, `?' for portable, `^' for BITS),
+ and name for each FILE.
Report shasum bugs to mshelor@cpan.org
@@ -82,7 +83,7 @@ the 7-bit message I<0001100>:
=head1 AUTHOR
-Copyright (c) 2003-2013 Mark Shelor <mshelor@cpan.org>.
+Copyright (c) 2003-2014 Mark Shelor <mshelor@cpan.org>.
=head1 SEE ALSO
@@ -97,23 +98,7 @@ use strict;
use Fcntl;
use Getopt::Long;
-my $VERSION = "5.85";
-
-
- ## Try to use Digest::SHA. If not installed, use the slower
- ## but functionally equivalent Digest::SHA::PurePerl instead.
-
-my $MOD_PREFER = "Digest::SHA";
-my $MOD_SECOND = "Digest::SHA::PurePerl";
-
-my $module = $MOD_PREFER;
-eval "require $module";
-if ($@) {
- $module = $MOD_SECOND;
- eval "require $module";
- die "Unable to find $MOD_PREFER or $MOD_SECOND\n" if $@;
-}
-
+my $VERSION = "5.88";
sub usage {
my($err, $msg) = @_;
@@ -123,9 +108,11 @@ sub usage {
warn($msg . "Type shasum -h for help\n");
exit($err);
}
- my($USAGE) = $POD =~ /SYNOPSIS\n\n(.+)\n=head1 DESCRIPTION\n/sm;
+ my($USAGE) = $POD =~ /SYNOPSIS(.+?)^=/sm;
+ $USAGE =~ s/^\s*//;
+ $USAGE =~ s/\s*$//;
$USAGE =~ s/^ //gm;
- print $USAGE;
+ print $USAGE, "\n";
exit($err);
}
@@ -139,7 +126,7 @@ select((select(STDERR), $| = 1)[0]);
## Collect options from command line
my ($alg, $binary, $check, $text, $status, $warn, $help, $version);
-my ($portable, $BITS);
+my ($portable, $BITS, $modules, $versions);
eval { Getopt::Long::Configure ("bundling") };
GetOptions(
@@ -148,7 +135,9 @@ GetOptions(
's|status' => \$status, 'w|warn' => \$warn,
'h|help' => \$help, 'v|version' => \$version,
'p|portable' => \$portable,
- '0|01' => \$BITS
+ '0|01' => \$BITS,
+ 'M|MODULES=s' => \$modules,
+ 'V|VERSIONS' => \$versions,
) or usage(1, "");
@@ -164,6 +153,28 @@ usage(1, "shasum: --status option used only when verifying checksums\n")
if $status && !$check;
+ ## Try to use Digest::SHA. If not installed, use the slower
+ ## but functionally equivalent Digest::SHA::PurePerl instead.
+
+ ## If option -M "Mod::Num1 Mod::Num2 ..." is invoked, try
+ ## those modules instead, in the order indicated.
+
+my @MODS = defined $modules
+ ? split(" ", $modules)
+ : qw(Digest::SHA Digest::SHA::PurePerl);
+
+my $module;
+for (@MODS) {
+ my $mod = $_;
+ if (eval "require $mod") {
+ $module = $mod;
+ last;
+ }
+}
+die "shasum: Unable to find " . join(" or ", @MODS) . "\n"
+ unless defined $module;
+
+
## Default to SHA-1 unless overridden by command line option
$alg = 1 unless defined $alg;
@@ -178,6 +189,13 @@ if ($version) {
exit(0);
}
+if ($versions) {
+ print "shasum $VERSION\n";
+ print "$module ", eval "\$${module}::VERSION", "\n";
+ print "perl ", defined $^V ? sprintf("%vd", $^V) : $], "\n";
+ exit(0);
+}
+
## Try to figure out if the OS is DOS-like. If it is,
## default to binary mode when reading files, unless
@@ -1,102 +0,0 @@
-use strict;
-use FileHandle;
-
-my $MODULE;
-
-BEGIN {
- $MODULE = (-d "src") ? "Digest::SHA" : "Digest::SHA::PurePerl";
- eval "require $MODULE" || die $@;
- $MODULE->import(qw(sha384_hex sha512_hex));
-}
-
-BEGIN {
- if ($ENV{PERL_CORE}) {
- chdir 't' if -d 't';
- @INC = '../lib';
- }
-}
-
-my @sharsp = (
- "34aa973cd4c4daa4f61eeb2bdbad27316534016f",
- "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0",
- "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985",
- "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
-);
-
-my $numtests = scalar @sharsp;
-print "1..$numtests\n";
-
-my @tempfiles;
-END { 1 while unlink @tempfiles }
-
-my @statefiles = ("dl001.tmp", "dl256.tmp", "dl384.tmp", "dl512.tmp");
-for (@statefiles) {
- push @tempfiles, $_;
- my $fh = FileHandle->new($_, "w");
- for (1 .. 8) { my $line = <DATA>; print $fh $line }
- $fh->close;
-}
-my $tmpfile = "dumpload.tmp";
-push @tempfiles, $tmpfile;
-
-my @alg = (1, 256, 384, 512);
-my $data = "a" x 990000;
-
-my $testnum = 1;
-while (@sharsp) {
- my $skip = 0;
- my $alg = shift @alg;
- my $rsp = shift @sharsp;
- my $file = shift @statefiles; push(@statefiles, $file);
- if ($alg == 384) { $skip = sha384_hex("") ? 0 : 1 }
- if ($alg == 512) { $skip = sha512_hex("") ? 0 : 1 }
- if ($skip) {
- print "ok ", $testnum++, " # skip: no 64-bit\n";
- next;
- }
- my $digest;
- my $state;
- unless ($state = $MODULE->load($file)) {
- print "not ok ", $testnum++, "\n";
- next;
- }
- $state->add_bits($data, 79984)->dump($tmpfile);
- $state->load($tmpfile)->add_bits($data, 16);
- $digest = $state->hexdigest;
- print "not " unless $digest eq $rsp;
- print "ok ", $testnum++, "\n";
-}
-
-__DATA__
-alg:1
-H:9d6f7d2f:65e21307:c6f41af6:7c7fd3a9:8dec6058:00000000:00000000:00000000
-block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
-blockcnt:384
-lenhh:0
-lenhl:0
-lenlh:0
-lenll:7920000
-alg:256
-H:2d6c0def:4244ade7:fc8c121c:108f4493:ec3fbec2:91425a6e:b8d30d2a:9db24273
-block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
-blockcnt:384
-lenhh:0
-lenhl:0
-lenlh:0
-lenll:7920000
-alg:384
-H:598147f4583a61f7:8d194a4d7c9008cb:39725c96557d600f:d7f2079ce8251f19:bd735d446f9a3c7c:234de90b9060898d:a5b481b9d635d190:81c6e74ee4556125
-block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
-blockcnt:384
-lenhh:0
-lenhl:0
-lenlh:0
-lenll:7920000
-alg:512
-H:0442fe29a02b8c30:13553e6dbedc2aa0:8f891a0cb2ac3107:6fa1762b40ac04dd:dcbf420d729eea79:34703e9672dcf145:7bf9aaa14d400433:2aa65f044825466d
-block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
-blockcnt:384
-lenhh:0
-lenhl:0
-lenlh:0
-lenll:7920000
@@ -1,7 +1,6 @@
# Test against long bitwise vectors from Jim Gillogly and Francois Grieu
use strict;
-use FileHandle;
my $MODULE;
@@ -50,97 +49,42 @@ my @vec011 = ( # 011 rep 1431655764
"0110", "a3d7438c589b0b932aa91cc2446f06df9abc73f0",
"01101", "3eee3e1e28dede2ca444d68da5675b2faaab3203"
);
-print "1..", scalar(@vec110) / 2 + scalar(@vec011) / 2, "\n";
-my $STATE110 = "gglong0.tmp";
-my $STATE011 = "gglong1.tmp";
-
-END { 1 while unlink $STATE110, $STATE011 }
-
-for ($STATE011, $STATE110) {
- my $fh = FileHandle->new($_, "w");
- for (1 .. 8) { my $line = <DATA>; print $fh $line }
- $fh->close;
-}
-
-my $reps = 1 << 14;
-my $loops = int(1431655764 / $reps);
-my $rest = 3 * (1431655764 - $loops * $reps);
-
-sub state110 {
- my $i;
- my $state;
- my $bitstr;
-
- $state = $MODULE->new(1);
- if (-r $STATE110) {
- if ($state->load($STATE110)) {
- return($state);
- }
- }
- $bitstr = pack("B*", "110" x $reps);
- $state->reset;
- for ($i = 0; $i < $loops; $i++) {
- $state->add_bits($bitstr, 3 * $reps);
- }
- $state->add_bits($bitstr, $rest);
- $state->dump($STATE110);
- return($state);
-}
-
-sub state011 {
- my $i;
- my $state;
- my $bitstr;
-
- $state = $MODULE->new(1);
- if (-r $STATE011) {
- if ($state->load($STATE011)) {
- return($state);
- }
- }
- $bitstr = pack("B*", "011" x $reps);
- $state->reset;
- for ($i = 0; $i < $loops; $i++) {
- $state->add_bits($bitstr, 3 * $reps);
- }
- $state->add_bits($bitstr, $rest);
- $state->dump($STATE011);
- return($state);
-}
-
-my $i;
+my($STATE110, $STATE011) = ('', '');
+for (1 .. 8) { my $line = <DATA>; $STATE110 .= $line }
+for (1 .. 8) { my $line = <DATA>; $STATE011 .= $line }
my $testnum = 1;
+print "1..", scalar(@vec110)/2 + scalar(@vec011)/2, "\n";
-my $state110 = state110();
-for ($i = 0; $i < @vec110/2; $i++) {
+my $state110 = $MODULE->putstate($STATE110);
+while (@vec110) {
my $state = $state110->clone;
- $state->add_bits($vec110[2*$i]);
- print "not " unless $state->hexdigest eq $vec110[2*$i+1];
+ $state->add_bits(shift @vec110);
+ print "not " unless $state->hexdigest eq (shift @vec110);
print "ok ", $testnum++, "\n";
}
-my $state011 = state011();
-for ($i = 0; $i < @vec011/2; $i++) {
+my $state011 = $MODULE->putstate($STATE011);
+while (@vec011) {
my $state = $state011->clone;
- $state->add_bits($vec011[2*$i]);
- print "not " unless $state->hexdigest eq $vec011[2*$i+1];
+ $state->add_bits(shift @vec011);
+ print "not " unless $state->hexdigest eq (shift @vec011);
print "ok ", $testnum++, "\n";
}
__DATA__
alg:1
-H:7950cbe2:86a45aa0:91ff7dff:29015b42:3912e764:00000000:00000000:00000000
-block:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6
+H:dfc51a14:87b4a4b7:ecf19acd:8cbbe40e:03a435f8:00000000:00000000:00000000
+block:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d
blockcnt:508
lenhh:0
lenhl:0
lenlh:0
lenll:4294967292
alg:1
-H:dfc51a14:87b4a4b7:ecf19acd:8cbbe40e:03a435f8:00000000:00000000:00000000
-block:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d
+H:7950cbe2:86a45aa0:91ff7dff:29015b42:3912e764:00000000:00000000:00000000
+block:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6:db:6d:b6
blockcnt:508
lenhh:0
lenhl:0
@@ -7,7 +7,7 @@ my $MODULE;
BEGIN {
$MODULE = (-d "src") ? "Digest::SHA" : "Digest::SHA::PurePerl";
eval "require $MODULE" || die $@;
- $MODULE->import(qw(hmac_sha256_hex));
+ $MODULE->import(qw(hmac_sha256 hmac_sha256_hex));
}
BEGIN {
@@ -51,11 +51,11 @@ my @out = (
"6355ac22e890d0a3c8481a5ca4825bc884d3e7a1ff98a2fc2ac7d8e064c3b2e6"
);
- # do the first one using multi-argument data feed
+ # do first one using multi-argument data feed and binary output
my $testnum = 1;
my @args = split(//, shift @data);
-print "not " unless hmac_sha256_hex(@args, shift @keys) eq shift @out;
+print "not " unless hmac_sha256(@args, shift @keys) eq pack("H*", shift @out);
print "ok ", $testnum++, "\n";
while (@data) {
@@ -1,5 +1,4 @@
use strict;
-use FileHandle;
my $MODULE;
@@ -19,20 +18,14 @@ BEGIN {
# David Ireland's test vector - SHA-256 digest of "a" x 536870912
# Adapted from Julius Duque's original script (t/24-ireland.tmp)
-# - modified to use state cache via dump()/load() methods
+# - modified to use state cache via putstate method
print "1..1\n";
-my $tempfile = "ireland.tmp";
-END { 1 while unlink $tempfile }
-
-my $fh = FileHandle->new($tempfile, "w");
-while (<DATA>) { print $fh $_ } close($fh);
-
my $rsp = "b9045a713caed5dff3d3b783e98d1ce5778d8bc331ee4119d707072312af06a7";
my $sha;
-if ($sha = $MODULE->load($tempfile)) {
+if ($sha = $MODULE->putstate(join('', <DATA>))) {
$sha->add("aa");
print "not " unless $sha->hexdigest eq $rsp;
print "ok 1\n";
@@ -40,11 +33,19 @@ if ($sha = $MODULE->load($tempfile)) {
else { print "not ok 1\n" }
__DATA__
+
+ # Verify comments/blank lines ignored in state data
+
alg:256
H:dd75eb45:02d4f043:06b41193:6fda751d:73064db9:787d54e1:52dc3fe0:48687dfa
-block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
+
+block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00
blockcnt:496
+
lenhh:0
lenhl:0
lenlh:0
+
+# Note: add'ing two more bytes will cause lenll (below) to overflow
+
lenll:4294967280
@@ -32,9 +32,7 @@ if ($MODULE eq "Digest::SHA") {
B64digest
Hexdigest
shaclose
- shadump
shadup
- shaload
shaopen
sharewind
shawrite
@@ -0,0 +1,94 @@
+use strict;
+
+my $MODULE;
+
+BEGIN {
+ $MODULE = (-d "src") ? "Digest::SHA" : "Digest::SHA::PurePerl";
+ eval "require $MODULE" || die $@;
+ $MODULE->import(qw(sha384_hex sha512_hex));
+}
+
+BEGIN {
+ if ($ENV{PERL_CORE}) {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ }
+}
+
+my @sharsp = (
+ "34aa973cd4c4daa4f61eeb2bdbad27316534016f",
+ "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0",
+ "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985",
+ "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
+);
+
+my $numtests = scalar @sharsp;
+print "1..$numtests\n";
+
+my($state001, $state256, $state384, $state512) = ('', '', '', '');
+for (1 .. 8) { my $line = <DATA>; $state001 .= $line }
+for (1 .. 8) { my $line = <DATA>; $state256 .= $line }
+for (1 .. 8) { my $line = <DATA>; $state384 .= $line }
+for (1 .. 8) { my $line = <DATA>; $state512 .= $line }
+my @states = ($state001, $state256, $state384, $state512);
+
+my @alg = (1, 256, 384, 512);
+my $data = "a" x 990000;
+
+my $testnum = 1;
+while (@sharsp) {
+ my $skip = 0;
+ my $alg = shift @alg;
+ my $rsp = shift @sharsp;
+ if ($alg == 384) { $skip = sha384_hex("") ? 0 : 1 }
+ if ($alg == 512) { $skip = sha512_hex("") ? 0 : 1 }
+ if ($skip) {
+ print "ok ", $testnum++, " # skip: no 64-bit\n";
+ next;
+ }
+ my $digest;
+ my $state;
+ unless ($state = $MODULE->putstate(shift @states)) {
+ print "not ok ", $testnum++, "\n";
+ next;
+ }
+ my $statestr = $state->add_bits($data, 79984)->getstate;
+ $state->putstate($statestr)->add_bits($data, 16);
+ $digest = $state->hexdigest;
+ print "not " unless $digest eq $rsp;
+ print "ok ", $testnum++, "\n";
+}
+
+__DATA__
+alg:1
+H:9d6f7d2f:65e21307:c6f41af6:7c7fd3a9:8dec6058:00000000:00000000:00000000
+block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
+blockcnt:384
+lenhh:0
+lenhl:0
+lenlh:0
+lenll:7920000
+alg:256
+H:2d6c0def:4244ade7:fc8c121c:108f4493:ec3fbec2:91425a6e:b8d30d2a:9db24273
+block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
+blockcnt:384
+lenhh:0
+lenhl:0
+lenlh:0
+lenll:7920000
+alg:384
+H:598147f4583a61f7:8d194a4d7c9008cb:39725c96557d600f:d7f2079ce8251f19:bd735d446f9a3c7c:234de90b9060898d:a5b481b9d635d190:81c6e74ee4556125
+block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
+blockcnt:384
+lenhh:0
+lenhl:0
+lenlh:0
+lenll:7920000
+alg:512
+H:0442fe29a02b8c30:13553e6dbedc2aa0:8f891a0cb2ac3107:6fa1762b40ac04dd:dcbf420d729eea79:34703e9672dcf145:7bf9aaa14d400433:2aa65f044825466d
+block:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:61:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
+blockcnt:384
+lenhh:0
+lenhl:0
+lenlh:0
+lenll:7920000