summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Peters <steve@fisharerojo.org>2006-01-08 04:17:08 +0000
committerSteve Peters <steve@fisharerojo.org>2006-01-08 04:17:08 +0000
commit6bc89f92370990b836308b02c6551b4e758e7401 (patch)
treed0b0e698cd78731e731509254694ad7f843b6fcd
parentd00eb2498c2f3efedfc04e6a6a3691e600b0c96a (diff)
downloadperl-6bc89f92370990b836308b02c6551b4e758e7401.tar.gz
Add Digest-SHA-5.32 for SHA-256 support for CPAN.
p4raw-id: //depot/perl@26704
-rw-r--r--MANIFEST52
-rw-r--r--Porting/Maintainers.pl8
-rw-r--r--ext/Digest/SHA/Changes303
-rw-r--r--ext/Digest/SHA/Makefile.PL34
-rw-r--r--ext/Digest/SHA/README44
-rw-r--r--ext/Digest/SHA/SHA.pm560
-rw-r--r--ext/Digest/SHA/SHA.xs201
-rwxr-xr-xext/Digest/SHA/bin/shasum212
-rw-r--r--ext/Digest/SHA/ppport.h540
-rw-r--r--ext/Digest/SHA/t/0-pod-coverage.t25
-rw-r--r--ext/Digest/SHA/t/0-pod.t11
-rw-r--r--ext/Digest/SHA/t/1-exist.t17
-rw-r--r--ext/Digest/SHA/t/1-hello-world.t20
-rw-r--r--ext/Digest/SHA/t/2-nist-sha-1.t26
-rw-r--r--ext/Digest/SHA/t/2-nist-sha-224.t26
-rw-r--r--ext/Digest/SHA/t/2-nist-sha-256.t26
-rw-r--r--ext/Digest/SHA/t/2-nist-sha-384.t28
-rw-r--r--ext/Digest/SHA/t/2-nist-sha-512.t28
-rw-r--r--ext/Digest/SHA/t/2-nist-sha-base64.t30
-rw-r--r--ext/Digest/SHA/t/2-nist-sha-oo.t44
-rw-r--r--ext/Digest/SHA/t/2-nist-vectors-bit.t82
-rw-r--r--ext/Digest/SHA/t/2-nist-vectors-byte.t82
-rw-r--r--ext/Digest/SHA/t/3-gillogly-easy.t61
-rw-r--r--ext/Digest/SHA/t/3-gillogly-hard.t114
-rw-r--r--ext/Digest/SHA/t/4-bitstr-increasing.t22
-rw-r--r--ext/Digest/SHA/t/4-bitstr-large.t21
-rw-r--r--ext/Digest/SHA/t/4-bitstr-random.t24
-rw-r--r--ext/Digest/SHA/t/5-hmac-fips198.t44
-rw-r--r--ext/Digest/SHA/t/5-hmac-rfc2202.t49
-rw-r--r--ext/Digest/SHA/t/5-hmac-sha-256.t64
-rw-r--r--ext/Digest/SHA/t/5-hmac-woodbury.t114
-rw-r--r--ext/Digest/SHA/t/6-dump-load.t53
-rw-r--r--ext/Digest/SHA/t/7-ireland.t41
-rw-r--r--ext/Digest/SHA/t/gillogly/state.0118
-rw-r--r--ext/Digest/SHA/t/gillogly/state.1108
-rw-r--r--ext/Digest/SHA/t/nist/COPYRIGHT17
-rw-r--r--ext/Digest/SHA/t/nist/Readme.txt82
-rw-r--r--ext/Digest/SHA/t/nist/bit-hashes.sha114
-rw-r--r--ext/Digest/SHA/t/nist/bit-messages.sha114
-rw-r--r--ext/Digest/SHA/t/nist/byte-hashes.sha114
-rw-r--r--ext/Digest/SHA/t/nist/byte-messages.sha114
-rw-r--r--ext/Digest/SHA/t/state/state.18
-rw-r--r--ext/Digest/SHA/t/state/state.2568
-rw-r--r--ext/Digest/SHA/t/state/state.3848
-rw-r--r--ext/Digest/SHA/t/state/state.5128
-rw-r--r--ext/Digest/SHA/typemap2
-rw-r--r--utils/Makefile8
-rw-r--r--utils/shasum.PL51
48 files changed, 3267 insertions, 3 deletions
diff --git a/MANIFEST b/MANIFEST
index 78436f4c01..bfc436e01f 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -395,6 +395,58 @@ ext/Digest/MD5/t/files.t See if Digest::MD5 extension works
ext/Digest/MD5/t/md5-aaa.t See if Digest::MD5 extension works
ext/Digest/MD5/t/utf8.t See if Digest::MD5 extension works
ext/Digest/MD5/typemap Digest::MD5 extension
+ext/Digest/SHA/bin/shasum shasum script
+ext/Digest/SHA/Changes Digest::SHA changes
+ext/Digest/SHA/Makefile.PL Digest::SHA Makefile.PL
+ext/Digest/SHA/README Digest::SHA README
+ext/Digest/SHA/SHA.pm Digest::SHA extension
+ext/Digest/SHA/SHA.xs Digest::SHA extension
+ext/Digest/SHA/ppport.h Digest::SHA extension
+ext/Digest/SHA/src/hmac.c Digest::SHA extension
+ext/Digest/SHA/src/hmac.h Digest::SHA extension
+ext/Digest/SHA/src/hmacxtra.c Digest::SHA extension
+ext/Digest/SHA/src/sha.c Digest::SHA extension
+ext/Digest/SHA/src/sha.h Digest::SHA extension
+ext/Digest/SHA/src/sha64bit.c Digest::SHA extension
+ext/Digest/SHA/src/sha64bit.h Digest::SHA extension
+ext/Digest/SHA/src/shaxtra.c Digest::SHA extension
+ext/Digest/SHA/t/0-pod-coverage.t See if Digest::SHA works
+ext/Digest/SHA/t/0-pod.t See if Digest::SHA works
+ext/Digest/SHA/t/1-exist.t See if Digest::SHA works
+ext/Digest/SHA/t/1-hello-world.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-sha-1.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-sha-224.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-sha-256.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-sha-384.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-sha-512.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-sha-base64.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-sha-oo.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-vectors-bit.t See if Digest::SHA works
+ext/Digest/SHA/t/2-nist-vectors-byte.t See if Digest::SHA works
+ext/Digest/SHA/t/3-gillogly-easy.t See if Digest::SHA works
+ext/Digest/SHA/t/3-gillogly-hard.t See if Digest::SHA works
+ext/Digest/SHA/t/4-bitstr-increasing.t See if Digest::SHA works
+ext/Digest/SHA/t/4-bitstr-large.t See if Digest::SHA works
+ext/Digest/SHA/t/4-bitstr-random.t See if Digest::SHA works
+ext/Digest/SHA/t/5-hmac-fips198.t See if Digest::SHA works
+ext/Digest/SHA/t/5-hmac-rfc2202.t See if Digest::SHA works
+ext/Digest/SHA/t/5-hmac-sha-256.t See if Digest::SHA works
+ext/Digest/SHA/t/5-hmac-woodbury.t See if Digest::SHA works
+ext/Digest/SHA/t/6-dump-load.t See if Digest::SHA works
+ext/Digest/SHA/t/7-ireland.t See if Digest::SHA works
+ext/Digest/SHA/t/gillogly/state.011 See if Digest::SHA works
+ext/Digest/SHA/t/gillogly/state.110 See if Digest::SHA works
+ext/Digest/SHA/t/nist/COPYRIGHT See if Digest::SHA works
+ext/Digest/SHA/t/nist/Readme.txt See if Digest::SHA works
+ext/Digest/SHA/t/nist/bit-hashes.sha1 See if Digest::SHA works
+ext/Digest/SHA/t/nist/bit-messages.sha1 See if Digest::SHA works
+ext/Digest/SHA/t/nist/byte-hashes.sha1 See if Digest::SHA works
+ext/Digest/SHA/t/nist/byte-messages.sha1 See if Digest::SHA works
+ext/Digest/SHA/t/state/state.1 See if Digest::SHA works
+ext/Digest/SHA/t/state/state.256 See if Digest::SHA works
+ext/Digest/SHA/t/state/state.384 See if Digest::SHA works
+ext/Digest/SHA/t/state/state.512 See if Digest::SHA works
+ext/Digest/SHA/typemap See if Digest::SHA works
ext/DynaLoader/dl_aix.xs AIX implementation
ext/DynaLoader/dl_beos.xs BeOS implementation
ext/DynaLoader/dl_dld.xs GNU dld style implementation
diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl
index bf434fbd65..c2df788234 100644
--- a/Porting/Maintainers.pl
+++ b/Porting/Maintainers.pl
@@ -38,6 +38,7 @@ package Maintainers;
'marekr' => 'Marek Rouchal <marekr@cpan.org>',
'mhx' => 'Marcus Holland-Moritz <mhx@cpan.org>',
'mjd' => 'Mark-Jason Dominus <mjd@plover.com>',
+ 'mshelor' => 'Mark Shelor <mshelor@cpan.org>',
'muir' => 'David Muir Sharnoff <muir@cpan.org>',
'neilb' => 'Neil Bowers <neilb@cpan.org>',
'ni-s' => 'Nick Ing-Simmons <nick@ing-simmons.net>',
@@ -179,6 +180,13 @@ package Maintainers;
'CPAN' => 1,
},
+ 'Digest::SHA' =>
+ {
+ 'MAINTAINER' => 'mshelor',
+ 'FILES' => q[ext/Digest/SHA],
+ 'CPAN' => 1,
+ },
+
'Encode' =>
{
'MAINTAINER' => 'dankogai',
diff --git a/ext/Digest/SHA/Changes b/ext/Digest/SHA/Changes
new file mode 100644
index 0000000000..68f5e6ab0f
--- /dev/null
+++ b/ext/Digest/SHA/Changes
@@ -0,0 +1,303 @@
+Revision history for Perl extension Digest::SHA.
+
+5.32 Fri Dec 2 02:32:20 MST 2005
+ - added POD section to shasum script
+ -- thanks to Gunnar Wolf for patch
+ - made minor code changes to silence compiler warnings
+ -- resulting from signed/unsigned integer mixing
+ - inserted code in test scripts for POD checking
+ -- to recover gracefully if Test::More isn't installed
+
+5.31 Mon Sep 5 00:52:42 MST 2005
+ - added standard tests for pod and pod-coverage checking
+ - inserted subtest to check for failure when using
+ unrecognized SHA algorithm
+
+5.30 Sat Aug 20 16:46:08 MST 2005
+ - updated docs with recent NIST statement on SHA-1
+ -- advises use of larger and stronger hash functions
+ (i.e. SHA-224/256/384/512) for new developments
+
+5.29 Sun Aug 14 04:48:34 MST 2005
+ - added explicit casts in "shaload" routine (ref. "ldvals")
+ -- thanks to E. Allen Smith for pointing out SGI compiler
+ warnings on IPxx-irix platforms
+ - updated docs with cautionary note about SHA-1
+
+5.28 Wed Nov 10 15:33:20 MST 2004
+ - provided more flexible formatting of SHA state files
+ -- entries may now contain embedded whitespace
+ for improved readability
+ - minor code cleanups
+
+5.27 Sun Oct 24 02:54:00 MST 2004
+ - minor code cleanups
+ -- reduces size of dump files for SHA-1/224/256
+
+5.26 Thu Oct 7 14:52:00 MST 2004
+ - streamlined distribution
+ -- reduced NIST vector tests from 200 to 20
+ -- former number was overkill
+ -- distro now downloads and builds more quickly
+ - rewrote SYNOPSIS sections in pod file
+ - made additional tweaks to t/8-shasum.t for portability
+ - cleaned up test scripts
+
+5.25 Sun Sep 12 18:48:00 MST 2004
+ - removed non-essential test script
+ -- t/8-shasum.t causes problems on sparc64-linux
+ - reverted to using eval "require $module" in shasum
+
+5.24 Sun Sep 12 02:50:18 MST 2004
+ - modified shasum to use barewords in "require" statements
+ -- ref. perl.cpan.testers (157305)
+
+5.23 Thu Sep 9 23:06:18 MST 2004
+ - corrected bug in test script
+ -- use blib when invoking perl as an external
+ command in t/8-shasum.t
+
+5.22 Tue Sep 7 19:12:40 MST 2004
+ - broadened SHA-384/512 support
+ -- to compilers with no ULLONG_MAX in limits.h
+ -- e.g IBM C (xlC 6.0.0) on AIX 4.3.3
+ -- thanks to Chris Carey for suggestions
+ and technical expertise
+ - improved use of static storage class in transforms
+ -- detection of Intel arch. now done in Makefile.PL
+ -- NB: static not used if compiling for thread safety
+ - minor changes to documentation
+
+5.21 Mon Aug 23 04:02:00 MST 2004
+ - removed 64-bit constant expressions from #if statements
+ -- ref. src/sha.h (lines 55, 58, and 61)
+ -- even if compiler supports long long's, preprocessor
+ may use long's when evaluating expressions
+ - improved test script for "shasum" (t/8-shasum.t)
+ -- exercises check file option (-c)
+
+5.20 Sun Aug 15 04:24:48 MST 2004
+ - introduced "shasum" script
+ -- mimics the usage and behavior of "md5sum"
+ -- adds "-a" option to select SHA algorithm
+ -- for help, just type "shasum -h"
+
+5.10 Fri Aug 6 02:04:38 MST 2004
+ - simplified module documentation
+ -- made it consistent with Digest::SHA::PurePerl docs
+
+5.03 Sat Jul 31 00:00:48 MST 2004
+ - corrected HMAC-SHA-384/512 bug (cpan #7181, Adam Woodbury)
+ -- code was using hardwired blocksize for SHA-1/256
+ -- ref. src/hmac.c, src/hmac.h
+
+5.02 Thu Jul 29 02:48:00 MST 2004
+ - updated documentation and "dump-load.t" test script
+ -- to be consistent with Digest::SHA::PurePerl
+ - included a SIGNATURE file
+ -- for stronger authentication of module contents
+ -- ref. Module::Signature on CPAN
+ - corrected embarrassing misspelling in docs
+ -- apologies to Gisle Aas
+
+5.01 Fri May 21 13:08:12 MST 2004
+ - check for undefined SHA handle when calling "shaclose()"
+ -- prevents intermittent cleanup errors during
+ global object destruction
+
+5.00 Fri May 14 04:45:00 MST 2004
+ - minor documentation fixes
+ - restored classical style of version numbering (X.YZ)
+ -- previous X.Y.Z style caused installation difficulties
+ when using CPANPLUS
+
+4.3.3 Wed May 5 00:30:40 MST 2004
+ - fixed bug in "strto64()" function
+ -- caused problems in state files with CR/LF pairs
+ -- thanks to Martin Thurn for testing support
+
+4.3.2 Wed Apr 28 03:56:00 MST 2004
+ - added Makefile.PL options
+ -- thread-safety: -t
+ -- exclude 384/512 support: -x
+ -- e.g. perl Makefile.PL -t
+ - temporarily suppress dump/load tests for SHA-384/512
+ -- pending clarification of problem on sun4u sparc
+
+4.3.1 Thu Mar 4 02:54:00 MST 2004
+ - removed unused functions from XS file
+ -- reduces size of compiled objects
+ - simplified implementation of Digest::SHA object
+ -- now a blessed SHAPtr ref instead of blessed array ref
+ -- results in slight speed-up of OO operations
+ - streamlined underlying C source
+ -- used macros to consolidate repetitive code
+ - rewrote test scripts to depend on Test rather than Test::More
+ -- allows module to be checked in minimal Perl environments
+ - added compilation option for thread-safety
+ -- overrides use of static arrays
+
+4.3.0 Sat Feb 7 02:58:00 MST 2004
+ - included SHA-384/512 support if using Microsoft C/C++
+ -- uses MSVC's __int64 in place of "long long"
+ - enhanced portability and efficiency on diverse platforms
+ -- automatically sets up optimal types for 32/64-bit ops
+ - improved test scripts for better reporting
+ -- many thanks to Alex Muntada for helpful suggestions
+
+4.2.2 Sat Jan 31 17:10:20 MST 2004
+ - repaired 32-bit SHA operations for 8-byte longs
+
+4.2.1 Sat Jan 24 00:56:54 MST 2004
+ - modified I/O and memory management in underlying C code
+ -- uses Perl libraries when compiled as CPAN module
+ -- otherwise defaults to ANSI C libraries
+ -- bypasses problems in MSWin multi-threaded Perls
+ -- avoids "Free to wrong pool" error
+ -- special thanks to Robert Gilmour and Brian Gladman
+ for technical guidance and testing
+
+4.2.0 Sat Dec 27 16:08:00 MST 2003
+ - added support for recently-announced SHA-224 algorithm
+ -- ref. FIPS 180-2 Change Notice 1
+ -- also includes HMAC-SHA-224
+
+4.1.0 Thu Dec 25 00:58:00 MST 2003
+ - repaired "nist-vectors" test scripts for MSWin32 portability
+ -- use binmode for data files
+
+4.0.9 Wed Dec 24 02:58:22 MST 2003
+ - use canonical file specs in test scripts
+ -- enhances portability across different OSes
+ - modify type declarations of objects in XS file
+ -- re-declare as (SV *) and cast to (AV *) SvRV(self)
+ -- in response to AVPtr problem on MSWin32
+
+4.0.8 Thu Dec 18 23:32:00 MST 2003
+ - inherits from Digest::base if installed
+ -- also checks for MIME::Base64
+ -- still fully-functional if neither are installed
+ - added buffer overflow protection in underlying C code
+ -- ref. shahex() and shabase64() routines
+ -- prior code appeared impossible to exploit, but ...
+ -- better safe than sorry
+ -- does not impact runtime efficiency
+ - minor code cleanup
+
+4.0.7 Sat Dec 13 00:48:24 MST 2003
+ - check for undefined SHA handle when calling "shaclose()"
+ -- was causing cleanup err during global destruction
+
+4.0.6 Thu Dec 11 02:18:00 MST 2003
+ - more optimization and streamlining
+ -- a bit faster on non-big-endians (e.g. Intel)
+ - rewrote time-critical functions and methods in XS
+ - removed unused C functions from source files
+
+4.0.5 Sat Dec 6 00:02:24 MST 2003
+ - performance optimizations
+ -- rewrote "add" method in XS
+ -- unrolled loops in sha256 transform
+
+4.0.4 Thu Dec 4 00:07:00 MST 2003
+ - made Digest::SHA into a self-contained module
+ -- no longer depends on Digest::base
+ -- more convenient for users
+ -- no need to install Digest:: module
+
+4.0.3 Wed Dec 3 00:01:20 MST 2003
+ - Digest::SHA now a subclass of Digest::base
+ -- inherits hexdigest/b64digest/addfile methods
+ - added "hashsize" method
+ - removed old "shaopen()/shawrite()/..." legacy code
+ -- in favor of standard, streamlined OO interface
+ - renamed test vector files from NIST
+ -- prevents problems on 8+3 filesystems
+ - added test for Dave Ireland's SHA-256 vector
+
+4.0.0 Sat Nov 29 21:14:09 MST 2003
+ - major streamlining of interface (hence, major version change)
+ -- coordinated with Gisle Aas and J. Duque
+ -- goal is to produce a single SHA module
+ -- adheres to OO and functional styles of Digest::
+ -- greatly reduces the number of interface functions
+ -- old functions still supported
+ -- use Digest::SHA ':legacy'
+ -- will be deprecated in near future
+ - rewrote all test scripts to match new interface
+ -- very easy to modify all 281 tests
+ -- old interface maps cleanly to new one
+
+3.0 Wed Nov 26 05:02:34 MST 2003
+ - added functions that conform to Digest:: interface
+ -- both functional and OO styles
+ -- byte-oriented data only
+ -- continue to support original interface as well
+ -- necessary for bit-oriented data
+ - supplied formal test vectors for HMAC-SHA-256
+ -- from draft-ietf-ipsec-ciph-sha-256-01.txt
+ - included tests for all OO methods
+
+2.4 Sat Nov 22 17:10:22 MST 2003
+ - code cleanup
+ -- "sha.c" now completely free of #ifdef's
+ - modularized all 64-bit (long long) code
+ - improved readability of header files
+ - simplified logic of "fixdump" utility
+
+2.3 Wed Nov 19 03:54:31 MST 2003
+ - minor optimizations and code cleanup
+ -- improved maintainability by reducing #ifdef's
+ -- sha1 transform code now easier to follow
+ - streamlined shadump/shaload file format
+ -- eliminated special "HQ" entry
+ -- state now held in "H" for all transforms
+ -- supplied "fixdump" utility to convert old format
+ - SHA-384/512 functions now return NULL for no 64-bit operations
+ -- previously they were undefined
+ -- no longer necessary to use eval's to test for presence
+
+2.2 Sun Nov 16 01:54:00 MST 2003
+ - optimized the performance of the SHA-1 transform
+ -- around 20-30% faster than previous version
+ -- achieved by loop unrolling and assignment consolidation
+ - enhanced shaload/shadump to allow interaction with stdin/stdout
+ -- "$filename" argument now optional
+
+2.1 Sun Nov 9 03:28:04 MST 2003
+ - simplified data input routines
+ -- length argument now optional for byte data
+ (special thanks to Jeffrey Friedl for this idea)
+ -- interface still compatible with earlier versions
+ -- changes will not affect existing client code
+ - streamlined underlying C code for easier maintenance
+ - provided additional tests for persistent data
+
+2.0 Sat Nov 1 03:55:36 MST 2003
+ - added functions for HMAC-SHA-1/256/384/512 (FIPS PUB 198)
+ - shadump/shaload files now compatible between 32/64-bit machines
+
+1.01 Sat Oct 25 02:44:55 MST 2003
+ - package now downloads and installs much faster
+ - reduced distribution size by 80%
+ -- pruned extensive NIST vectors to a useful subset
+ -- still possible to test all vectors if desired
+ --- see "t/nist/COPYRIGHT" file for details
+ - added routines to provide persistent storage of SHA states
+ -- shadump() and shaload()
+ - reduced runtime of large bitstring tests (gillogly-hard)
+ -- illustrates usefulness of shadump()/shaload()
+
+1.0 Sat Oct 18 17:35:07 MST 2003
+ - documentation fixes
+ - code cleanup: no more compiler warnings from gcc -Wall
+ - added code to allow reading of intermediate digest state
+ -- shahex() prior to shafinish() returns current state
+
+0.9 Thu Oct 9 20:43:54 MST 2003
+ - version updated to reflect portability check and passing
+ of all tests (1401)
+
+0.01 Wed Oct 8 22:28:05 2003
+ - original version; created by h2xs 1.22 with options
+ -x -A -n Digest::SHA sha.h
diff --git a/ext/Digest/SHA/Makefile.PL b/ext/Digest/SHA/Makefile.PL
new file mode 100644
index 0000000000..fea734c2d7
--- /dev/null
+++ b/ext/Digest/SHA/Makefile.PL
@@ -0,0 +1,34 @@
+use ExtUtils::MakeMaker;
+use Getopt::Std;
+use Config;
+
+my %opts;
+getopts('tx', \%opts);
+
+my @defines = ('-DSHA_PERL_MODULE');
+
+push(@defines, '-DSHA_THREAD_SAFE') if $opts{'t'};
+push(@defines, '-DNO_SHA_384_512') if $opts{'x'};
+
+ # Configure SHA source to use static arrays for
+ # message schedules if compiling on Intel platforms.
+ # This seems to speed things up a bit. However,
+ # DON'T do this if thread-safe option is in force.
+
+if ($Config{archname} =~ /^i[3456]86/) {
+ push(@defines, '-DSHA_STO_CLASS=static') unless $opts{'t'};
+}
+
+my $define = join(' ', @defines);
+
+WriteMakefile(
+ 'NAME' => 'Digest::SHA',
+ 'VERSION_FROM' => 'SHA.pm',
+ 'PREREQ_PM' => {},
+ 'AUTHOR' => 'Mark Shelor <mshelor@cpan.org>',
+ 'LIBS' => [''],
+ MAN3PODS => {}, # Pods will be built by installman.
+ 'DEFINE' => $define,
+ 'INC' => '-I.',
+ 'NO_META' => 1,
+);
diff --git a/ext/Digest/SHA/README b/ext/Digest/SHA/README
new file mode 100644
index 0000000000..1eae56a561
--- /dev/null
+++ b/ext/Digest/SHA/README
@@ -0,0 +1,44 @@
+Digest::SHA version 5.32
+========================
+
+Digest::SHA is a complete implementation of the NIST Secure Hash
+Standard. It gives Perl programmers a convenient way to calculate
+SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 message digests.
+The module can handle all types of input, including partial-byte
+data.
+
+Digest::SHA is written in C for speed. If your platform lacks a
+C compiler, you can install the functionally-equivalent (but much
+slower) Digest::SHA::PurePerl module.
+
+The tests subdirectory (t/*.t) contains an extensive set of SHA
+vectors compiled from various sources.
+
+INSTALLATION
+
+To install this module type the following:
+
+ perl Makefile.PL [ options ]
+ make
+ make test
+ make install
+
+The Makefile.PL options are:
+
+ -t : build a thread-safe version of module
+ -x : exclude support for SHA-384/512
+
+DEPENDENCIES
+
+ None
+
+COPYRIGHT AND LICENSE
+
+Copyright (C) 2003-2005 Mark Shelor
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+Please refer to the Perl Artistic License for details:
+
+http://search.cpan.org/perldoc?perlartistic
diff --git a/ext/Digest/SHA/SHA.pm b/ext/Digest/SHA/SHA.pm
new file mode 100644
index 0000000000..062562f0a4
--- /dev/null
+++ b/ext/Digest/SHA/SHA.pm
@@ -0,0 +1,560 @@
+package Digest::SHA;
+
+use strict;
+use warnings;
+use integer;
+
+our $VERSION = '5.32';
+
+require Exporter;
+our @ISA = qw(Exporter);
+
+our @EXPORT_OK = qw(
+ hmac_sha1 hmac_sha1_base64 hmac_sha1_hex
+ hmac_sha224 hmac_sha224_base64 hmac_sha224_hex
+ hmac_sha256 hmac_sha256_base64 hmac_sha256_hex
+ hmac_sha384 hmac_sha384_base64 hmac_sha384_hex
+ hmac_sha512 hmac_sha512_base64 hmac_sha512_hex
+ sha1 sha1_base64 sha1_hex
+ sha224 sha224_base64 sha224_hex
+ sha256 sha256_base64 sha256_hex
+ sha384 sha384_base64 sha384_hex
+ sha512 sha512_base64 sha512_hex);
+
+# If possible, inherit from Digest::base (which depends on MIME::Base64)
+
+eval {
+ require MIME::Base64;
+ require Digest::base;
+ push(@ISA, 'Digest::base');
+};
+if ($@) {
+ *addfile = \&Addfile;
+ *hexdigest = \&Hexdigest;
+ *b64digest = \&B64digest;
+}
+
+require XSLoader;
+XSLoader::load('Digest::SHA', $VERSION);
+
+# Preloaded methods go here.
+
+# The following routines aren't time-critical, so they can be left in Perl
+
+sub new {
+ my($class, $alg) = @_;
+ $alg =~ s/\D+//g if defined $alg;
+ if (ref($class)) { # instance method
+ unless (defined($alg) && ($alg != $class->algorithm)) {
+ sharewind($$class);
+ return($class);
+ }
+ shaclose($$class) if $$class;
+ $$class = shaopen($alg) || return;
+ return($class);
+ }
+ $alg = 1 unless defined $alg;
+ my $state = shaopen($alg) || return;
+ my $self = \$state;
+ bless($self, $class);
+ return($self);
+}
+
+sub DESTROY {
+ my $self = shift;
+ shaclose($$self) if $$self;
+}
+
+sub clone {
+ my $self = shift;
+ my $state = shadup($$self) || return;
+ my $copy = \$state;
+ bless($copy, ref($self));
+ return($copy);
+}
+
+*reset = \&new;
+
+sub add_bits {
+ my($self, $data, $nbits) = @_;
+ unless (defined $nbits) {
+ $nbits = length($data);
+ $data = pack("B*", $data);
+ }
+ shawrite($data, $nbits, $$self);
+ return($self);
+}
+
+# local copy of "addfile" in case Digest::base not installed
+
+sub Addfile { # this is "addfile" from Digest::base 1.00
+ my ($self, $handle) = @_;
+
+ my $n;
+ my $buf = "";
+
+ while (($n = read($handle, $buf, 4096))) {
+ $self->add($buf);
+ }
+ unless (defined $n) {
+ require Carp;
+ Carp::croak("Read failed: $!");
+ }
+
+ $self;
+}
+
+sub dump {
+ my $self = shift;
+ my $file = shift || "";
+
+ shadump($file, $$self) || return;
+ return($self);
+}
+
+sub load {
+ my $class = shift;
+ my $file = shift || "";
+ if (ref($class)) { # instance method
+ shaclose($$class) if $$class;
+ $$class = shaload($file) || return;
+ return($class);
+ }
+ my $state = shaload($file) || return;
+ my $self = \$state;
+ bless($self, $class);
+ return($self);
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Digest::SHA - Perl extension for SHA-1/224/256/384/512
+
+=head1 SYNOPSIS (SHA)
+
+In programs:
+
+ # Functional interface
+
+ use Digest::SHA qw(sha1 sha1_hex sha1_base64 ...);
+
+ $digest = sha1($data);
+ $digest = sha1_hex($data);
+ $digest = sha1_base64($data);
+
+ $digest = sha256($data);
+ $digest = sha384_hex($data);
+ $digest = sha512_base64($data);
+
+ # Object-oriented
+
+ use Digest::SHA;
+
+ $sha = Digest::SHA->new($alg);
+
+ $sha->add($data); # feed data into stream
+ $sha->addfile(*F);
+ $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
+
+ $digest = $sha->digest; # compute digest
+ $digest = $sha->hexdigest;
+ $digest = $sha->b64digest;
+
+From the command line:
+
+ $ shasum files
+
+ $ shasum --help
+
+=head1 SYNOPSIS (HMAC-SHA)
+
+ # Functional interface only
+
+ use Digest::SHA qw(hmac_sha1 hmac_sha1_hex ...);
+
+ $digest = hmac_sha1($data, $key);
+ $digest = hmac_sha224_hex($data, $key);
+ $digest = hmac_sha256_base64($data, $key);
+
+=head1 ABSTRACT
+
+Digest::SHA is a complete implementation of the NIST Secure Hash
+Standard. It gives Perl programmers a convenient way to calculate
+SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 message digests.
+The module can handle all types of input, including partial-byte
+data.
+
+=head1 DESCRIPTION
+
+Digest::SHA is written in C for speed. If your platform lacks a
+C compiler, you can install the functionally equivalent (but much
+slower) L<Digest::SHA::PurePerl> module.
+
+The programming interface is easy to use: it's the same one found
+in CPAN's L<Digest> module. So, if your applications currently
+use L<Digest::MD5> and you'd prefer the stronger security of SHA,
+it's a simple matter to convert them.
+
+The interface provides two ways to calculate digests: all-at-once,
+or in stages. To illustrate, the following short program computes
+the SHA-256 digest of "hello world" using each approach:
+
+ use Digest::SHA qw(sha256_hex);
+
+ $data = "hello world";
+ @frags = split(//, $data);
+
+ # all-at-once (Functional style)
+ $digest1 = sha256_hex($data);
+
+ # in-stages (OOP style)
+ $state = Digest::SHA->new(256);
+ for (@frags) { $state->add($_) }
+ $digest2 = $state->hexdigest;
+
+ print $digest1 eq $digest2 ?
+ "whew!\n" : "oops!\n";
+
+To calculate the digest of an n-bit message where I<n> is not a
+multiple of 8, use the I<add_bits()> method. For example, consider
+the 446-bit message consisting of the bit-string "110" repeated
+148 times, followed by "11". Here's how to display its SHA-1
+digest:
+
+ use Digest::SHA;
+ $bits = "110" x 148 . "11";
+ $sha = Digest::SHA->new(1)->add_bits($bits);
+ print $sha->hexdigest, "\n";
+
+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.
+
+To see what a state description looks like, just run the following:
+
+ use Digest::SHA;
+ Digest::SHA->new->add("Shaw" x 1962)->dump;
+
+As an added convenience, the Digest::SHA module offers routines to
+calculate keyed hashes using the HMAC-SHA-1/224/256/384/512
+algorithms. These services exist in functional form only, and
+mimic the style and behavior of the I<sha()>, I<sha_hex()>, and
+I<sha_base64()> functions.
+
+ # Test vector from draft-ietf-ipsec-ciph-sha-256-01.txt
+
+ use Digest::SHA qw(hmac_sha256_hex);
+ print hmac_sha256_hex("Hi There", chr(0x0b) x 32), "\n";
+
+=head1 NIST STATEMENT ON SHA-1
+
+I<NIST was recently informed that researchers had discovered a way
+to "break" the current Federal Information Processing Standard SHA-1
+algorithm, which has been in effect since 1994. The researchers
+have not yet published their complete results, so NIST has not
+confirmed these findings. However, the researchers are a reputable
+research team with expertise in this area.>
+
+I<Due to advances in computing power, NIST already planned to phase
+out SHA-1 in favor of the larger and stronger hash functions (SHA-224,
+SHA-256, SHA-384 and SHA-512) by 2010. New developments should use
+the larger and stronger hash functions.>
+
+ref. L<http://www.csrc.nist.gov/pki/HashWorkshop/NIST%20Statement/Burr_Mar2005.html>
+
+=head1 EXPORT
+
+None by default.
+
+=head1 EXPORTABLE FUNCTIONS
+
+Provided your C compiler supports a 64-bit type (e.g. the I<long
+long> of C99, or I<__int64> used by Microsoft C/C++), all of these
+functions will be available for use. Otherwise, you won't be able
+to perform the SHA-384 and SHA-512 transforms, both of which require
+64-bit operations.
+
+I<Functional style>
+
+=over 4
+
+=item B<sha1($data, ...)>
+
+=item B<sha224($data, ...)>
+
+=item B<sha256($data, ...)>
+
+=item B<sha384($data, ...)>
+
+=item B<sha512($data, ...)>
+
+Logically joins the arguments into a single string, and returns
+its SHA-1/224/256/384/512 digest encoded as a binary string.
+
+=item B<sha1_hex($data, ...)>
+
+=item B<sha224_hex($data, ...)>
+
+=item B<sha256_hex($data, ...)>
+
+=item B<sha384_hex($data, ...)>
+
+=item B<sha512_hex($data, ...)>
+
+Logically joins the arguments into a single string, and returns
+its SHA-1/224/256/384/512 digest encoded as a hexadecimal string.
+
+=item B<sha1_base64($data, ...)>
+
+=item B<sha224_base64($data, ...)>
+
+=item B<sha256_base64($data, ...)>
+
+=item B<sha384_base64($data, ...)>
+
+=item B<sha512_base64($data, ...)>
+
+Logically joins the arguments into a single string, and returns
+its SHA-1/224/256/384/512 digest encoded as a Base64 string.
+
+=back
+
+I<OOP style>
+
+=over 4
+
+=item B<new($alg)>
+
+Returns a new Digest::SHA object. Allowed values for I<$alg> are
+1, 224, 256, 384, or 512. It's also possible to use common string
+representations of the algorithm (e.g. "sha256", "SHA-384"). If
+the argument is missing, SHA-1 will be used by default.
+
+Invoking I<new> as an instance method will not create a new object;
+instead, it will simply reset the object to the initial state
+associated with I<$alg>. If the argument is missing, the object
+will continue using the same algorithm that was selected at creation.
+
+=item B<reset($alg)>
+
+This method has exactly the same effect as I<new($alg)>. In fact,
+I<reset> is just an alias for I<new>.
+
+=item B<hashsize>
+
+Returns the number of digest bits for this object. The values are
+160, 224, 256, 384, and 512 for SHA-1, SHA-224, SHA-256, SHA-384,
+and SHA-512, respectively.
+
+=item B<algorithm>
+
+Returns the digest algorithm for this object. The values are 1,
+224, 256, 384, and 512 for SHA-1, SHA-224, SHA-256, SHA-384, and
+SHA-512, respectively.
+
+=item B<clone>
+
+Returns a duplicate copy of the object.
+
+=item B<add($data, ...)>
+
+Logically joins the arguments into a single string, and uses it to
+update the current digest state. In other words, the following
+statements have the same effect:
+
+ $sha->add("a"); $sha->add("b"); $sha->add("c");
+ $sha->add("a")->add("b")->add("c");
+ $sha->add("a", "b", "c");
+ $sha->add("abc");
+
+The return value is the updated object itself.
+
+=item B<add_bits($data, $nbits)>
+
+=item B<add_bits($bits)>
+
+Updates the current digest state by appending bits to it. The
+return value is the updated object itself.
+
+The first form causes the most-significant I<$nbits> of I<$data>
+to be appended to the stream. The I<$data> argument is in the
+customary binary format used for Perl strings.
+
+The second form takes an ASCII string of "0" and "1" characters as
+its argument. It's equivalent to
+
+ $sha->add_bits(pack("B*", $bits), length($bits));
+
+So, the following two statements do the same thing:
+
+ $sha->add_bits("111100001010");
+ $sha->add_bits("\xF0\xA0", 12);
+
+=item B<addfile(*FILE)>
+
+Reads from I<FILE> until EOF, and appends that data to the current
+state. The return value is the updated object itself.
+
+This method is inherited if L<Digest::base> is installed on your
+system. Otherwise, a functionally equivalent substitute is used.
+
+=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.
+
+=item B<load($filename)>
+
+Returns a Digest::SHA 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.
+
+=item B<digest>
+
+Returns the digest encoded as a binary string.
+
+Note that the I<digest> method is a read-once operation. Once it
+has been performed, the Digest::SHA object is automatically reset
+in preparation for calculating another digest value. Call
+I<$sha-E<gt>clone-E<gt>digest> if it's necessary to preserve the
+original digest state.
+
+=item B<hexdigest>
+
+Returns the digest encoded as a hexadecimal string.
+
+Like I<digest>, this method is a read-once operation. Call
+I<$sha-E<gt>clone-E<gt>hexdigest> if it's necessary to preserve
+the original digest state.
+
+This method is inherited if L<Digest::base> is installed on your
+system. Otherwise, a functionally equivalent substitute is used.
+
+=item B<b64digest>
+
+Returns the digest encoded as a Base64 string.
+
+Like I<digest>, this method is a read-once operation. Call
+I<$sha-E<gt>clone-E<gt>b64digest> if it's necessary to preserve
+the original digest state.
+
+This method is inherited if L<Digest::base> is installed on your
+system. Otherwise, a functionally equivalent substitute is used.
+
+=back
+
+I<HMAC-SHA-1/224/256/384/512>
+
+=over 4
+
+=item B<hmac_sha1($data, $key)>
+
+=item B<hmac_sha224($data, $key)>
+
+=item B<hmac_sha256($data, $key)>
+
+=item B<hmac_sha384($data, $key)>
+
+=item B<hmac_sha512($data, $key)>
+
+Returns the HMAC-SHA-1/224/256/384/512 digest of I<$data>/I<$key>,
+with the result encoded as a binary string. Multiple I<$data>
+arguments are allowed, provided that I<$key> is the last argument
+in the list.
+
+=item B<hmac_sha1_hex($data, $key)>
+
+=item B<hmac_sha224_hex($data, $key)>
+
+=item B<hmac_sha256_hex($data, $key)>
+
+=item B<hmac_sha384_hex($data, $key)>
+
+=item B<hmac_sha512_hex($data, $key)>
+
+Returns the HMAC-SHA-1/224/256/384/512 digest of I<$data>/I<$key>,
+with the result encoded as a hexadecimal string. Multiple I<$data>
+arguments are allowed, provided that I<$key> is the last argument
+in the list.
+
+=item B<hmac_sha1_base64($data, $key)>
+
+=item B<hmac_sha224_base64($data, $key)>
+
+=item B<hmac_sha256_base64($data, $key)>
+
+=item B<hmac_sha384_base64($data, $key)>
+
+=item B<hmac_sha512_base64($data, $key)>
+
+Returns the HMAC-SHA-1/224/256/384/512 digest of I<$data>/I<$key>,
+with the result encoded as a Base64 string. Multiple I<$data>
+arguments are allowed, provided that I<$key> is the last argument
+in the list.
+
+=back
+
+=head1 SEE ALSO
+
+L<Digest>, L<Digest::SHA::PurePerl>
+
+The Secure Hash Standard (FIPS PUB 180-2) can be found at:
+
+L<http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf>
+
+The Keyed-Hash Message Authentication Code (HMAC):
+
+L<http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf>
+
+=head1 AUTHOR
+
+ Mark Shelor <mshelor@cpan.org>
+
+=head1 ACKNOWLEDGMENTS
+
+The author is particularly grateful to
+
+ Gisle Aas
+ Chris Carey
+ Julius Duque
+ Jeffrey Friedl
+ Robert Gilmour
+ Brian Gladman
+ Andy Lester
+ Alex Muntada
+ Chris Skiscim
+ Martin Thurn
+ Gunnar Wolf
+ Adam Woodbury
+
+for their valuable comments and suggestions.
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2003-2005 Mark Shelor
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+L<perlartistic>
+
+=cut
diff --git a/ext/Digest/SHA/SHA.xs b/ext/Digest/SHA/SHA.xs
new file mode 100644
index 0000000000..a1b678b737
--- /dev/null
+++ b/ext/Digest/SHA/SHA.xs
@@ -0,0 +1,201 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "ppport.h"
+
+#include <src/sha.c>
+#include <src/hmac.c>
+
+static int ix2alg[] =
+ {1,1,1,224,224,224,256,256,256,384,384,384,512,512,512};
+
+MODULE = Digest::SHA PACKAGE = Digest::SHA
+
+PROTOTYPES: ENABLE
+
+#include <src/sha.h>
+#include <src/hmac.h>
+
+int
+shaclose(s)
+ SHA * s
+
+int
+shadump(file, s)
+ char * file
+ SHA * s
+
+SHA *
+shadup(s)
+ SHA * s
+
+SHA *
+shaload(file)
+ char * file
+
+SHA *
+shaopen(alg)
+ int alg
+
+void
+sharewind(s)
+ SHA * s
+
+unsigned long
+shawrite(bitstr, bitcnt, s)
+ unsigned char * bitstr
+ unsigned long bitcnt
+ SHA * s
+
+void
+sha1(...)
+ALIAS:
+ Digest::SHA::sha1 = 0
+ Digest::SHA::sha1_hex = 1
+ Digest::SHA::sha1_base64 = 2
+ Digest::SHA::sha224 = 3
+ Digest::SHA::sha224_hex = 4
+ Digest::SHA::sha224_base64 = 5
+ Digest::SHA::sha256 = 6
+ Digest::SHA::sha256_hex = 7
+ Digest::SHA::sha256_base64 = 8
+ Digest::SHA::sha384 = 9
+ Digest::SHA::sha384_hex = 10
+ Digest::SHA::sha384_base64 = 11
+ Digest::SHA::sha512 = 12
+ Digest::SHA::sha512_hex = 13
+ Digest::SHA::sha512_base64 = 14
+PREINIT:
+ int i;
+ unsigned char *data;
+ STRLEN len;
+ SHA *state;
+ char *result;
+PPCODE:
+ if ((state = shaopen(ix2alg[ix])) == NULL)
+ XSRETURN_UNDEF;
+ for (i = 0; i < items; i++) {
+ data = (unsigned char *) (SvPV(ST(i), len));
+ shawrite(data, len << 3, state);
+ }
+ shafinish(state);
+ len = 0;
+ if (ix % 3 == 0) {
+ result = (char *) shadigest(state);
+ len = shadsize(state);
+ }
+ else if (ix % 3 == 1)
+ result = shahex(state);
+ else
+ result = shabase64(state);
+ ST(0) = sv_2mortal(newSVpv(result, len));
+ shaclose(state);
+ XSRETURN(1);
+
+void
+hmac_sha1(...)
+ALIAS:
+ Digest::SHA::hmac_sha1 = 0
+ Digest::SHA::hmac_sha1_hex = 1
+ Digest::SHA::hmac_sha1_base64 = 2
+ Digest::SHA::hmac_sha224 = 3
+ Digest::SHA::hmac_sha224_hex = 4
+ Digest::SHA::hmac_sha224_base64 = 5
+ Digest::SHA::hmac_sha256 = 6
+ Digest::SHA::hmac_sha256_hex = 7
+ Digest::SHA::hmac_sha256_base64 = 8
+ Digest::SHA::hmac_sha384 = 9
+ Digest::SHA::hmac_sha384_hex = 10
+ Digest::SHA::hmac_sha384_base64 = 11
+ Digest::SHA::hmac_sha512 = 12
+ Digest::SHA::hmac_sha512_hex = 13
+ Digest::SHA::hmac_sha512_base64 = 14
+PREINIT:
+ int i;
+ unsigned char *key;
+ unsigned char *data;
+ STRLEN len;
+ HMAC *state;
+ char *result;
+PPCODE:
+ key = (unsigned char *) (SvPV(ST(items-1), len));
+ if ((state = hmacopen(ix2alg[ix], key, len)) == NULL)
+ XSRETURN_UNDEF;
+ for (i = 0; i < items - 1; i++) {
+ data = (unsigned char *) (SvPV(ST(i), len));
+ hmacwrite(data, len << 3, state);
+ }
+ hmacfinish(state);
+ len = 0;
+ if (ix % 3 == 0) {
+ result = (char *) hmacdigest(state);
+ len = shadsize(state->osha);
+ }
+ else if (ix % 3 == 1)
+ result = hmachex(state);
+ else
+ result = hmacbase64(state);
+ ST(0) = sv_2mortal(newSVpv(result, len));
+ hmacclose(state);
+ XSRETURN(1);
+
+void
+hashsize(self)
+ SV * self
+ALIAS:
+ Digest::SHA::hashsize = 0
+ Digest::SHA::algorithm = 1
+PREINIT:
+ SHA *state;
+ int result;
+PPCODE:
+ state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self))));
+ result = shadsize(state) << 3;
+ if (ix == 1 && result == 160)
+ result = 1;
+ ST(0) = sv_2mortal(newSViv(result));
+ XSRETURN(1);
+
+void
+add(self, ...)
+ SV * self
+PREINIT:
+ int i;
+ unsigned char *data;
+ STRLEN len;
+ SHA *state;
+PPCODE:
+ state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self))));
+ for (i = 1; i < items; i++) {
+ data = (unsigned char *) (SvPV(ST(i), len));
+ shawrite(data, len << 3, state);
+ }
+ XSRETURN(1);
+
+void
+digest(self)
+ SV * self
+ALIAS:
+ Digest::SHA::digest = 0
+ Digest::SHA::Hexdigest = 1
+ Digest::SHA::B64digest = 2
+PREINIT:
+ STRLEN len;
+ SHA *state;
+ char *result;
+PPCODE:
+ state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self))));
+ shafinish(state);
+ len = 0;
+ if (ix == 0) {
+ result = (char *) shadigest(state);
+ len = shadsize(state);
+ }
+ else if (ix == 1)
+ result = shahex(state);
+ else
+ result = shabase64(state);
+ ST(0) = sv_2mortal(newSVpv(result, len));
+ sharewind(state);
+ XSRETURN(1);
diff --git a/ext/Digest/SHA/bin/shasum b/ext/Digest/SHA/bin/shasum
new file mode 100755
index 0000000000..a10262040e
--- /dev/null
+++ b/ext/Digest/SHA/bin/shasum
@@ -0,0 +1,212 @@
+#!perl -w
+
+ # shasum: filter for computing SHA digests (analogous to md5sum)
+ #
+ # Copyright (C) 2003-2005 Mark Shelor, All Rights Reserved
+ #
+ # Version: 5.32
+ # Fri Dec 2 02:32:20 MST 2005
+
+=head1 NAME
+
+shasum - Print or Check SHA Checksums
+
+=head1 SYNOPSIS
+
+ Usage: shasum [OPTION] [FILE]...
+ or: shasum [OPTION] --check [FILE]
+ Print or check SHA checksums.
+ With no FILE, or when FILE is -, read standard input.
+
+ -a, --algorithm 1 (default), 224, 256, 384, 512
+ -b, --binary read files in binary mode (default on DOS/Windows)
+ -c, --check check SHA sums against given list
+ -t, --text read files in text mode (default)
+
+ The following two options are useful only when verifying checksums:
+
+ --status don't output anything, status code shows success
+ -w, --warn warn about improperly formatted SHA checksum lines
+
+ --help display this help and exit
+ --version output version information and exit
+
+The sums are computed as described in FIPS PUB 180-2. 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), and name for each FILE.
+
+=head1 AUTHOR
+
+Copyright (c) 2003-2005 Mark Shelor <mshelor@cpan.org>.
+
+=head1 SEE ALSO
+
+Shasum is implemented using the Perl module L<Digest::SHA> or
+L<Digest::SHA::PurePerl>.
+
+=cut
+
+use strict;
+use Getopt::Long;
+
+my $VERSION = "5.32";
+
+
+ # Try to use Digest::SHA, since it's faster. If not installed,
+ # use 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 $@;
+}
+
+
+ # Usage statement adapted from Ulrich Drepper's md5sum.
+ # Include an "-a" option for algorithm selection.
+
+sub usage {
+ my($err) = @_;
+
+ my $stream = $err ? *STDERR : *STDOUT;
+ print $stream <<'END_OF_USAGE';
+Usage: shasum [OPTION] [FILE]...
+ or: shasum [OPTION] --check [FILE]
+Print or check SHA checksums.
+With no FILE, or when FILE is -, read standard input.
+
+ -a, --algorithm 1 (default), 224, 256, 384, 512
+ -b, --binary read files in binary mode (default on DOS/Windows)
+ -c, --check check SHA sums against given list
+ -t, --text read files in text mode (default)
+
+The following two options are useful only when verifying checksums:
+ --status don't output anything, status code shows success
+ -w, --warn warn about improperly formatted SHA checksum lines
+
+ --help display this help and exit
+ --version output version information and exit
+
+The sums are computed as described in FIPS PUB 180-2. 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), and name for each FILE.
+
+Report bugs to <mshelor@cpan.org>.
+END_OF_USAGE
+ exit($err);
+}
+
+
+ # Collect options from command line
+
+my ($alg, $binary, $check, $text, $status, $warn, $help, $version);
+
+GetOptions(
+ 'binary' => \$binary, 'check' => \$check,
+ 'text' => \$text, 'algorithm=i' => \$alg,
+ 'status' => \$status, 'warn' => \$warn,
+ 'help' => \$help, 'version' => \$version
+) or usage(1);
+
+
+ # Deal with help requests and incorrect uses
+
+usage(0) if $help;
+usage(1) if $binary and $text;
+usage(1) if $warn and not $check;
+usage(1) if $status and not $check;
+
+
+ # Default to SHA-1 unless overriden by command line option
+
+$alg = 1 unless $alg;
+grep { $_ == $alg } (1, 224, 256, 384, 512) or usage(1);
+
+
+ # Display version information if requested
+
+if ($version) {
+ print "$VERSION\n";
+ exit(0);
+}
+
+
+ # Try to figure out if the OS is DOS-like. If it is,
+ # default to binary mode when reading files, unless
+ # explicitly overriden by command line "text" option.
+
+my $isDOSish = ($^O =~ /^(MSWin\d\d|os2|dos|mint|cygwin)$/);
+if ($isDOSish) { $binary = 1 unless $text }
+
+
+ # Read from STDIN (-) if no files listed on command line
+
+@ARGV = ("-") unless @ARGV;
+
+
+ # sumfile($file): computes SHA digest of $file
+
+sub sumfile {
+ my($file) = @_;
+ my($fh, $digest);
+
+ unless (open($fh, "<$file")) {
+ print STDERR "shasum: $file: No such file or directory\n";
+ return;
+ }
+ binmode($fh) if $binary;
+ $digest = $module->new($alg)->addfile($fh)->hexdigest;
+ close($fh);
+ return($digest);
+}
+
+
+ # %len2alg: maps hex digest length to SHA algorithm
+
+my %len2alg = (40 => 1, 56 => 224, 64 => 256, 96 => 384, 128 => 512);
+
+
+ # Verify checksums if requested
+
+if ($check) {
+ my $checkfile = shift(@ARGV);
+ my $err = 0;
+ my ($fh, $sum, $fname, $rsp);
+
+ die "shasum: $checkfile: No such file or directory\n"
+ unless open($fh, "<$checkfile");
+ while (<$fh>) {
+ s/\s+$//;
+ ($sum, $binary, $fname) = /^(\S+)\s+(\*?)(.*)$/;
+ unless ($alg = $len2alg{length($sum)}) {
+ print STDERR "shasum: $checkfile: $.: improperly ",
+ "formatted SHA checksum line\n" if $warn;
+ next;
+ }
+ $rsp = "$fname: ";
+ if (lc($sum) eq sumfile($fname)) { $rsp .= "OK\n" }
+ else { $rsp .= "FAILED\n"; $err = 1 }
+ print $rsp unless $status;
+ }
+ close($fh);
+ exit($err);
+}
+
+
+ # Compute and display SHA checksums of requested files
+
+for (@ARGV) {
+ if (-d $_) {
+ print STDERR "shasum: $_: Is a directory\n";
+ next;
+ }
+ next unless my $digest = sumfile($_);
+ print "$digest ", $binary ? "\*" : " ", "$_\n";
+}
diff --git a/ext/Digest/SHA/ppport.h b/ext/Digest/SHA/ppport.h
new file mode 100644
index 0000000000..5f3d998b62
--- /dev/null
+++ b/ext/Digest/SHA/ppport.h
@@ -0,0 +1,540 @@
+
+/* ppport.h -- Perl/Pollution/Portability Version 2.0002
+ *
+ * Automatically Created by Devel::PPPort on Wed Oct 8 22:28:04 2003
+ *
+ * Do NOT edit this file directly! -- Edit PPPort.pm instead.
+ *
+ * Version 2.x, Copyright (C) 2001, Paul Marquess.
+ * Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
+ * This code may be used and distributed under the same license as any
+ * version of Perl.
+ *
+ * This version of ppport.h is designed to support operation with Perl
+ * installations back to 5.004, and has been tested up to 5.8.0.
+ *
+ * If this version of ppport.h is failing during the compilation of this
+ * module, please check if a newer version of Devel::PPPort is available
+ * on CPAN before sending a bug report.
+ *
+ * If you are using the latest version of Devel::PPPort and it is failing
+ * during compilation of this module, please send a report to perlbug@perl.com
+ *
+ * Include all following information:
+ *
+ * 1. The complete output from running "perl -V"
+ *
+ * 2. This file.
+ *
+ * 3. The name & version of the module you were trying to build.
+ *
+ * 4. A full log of the build that failed.
+ *
+ * 5. Any other information that you think could be relevant.
+ *
+ *
+ * For the latest version of this code, please retreive the Devel::PPPort
+ * module from CPAN.
+ *
+ */
+
+/*
+ * In order for a Perl extension module to be as portable as possible
+ * across differing versions of Perl itself, certain steps need to be taken.
+ * Including this header is the first major one, then using dTHR is all the
+ * appropriate places and using a PL_ prefix to refer to global Perl
+ * variables is the second.
+ *
+ */
+
+
+/* If you use one of a few functions that were not present in earlier
+ * versions of Perl, please add a define before the inclusion of ppport.h
+ * for a static include, or use the GLOBAL request in a single module to
+ * produce a global definition that can be referenced from the other
+ * modules.
+ *
+ * Function: Static define: Extern define:
+ * newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL
+ *
+ */
+
+
+/* To verify whether ppport.h is needed for your module, and whether any
+ * special defines should be used, ppport.h can be run through Perl to check
+ * your source code. Simply say:
+ *
+ * perl -x ppport.h *.c *.h *.xs foo/bar*.c [etc]
+ *
+ * The result will be a list of patches suggesting changes that should at
+ * least be acceptable, if not necessarily the most efficient solution, or a
+ * fix for all possible problems. It won't catch where dTHR is needed, and
+ * doesn't attempt to account for global macro or function definitions,
+ * nested includes, typemaps, etc.
+ *
+ * In order to test for the need of dTHR, please try your module under a
+ * recent version of Perl that has threading compiled-in.
+ *
+ */
+
+
+/*
+#!/usr/bin/perl
+@ARGV = ("*.xs") if !@ARGV;
+%badmacros = %funcs = %macros = (); $replace = 0;
+foreach (<DATA>) {
+ $funcs{$1} = 1 if /Provide:\s+(\S+)/;
+ $macros{$1} = 1 if /^#\s*define\s+([a-zA-Z0-9_]+)/;
+ $replace = $1 if /Replace:\s+(\d+)/;
+ $badmacros{$2}=$1 if $replace and /^#\s*define\s+([a-zA-Z0-9_]+).*?\s+([a-zA-Z0-9_]+)/;
+ $badmacros{$1}=$2 if /Replace (\S+) with (\S+)/;
+}
+foreach $filename (map(glob($_),@ARGV)) {
+ unless (open(IN, "<$filename")) {
+ warn "Unable to read from $file: $!\n";
+ next;
+ }
+ print "Scanning $filename...\n";
+ $c = ""; while (<IN>) { $c .= $_; } close(IN);
+ $need_include = 0; %add_func = (); $changes = 0;
+ $has_include = ($c =~ /#.*include.*ppport/m);
+
+ foreach $func (keys %funcs) {
+ if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) {
+ if ($c !~ /\b$func\b/m) {
+ print "If $func isn't needed, you don't need to request it.\n" if
+ $changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m);
+ } else {
+ print "Uses $func\n";
+ $need_include = 1;
+ }
+ } else {
+ if ($c =~ /\b$func\b/m) {
+ $add_func{$func} =1 ;
+ print "Uses $func\n";
+ $need_include = 1;
+ }
+ }
+ }
+
+ if (not $need_include) {
+ foreach $macro (keys %macros) {
+ if ($c =~ /\b$macro\b/m) {
+ print "Uses $macro\n";
+ $need_include = 1;
+ }
+ }
+ }
+
+ foreach $badmacro (keys %badmacros) {
+ if ($c =~ /\b$badmacro\b/m) {
+ $changes += ($c =~ s/\b$badmacro\b/$badmacros{$badmacro}/gm);
+ print "Uses $badmacros{$badmacro} (instead of $badmacro)\n";
+ $need_include = 1;
+ }
+ }
+
+ if (scalar(keys %add_func) or $need_include != $has_include) {
+ if (!$has_include) {
+ $inc = join('',map("#define NEED_$_\n", sort keys %add_func)).
+ "#include \"ppport.h\"\n";
+ $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m;
+ } elsif (keys %add_func) {
+ $inc = join('',map("#define NEED_$_\n", sort keys %add_func));
+ $c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m;
+ }
+ if (!$need_include) {
+ print "Doesn't seem to need ppport.h.\n";
+ $c =~ s/^.*#.*include.*ppport.*\n//m;
+ }
+ $changes++;
+ }
+
+ if ($changes) {
+ open(OUT,">/tmp/ppport.h.$$");
+ print OUT $c;
+ close(OUT);
+ open(DIFF, "diff -u $filename /tmp/ppport.h.$$|");
+ while (<DIFF>) { s!/tmp/ppport\.h\.$$!$filename.patched!; print STDOUT; }
+ close(DIFF);
+ unlink("/tmp/ppport.h.$$");
+ } else {
+ print "Looks OK\n";
+ }
+}
+__DATA__
+*/
+
+#ifndef _P_P_PORTABILITY_H_
+#define _P_P_PORTABILITY_H_
+
+#ifndef PERL_REVISION
+# ifndef __PATCHLEVEL_H_INCLUDED__
+# include "patchlevel.h"
+# endif
+# ifndef PERL_REVISION
+# define PERL_REVISION (5)
+ /* Replace: 1 */
+# define PERL_VERSION PATCHLEVEL
+# define PERL_SUBVERSION SUBVERSION
+ /* Replace PERL_PATCHLEVEL with PERL_VERSION */
+ /* Replace: 0 */
+# endif
+#endif
+
+#define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION)
+
+/* It is very unlikely that anyone will try to use this with Perl 6
+ (or greater), but who knows.
+ */
+#if PERL_REVISION != 5
+# error ppport.h only works with Perl version 5
+#endif /* PERL_REVISION != 5 */
+
+#ifndef ERRSV
+# define ERRSV perl_get_sv("@",FALSE)
+#endif
+
+#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5))
+/* Replace: 1 */
+# define PL_Sv Sv
+# define PL_compiling compiling
+# define PL_copline copline
+# define PL_curcop curcop
+# define PL_curstash curstash
+# define PL_defgv defgv
+# define PL_dirty dirty
+# define PL_dowarn dowarn
+# define PL_hints hints
+# define PL_na na
+# define PL_perldb perldb
+# define PL_rsfp_filters rsfp_filters
+# define PL_rsfpv rsfp
+# define PL_stdingv stdingv
+# define PL_sv_no sv_no
+# define PL_sv_undef sv_undef
+# define PL_sv_yes sv_yes
+/* Replace: 0 */
+#endif
+
+#ifdef HASATTRIBUTE
+# if defined(__GNUC__) && defined(__cplusplus)
+# define PERL_UNUSED_DECL
+# else
+# define PERL_UNUSED_DECL __attribute__((unused))
+# endif
+#else
+# define PERL_UNUSED_DECL
+#endif
+
+#ifndef dNOOP
+# define NOOP (void)0
+# define dNOOP extern int Perl___notused PERL_UNUSED_DECL
+#endif
+
+#ifndef dTHR
+# define dTHR dNOOP
+#endif
+
+#ifndef dTHX
+# define dTHX dNOOP
+# define dTHXa(x) dNOOP
+# define dTHXoa(x) dNOOP
+#endif
+
+#ifndef pTHX
+# define pTHX void
+# define pTHX_
+# define aTHX
+# define aTHX_
+#endif
+
+#ifndef UVSIZE
+# define UVSIZE IVSIZE
+#endif
+
+#ifndef NVTYPE
+# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE)
+# define NVTYPE long double
+# else
+# define NVTYPE double
+# endif
+typedef NVTYPE NV;
+#endif
+
+#ifndef INT2PTR
+
+#if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE)
+# define PTRV UV
+# define INT2PTR(any,d) (any)(d)
+#else
+# if PTRSIZE == LONGSIZE
+# define PTRV unsigned long
+# else
+# define PTRV unsigned
+# endif
+# define INT2PTR(any,d) (any)(PTRV)(d)
+#endif
+#define NUM2PTR(any,d) (any)(PTRV)(d)
+#define PTR2IV(p) INT2PTR(IV,p)
+#define PTR2UV(p) INT2PTR(UV,p)
+#define PTR2NV(p) NUM2PTR(NV,p)
+#if PTRSIZE == LONGSIZE
+# define PTR2ul(p) (unsigned long)(p)
+#else
+# define PTR2ul(p) INT2PTR(unsigned long,p)
+#endif
+
+#endif /* !INT2PTR */
+
+#ifndef boolSV
+# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
+#endif
+
+#ifndef gv_stashpvn
+# define gv_stashpvn(str,len,flags) gv_stashpv(str,flags)
+#endif
+
+#ifndef newSVpvn
+# define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0))
+#endif
+
+#ifndef newRV_inc
+/* Replace: 1 */
+# define newRV_inc(sv) newRV(sv)
+/* Replace: 0 */
+#endif
+
+/* DEFSV appears first in 5.004_56 */
+#ifndef DEFSV
+# define DEFSV GvSV(PL_defgv)
+#endif
+
+#ifndef SAVE_DEFSV
+# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
+#endif
+
+#ifndef newRV_noinc
+# ifdef __GNUC__
+# define newRV_noinc(sv) \
+ ({ \
+ SV *nsv = (SV*)newRV(sv); \
+ SvREFCNT_dec(sv); \
+ nsv; \
+ })
+# else
+# if defined(USE_THREADS)
+static SV * newRV_noinc (SV * sv)
+{
+ SV *nsv = (SV*)newRV(sv);
+ SvREFCNT_dec(sv);
+ return nsv;
+}
+# else
+# define newRV_noinc(sv) \
+ (PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv)
+# endif
+# endif
+#endif
+
+/* Provide: newCONSTSUB */
+
+/* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */
+#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63))
+
+#if defined(NEED_newCONSTSUB)
+static
+#else
+extern void newCONSTSUB(HV * stash, char * name, SV *sv);
+#endif
+
+#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL)
+void
+newCONSTSUB(stash,name,sv)
+HV *stash;
+char *name;
+SV *sv;
+{
+ U32 oldhints = PL_hints;
+ HV *old_cop_stash = PL_curcop->cop_stash;
+ HV *old_curstash = PL_curstash;
+ line_t oldline = PL_curcop->cop_line;
+ PL_curcop->cop_line = PL_copline;
+
+ PL_hints &= ~HINT_BLOCK_SCOPE;
+ if (stash)
+ PL_curstash = PL_curcop->cop_stash = stash;
+
+ newSUB(
+
+#if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22))
+ /* before 5.003_22 */
+ start_subparse(),
+#else
+# if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22)
+ /* 5.003_22 */
+ start_subparse(0),
+# else
+ /* 5.003_23 onwards */
+ start_subparse(FALSE, 0),
+# endif
+#endif
+
+ newSVOP(OP_CONST, 0, newSVpv(name,0)),
+ newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */
+ newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
+ );
+
+ PL_hints = oldhints;
+ PL_curcop->cop_stash = old_cop_stash;
+ PL_curstash = old_curstash;
+ PL_curcop->cop_line = oldline;
+}
+#endif
+
+#endif /* newCONSTSUB */
+
+#ifndef START_MY_CXT
+
+/*
+ * Boilerplate macros for initializing and accessing interpreter-local
+ * data from C. All statics in extensions should be reworked to use
+ * this, if you want to make the extension thread-safe. See ext/re/re.xs
+ * for an example of the use of these macros.
+ *
+ * Code that uses these macros is responsible for the following:
+ * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts"
+ * 2. Declare a typedef named my_cxt_t that is a structure that contains
+ * all the data that needs to be interpreter-local.
+ * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t.
+ * 4. Use the MY_CXT_INIT macro such that it is called exactly once
+ * (typically put in the BOOT: section).
+ * 5. Use the members of the my_cxt_t structure everywhere as
+ * MY_CXT.member.
+ * 6. Use the dMY_CXT macro (a declaration) in all the functions that
+ * access MY_CXT.
+ */
+
+#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \
+ defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT)
+
+/* This must appear in all extensions that define a my_cxt_t structure,
+ * right after the definition (i.e. at file scope). The non-threads
+ * case below uses it to declare the data as static. */
+#define START_MY_CXT
+
+#if (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION < 68 ))
+/* Fetches the SV that keeps the per-interpreter data. */
+#define dMY_CXT_SV \
+ SV *my_cxt_sv = perl_get_sv(MY_CXT_KEY, FALSE)
+#else /* >= perl5.004_68 */
+#define dMY_CXT_SV \
+ SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \
+ sizeof(MY_CXT_KEY)-1, TRUE)
+#endif /* < perl5.004_68 */
+
+/* This declaration should be used within all functions that use the
+ * interpreter-local data. */
+#define dMY_CXT \
+ dMY_CXT_SV; \
+ my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv))
+
+/* Creates and zeroes the per-interpreter data.
+ * (We allocate my_cxtp in a Perl SV so that it will be released when
+ * the interpreter goes away.) */
+#define MY_CXT_INIT \
+ dMY_CXT_SV; \
+ /* newSV() allocates one more than needed */ \
+ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
+ Zero(my_cxtp, 1, my_cxt_t); \
+ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+
+/* This macro must be used to access members of the my_cxt_t structure.
+ * e.g. MYCXT.some_data */
+#define MY_CXT (*my_cxtp)
+
+/* Judicious use of these macros can reduce the number of times dMY_CXT
+ * is used. Use is similar to pTHX, aTHX etc. */
+#define pMY_CXT my_cxt_t *my_cxtp
+#define pMY_CXT_ pMY_CXT,
+#define _pMY_CXT ,pMY_CXT
+#define aMY_CXT my_cxtp
+#define aMY_CXT_ aMY_CXT,
+#define _aMY_CXT ,aMY_CXT
+
+#else /* single interpreter */
+
+
+#define START_MY_CXT static my_cxt_t my_cxt;
+#define dMY_CXT_SV dNOOP
+#define dMY_CXT dNOOP
+#define MY_CXT_INIT NOOP
+#define MY_CXT my_cxt
+
+#define pMY_CXT void
+#define pMY_CXT_
+#define _pMY_CXT
+#define aMY_CXT
+#define aMY_CXT_
+#define _aMY_CXT
+
+#endif
+
+#endif /* START_MY_CXT */
+
+#ifndef IVdf
+# if IVSIZE == LONGSIZE
+# define IVdf "ld"
+# define UVuf "lu"
+# define UVof "lo"
+# define UVxf "lx"
+# define UVXf "lX"
+# else
+# if IVSIZE == INTSIZE
+# define IVdf "d"
+# define UVuf "u"
+# define UVof "o"
+# define UVxf "x"
+# define UVXf "X"
+# endif
+# endif
+#endif
+
+#ifndef NVef
+# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \
+ defined(PERL_PRIfldbl) /* Not very likely, but let's try anyway. */
+# define NVef PERL_PRIeldbl
+# define NVff PERL_PRIfldbl
+# define NVgf PERL_PRIgldbl
+# else
+# define NVef "e"
+# define NVff "f"
+# define NVgf "g"
+# endif
+#endif
+
+#ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */
+# define AvFILLp AvFILL
+#endif
+
+#ifdef SvPVbyte
+# if PERL_REVISION == 5 && PERL_VERSION < 7
+ /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */
+# undef SvPVbyte
+# define SvPVbyte(sv, lp) \
+ ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \
+ ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp))
+ static char *
+ my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp)
+ {
+ sv_utf8_downgrade(sv,0);
+ return SvPV(sv,*lp);
+ }
+# endif
+#else
+# define SvPVbyte SvPV
+#endif
+
+#endif /* _P_P_PORTABILITY_H_ */
+
+/* End of File ppport.h */
diff --git a/ext/Digest/SHA/t/0-pod-coverage.t b/ext/Digest/SHA/t/0-pod-coverage.t
new file mode 100644
index 0000000000..f979796129
--- /dev/null
+++ b/ext/Digest/SHA/t/0-pod-coverage.t
@@ -0,0 +1,25 @@
+BEGIN {
+ eval "use Test::More";
+ if ($@) {
+ print "1..0 # Skipped: Test::More not installed\n";
+ exit;
+ }
+}
+
+eval "use Test::Pod::Coverage 0.08";
+plan skip_all => "Test::Pod::Coverage 0.08 required for testing POD coverage" if $@;
+
+my @privfcns = qw(
+ Addfile
+ Hexdigest
+ B64digest
+ shaclose
+ shadump
+ shadup
+ shaload
+ shaopen
+ sharewind
+ shawrite
+);
+
+all_pod_coverage_ok( { also_private => \@privfcns } );
diff --git a/ext/Digest/SHA/t/0-pod.t b/ext/Digest/SHA/t/0-pod.t
new file mode 100644
index 0000000000..1ec6bff52b
--- /dev/null
+++ b/ext/Digest/SHA/t/0-pod.t
@@ -0,0 +1,11 @@
+BEGIN {
+ eval "use Test::More";
+ if ($@) {
+ print "1..0 # Skipped: Test::More not installed\n";
+ exit;
+ }
+}
+
+eval "use Test::Pod 1.00";
+plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
+all_pod_files_ok();
diff --git a/ext/Digest/SHA/t/1-exist.t b/ext/Digest/SHA/t/1-exist.t
new file mode 100644
index 0000000000..07ced0ec2a
--- /dev/null
+++ b/ext/Digest/SHA/t/1-exist.t
@@ -0,0 +1,17 @@
+use Test;
+
+BEGIN { plan tests => 1 }
+
+use Digest::SHA qw(
+ hmac_sha1 hmac_sha1_base64 hmac_sha1_hex
+ hmac_sha224 hmac_sha224_base64 hmac_sha224_hex
+ hmac_sha256 hmac_sha256_base64 hmac_sha256_hex
+ hmac_sha384 hmac_sha384_base64 hmac_sha384_hex
+ hmac_sha512 hmac_sha512_base64 hmac_sha512_hex
+ sha1 sha1_base64 sha1_hex
+ sha224 sha224_base64 sha224_hex
+ sha256 sha256_base64 sha256_hex
+ sha384 sha384_base64 sha384_hex
+ sha512 sha512_base64 sha512_hex);
+
+ok(1);
diff --git a/ext/Digest/SHA/t/1-hello-world.t b/ext/Digest/SHA/t/1-hello-world.t
new file mode 100644
index 0000000000..6e5a0e65d3
--- /dev/null
+++ b/ext/Digest/SHA/t/1-hello-world.t
@@ -0,0 +1,20 @@
+use Test;
+use Digest::SHA qw(sha1);
+use strict;
+use integer;
+
+my(@vec, @rsp);
+
+BEGIN {
+
+ @vec = ( "hello world" );
+
+ @rsp = ( pack("H*", "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed") );
+
+ plan tests => scalar(@vec);
+
+}
+
+for (my $i = 0; $i < @vec; $i++) {
+ ok(sha1($vec[$i]), $rsp[$i]);
+}
diff --git a/ext/Digest/SHA/t/2-nist-sha-1.t b/ext/Digest/SHA/t/2-nist-sha-1.t
new file mode 100644
index 0000000000..18165bc6c1
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-sha-1.t
@@ -0,0 +1,26 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(sha1_hex);
+
+my(@vec, @rsp);
+
+BEGIN {
+ @vec = (
+"abc",
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+"a" x 1000000
+ );
+
+ @rsp = (
+"a9993e364706816aba3e25717850c26c9cd0d89d",
+"84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+"34aa973cd4c4daa4f61eeb2bdbad27316534016f"
+ );
+
+ plan tests => scalar(@vec);
+}
+
+for (my $i = 0; $i < @vec; $i++) {
+ ok(sha1_hex($vec[$i]), $rsp[$i]);
+}
diff --git a/ext/Digest/SHA/t/2-nist-sha-224.t b/ext/Digest/SHA/t/2-nist-sha-224.t
new file mode 100644
index 0000000000..a1d4d8cf00
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-sha-224.t
@@ -0,0 +1,26 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(sha224_hex);
+
+my(@vec, @rsp);
+
+BEGIN {
+ @vec = (
+"abc",
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+"a" x 1000000
+ );
+
+ @rsp = (
+"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7",
+"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525",
+"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"
+ );
+
+ plan tests => scalar(@vec);
+}
+
+for (my $i = 0; $i < @vec; $i++) {
+ ok(sha224_hex($vec[$i]), $rsp[$i]);
+}
diff --git a/ext/Digest/SHA/t/2-nist-sha-256.t b/ext/Digest/SHA/t/2-nist-sha-256.t
new file mode 100644
index 0000000000..b4eeb67aa3
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-sha-256.t
@@ -0,0 +1,26 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(sha256_hex);
+
+my(@vec, @rsp);
+
+BEGIN {
+ @vec = (
+"abc",
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+"a" x 1000000
+ );
+
+ @rsp = (
+"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
+"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
+"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
+ );
+
+ plan tests => scalar(@vec);
+}
+
+for (my $i = 0; $i < @vec; $i++) {
+ ok(sha256_hex($vec[$i]), $rsp[$i]);
+}
diff --git a/ext/Digest/SHA/t/2-nist-sha-384.t b/ext/Digest/SHA/t/2-nist-sha-384.t
new file mode 100644
index 0000000000..b993ca2a98
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-sha-384.t
@@ -0,0 +1,28 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(sha384_hex);
+
+my(@vec, @rsp);
+
+BEGIN {
+ @vec = (
+"abc",
+"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+"a" x 1000000
+ );
+
+ @rsp = (
+"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
+"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039",
+"9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985"
+ );
+
+ plan tests => scalar(@vec);
+}
+
+my $skip = sha384_hex("") ? 0 : 1;
+
+for (my $i = 0; $i < @vec; $i++) {
+ skip($skip, sha384_hex($vec[$i]), $rsp[$i]);
+}
diff --git a/ext/Digest/SHA/t/2-nist-sha-512.t b/ext/Digest/SHA/t/2-nist-sha-512.t
new file mode 100644
index 0000000000..b3317b818b
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-sha-512.t
@@ -0,0 +1,28 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(sha512_hex);
+
+my(@vec, @rsp);
+
+BEGIN {
+ @vec = (
+"abc",
+"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+"a" x 1000000
+ );
+
+ @rsp = (
+"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909",
+"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
+ );
+
+ plan tests => scalar(@vec);
+}
+
+my $skip = sha512_hex("") ? 0 : 1;
+
+for (my $i = 0; $i < @vec; $i++) {
+ skip($skip, sha512_hex($vec[$i]), $rsp[$i]);
+}
diff --git a/ext/Digest/SHA/t/2-nist-sha-base64.t b/ext/Digest/SHA/t/2-nist-sha-base64.t
new file mode 100644
index 0000000000..e3e9cda9ca
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-sha-base64.t
@@ -0,0 +1,30 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(sha1_base64 sha224_base64 sha256_base64 sha384_base64 sha512_base64);
+
+my(@vec, $data);
+
+BEGIN {
+ $data = "abc";
+ @vec = (
+\&sha1_base64, "qZk+NkcGgWq6PiVxeFDCbJzQ2J0",
+\&sha224_base64, "Iwl9IjQF2CKGQqR3vaJVsyqtvOS9oLP342ydpw",
+\&sha256_base64, "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0",
+\&sha384_base64, "ywB1P0WjXou1oD1pmsZQBycsMqsO3tFjGotgWkP/W+2AhgcroefMI1i67KE0yCWn",
+\&sha512_base64, "3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw"
+ );
+
+ plan tests => scalar(@vec) / 2;
+}
+
+my $fcn;
+my $rsp;
+my $skip;
+
+while (@vec) {
+ $fcn = shift(@vec);
+ $rsp = shift(@vec);
+ $skip = &$fcn("") ? 0 : 1;
+ skip($skip, &$fcn($data), $rsp);
+}
diff --git a/ext/Digest/SHA/t/2-nist-sha-oo.t b/ext/Digest/SHA/t/2-nist-sha-oo.t
new file mode 100644
index 0000000000..72f6243769
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-sha-oo.t
@@ -0,0 +1,44 @@
+use Test;
+use strict;
+use integer;
+use File::Basename qw(dirname);
+use File::Spec;
+use Digest::SHA;
+
+my(@vec);
+
+BEGIN {
+ @vec = (
+"ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0",
+"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
+ );
+
+ plan tests => 1 + scalar(@vec);
+}
+
+ # attempt to use an invalid algorithm, and check for failure
+
+my $NSA = "SHA-42"; # No Such Algorithm
+ok(Digest::SHA->new($NSA), undef);
+
+ # test OO methods using first two SHA-256 vectors from NIST
+
+my $temp = dirname($0) . "/oo.tmp";
+my $file = File::Spec->canonpath($temp);
+open(FILE, ">$file");
+binmode(FILE);
+print FILE "bcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+close(FILE);
+
+my $ctx = Digest::SHA->new()->reset("SHA-256")->new();
+$ctx->add_bits("a", 5)->add_bits("001");
+
+my $rsp = shift(@vec);
+ok($ctx->clone->add("b", "c")->b64digest, $rsp);
+
+$rsp = shift(@vec);
+open(FILE, "<$file");
+binmode(FILE);
+ok($ctx->addfile(*FILE)->hexdigest, $rsp);
+close(FILE);
+unlink($file);
diff --git a/ext/Digest/SHA/t/2-nist-vectors-bit.t b/ext/Digest/SHA/t/2-nist-vectors-bit.t
new file mode 100644
index 0000000000..dfa133de41
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-vectors-bit.t
@@ -0,0 +1,82 @@
+# Test against SHA-1 Sample Vectors from NIST
+#
+# ref: http://csrc.nist.gov/cryptval/shs.html
+#
+# Uses files "nist/bit-messages.sha1" and "nist/bit-hashes.sha1"
+
+use Test;
+use strict;
+use integer;
+
+use File::Basename qw(dirname);
+use File::Spec;
+use Digest::SHA;
+
+my @hashes;
+
+BEGIN {
+ my $file = dirname($0) . "/nist/bit-hashes.sha1";
+ my $datafile = File::Spec->canonpath($file);
+ open(F, $datafile);
+ while (<F>) {
+ next unless (/^[0-9A-F]/);
+ s/[\r\n]+$//;
+ if (/\^$/) {
+ s/\s*\^$//;
+ push(@hashes, $_);
+ }
+ }
+ close(F);
+ plan tests => scalar(@hashes);
+}
+
+sub doType3 {
+ my $hash;
+ my $str = pack("B*", shift);
+ my $ctx = Digest::SHA->new(1);
+ for (my $j = 0; $j <= 99; $j++) {
+ for (my $i = 1; $i <= 50000; $i++) {
+ $str .= chr(0x00) x (int($j/4)+3);
+ $str .= pack("N", $i);
+ $str = $ctx->add($str)->digest;
+ }
+ ok(uc(unpack("H*", $str)), $hash = shift(@hashes));
+ }
+}
+
+my @msgs;
+my @cnts;
+my $bitstr;
+my $bitval;
+my $line;
+my $hash;
+my $type3 = 0;
+my $ctx = Digest::SHA->new(1);
+
+my $file = dirname($0) . "/nist/bit-messages.sha1";
+my $datafile = File::Spec->canonpath($file);
+open(F, $datafile);
+while (<F>) {
+ $type3 = 1 if (/Type 3/);
+ $type3 = 0 if (/^<D/);
+ next unless (/^[0-9^ ]/);
+ s/[\r\n]+$//;
+ $line .= $_;
+ if (/\^$/) {
+ $line =~ s/\s*\^$//;
+ @cnts = split(/\s+/, $line);
+ $bitstr = "";
+ $bitval = $cnts[1];
+ for (my $i = 0; $i < $cnts[0]; $i++) {
+ $bitstr .= $bitval x $cnts[$i+2];
+ $bitval = $bitval eq "1" ? "0" : "1";
+ }
+ ok(
+ uc($ctx->add_bits($bitstr)->hexdigest),
+ $hash = shift(@hashes)
+ ) unless $type3;
+ doType3($bitstr) if ($type3);
+ $line = "";
+ }
+}
+close(F);
diff --git a/ext/Digest/SHA/t/2-nist-vectors-byte.t b/ext/Digest/SHA/t/2-nist-vectors-byte.t
new file mode 100644
index 0000000000..8c817c0a05
--- /dev/null
+++ b/ext/Digest/SHA/t/2-nist-vectors-byte.t
@@ -0,0 +1,82 @@
+# Test against SHA-1 Sample Vectors from NIST
+#
+# ref: http://csrc.nist.gov/cryptval/shs.html
+#
+# Uses files "nist/byte-messages.sha1" and "nist/byte-hashes.sha1"
+
+use Test;
+use strict;
+use integer;
+
+use File::Basename qw(dirname);
+use File::Spec;
+use Digest::SHA;
+
+my @hashes;
+
+BEGIN {
+ my $file = dirname($0) . "/nist/byte-hashes.sha1";
+ my $datafile = File::Spec->canonpath($file);
+ open(F, $datafile);
+ while (<F>) {
+ next unless (/^[0-9A-F]/);
+ s/[\r\n]+$//;
+ if (/\^$/) {
+ s/\s*\^$//;
+ push(@hashes, $_);
+ }
+ }
+ close(F);
+ plan tests => scalar(@hashes);
+}
+
+sub doType3 {
+ my $hash;
+ my $str = pack("B*", shift);
+ my $ctx = Digest::SHA->new(1);
+ for (my $j = 0; $j <= 99; $j++) {
+ for (my $i = 1; $i <= 50000; $i++) {
+ $str .= chr(0x00) x (int($j/4)+3);
+ $str .= pack("N", $i);
+ $str = $ctx->add($str)->digest;
+ }
+ ok(uc(unpack("H*", $str)), $hash = shift(@hashes));
+ }
+}
+
+my @msgs;
+my @cnts;
+my $bitstr;
+my $bitval;
+my $line;
+my $hash;
+my $type3 = 0;
+my $ctx = Digest::SHA->new(1);
+
+my $file = dirname($0) . "/nist/byte-messages.sha1";
+my $datafile = File::Spec->canonpath($file);
+open(F, $datafile);
+while (<F>) {
+ $type3 = 1 if (/Type 3/);
+ $type3 = 0 if (/^<D/);
+ next unless (/^[0-9^ ]/);
+ s/[\r\n]+$//;
+ $line .= $_;
+ if (/\^$/) {
+ $line =~ s/\s*\^$//;
+ @cnts = split(/\s+/, $line);
+ $bitstr = "";
+ $bitval = $cnts[1];
+ for (my $i = 0; $i < $cnts[0]; $i++) {
+ $bitstr .= $bitval x $cnts[$i+2];
+ $bitval = $bitval eq "1" ? "0" : "1";
+ }
+ ok (
+ uc($ctx->add(pack("B*", $bitstr))->hexdigest),
+ $hash = shift(@hashes)
+ ) unless $type3;
+ doType3($bitstr) if ($type3);
+ $line = "";
+ }
+}
+close(F);
diff --git a/ext/Digest/SHA/t/3-gillogly-easy.t b/ext/Digest/SHA/t/3-gillogly-easy.t
new file mode 100644
index 0000000000..603c7ec1a2
--- /dev/null
+++ b/ext/Digest/SHA/t/3-gillogly-easy.t
@@ -0,0 +1,61 @@
+# Test against short bitwise vectors from Jim Gillogly and Francois Grieu
+#
+# http://www.chiark.greenend.org.uk/pipermail/ukcrypto/1999-February/003538.html
+
+use Test;
+use strict;
+use integer;
+use Digest::SHA;
+
+# SHA-1 Test Vectors
+#
+# In the following we use the notation bitstring#n to mean a bitstring
+# repeated n (in decimal) times, and we use | for concatenation.
+# Therefore 110#3|1 is 1101101101.
+#
+# 110#148|11 : CE7387AE 577337BE 54EA94F8 2C842E8B E76BC3E1
+# 110#149 : DE244F06 3142CB2F 4C903B7F 7660577F 9E0D8791
+# 110#149|1 : A3D29824 27AE39C8 920CA5F4 99D6C2BD 71EBF03C
+# 110#149|11 : 351AAB58 FF93CF12 AF7D5A58 4CFC8F7D 81023D10
+#
+# 110#170 : 99638692 1E480D4E 2955E727 5DF3522C E8F5AB6E
+# 110#170|1 : BB5F4AD4 8913F51B 157EB985 A5C2034B 8243B01B
+# 110#170|11 : 9E92C554 2237B957 BA2244E8 141FDB66 DEC730A5
+# 110#171 : 2103E454 DA4491F4 E32DD425 A3341DC9 C2A90848
+#
+# 011#490 : B4B18049 DE405027 528CD9E7 4B2EC540 D4E6F06B
+# 011#490|0 : 34C63356 B3087427 20AB9669 14EB0FC9 26E4294B
+# 011#490|01 : 75FACE18 02B9F84F 326368AB 06E73E05 02E9EA34
+# 011#491 : 7C2C3D62 F6AEC28D 94CDF93F 02E739E7 490698A1
+#
+
+my(@vec);
+
+BEGIN {
+ @vec = (
+ "110",148,"11","ce7387ae577337be54ea94f82c842e8be76bc3e1",
+ "110",149,"","de244f063142cb2f4c903b7f7660577f9e0d8791",
+ "110",149,"1","a3d2982427ae39c8920ca5f499d6c2bd71ebf03c",
+ "110",149,"11","351aab58ff93cf12af7d5a584cfc8f7d81023d10",
+ "110",170,"","996386921e480d4e2955e7275df3522ce8f5ab6e",
+ "110",170,"1","bb5f4ad48913f51b157eb985a5c2034b8243b01b",
+ "110",170,"11","9e92c5542237b957ba2244e8141fdb66dec730a5",
+ "110",171,"","2103e454da4491f4e32dd425a3341dc9c2a90848",
+ "011",490,"","b4b18049de405027528cd9e74b2ec540d4e6f06b",
+ "011",490,"0","34c63356b308742720ab966914eb0fc926e4294b",
+ "011",490,"01","75face1802b9f84f326368ab06e73e0502e9ea34",
+ "011",491,"","7c2c3d62f6aec28d94cdf93f02e739e7490698a1",
+ );
+ plan tests => scalar(@vec) / 4;
+}
+
+my $bitstr;
+my $bitcnt;
+my $ctx = Digest::SHA->new(1);
+
+for (my $i = 0; $i < @vec/4; $i++) {
+ $bitstr = ($vec[4*$i] x $vec[4*$i+1]) . $vec[4*$i+2];
+ $bitcnt = length($bitstr);
+ $bitstr = pack("B*", $bitstr);
+ ok($ctx->add_bits($bitstr, $bitcnt)->hexdigest, $vec[4*$i+3]);
+}
diff --git a/ext/Digest/SHA/t/3-gillogly-hard.t b/ext/Digest/SHA/t/3-gillogly-hard.t
new file mode 100644
index 0000000000..db10a94b3c
--- /dev/null
+++ b/ext/Digest/SHA/t/3-gillogly-hard.t
@@ -0,0 +1,114 @@
+# Test against long bitwise vectors from Jim Gillogly and Francois Grieu
+#
+# http://www.chiark.greenend.org.uk/pipermail/ukcrypto/1999-February/003538.html
+
+use Test;
+use strict;
+use integer;
+use File::Basename qw(dirname);
+use File::Spec;
+use Digest::SHA;
+
+# SHA-1 Test Vectors
+#
+# In the following we use the notation bitstring#n to mean a bitstring
+# repeated n (in decimal) times, and we use | for concatenation.
+# Therefore 110#3|1 is 1101101101.
+#
+# Here is a set near 2^32 bits to test the roll-over in the length
+# field from one to two 32-bit words:
+#
+# 110#1431655764|11 1eef5a18 969255a3 b1793a2a 955c7ec2 8cd221a5
+# 110#1431655765| 7a1045b9 14672afa ce8d90e6 d19b3a6a da3cb879
+# 110#1431655765|1 d5e09777 a94f1ea9 240874c4 8d9fecb6 b634256b
+# 110#1431655765|11 eb256904 3c3014e5 1b2862ae 6eb5fb4e 0b851d99
+#
+# 011#1431655764|01 4CB0C4EF 69143D5B F34FC35F 1D4B19F6 ECCAE0F2
+# 011#1431655765 47D92F91 1FC7BB74 DE00ADFC 4E981A81 05556D52
+# 011#1431655765|0 A3D7438C 589B0B93 2AA91CC2 446F06DF 9ABC73F0
+# 011#1431655765|01 3EEE3E1E 28DEDE2C A444D68D A5675B2F AAAB3203
+
+my(@vec110, @vec011);
+
+BEGIN {
+ @vec110 = ( # 110 rep 1431655764
+ "11", "1eef5a18969255a3b1793a2a955c7ec28cd221a5",
+ "110", "7a1045b914672aface8d90e6d19b3a6ada3cb879",
+ "1101", "d5e09777a94f1ea9240874c48d9fecb6b634256b",
+ "11011", "eb2569043c3014e51b2862ae6eb5fb4e0b851d99"
+ );
+
+ @vec011 = ( # 011 rep 1431655764
+ "01", "4cb0c4ef69143d5bf34fc35f1d4b19f6eccae0f2",
+ "011", "47d92f911fc7bb74de00adfc4e981a8105556d52",
+ "0110", "a3d7438c589b0b932aa91cc2446f06df9abc73f0",
+ "01101", "3eee3e1e28dede2ca444d68da5675b2faaab3203"
+ );
+ plan tests => scalar(@vec110) / 2 + scalar(@vec011) / 2;
+}
+
+my $fileSTATE110 = dirname($0) . "/gillogly/state.110";
+my $fileSTATE011 = dirname($0) . "/gillogly/state.011";
+
+my $STATE110 = File::Spec->canonpath($fileSTATE110);
+my $STATE011 = File::Spec->canonpath($fileSTATE011);
+
+my $reps = 1 << 14;
+my $loops = int(1431655764 / $reps);
+my $rest = 3 * (1431655764 - $loops * $reps);
+
+sub state110 {
+ my $state;
+ my $bitstr;
+
+ $state = Digest::SHA->new(1);
+ if (-r $STATE110) {
+ if ($state->load($STATE110)) {
+ return($state);
+ }
+ }
+ $bitstr = pack("B*", "110" x $reps);
+ $state->reset;
+ for (my $i = 0; $i < $loops; $i++) {
+ $state->add_bits($bitstr, 3 * $reps);
+ }
+ $state->add_bits($bitstr, $rest);
+ $state->dump($STATE110);
+ return($state);
+}
+
+sub state011 {
+ my $state;
+ my $bitstr;
+
+ $state = Digest::SHA->new(1);
+ if (-r $STATE011) {
+ if ($state->load($STATE011)) {
+ return($state);
+ }
+ }
+ $bitstr = pack("B*", "011" x $reps);
+ $state->reset;
+ for (my $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 = state110();
+for ($i = 0; $i < @vec110/2; $i++) {
+ my $state = $state110->clone;
+ $state->add_bits($vec110[2*$i]);
+ ok($state->hexdigest, $vec110[2*$i+1]);
+}
+
+my $state011 = state011();
+for ($i = 0; $i < @vec011/2; $i++) {
+ my $state = $state011->clone;
+ $state->add_bits($vec011[2*$i]);
+ ok($state->hexdigest, $vec011[2*$i+1]);
+}
diff --git a/ext/Digest/SHA/t/4-bitstr-increasing.t b/ext/Digest/SHA/t/4-bitstr-increasing.t
new file mode 100644
index 0000000000..160a344511
--- /dev/null
+++ b/ext/Digest/SHA/t/4-bitstr-increasing.t
@@ -0,0 +1,22 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA;
+
+BEGIN { plan tests => 1 }
+
+my $i;
+my $bitstr = pack("B*", "1" x 3999);
+my $state = Digest::SHA->new("sHa1");
+
+# Note that (1 + 2 + ... + 3999) + 2000 = 8000000
+
+for ($i = 0; $i <= 3999; $i++) {
+ $state->add_bits($bitstr, $i);
+}
+$state->add_bits($bitstr, 2000);
+
+ok(
+ $state->hexdigest,
+ "559a512393dd212220ee080730d6f11644ba0222"
+);
diff --git a/ext/Digest/SHA/t/4-bitstr-large.t b/ext/Digest/SHA/t/4-bitstr-large.t
new file mode 100644
index 0000000000..e1220adc1d
--- /dev/null
+++ b/ext/Digest/SHA/t/4-bitstr-large.t
@@ -0,0 +1,21 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA;
+
+BEGIN { plan tests => 1 }
+
+my $i;
+my $bitstr = pack("B*", "11111111" x 10000);
+my $state = Digest::SHA->new("1");
+
+$state->add_bits($bitstr, 1); # creates an alignment nuisance
+for ($i = 0; $i < 99; $i++) {
+ $state->add_bits($bitstr, 80000);
+}
+$state->add_bits($bitstr, 79999);
+
+ok(
+ $state->hexdigest,
+ "559a512393dd212220ee080730d6f11644ba0222"
+);
diff --git a/ext/Digest/SHA/t/4-bitstr-random.t b/ext/Digest/SHA/t/4-bitstr-random.t
new file mode 100644
index 0000000000..8c71c5a75c
--- /dev/null
+++ b/ext/Digest/SHA/t/4-bitstr-random.t
@@ -0,0 +1,24 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA;
+
+BEGIN { plan tests => 1 }
+
+my $reps = 8000000;
+my $bitstr = pack("B*", "11111111" x 127);
+my $maxbits = 8 * 127;
+my $state = Digest::SHA->new(1);
+my $num;
+
+while ($reps > $maxbits) {
+ $num = int(rand($maxbits));
+ $state->add_bits($bitstr, $num);
+ $reps -= $num;
+}
+$state->add_bits($bitstr, $reps);
+
+ok(
+ $state->hexdigest,
+ "559a512393dd212220ee080730d6f11644ba0222"
+);
diff --git a/ext/Digest/SHA/t/5-hmac-fips198.t b/ext/Digest/SHA/t/5-hmac-fips198.t
new file mode 100644
index 0000000000..a6af3425fc
--- /dev/null
+++ b/ext/Digest/SHA/t/5-hmac-fips198.t
@@ -0,0 +1,44 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(hmac_sha1_hex);
+
+my(@vec);
+
+BEGIN {
+ @vec = (
+ "Sample #1",
+ "Sample #2",
+ "Sample #3",
+ "Sample #4"
+ );
+ plan tests => scalar(@vec);
+}
+
+my @keys = ("", "", "", "");
+
+my $i = 0;
+$keys[0] .= chr($i++) while (length($keys[0]) < 64);
+
+$i = 0x30;
+$keys[1] .= chr($i++) while (length($keys[1]) < 20);
+
+$i = 0x50;
+$keys[2] .= chr($i++) while (length($keys[2]) < 100);
+
+$i = 0x70;
+$keys[3] .= chr($i++) while (length($keys[3]) < 49);
+
+my @hmac1rsp = (
+ "4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a",
+ "0922d3405faa3d194f82a45830737d5cc6c75d24",
+ "bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa",
+ "9ea886efe268dbecce420c7524df32e0751a2a26"
+);
+
+for ($i = 0; $i < @vec; $i++) {
+ ok(
+ hmac_sha1_hex($vec[$i], $keys[$i]),
+ $hmac1rsp[$i]
+ );
+}
diff --git a/ext/Digest/SHA/t/5-hmac-rfc2202.t b/ext/Digest/SHA/t/5-hmac-rfc2202.t
new file mode 100644
index 0000000000..6e77f3d6bc
--- /dev/null
+++ b/ext/Digest/SHA/t/5-hmac-rfc2202.t
@@ -0,0 +1,49 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(hmac_sha1_hex);
+
+my(@vec);
+
+BEGIN {
+ @vec = (
+"Hi There",
+"what do ya want for nothing?",
+chr(0xdd) x 50,
+chr(0xcd) x 50,
+"Test With Truncation",
+"Test Using Larger Than Block-Size Key - Hash Key First",
+"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
+ );
+ plan tests => scalar(@vec);
+}
+
+my @keys = (
+ chr(0x0b) x 20,
+ "Jefe",
+ chr(0xaa) x 20,
+ "",
+ chr(0x0c) x 20,
+ chr(0xaa) x 80,
+ chr(0xaa) x 80
+);
+
+my @hmac1rsp = (
+ "b617318655057264e28bc0b6fb378c8ef146be00",
+ "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79",
+ "125d7342b9ac11cd91a39af48aa17b4f63f175d3",
+ "4c9007f4026250c6bc8414f9bf50c86c2d7235da",
+ "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04",
+ "aa4ae5e15272d00e95705637ce8a3b55ed402112",
+ "e8e99d0f45237d786d6bbaa7965c7808bbff1a91"
+);
+
+my $i = 0x01;
+$keys[3] .= chr($i++) while (length($keys[3]) < 25);
+
+for ($i = 0; $i < @vec; $i++) {
+ ok(
+ hmac_sha1_hex($vec[$i], $keys[$i]),
+ $hmac1rsp[$i]
+ );
+}
diff --git a/ext/Digest/SHA/t/5-hmac-sha-256.t b/ext/Digest/SHA/t/5-hmac-sha-256.t
new file mode 100644
index 0000000000..55731c8bb8
--- /dev/null
+++ b/ext/Digest/SHA/t/5-hmac-sha-256.t
@@ -0,0 +1,64 @@
+# HMAC-SHA-256 test vectors from draft-ietf-ipsec-ciph-sha-256-01.txt
+
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(hmac_sha256_hex);
+
+my(@data);
+
+BEGIN {
+ @data = (
+"abc",
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+"Hi There",
+"what do ya want for nothing?",
+chr(0xdd) x 50,
+chr(0xcd) x 50,
+"Test With Truncation",
+"Test Using Larger Than Block-Size Key - Hash Key First",
+"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
+ );
+ plan tests => scalar(@data);
+}
+
+my $k1 = pack("H*", "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20");
+my $k2 = pack("H*", "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425");
+
+my @key = (
+ $k1,
+ $k1,
+ $k1,
+ chr(0x0b) x 32,
+ "Jefe",
+ chr(0xaa) x 32,
+ $k2,
+ chr(0x0c) x 32,
+ chr(0xaa) x 80,
+ chr(0xaa) x 80
+);
+
+my @hmac256rsp = (
+ "a21b1f5d4cf4f73a4dd939750f7a066a7f98cc131cb16a6692759021cfab8181",
+ "104fdc1257328f08184ba73131c53caee698e36119421149ea8c712456697d30",
+ "470305fc7e40fe34d3eeb3e773d95aab73acf0fd060447a5eb4595bf33a9d1a3",
+ "198a607eb44bfbc69903a0f1cf2bbdc5ba0aa3f3d9ae3c1c7a3b1696a0b68cf7",
+ "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
+ "cdcb1220d1ecccea91e53aba3092f962e549fe6ce9ed7fdc43191fbde45c30b0",
+ "d4633c17f6fb8d744c66dee0f8f074556ec4af55ef07998541468eb49bd2e917",
+ "7546af01841fc09b1ab9c3749a5f1c17d4f589668a587b2700a9c97c1193cf42",
+ "6953025ed96f0c09f80a96f78e6538dbe2e7b820e3dd970e7ddd39091b32352f",
+ "6355ac22e890d0a3c8481a5ca4825bc884d3e7a1ff98a2fc2ac7d8e064c3b2e6"
+);
+
+ # do the first one by hand to test multi-argument data feed
+
+ok(hmac_sha256_hex("a", "b", "c", $k1), $hmac256rsp[0]);
+
+for (my $i = 1; $i < @data; $i++) {
+ ok(
+ hmac_sha256_hex($data[$i], $key[$i]),
+ $hmac256rsp[$i]
+ );
+}
diff --git a/ext/Digest/SHA/t/5-hmac-woodbury.t b/ext/Digest/SHA/t/5-hmac-woodbury.t
new file mode 100644
index 0000000000..d71af92cfe
--- /dev/null
+++ b/ext/Digest/SHA/t/5-hmac-woodbury.t
@@ -0,0 +1,114 @@
+# Test Vectors for HMAC-SHA-256/384/512
+#
+# Vectors and script courtesy of Adam Woodbury, The MITRE Corporation
+
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(hmac_sha256_hex hmac_sha384_hex hmac_sha512_hex);
+
+BEGIN { plan tests => 21 }
+
+# Use RFC 2202 data/key values for 512-bit blocks
+
+my @vecs_bs512 = (
+ "Hi There",
+ "what do ya want for nothing?",
+ chr(0xdd) x 50,
+ chr(0xcd) x 50,
+ "Test With Truncation",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
+);
+
+my @keys_bs512 = (
+ chr(0x0b) x 20,
+ "Jefe",
+ chr(0xaa) x 20,
+ "",
+ chr(0x0c) x 20,
+ chr(0xaa) x 80,
+ chr(0xaa) x 80
+);
+
+# Lengthen final RFC 2202 data/key values for 1024-bit blocks
+
+my @vecs_bs1024 = (
+ "Hi There",
+ "what do ya want for nothing?",
+ chr(0xdd) x 50,
+ chr(0xcd) x 50,
+ "Test With Truncation",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data. The Larger Block-Sizes Make For Much Longer Test Vectors"
+);
+
+my @keys_bs1024 = (
+ chr(0x0b) x 20,
+ "Jefe",
+ chr(0xaa) x 20,
+ "",
+ chr(0x0c) x 20,
+ chr(0xaa) x 200,
+ chr(0xaa) x 200
+);
+
+my @hmac256rsp = (
+ "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
+ "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
+ "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
+ "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
+ "a3b6167473100ee06e0c796c2955552bfa6f7c0a6a8aef8b93f860aab0cd20c5",
+ "6953025ed96f0c09f80a96f78e6538dbe2e7b820e3dd970e7ddd39091b32352f",
+ "6355ac22e890d0a3c8481a5ca4825bc884d3e7a1ff98a2fc2ac7d8e064c3b2e6"
+);
+
+my @hmac384rsp = (
+"afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6",
+"af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649",
+"88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27",
+"3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb",
+"3abf34c3503b2a23a46efc619baef897f4c8e42c934ce55ccbae9740fcbc1af4ca62269e2a37cd88ba926341efe4aeea",
+"ec629fe0dc1fab504fc1c89572d6573cf15c3a4b5b69d53f0c13849561a6c13e153af48d2538ce056a3fe10d69da16c3",
+"07109d2c6c2fdcac39c3a8b5f36fc9a69e029d3d8647cc3e4ddb77888418c5c09d807942e5f96d17ee9fd46aed64b7f2"
+);
+
+my @hmac512rsp = (
+"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854",
+"164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737",
+"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb",
+"b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd",
+"415fad6271580a531d4179bc891d87a650188707922a4fbb36663a1eb16da008711c5b50ddd0fc235084eb9d3364a1454fb2ef67cd1d29fe6773068ea266e96b",
+"9dc6330f4c966b62b735d565343cb77413deccdf42a92d9ef5e4e2ae33f6c924bbc8e34c47111bc069482d4dbcfee148419a6547f2d01500e8160b39cc2e4ae8",
+"396ed3a17cef82cddbd987ea66a5dd1f38b68167df31f049463b85fa10b531d0e90d1052f8c9c7cda263468ec3f980a8fec06213c2944c92a0ac95a2d8ade76d"
+);
+
+my $i = 0x01;
+$keys_bs512[3] .= chr($i++) while (length($keys_bs512[3]) < 25);
+$i = 0x01;
+$keys_bs1024[3] .= chr($i++) while (length($keys_bs1024[3]) < 25);
+
+for ($i = 0; $i < @vecs_bs512; $i++) {
+ ok(
+ hmac_sha256_hex($vecs_bs512[$i], $keys_bs512[$i]),
+ $hmac256rsp[$i]
+ );
+}
+
+my $skip = hmac_sha384_hex("", "") ? 0 : 1;
+
+for ($i = 0; $i < @vecs_bs1024; $i++) {
+ skip(
+ $skip,
+ hmac_sha384_hex($vecs_bs1024[$i], $keys_bs1024[$i]),
+ $hmac384rsp[$i]
+ );
+}
+
+for ($i = 0; $i < @vecs_bs1024; $i++) {
+ skip(
+ $skip,
+ hmac_sha512_hex($vecs_bs1024[$i], $keys_bs1024[$i]),
+ $hmac512rsp[$i]
+ );
+}
diff --git a/ext/Digest/SHA/t/6-dump-load.t b/ext/Digest/SHA/t/6-dump-load.t
new file mode 100644
index 0000000000..c369ac18e2
--- /dev/null
+++ b/ext/Digest/SHA/t/6-dump-load.t
@@ -0,0 +1,53 @@
+use Test;
+use strict;
+use integer;
+use Digest::SHA qw(sha384_hex sha512_hex);
+use File::Basename qw(dirname);
+use File::Spec;
+
+my(@sharsp);
+
+BEGIN {
+ @sharsp = (
+"34aa973cd4c4daa4f61eeb2bdbad27316534016f",
+"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0",
+"9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985",
+"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
+ );
+ plan tests => scalar(@sharsp);
+}
+
+my @ext = (1, 256, 384, 512);
+my $data = "a" x 990000;
+my $skip;
+my $tmpname = dirname($0) . "/dumpload.tmp";
+my $tmpfile = File::Spec->canonpath($tmpname);
+
+for (my $i = 0; $i < @sharsp; $i++) {
+ $skip = 0;
+ if ($ext[$i] == 384) {
+ $skip = sha384_hex("") ? 0 : 1;
+ }
+ if ($ext[$i] == 512) {
+ $skip = sha512_hex("") ? 0 : 1;
+ }
+ my $digest;
+ unless ($skip) {
+ my $state;
+ my $file;
+ my $filename;
+ $filename = dirname($0) . "/state/state.$ext[$i]";
+ $file = File::Spec->canonpath($filename);
+ unless ($state = Digest::SHA->load($file)) {
+ $state = Digest::SHA->new($ext[$i]);
+ $state->add($data);
+ $state->dump($file);
+ $state->load($file);
+ }
+ $state->add_bits($data, 79984)->dump($tmpfile);
+ $state->load($tmpfile)->add_bits($data, 16);
+ unlink($tmpfile);
+ $digest = $state->hexdigest;
+ }
+ skip($skip, $digest, $sharsp[$i]);
+}
diff --git a/ext/Digest/SHA/t/7-ireland.t b/ext/Digest/SHA/t/7-ireland.t
new file mode 100644
index 0000000000..76ca9e2ee3
--- /dev/null
+++ b/ext/Digest/SHA/t/7-ireland.t
@@ -0,0 +1,41 @@
+use Test;
+use strict;
+use File::Basename qw(dirname);
+use File::Spec;
+use Digest::SHA;
+
+# 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
+
+BEGIN { plan tests => 1 }
+
+my $filename = dirname($0) . "/ireland.tmp";
+my $file = File::Spec->canonpath($filename);
+open(F, ">$file"); while (<DATA>) { print F $_ } close(F);
+
+my $data = "a" x 1000000;
+my $vec = "b9045a713caed5dff3d3b783e98d1ce5778d8bc331ee4119d707072312af06a7";
+
+my $ctx;
+unless ($ctx = Digest::SHA->load($file)) {
+ $ctx = Digest::SHA->new(256);
+ for (1 .. 536) { $ctx->add($data) }
+ $ctx->add(substr($data, 0, 870910));
+ $ctx->dump($file);
+}
+$ctx->add("aa");
+ok($ctx->hexdigest, $vec);
+
+unlink($file);
+
+__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
+blockcnt:496
+lenhh:0
+lenhl:0
+lenlh:0
+lenll:4294967280
diff --git a/ext/Digest/SHA/t/gillogly/state.011 b/ext/Digest/SHA/t/gillogly/state.011
new file mode 100644
index 0000000000..005c3c5c0c
--- /dev/null
+++ b/ext/Digest/SHA/t/gillogly/state.011
@@ -0,0 +1,8 @@
+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
+blockcnt:508
+lenhh:0
+lenhl:0
+lenlh:0
+lenll:4294967292
diff --git a/ext/Digest/SHA/t/gillogly/state.110 b/ext/Digest/SHA/t/gillogly/state.110
new file mode 100644
index 0000000000..41b621543d
--- /dev/null
+++ b/ext/Digest/SHA/t/gillogly/state.110
@@ -0,0 +1,8 @@
+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
+blockcnt:508
+lenhh:0
+lenhl:0
+lenlh:0
+lenll:4294967292
diff --git a/ext/Digest/SHA/t/nist/COPYRIGHT b/ext/Digest/SHA/t/nist/COPYRIGHT
new file mode 100644
index 0000000000..3671be9f90
--- /dev/null
+++ b/ext/Digest/SHA/t/nist/COPYRIGHT
@@ -0,0 +1,17 @@
+The files in this directory were extracted from the "sha1-vectors.zip"
+archive, which is publicly available through the National Institute
+of Standards and Technology (NIST) website at the following URL:
+
+ http://csrc.nist.gov/cryptval/shs.html
+
+The files have been truncated to include only the first 10 test
+cases for bit and byte messages. This was done solely to decrease
+the size of the module distribution, thereby making downloads much
+quicker for users. If a more extensive test run is desired, simply
+replace these files by the originals from the above URL.
+
+NIST advises that the archive file describes "tests and vectors
+that can be used to informally verify the correctness of an SHA-1
+implementation. However, use of these vectors does not take the
+place of validation obtained through the Cryptographic Module
+Validation Program."
diff --git a/ext/Digest/SHA/t/nist/Readme.txt b/ext/Digest/SHA/t/nist/Readme.txt
new file mode 100644
index 0000000000..470a00d982
--- /dev/null
+++ b/ext/Digest/SHA/t/nist/Readme.txt
@@ -0,0 +1,82 @@
+
+ Sample Vectors for SHA-1 Testing
+
+ This file describes tests and vectors that can be used in verifying the correctness of
+an SHA-1 implementation. However, use of these vectors does not take the place of validation
+obtained through the Cryptographic Module Validation Program.
+
+ There are three areas of the Secure Hash Standard for which test vectors are supplied:
+short messages of varying length, selected long messages, and pseudorandomly generated messages.
+Since it is possible for an implementation to correctly handle the hashing of byte-oriented
+messages (and not messages of a non-byte length), the SHS tests each come in two flavors. For
+both byte oriented and bit oriented messages, the message lengths are given in bits.
+
+Type I Test: Messages of Varying Length
+
+ An implementation of the SHS must be able to correctly generate message digests for
+messages of arbitrary length. This functionality can be tested by supplying the implementation
+with 1025 pseudorandomly generated messages with lengths from 0 to 1024 bits (for an implementation
+that only hashes byte-oriented data correctly, 129 messages of length 0, 8, 16, 24,...,1024 bits
+will be supplied).
+
+Type II Test: Selected Long Messages
+
+ Additional testing of an implementation can be performed by testing that the implementation
+can correctly generate digests for longer messages. A list of 100 messages, each of length > 1024,
+is supplied. These can be used to verify the hashing of longer message lengths. For bit oriented
+testing the messages are from 1025 to 103425 bits long (length=1025+i*1024, where 0<=i<100). For
+byte oriented testing the messages are from 1032 to 103432 (length=1032+i*1024, where 0<=i<100).
+
+Type III Test: Pseudorandomly Generated Messages
+
+ This test determines whether the implementation can compute message digests for messages
+that are generated using a given seed. A sequence of 100 message digests is generated using this
+seed. The digests are generated according to the following pseudocode:
+
+procedure MonteCarlo(string SEED)
+{
+ integer i, j, a;
+ string M;
+
+ M := SEED;
+ for j = 0 to 99 do {
+ for i = 1 to 50000 do {
+ for a = 1 to (j/4*8 + 24) do M := M || ’0’; /*‘0' is the binary zero bit. */
+ M := M || i; /* Here, the value for ‘i’ is expressed as a 32-bit word
+ and concatenated with ‘M’. The first bit
+ concatenated with ‘M’ is the most significant bit of
+ this 32-bit word. */
+ M := SHA(M);
+ }
+ print(M);
+ }
+ }
+
+NOTE: In the above procedure, || denotes concatenation. Also, M || i denotes appending the 32-bit
+word representing the value ‘i’, as defined in section 2 of the SHS. Within the procedure, M is a string
+of variable length. The initial length of 416 bits ensures that the length of M never exceeds 512 bits
+during execution of the above procedure, and it ensures that messages will be of a byte length. Each
+element printed should be 160 bits in length.
+
+
+File formats:
+
+There are two files included for each test type (bit-oriented and byte-oriented). One file contains
+the messages and the other file contains the hashes.
+
+The message files provided use "compact strings" to store the message values. Compact strings are
+used to represented the messages in a compact form. A compact string has the form
+ z || b || n(1) || n(2) || ... || n(z)
+where z>=0 that represents the number of n, b is either 0 or 1, and each n(i) is a decimal integer
+representing a positive number. The length of the compact string is given by the summation of the n(i).
+
+The compact string is interpreted as the representation of the bit string consisting of b repeated n(1) times,
+followed by 1-b repeated n(2) times, followed by b repeated n(3) times, and so on.
+
+Example:
+ M = 5 1 7 13 5 1 2
+ where z = 5 and b = 1. Then the compact string M represents the bit string
+ 1111111000000000000011111011
+ where 1 is repeated 7 times, 0 is repeated 13 times, 1 is repeated 5 times,
+ 0 is repeated 1 time, and 1 is repeated 2 times.
+
diff --git a/ext/Digest/SHA/t/nist/bit-hashes.sha1 b/ext/Digest/SHA/t/nist/bit-hashes.sha1
new file mode 100644
index 0000000000..cf95264a16
--- /dev/null
+++ b/ext/Digest/SHA/t/nist/bit-hashes.sha1
@@ -0,0 +1,14 @@
+# Configuration information for "SHA-1 Test"
+# SHA tests are configured for BIT oriented implementations
+H>SHS Type 1 Hashes<H
+D>
+DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 ^
+59C4526AA2CC59F9A5F56B5579BA7108E7CCB61A ^
+6E42FB84067CFF056C43A49E484997AF23190879 ^
+C63FBB9A87171A176E6E054890E29A8C5F125F6C ^
+3109E33C1C4B9A0169D1599169D0E5A520A1E71C ^
+9195E1E73CC68D7170F44BD1D83CB624BC87FA0B ^
+64F7C374527278C0436DBC8DE5AABEC2BBF634BC ^
+154B622EA426FB151B1FF1BE1CE871752B9EDEB4 ^
+12BDD00FD4038756CBCF8ECDAD1B0CD862603CD8 ^
+6700F93E1691E83735279E167F67AF61FEE9813B ^
diff --git a/ext/Digest/SHA/t/nist/bit-messages.sha1 b/ext/Digest/SHA/t/nist/bit-messages.sha1
new file mode 100644
index 0000000000..a4f9951beb
--- /dev/null
+++ b/ext/Digest/SHA/t/nist/bit-messages.sha1
@@ -0,0 +1,14 @@
+# Configuration information for "SHA-1 Test"
+# SHA tests are configured for BIT oriented implementations
+H>SHS Type 1 Strings<H
+D>
+0 1 ^
+1 1 1 ^
+2 1 1 1 ^
+3 0 1 1 1 ^
+2 0 2 2 ^
+4 1 1 1 2 1 ^
+3 0 2 2 2 ^
+4 1 1 2 2 2 ^
+5 1 2 2 1 1 2 ^
+5 0 2 2 1 1 3 ^
diff --git a/ext/Digest/SHA/t/nist/byte-hashes.sha1 b/ext/Digest/SHA/t/nist/byte-hashes.sha1
new file mode 100644
index 0000000000..d28980d937
--- /dev/null
+++ b/ext/Digest/SHA/t/nist/byte-hashes.sha1
@@ -0,0 +1,14 @@
+# Configuration information for "SHA-1 Test"
+# SHA tests are configured for BYTE oriented implementations
+H>SHS Type 1 Hashes<H
+D>
+DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 ^
+3CDF2936DA2FC556BFA533AB1EB59CE710AC80E5 ^
+19C1E2048FA7393CFBF2D310AD8209EC11D996E5 ^
+CA775D8C80FAA6F87FA62BECA6CA6089D63B56E5 ^
+71AC973D0E4B50AE9E5043FF4D615381120A25A0 ^
+A6B5B9F854CFB76701C3BDDBF374B3094EA49CBA ^
+D87A0EE74E4B9AD72E6847C87BDEEB3D07844380 ^
+1976B8DD509FE66BF09C9A8D33534D4EF4F63BFD ^
+5A78F439B6DB845BB8A558E4CEB106CD7B7FF783 ^
+F871BCE62436C1E280357416695EE2EF9B83695C ^
diff --git a/ext/Digest/SHA/t/nist/byte-messages.sha1 b/ext/Digest/SHA/t/nist/byte-messages.sha1
new file mode 100644
index 0000000000..b0682fea02
--- /dev/null
+++ b/ext/Digest/SHA/t/nist/byte-messages.sha1
@@ -0,0 +1,14 @@
+# Configuration information for "SHA-1 Test"
+# SHA tests are configured for BYTE oriented implementations
+H>SHS Type 1 Strings<H
+D>
+0 1 ^
+5 0 2 1 2 1 2 ^
+5 0 1 3 4 4 4 ^
+7 0 4 3 4 4 1 4 4 ^
+10 0 4 1 5 3 4 4 3 1 3 4 ^
+10 0 3 1 6 5 5 1 3 6 6 4 ^
+13 1 3 2 5 3 3 3 4 6 6 1 4 6 2 ^
+16 1 3 5 5 1 2 1 3 3 6 3 5 2 3 5 7 2 ^
+15 1 8 1 5 3 2 7 4 5 6 7 3 3 1 6 3 ^
+15 1 4 6 8 2 1 4 2 5 1 6 8 8 6 4 7 ^
diff --git a/ext/Digest/SHA/t/state/state.1 b/ext/Digest/SHA/t/state/state.1
new file mode 100644
index 0000000000..685db037b8
--- /dev/null
+++ b/ext/Digest/SHA/t/state/state.1
@@ -0,0 +1,8 @@
+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
diff --git a/ext/Digest/SHA/t/state/state.256 b/ext/Digest/SHA/t/state/state.256
new file mode 100644
index 0000000000..4fad8ed755
--- /dev/null
+++ b/ext/Digest/SHA/t/state/state.256
@@ -0,0 +1,8 @@
+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
diff --git a/ext/Digest/SHA/t/state/state.384 b/ext/Digest/SHA/t/state/state.384
new file mode 100644
index 0000000000..8c1bb59117
--- /dev/null
+++ b/ext/Digest/SHA/t/state/state.384
@@ -0,0 +1,8 @@
+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
diff --git a/ext/Digest/SHA/t/state/state.512 b/ext/Digest/SHA/t/state/state.512
new file mode 100644
index 0000000000..444b2ecf4e
--- /dev/null
+++ b/ext/Digest/SHA/t/state/state.512
@@ -0,0 +1,8 @@
+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
diff --git a/ext/Digest/SHA/typemap b/ext/Digest/SHA/typemap
new file mode 100644
index 0000000000..70c4dc1acb
--- /dev/null
+++ b/ext/Digest/SHA/typemap
@@ -0,0 +1,2 @@
+SHA * T_PTROBJ
+HMAC * T_PTROBJ
diff --git a/utils/Makefile b/utils/Makefile
index 5b21d0afb6..b820bd8a64 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -5,9 +5,9 @@ REALPERL = ../perl
# Files to be built with variable substitution after miniperl is
# available. Dependencies handled manually below (for now).
-pl = c2ph.PL cpan.PL corelist.PL h2ph.PL h2xs.PL instmodsh.PL perlbug.PL perldoc.PL perlivp.PL pl2pm.PL prove.PL ptar.PL splain.PL perlcc.PL dprofpp.PL libnetcfg.PL piconv.PL enc2xs.PL xsubpp.PL
-plextract = c2ph cpan corelist h2ph h2xs instmodsh perlbug perldoc perlivp pl2pm prove ptar splain perlcc dprofpp libnetcfg piconv enc2xs xsubpp
-plextractexe = ./c2ph ./cpan ./corelist ./h2ph ./h2xs ./instmodsh ./perlbug ./perldoc ./perlivp ./pl2pm ./prove ./ptar ./splain ./perlcc ./dprofpp ./libnetcfg ./piconv ./enc2xs ./xsubpp
+pl = c2ph.PL cpan.PL corelist.PL h2ph.PL h2xs.PL instmodsh.PL perlbug.PL perldoc.PL perlivp.PL pl2pm.PL prove.PL ptar.PL shasum.PL splain.PL perlcc.PL dprofpp.PL libnetcfg.PL piconv.PL enc2xs.PL xsubpp.PL
+plextract = c2ph cpan corelist h2ph h2xs instmodsh perlbug perldoc perlivp pl2pm prove ptar shasum splain perlcc dprofpp libnetcfg piconv enc2xs xsubpp
+plextractexe = ./c2ph ./cpan ./corelist ./h2ph ./h2xs ./instmodsh ./perlbug ./perldoc ./perlivp ./pl2pm ./prove ./ptar ./shasum ./splain ./perlcc ./dprofpp ./libnetcfg ./piconv ./enc2xs ./xsubpp
all: $(plextract)
@@ -51,6 +51,8 @@ ptar: ptar.PL ../config.sh
pl2pm: pl2pm.PL ../config.sh
+shasum: shasum.PL ../config.sh
+
splain: splain.PL ../config.sh ../lib/diagnostics.pm
perlcc: perlcc.PL ../config.sh
diff --git a/utils/shasum.PL b/utils/shasum.PL
new file mode 100644
index 0000000000..51e6ead62b
--- /dev/null
+++ b/utils/shasum.PL
@@ -0,0 +1,51 @@
+#!/usr/local/bin/perl
+
+use Config;
+use File::Basename qw(&basename &dirname);
+use Cwd;
+
+# List explicitly here the variables you want Configure to
+# generate. Metaconfig only looks for shell variables, so you
+# have to mention them as if they were shell variables, not
+# %Config entries. Thus you write
+# $startperl
+# to ensure Configure will look for $Config{startperl}.
+
+# This forces PL files to create target in same directory as PL file.
+# This is so that make depend always knows where to find PL derivatives.
+my $origdir = cwd;
+chdir dirname($0);
+my $file = basename($0, '.PL');
+$file .= '.com' if $^O eq 'VMS';
+
+open OUT,">$file" or die "Can't create $file: $!";
+
+print "Extracting $file (with variable substitutions)\n";
+
+# In this section, perl variables will be expanded during extraction.
+# You can use $Config{...} to use Configure variables.
+
+print OUT <<"!GROK!THIS!";
+$Config{startperl}
+ eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+ if \$running_under_some_shell;
+!GROK!THIS!
+
+use File::Spec;
+
+my $script = File::Spec->catfile(
+ File::Spec->catdir(
+ File::Spec->updir, qw[ext Digest SHA bin]
+ ), "shasum");
+
+if (open(IN, $script)) {
+ print OUT <IN>;
+ close IN;
+} else {
+ die "$0: cannot find '$script'\n";
+}
+
+close OUT or die "Can't close $file: $!";
+chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
+exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
+chdir $origdir;