Digest-SHA3-0.24/0000755000175000017500000000000012454171765013272 5ustar mshelormshelorDigest-SHA3-0.24/META.yml0000644000175000017500000000053512454154237014541 0ustar mshelormshelor--- #YAML:1.0 name: Digest-SHA3 version: 0.24 abstract: Perl extension for SHA-3 license: perl author: - Mark Shelor, mshelor@cpan.org requires: perl: 5.003 provides: Digest::SHA3: file: lib/Digest/SHA3.pm version: 0.24 meta-spec: version: 1.3 url: http://module-build.sourceforge.net/META-spec-v1.3.html generated_by: Mark Shelor Digest-SHA3-0.24/sha3sum0000755000175000017500000002051612454155405014600 0ustar mshelormshelor#!perl -w ## sha3sum: filter for computing SHA-3 digests (ref. shasum) ## ## Copyright (C) 2012-2015 Mark Shelor, All Rights Reserved ## ## Version: 0.24 ## Sat Jan 10 00:45:34 MST 2015 ## sha3sum SYNOPSIS adapted from GNU Coreutils sha1sum. Add ## "-a" option for algorithm selection, ## "-U" option for Universal Newlines support, ## "-0" option for reading bit strings, and ## "-p" option for portable digests (to be deprecated). use strict; use warnings; use Fcntl; use Getopt::Long; my $POD = <<'END_OF_POD'; =head1 NAME sha3sum - Print or Check SHA-3 Checksums =head1 SYNOPSIS Usage: sha3sum [OPTION]... [FILE]... Print or check SHA-3 checksums. With no FILE, or when FILE is -, read standard input. -a, --algorithm 224 (default), 256, 384, 512, 128000, 256000 -b, --binary read in binary mode -c, --check read SHA-3 sums from the FILEs and check them -t, --text read in text mode (default) -U, --UNIVERSAL read in Universal Newlines mode produces same digest on Windows/Unix/Mac -0, --01 read in BITS mode ASCII '0' interpreted as 0-bit, ASCII '1' interpreted as 1-bit, all other characters ignored -p, --portable read in portable mode (to be deprecated) The following two options are useful only when verifying checksums: -s, --status don't output anything, status code shows success -w, --warn warn about improperly formatted checksum lines -h, --help display this help and exit -v, --version output version information and exit The sums are computed as described in the FIPS 202 SHA-3 submission. 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, `U' for UNIVERSAL, `^' for BITS, `?' for portable), and name for each FILE. Report sha3sum bugs to mshelor@cpan.org =head1 DESCRIPTION Running I is often the quickest way to compute SHA-3 message digests. The user simply feeds data to the script through files or standard input, and then collects the results from standard output. The following command shows how to compute digests for typical inputs such as the NIST test vector "abc": perl -e "print qq(abc)" | sha3sum Or, if you want to use SHA3-256 instead of the default SHA3-224, simply say: perl -e "print qq(abc)" | sha3sum -a 256 Unlike many other digest computation programs, I implements the full SHA-3 standard by allowing partial-byte inputs, which can be recognized through the BITS option (I<-0>). The following example computes the SHA3-384 digest of the 7-bit message I<0001100>: perl -e "print qq(0001100)" | sha3sum -0 -a 384 =head1 AUTHOR Copyright (c) 2012-2015 Mark Shelor . =head1 SEE ALSO I is implemented using the Perl module L. =cut END_OF_POD my $VERSION = "0.24"; ## Try to use Digest::SHA3. If not installed, use the slower ## but functionally equivalent Digest::SHA3::PurePerl instead. my $MOD_PREFER = "Digest::SHA3"; my $MOD_SECOND = "Digest::SHA3::PurePerl"; # Not yet implemented 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 $@; die "Unable to find $MOD_PREFER\n" if $@; } sub usage { my($err, $msg) = @_; $msg = "" unless defined $msg; if ($err) { warn($msg . "Type sha3sum -h for help\n"); exit($err); } my($USAGE) = $POD =~ /SYNOPSIS\n\n(.+)\n=head1 DESCRIPTION\n/sm; $USAGE =~ s/^ //gm; print $USAGE; exit($err); } ## Sync stdout and stderr by forcing a flush after every write select((select(STDOUT), $| = 1)[0]); select((select(STDERR), $| = 1)[0]); ## Collect options from command line my ($alg, $binary, $check, $text, $status, $warn, $help, $version); my ($portable, $BITS, $UNIVERSAL); eval { Getopt::Long::Configure ("bundling") }; GetOptions( 'b|binary' => \$binary, 'c|check' => \$check, 't|text' => \$text, 'a|algorithm=i' => \$alg, 's|status' => \$status, 'w|warn' => \$warn, 'h|help' => \$help, 'v|version' => \$version, 'U|UNIVERSAL' => \$UNIVERSAL, '0|01' => \$BITS, 'p|portable' => \$portable, ) or usage(1, ""); ## Deal with help requests and incorrect uses usage(0) if $help; usage(1, "sha3sum: Ambiguous file mode\n") if scalar(grep {defined $_} ($binary, $portable, $text, $BITS, $UNIVERSAL)) > 1; usage(1, "sha3sum: --warn option used only when verifying checksums\n") if $warn && !$check; usage(1, "sha3sum: --status option used only when verifying checksums\n") if $status && !$check; ## Default to SHA3-224 unless overridden by command line option $alg = 224 unless defined $alg; grep { $_ == $alg } (224, 256, 384, 512, 128000, 256000) or usage(1, "sha3sum: Unrecognized algorithm\n"); ## 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 overridden by command line "--text" or ## "--UNIVERSAL" or "--portable" options. my $isDOSish = ($^O =~ /^(MSWin\d\d|os2|dos|mint|cygwin)$/); if ($isDOSish) { $binary = 1 unless $text || $UNIVERSAL || $portable } my $modesym = $binary ? '*' : ($UNIVERSAL ? 'U' : ($BITS ? '^' : ($portable ? '?' : ' '))); ## Read from STDIN (-) if no files listed on command line @ARGV = ("-") unless @ARGV; ## sumfile($file): computes SHA-3 digest of $file sub sumfile { my $file = shift; my $mode = $binary ? 'b' : ($UNIVERSAL ? 'U' : ($BITS ? '0' : ($portable ? 'p' : ''))); my $digest = eval { $module->new($alg)->addfile($file, $mode) }; if ($@) { warn "sha3sum: $file: $!\n"; return } $digest->hexdigest; } ## %len2alg: maps hex digest length to SHA-3 algorithm my %len2alg = (56 => 224, 64 => 256, 96 => 384, 128 => 512, 336 => 128000, 272 => 256000); ## unescape: convert backslashed filename to plain filename sub unescape { $_ = shift; s/\\\\/\0/g; s/\\n/\n/g; return if /\\/; s/\0/\\/g; return $_; } ## verify: confirm the digest values in a checksum file sub verify { my $checkfile = shift; my ($err, $fmt_errs, $read_errs, $match_errs) = (0, 0, 0, 0); my ($num_lines, $num_files) = (0, 0); my ($bslash, $sum, $fname, $rsp, $digest); local *FH; $checkfile eq '-' and open(FH, '< -') and $checkfile = 'standard input' or sysopen(FH, $checkfile, O_RDONLY) or die "sha3sum: $checkfile: $!\n"; while () { next if /^#/; s/\n$//; s/^[ \t]+//; $num_lines++; $bslash = s/^\\//; ($sum, $modesym, $fname) = /^([\da-fA-F]+)[ \t]([ *?^U])([^\0]*)/; $alg = defined $sum ? $len2alg{length($sum)} : undef; $fname = unescape($fname) if defined $fname && $bslash; if (grep { ! defined $_ } ($alg, $sum, $modesym, $fname)) { $alg = 1 unless defined $alg; warn("sha3sum: $checkfile: $.: improperly formatted" . " SHA3-$alg checksum line\n") if $warn; $fmt_errs++; next; } $fname =~ s/\r$// unless -e $fname; $rsp = "$fname: "; $num_files++; ($binary, $text, $UNIVERSAL, $BITS, $portable) = map { $_ eq $modesym } ('*', ' ', 'U', '^', 'p'); unless ($digest = sumfile($fname)) { $rsp .= "FAILED open or read\n"; $err = 1; $read_errs++; } else { if (lc($sum) eq $digest) { $rsp .= "OK\n" } else { $rsp .= "FAILED\n"; $err = 1; $match_errs++ } } print $rsp unless $status; } close(FH); unless ($num_files) { $alg = 1 unless defined $alg; warn("sha3sum: $checkfile: no properly formatted " . "SHA3-$alg checksum lines found\n"); $err = 1; } elsif (! $status) { warn("sha3sum: WARNING: $fmt_errs line" . ($fmt_errs>1? 's are':' is') . " improperly formatted\n") if $fmt_errs; warn("sha3sum: WARNING: $read_errs listed file" . ($read_errs>1?'s':'') . " could not be read\n") if $read_errs; warn("sha3sum: WARNING: $match_errs computed checksum" . ($match_errs>1?'s':'') . " did NOT match\n") if $match_errs; } return($err == 0); } ## Verify or compute SHA-3 checksums of requested files my($file, $digest); my $STATUS = 0; for $file (@ARGV) { if ($check) { $STATUS = 1 unless verify($file) } elsif ($digest = sumfile($file)) { if ($file =~ /[\n\\]/) { $file =~ s/\\/\\\\/g; $file =~ s/\n/\\n/g; $digest = "\\$digest"; } print "$digest $modesym", "$file\n"; } else { $STATUS = 1 } } exit($STATUS) Digest-SHA3-0.24/SHA3.xs0000644000175000017500000001271512453641273014345 0ustar mshelormshelor#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef SvPVbyte #if PERL_REVISION == 5 && PERL_VERSION < 8 #undef SvPVbyte #define SvPVbyte(sv, lp) \ (sv_utf8_downgrade((sv), 0), SvPV((sv), (lp))) #endif #else #define SvPVbyte SvPV #endif #ifndef dTHX #define pTHX_ #define aTHX_ #endif #ifndef PerlIO #define PerlIO FILE #define PerlIO_read(f, buf, count) fread(buf, 1, count, f) #endif #ifndef sv_derived_from #include "src/sdf.c" #endif #ifndef Newx #define Newx(ptr, num, type) New(0, ptr, num, type) #define Newxz(ptr, num, type) Newz(0, ptr, num, type) #endif #include "src/sha3.c" static const int ix2alg[] = {224,224,224,256,256,256,384,384,384,512,512,512, 128000,128000,128000,256000,256000,256000}; #ifndef INT2PTR #define INT2PTR(p, i) (p) (i) #endif #define MAX_WRITE_SIZE 16384 #define IO_BUFFER_SIZE 4096 static SHA3 *getSHA3(pTHX_ SV *self) { if (!sv_isobject(self) || !sv_derived_from(self, "Digest::SHA3")) return(NULL); return INT2PTR(SHA3 *, SvIV(SvRV(self))); } MODULE = Digest::SHA3 PACKAGE = Digest::SHA3 PROTOTYPES: ENABLE int shainit(s, alg) SHA3 * s int alg void sharewind(s) SHA3 * s unsigned long shawrite(bitstr, bitcnt, s) unsigned char * bitstr unsigned long bitcnt SHA3 * s SV * newSHA3(classname, alg) char * classname int alg PREINIT: SHA3 *state; CODE: Newxz(state, 1, SHA3); if (!shainit(state, alg)) { Safefree(state); XSRETURN_UNDEF; } RETVAL = newSV(0); sv_setref_pv(RETVAL, classname, (void *) state); SvREADONLY_on(SvRV(RETVAL)); OUTPUT: RETVAL SV * clone(self) SV * self PREINIT: SHA3 *state; SHA3 *clone; CODE: if ((state = getSHA3(aTHX_ self)) == NULL) XSRETURN_UNDEF; Newx(clone, 1, SHA3); RETVAL = newSV(0); sv_setref_pv(RETVAL, sv_reftype(SvRV(self), 1), (void *) clone); SvREADONLY_on(SvRV(RETVAL)); Copy(state, clone, 1, SHA3); OUTPUT: RETVAL void DESTROY(s) SHA3 * s CODE: Safefree(s); SV * sha3_224(...) ALIAS: Digest::SHA3::sha3_224 = 0 Digest::SHA3::sha3_224_hex = 1 Digest::SHA3::sha3_224_base64 = 2 Digest::SHA3::sha3_256 = 3 Digest::SHA3::sha3_256_hex = 4 Digest::SHA3::sha3_256_base64 = 5 Digest::SHA3::sha3_384 = 6 Digest::SHA3::sha3_384_hex = 7 Digest::SHA3::sha3_384_base64 = 8 Digest::SHA3::sha3_512 = 9 Digest::SHA3::sha3_512_hex = 10 Digest::SHA3::sha3_512_base64 = 11 Digest::SHA3::shake128 = 12 Digest::SHA3::shake128_hex = 13 Digest::SHA3::shake128_base64 = 14 Digest::SHA3::shake256 = 15 Digest::SHA3::shake256_hex = 16 Digest::SHA3::shake256_base64 = 17 PREINIT: int i; UCHR *data; STRLEN len; SHA3 sha3; char *result; CODE: if (!shainit(&sha3, ix2alg[ix])) XSRETURN_UNDEF; for (i = 0; i < items; i++) { data = (UCHR *) (SvPVbyte(ST(i), len)); while (len > MAX_WRITE_SIZE) { shawrite(data, MAX_WRITE_SIZE << 3, &sha3); data += MAX_WRITE_SIZE; len -= MAX_WRITE_SIZE; } shawrite(data, len << 3, &sha3); } shafinish(&sha3); len = 0; if (ix % 3 == 0) { result = (char *) shadigest(&sha3); len = (STRLEN) sha3.digestlen; } else if (ix % 3 == 1) result = shahex(&sha3); else result = shabase64(&sha3); RETVAL = newSVpv(result, len); OUTPUT: RETVAL int hashsize(self) SV * self ALIAS: Digest::SHA3::hashsize = 0 Digest::SHA3::algorithm = 1 PREINIT: SHA3 *state; CODE: if ((state = getSHA3(aTHX_ self)) == NULL) XSRETURN_UNDEF; RETVAL = ix ? state->alg : state->digestlen << 3; OUTPUT: RETVAL void add(self, ...) SV * self PREINIT: int i; UCHR *data; STRLEN len; SHA3 *state; PPCODE: if ((state = getSHA3(aTHX_ self)) == NULL) XSRETURN_UNDEF; for (i = 1; i < items; i++) { data = (UCHR *) (SvPVbyte(ST(i), len)); while (len > MAX_WRITE_SIZE) { shawrite(data, MAX_WRITE_SIZE << 3, state); data += MAX_WRITE_SIZE; len -= MAX_WRITE_SIZE; } shawrite(data, len << 3, state); } XSRETURN(1); SV * digest(self) SV * self ALIAS: Digest::SHA3::digest = 0 Digest::SHA3::hexdigest = 1 Digest::SHA3::b64digest = 2 Digest::SHA3::squeeze = 3 PREINIT: STRLEN len; SHA3 *state; char *result; CODE: if ((state = getSHA3(aTHX_ self)) == NULL) XSRETURN_UNDEF; shafinish(state); len = 0; if (ix == 0) { result = (char *) shadigest(state); len = (STRLEN) state->digestlen; } else if (ix == 1) result = shahex(state); else if (ix == 2) result = shabase64(state); else { if ((result = (char *) shasqueeze(state)) == NULL) XSRETURN_UNDEF; len = (STRLEN) state->digestlen; } RETVAL = newSVpv(result, len); if (ix != 3) sharewind(state); OUTPUT: RETVAL void _addfilebin(self, f) SV * self PerlIO * f PREINIT: SHA3 *state; int n; UCHR in[IO_BUFFER_SIZE]; PPCODE: if (!f || (state = getSHA3(aTHX_ self)) == NULL) XSRETURN_UNDEF; while ((n = PerlIO_read(f, in, sizeof(in))) > 0) shawrite(in, (ULNG) n << 3, state); XSRETURN(1); void _addfileuniv(self, f) SV * self PerlIO * f PREINIT: UCHR c; int n; int cr = 0; UCHR *src, *dst; UCHR in[IO_BUFFER_SIZE+1]; SHA3 *state; PPCODE: if (!f || (state = getSHA3(aTHX_ self)) == NULL) XSRETURN_UNDEF; while ((n = PerlIO_read(f, in+1, IO_BUFFER_SIZE)) > 0) { for (dst = in, src = in + 1; n; n--) { c = *src++; if (!cr) { if (c == '\015') cr = 1; else *dst++ = c; } else { if (c == '\015') *dst++ = '\012'; else if (c == '\012') { *dst++ = '\012'; cr = 0; } else { *dst++ = '\012'; *dst++ = c; cr = 0; } } } shawrite(in, (ULNG) (dst - in) << 3, state); } if (cr) { in[0] = '\012'; shawrite(in, 1UL << 3, state); } XSRETURN(1); Digest-SHA3-0.24/t/0000755000175000017500000000000012454171765013535 5ustar mshelormshelorDigest-SHA3-0.24/t/bit-sha3-224.t0000644000175000017500000000340112453470457015636 0ustar mshelormsheloruse strict; use Digest::SHA3; my $TAGS = join('|', qw(Len Msg MD)); my @vecs = (); while () { next unless /^\s*($TAGS)\s*=\s*([\dA-F]+)/o; push(@vecs, $2); } my $numtests = scalar(@vecs) / 3; print "1..$numtests\n"; for (1 .. $numtests) { my $sha3 = Digest::SHA3->new(); # use SHA3-224 by default my $Len = shift @vecs; my $Msg = pack("H*", shift @vecs); if ($Len % 8) { my @a = unpack("C*", $Msg); my $b = pop(@a); $b <<= (8 - $Len % 8); push(@a, $b); $Msg = pack("C*", @a); } my $MD = shift @vecs; my $computed = $sha3->add_bits($Msg, $Len)->hexdigest; print "not " unless $computed eq lc($MD); print "ok ", $_, "\n"; } __DATA__ # Keccak(input|01)[r=1152, c=448] truncated to 224 bits, or SHA3-224 as in FIPS 202 draft Len = 7 Msg = 4C MD = 255827559076E5ADCBF04537A98CEF483414AE3B81841B528923436E Len = 1147 Msg = 856344695FFA7F9E71CCA31E66780E83E946374FEB320A3D0D4E944EE8AD38917B892B1E4842817E9B9572EAE8BE6340A1DDED6DDB8216944CD9D403E137F1B3CD53688043E145D6D5BBE9C6A5078958AC10A96F1FB9953983996D386AF3E368394F57A7BABE20A22A7D9F8F5AC665B996B34989CECAFA60A618743CB5970FB4167F6A46635090E32C381D9A8E68DB05 MD = 9C831FF4EC2340AFEE0124D43B7C6F94EA092A08A3C9D610A7C79578 Len = 2037 Msg = B652BCB949215CC82A08AA428F90CAA72755D785F102D112689205ECB97F68844B120FAE0F68F87AFB41BE7AFFE3946CDE47AFDD5F1A2AC8326D1C15976C610CF261F95D49D7F13DF9619D58B585446D0F572514C046AC5DB3AA8CD2BFBA41DC9332ECCD4C9DD946FBC60EA604E9E69319ECA5A3EF3910E446D57AC1543CA4DD29F2A42ED3F12B2F21B40911258DB642365F8D5F9737E3F39D77B8BC53CED9E3A2E0C0C8328F27428764E25CFA14FAA401A42B8C5EC1586DC1B4EA108D8AEC3CCC312738D8320F41917D413D3E5214DC46A7AD5EAB4E7326279CD5CEB30FA881535621E096925D18E62C71CBABEADD9DA58321F80C8F6777FB97C516426A03 MD = 7226B281116D796F7C474195B563AFCD3BB1F4E1B9B7156A03A5E7C9 Digest-SHA3-0.24/t/sha3-512.t0000644000175000017500000000141012453470457015060 0ustar mshelormsheloruse strict; use Digest::SHA3 qw(sha3_512_hex); my @vecs = map { eval } ; my $numtests = scalar(@vecs) / 2; print "1..$numtests\n"; for (1 .. $numtests) { my $data = shift @vecs; my $digest = shift @vecs; print "not " unless sha3_512_hex($data) eq $digest; print "ok ", $_, "\n"; } __DATA__ "abc" "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0" "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e" "a" x 1000000 "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87" Digest-SHA3-0.24/t/allfcns.t0000644000175000017500000000046412453470457015347 0ustar mshelormsheloruse strict; use Digest::SHA3 qw( shake128 shake128_base64 shake128_hex shake256 shake256_base64 shake256_hex sha3_224 sha3_224_base64 sha3_224_hex sha3_256 sha3_256_base64 sha3_256_hex sha3_384 sha3_384_base64 sha3_384_hex sha3_512 sha3_512_base64 sha3_512_hex); print "1..1\n"; print "ok 1\n"; Digest-SHA3-0.24/t/pod.t0000644000175000017500000000034012453470457014500 0ustar mshelormshelorBEGIN { 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(); Digest-SHA3-0.24/t/bit-shake128.t0000644000175000017500000000661112453470457016027 0ustar mshelormsheloruse strict; use Digest::SHA3; my $TAGS = join('|', qw(Len Msg Squeezed)); my @vecs = (); while () { next unless /^\s*($TAGS)\s*=\s*([\dA-F]+)/o; push(@vecs, $2); } my $numtests = scalar(@vecs) / 3; print "1..$numtests\n"; for (1 .. $numtests) { my $sha3 = Digest::SHA3->new(128000); my $Len = shift @vecs; my $Msg = pack("H*", shift @vecs); if ($Len % 8) { my @a = unpack("C*", $Msg); my $b = pop(@a); $b <<= (8 - $Len % 8); push(@a, $b); $Msg = pack("C*", @a); } $sha3->add_bits($Msg, $Len); my $MD = shift @vecs; my $computed = ""; while (length($computed) < 512) { $computed .= $sha3->squeeze; } $computed = unpack("H*", substr($computed, 0, 512)); print "not " unless $computed eq lc($MD); print "ok ", $_, "\n"; } __DATA__ # Keccak(SakuraSequential|11)[r=1344, c=256], or SHAKE128 as in FIPS 202 draft Len = 7 Msg = 4C Squeezed = A656F4647F54B23452C2A911A75A027E5BADE8053DEB1D7456B40A6E619A9B1FF593F3B444FBFAA467B394A55162694B07091E8F107B8A7BCB8E053FD0336F11D09A933576C379EB9EDF7818C44E9B7A6947BECD1488ABC08A338D1771CD43CAAFD778F7EA4894824543F75D5F07D7D401EF5AA59E50CC2F1D9D5FA1CF248B5D0B4016876253BDEA8A9E5C308CD36CAB84E693AA63A6E4A1A97EA93D62604B19EDFDA3EA554E6138C110EA62F107D79EB4C920CFBFA53A2030F65326D62CBAAE014ED76ABA91F5621806D295364EA0818794D3C10A9855F8B77795C8A4A537B187A858EA6966BC509F43CA08ABBF2E7E2B372900739EA9564D68CDF9824693E022263EC497E52871399545F51EFA9EDCDC36DF3A460EBE4018AC9C46396F0E2E2A3F8642479CCF06B6192E21ED580DAF125C57FA725DEEEA7C45FB3148E6995164A182293CB8EDE54A803B4D0FA95A1D2C87B195957AD51234A45372F65622A65F854E1CB66D2B9E82D7D4CF553958F10F4AFE88DEE333F638E1D78791120B5C9C376D3D526149E803704BD9B64E9A1E4CEC6744CF08343E81DAC9054804FB12903DE045D9A55938ECCD2B6FCA009BFEBAF833255BD04FAC7A0E623B8A1827BCC858B1CD0AA5A27602F07DC3C1164D4E968CB27CF28EA7A8A0F05147F75035889BA2DA5A628D638E502852FFDF0E463397C7172373DAB0F5525642A759F12599 Len = 2047 Msg = 1F42ADD25C0A80A4C82AAE3A0E302ABF9261DCA7E7884FD869D96ED4CE88AAAA25304D2D79E1FA5CC1FA2C95899229BC87431AD06DA524F2140E70BD0536E9685EE7808F598D8A9FE15D40A72AEFF431239292C5F64BDB7F620E5D160B329DEB58CF6D5C0665A3DED61AE4ADBCA94DC2B7B02CDF3992FDF79B3D93E546D5823C3A630923064ED24C3D974C4602A49DF75E49CF7BD51EDC7382214CBA850C4D3D11B40A70B1D926E3755EC79693620C242AB0F23EA206BA337A7EDC5421D63126CB6C7094F6BC1CF9943796BE2A0D9EB74FC726AA0C0D3B3D39039DEAD39A7169F8C3E2365DD349E358BF08C717D2E436D65172A76ED5E1F1E694A75C19280B15 Squeezed = 745B6570B7EA6AF48BC476056E6810D9673EE24E32D3E1C352C0C3BE0F26BFB489EBF18D76DD26673FA2B96483847849EA2FA0D57361F25490965D546FEB3D15DBCCCC2366623F5C57951B898C18595653E58A866207995417A76F345DA4D3663F2624CB04D8FB45DE1D8A51E7F87BCB819AAA14F0D7F33E0E8E2E0753FE9E894E44581F1C56096B3215CA381269AC81F730A4F4B3C2E5903FB2B394CEBC7B3D87384582EF557BC5E34D46B4246714939D6840911A29827E566FC3CB49A5A6A599BDB55E704AC60C97BE158C52523F251C62139DB122091936E68F0E8A3E2EB6236FC2386D7A287DFAB845F4D8BD2F7B39456F6BD0BD8B79C8A6AE1713224C65D7B95BDA52F070AE3AF279D73224E997830D085F30AFC5B691278A809D2BD02E6D64ED9EF00B530AB4152F42871BF4C4719AE2D28E12FC70813653B7330AAE1664CDD4AFAB82619BB3D9A8BF1E5F483A9A3CC58B78D4C719CD3C8D2DC9CDF7C6776BC0829E796842657FD058DFE439931C1791D1F40EA997580FBDB5314BE868BBB20C330AD6466A7383058EF386480D609E9E11E7813DFD8186B1419C0F6007EDF017579B53766A207236450C97AA15C37C2FA14100E0153DD8A88E068BD27523252E157B55240190A6F18F7FFEBC029F6B84E1BE2850C0E2BD3F459FC90F36164C48A5E05B5EBACDB72DF25577B9E71CA2E624DF58D1BF36B8DB7073812B4B Digest-SHA3-0.24/t/bit-sha3-256.t0000644000175000017500000000336312453470457015652 0ustar mshelormsheloruse strict; use Digest::SHA3; my $TAGS = join('|', qw(Len Msg MD)); my @vecs = (); while () { next unless /^\s*($TAGS)\s*=\s*([\dA-F]+)/o; push(@vecs, $2); } my $numtests = scalar(@vecs) / 3; print "1..$numtests\n"; for (1 .. $numtests) { my $sha3 = Digest::SHA3->new(256); my $Len = shift @vecs; my $Msg = pack("H*", shift @vecs); if ($Len % 8) { my @a = unpack("C*", $Msg); my $b = pop(@a); $b <<= (8 - $Len % 8); push(@a, $b); $Msg = pack("C*", @a); } my $MD = shift @vecs; my $computed = $sha3->add_bits($Msg, $Len)->hexdigest; print "not " unless $computed eq lc($MD); print "ok ", $_, "\n"; } __DATA__ # Keccak(input|01)[r=1088, c=512] truncated to 256 bits, or SHA3-256 as in FIPS 202 draft Len = 7 Msg = 4C MD = A760C277ADA43D6377D3B12DBD27A1402EC0DD84E73058E69EDD90DBE5460DDF Len = 1083 Msg = A676AE811E49EDACA42C55FF4305E2A12648C465B8FCE4828598D85B6F8821E7DC35731B21AE6A963CDB6CC3D35F1E30B165D42E5844B64475A9E75D6474D9A044BD46696D44929FC185AC54580165FC74BB855FF1CA1E31041B960E6E5AFA62B3E9E216EA004D3EDA3C893B5C2A091161314EDD55DDE464460152684C5154298E0FDEA58C692E02 MD = F0E255991AAB1A085F04AEAF81CEEDF0843FFA113348992A3ABE371F7D9969C1 Len = 2047 Msg = 1F42ADD25C0A80A4C82AAE3A0E302ABF9261DCA7E7884FD869D96ED4CE88AAAA25304D2D79E1FA5CC1FA2C95899229BC87431AD06DA524F2140E70BD0536E9685EE7808F598D8A9FE15D40A72AEFF431239292C5F64BDB7F620E5D160B329DEB58CF6D5C0665A3DED61AE4ADBCA94DC2B7B02CDF3992FDF79B3D93E546D5823C3A630923064ED24C3D974C4602A49DF75E49CF7BD51EDC7382214CBA850C4D3D11B40A70B1D926E3755EC79693620C242AB0F23EA206BA337A7EDC5421D63126CB6C7094F6BC1CF9943796BE2A0D9EB74FC726AA0C0D3B3D39039DEAD39A7169F8C3E2365DD349E358BF08C717D2E436D65172A76ED5E1F1E694A75C19280B15 MD = 740E7E1C3348107E67728DDA6F95ED48D4387B84650FBE67A9789215222E77D7 Digest-SHA3-0.24/t/bit-sha3-384.t0000644000175000017500000000342112453470457015647 0ustar mshelormsheloruse strict; use Digest::SHA3; my $TAGS = join('|', qw(Len Msg MD)); my @vecs = (); while () { next unless /^\s*($TAGS)\s*=\s*([\dA-F]+)/o; push(@vecs, $2); } my $numtests = scalar(@vecs) / 3; print "1..$numtests\n"; for (1 .. $numtests) { my $sha3 = Digest::SHA3->new(384); my $Len = shift @vecs; my $Msg = pack("H*", shift @vecs); if ($Len % 8) { my @a = unpack("C*", $Msg); my $b = pop(@a); $b <<= (8 - $Len % 8); push(@a, $b); $Msg = pack("C*", @a); } my $MD = shift @vecs; my $computed = $sha3->add_bits($Msg, $Len)->hexdigest; print "not " unless $computed eq lc($MD); print "ok ", $_, "\n"; } __DATA__ # Keccak(input|01)[r=832, c=768] truncated to 384 bits, or SHA3-384 as in FIPS 202 draft Len = 7 Msg = 4C MD = 98B40541E6CC2807193976B1848AE2611683002C16CC325AC04DDC0C64FA3BE89DB2AA2379642342A9F23453BE520D02 Len = 827 Msg = D076043F4045A478C51530D457FC950916FAEAF555C2B28E8567394D0BB8A3C7D8A7225E6C0C94D39D03F0F50133ABBE6F009302153014025FB4B1F7B8EFCC9F4F9C3EAB0608DB41095AAD0D2B63037F3986DF71D6651946EE9F18DF52635BBD360F21E2555C5001 MD = 38F5D214B253434EF9B90518651AFEABC46CDDB006CB40A1F68219E42C62D73572B144D84C9E9F2602BEC91852D568DD Len = 2047 Msg = 1F42ADD25C0A80A4C82AAE3A0E302ABF9261DCA7E7884FD869D96ED4CE88AAAA25304D2D79E1FA5CC1FA2C95899229BC87431AD06DA524F2140E70BD0536E9685EE7808F598D8A9FE15D40A72AEFF431239292C5F64BDB7F620E5D160B329DEB58CF6D5C0665A3DED61AE4ADBCA94DC2B7B02CDF3992FDF79B3D93E546D5823C3A630923064ED24C3D974C4602A49DF75E49CF7BD51EDC7382214CBA850C4D3D11B40A70B1D926E3755EC79693620C242AB0F23EA206BA337A7EDC5421D63126CB6C7094F6BC1CF9943796BE2A0D9EB74FC726AA0C0D3B3D39039DEAD39A7169F8C3E2365DD349E358BF08C717D2E436D65172A76ED5E1F1E694A75C19280B15 MD = 63B0BF06BE376C877B378D26C80B7D8FCC6BC501C68EEB653F9A82E705997D0F92687C94D7BA8FE52F083BE7D6534B19 Digest-SHA3-0.24/t/sha3-384.t0000644000175000017500000000125012453470457015071 0ustar mshelormsheloruse strict; use Digest::SHA3 qw(sha3_384_hex); my @vecs = map { eval } ; my $numtests = scalar(@vecs) / 2; print "1..$numtests\n"; for (1 .. $numtests) { my $data = shift @vecs; my $digest = shift @vecs; print "not " unless sha3_384_hex($data) eq $digest; print "ok ", $_, "\n"; } __DATA__ "abc" "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25" "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" "991c665755eb3a4b6bbdfb75c78a492e8c56a22c5c4d7e429bfdbc32b9d4ad5aa04a1f076e62fea19eef51acd0657c22" "a" x 1000000 "eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340" Digest-SHA3-0.24/t/bit-order.t0000644000175000017500000000050512453502272015577 0ustar mshelormsheloruse strict; use Digest::SHA3; my $s1 = Digest::SHA3->new; my $s2 = Digest::SHA3->new; my $d1 = $s1->add_bits("110")->hexdigest; my $d2 = $s2->add_bits("0")->add_bits("1")->add_bits("1")->hexdigest; my $numtests = 1; print "1..$numtests\n"; for (1 .. $numtests) { print "not " unless $d1 eq $d2; print "ok ", $_, "\n"; } Digest-SHA3-0.24/t/sha3-256.t0000644000175000017500000000111012453470457015062 0ustar mshelormsheloruse strict; use Digest::SHA3 qw(sha3_256_hex); my @vecs = map { eval } ; my $numtests = scalar(@vecs) / 2; print "1..$numtests\n"; for (1 .. $numtests) { my $data = shift @vecs; my $digest = shift @vecs; print "not " unless sha3_256_hex($data) eq $digest; print "ok ", $_, "\n"; } __DATA__ "abc" "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532" "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376" "a" x 1000000 "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1" Digest-SHA3-0.24/t/podcover.t0000644000175000017500000000100712453470457015540 0ustar mshelormshelormy $MODULE; BEGIN { $MODULE = "Digest::SHA3"; eval "require $MODULE" || die $@; $MODULE->import(qw()); } 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 = (); if ($MODULE eq "Digest::SHA3") { @privfcns = qw( newSHA3 shainit sharewind shawrite ); } all_pod_coverage_ok( { also_private => \@privfcns } ); Digest-SHA3-0.24/t/bit-sha3-512.t0000644000175000017500000000346212453470457015645 0ustar mshelormsheloruse strict; use Digest::SHA3; my $TAGS = join('|', qw(Len Msg MD)); my @vecs = (); while () { next unless /^\s*($TAGS)\s*=\s*([\dA-F]+)/o; push(@vecs, $2); } my $numtests = scalar(@vecs) / 3; print "1..$numtests\n"; for (1 .. $numtests) { my $sha3 = Digest::SHA3->new(512); my $Len = shift @vecs; my $Msg = pack("H*", shift @vecs); if ($Len % 8) { my @a = unpack("C*", $Msg); my $b = pop(@a); $b <<= (8 - $Len % 8); push(@a, $b); $Msg = pack("C*", @a); } my $MD = shift @vecs; my $computed = $sha3->add_bits($Msg, $Len)->hexdigest; print "not " unless $computed eq lc($MD); print "ok ", $_, "\n"; } __DATA__ # Keccak(input|01)[r=576, c=1024] truncated to 512 bits, or SHA3-512 as in FIPS 202 draft Len = 7 Msg = 4C MD = E18E79FB35F92AFEEDF91A83D593BC8194F551F6AFDB21991F8F886E1B49337DC8208F4C4F5D77A79DC4BEA97B93C002CFB336D4B4D86F30DBA9C7862CCF6566 Len = 571 Msg = 18057027D18CD129DFB5584F87C48D8ECE475A366F33C62736932F55CD9ADE656B6D7F27EC182DC565B5FC6E3E125D4A0C5904A3666CD79F611562755C66D87EE6038B10C1E44F04 MD = DD90B9E95625099A9E1BAB4DD2C12A35F80BBEEC21FED2C56978F3436121ECAA32920F534655776C0323C5BB6579C8DD69B2B5164F380633DF407FB46085C4AE Len = 2047 Msg = 1F42ADD25C0A80A4C82AAE3A0E302ABF9261DCA7E7884FD869D96ED4CE88AAAA25304D2D79E1FA5CC1FA2C95899229BC87431AD06DA524F2140E70BD0536E9685EE7808F598D8A9FE15D40A72AEFF431239292C5F64BDB7F620E5D160B329DEB58CF6D5C0665A3DED61AE4ADBCA94DC2B7B02CDF3992FDF79B3D93E546D5823C3A630923064ED24C3D974C4602A49DF75E49CF7BD51EDC7382214CBA850C4D3D11B40A70B1D926E3755EC79693620C242AB0F23EA206BA337A7EDC5421D63126CB6C7094F6BC1CF9943796BE2A0D9EB74FC726AA0C0D3B3D39039DEAD39A7169F8C3E2365DD349E358BF08C717D2E436D65172A76ED5E1F1E694A75C19280B15 MD = 2471F995EED05156F1036C345DD3764FBC5CB1DA6DE5D33627632B0EFC84A061AAF4A8775553A4602E49984C717C185A6F74FE4A0ED7FA5D96811ADCBD0953FA Digest-SHA3-0.24/t/sha3-224.t0000644000175000017500000000114612453470457015066 0ustar mshelormsheloruse strict; use Digest::SHA3 qw(sha3_224_hex); # ref. http://www.di-mgt.com.au/sha_testvectors.html my @vecs = map { eval } ; my $numtests = scalar(@vecs) / 2; print "1..$numtests\n"; for (1 .. $numtests) { my $data = shift @vecs; my $digest = shift @vecs; print "not " unless sha3_224_hex($data) eq $digest; print "ok ", $_, "\n"; } __DATA__ "abc" "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf" "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" "8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33" "a" x 1000000 "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c" Digest-SHA3-0.24/t/bit-shake256.t0000644000175000017500000000661112453470457016031 0ustar mshelormsheloruse strict; use Digest::SHA3; my $TAGS = join('|', qw(Len Msg Squeezed)); my @vecs = (); while () { next unless /^\s*($TAGS)\s*=\s*([\dA-F]+)/o; push(@vecs, $2); } my $numtests = scalar(@vecs) / 3; print "1..$numtests\n"; for (1 .. $numtests) { my $sha3 = Digest::SHA3->new(256000); my $Len = shift @vecs; my $Msg = pack("H*", shift @vecs); if ($Len % 8) { my @a = unpack("C*", $Msg); my $b = pop(@a); $b <<= (8 - $Len % 8); push(@a, $b); $Msg = pack("C*", @a); } $sha3->add_bits($Msg, $Len); my $MD = shift @vecs; my $computed = ""; while (length($computed) < 512) { $computed .= $sha3->squeeze; } $computed = unpack("H*", substr($computed, 0, 512)); print "not " unless $computed eq lc($MD); print "ok ", $_, "\n"; } __DATA__ # Keccak(SakuraSequential|11)[r=1088, c=512], or SHAKE256 as in FIPS 202 draft Len = 7 Msg = 4C Squeezed = 8DE08ECF3885D613C0F3AE2987F94495678334B7880E48234785925A72D4567B8B8CD6D35B580151928A61BB4F55537B03CEB1AAC592AF5B2372E063001C23ED35CF03710524CBFB3A9A66004BA12C811E3881203F1117932D024954420156DD13418DA78C463902ABEEED04C6EEC60613C1FEDD492A9C0C3A1B265C9C67BE587CBF5F84EB78C65A166A1E49476C5D39EBF256CDBF3AC53ED68E46370D2E9A9A916E2A481A35E330FF122EB3CC87F313E2766A6818E34EEC24C149494FEBF2DCF57254CE25414BAFD9BBB4B86457847F3243933240D7F3576CC136D777F89AFE203E37A4F28F98BA844409E7A2E44873F801A954C1762174440644E5FF1051794761BA23914426E94D7B1047658DCA7E9540B0DD844ECB0758716E188CCDE3C61D590477EC4E187E742FFACDB509D47D931A128552979650353FFC50A6C35E19947015103483B86156EC9E956897C4DEFFB86E8128A1FF83AD473DD0B77BA68033A716102BC32C661305214B399F5D3CA92E3B856D8A6D1E9808FF6A12FAF6BBF0D3E9B69D87EA098FED112F8B039F8B128B7F370118667A3DEEAAEC296056EB92557129886DA1A4FF34EC773CC678B8CFCF50412EC59F9D4D5A9C6D63EBA66F49C8CAF3C1CF274FB9A70C28ADAFC8205A788943935F8E2F1C11E7B274B23C8AE52A9DF1C8157924DCCE2D4136E0363289D4121F5795C82E6471CC5A65857E8F Len = 2047 Msg = 1F42ADD25C0A80A4C82AAE3A0E302ABF9261DCA7E7884FD869D96ED4CE88AAAA25304D2D79E1FA5CC1FA2C95899229BC87431AD06DA524F2140E70BD0536E9685EE7808F598D8A9FE15D40A72AEFF431239292C5F64BDB7F620E5D160B329DEB58CF6D5C0665A3DED61AE4ADBCA94DC2B7B02CDF3992FDF79B3D93E546D5823C3A630923064ED24C3D974C4602A49DF75E49CF7BD51EDC7382214CBA850C4D3D11B40A70B1D926E3755EC79693620C242AB0F23EA206BA337A7EDC5421D63126CB6C7094F6BC1CF9943796BE2A0D9EB74FC726AA0C0D3B3D39039DEAD39A7169F8C3E2365DD349E358BF08C717D2E436D65172A76ED5E1F1E694A75C19280B15 Squeezed = E826B639644A82131550584399CD05C5337311AACD629EACD7D21E50434109DF7125514D6A5FFA7268BC9AD15688EC40C00A665BE5BE021ACF2E066CB596CD7C0EB7D7FFDDD06888A4B8A37625B9C6D60C84E3538D5ACFD6F87C175606ECA438057F00F383DEAFB9A4D309D190A690E355A803811A66C309624C3163BD50FEE00D42381A4B17B015072E8B95BFE3ED0CC6EC297C38B87E54C8C57B61EBAA5F3CA393E5B68BAEDC9DF85155C79217BBC0D5240A834D90083D8C2694D2B9A244C7C4C06250F12F722935BC59C1C24FB88D1154EB81AA6C09E9C47E5C36EFD2577967AECD9B5FCE0AEF8203D632AF51CD523211B5807DF5CD9E300DA6CF13AA606E8F523E6CDF5353267862E059F697235A897DEF41CE048DE0548A8AE1688A73A1B95A68BF14BBBD7A9DFDC209A02ADA313326CCA97BCC5EC257A59DF263A7246E69FA88325813F594C8049277292D005507DF029C05F7B823C4D8E71CD9D380B87C786110E77DABBD242DE22AC55933CC01537FB56D51F0337FA6B295EC5B5FC1C0DE44983F44666B5352023F9AA1CD4FB7A79A02465EEFD2D89D416F125472DBE2A3B9DEED4E513D0A2B60D3C149E15754E40236BA470FF8A65C5575E9F8FA623FCCCD165BEE4B6E100E3E0013DF966BA39D3FB306DE789271B201C52CBF9D0093AF70C6DDAFAA9951B6E3FCFF6A833243CB333E708595F228C22609D5FC1EBF Digest-SHA3-0.24/examples/0000755000175000017500000000000012454171765015110 5ustar mshelormshelorDigest-SHA3-0.24/examples/dups30000755000175000017500000000233312452233267016067 0ustar mshelormshelor#!perl # dups3: simple script for showing duplicate files =head1 NAME dups3 - Show Duplicate Files =head1 SYNOPSIS Usage: dups3 files ... dups3 is a fast script for discovering duplicate files. It achieves its efficiency by comparing file digests rather than the file contents themselves, the latter being much larger in general. The NIST Secure Hash Algorithm 3 (SHA-3) is highly collision resistant, meaning that two files with the same SHA-3 digest have an almost certain probability of being identical. The dups3 script works by computing the SHA3-224 digest of each file and looking for matches. The search can reveal more than one set of duplicates, so the output is written as follows: match1_file1 match1_file2 match1_file3 etc. match2_file1 match2_file2 etc. =head1 AUTHOR Mark Shelor =head1 SEE ALSO Perl module L =cut use strict; use Digest::SHA3; die "usage: dups3 files ...\n" unless @ARGV; my @files = grep { -f $_ } @ARGV; my %dups3; for (@files) { my $digest = Digest::SHA3->new->addfile($_, "b")->hexdigest; push(@{$dups3{$digest}}, $_); } for (keys %dups3) { my $ref = $dups3{$_}; if (scalar(@$ref) > 1) { print join("\n\t", @$ref), "\n\n"; } } Digest-SHA3-0.24/Changes0000644000175000017500000001026212454154552014561 0ustar mshelormshelorRevision history for Perl extension Digest::SHA3. 0.24 Sat Jan 10 00:45:34 MST 2015 - simplified shabits() routine (bitwise input buffering) -- slightly less efficient but easier to understand - minor documentation tweaks and additions 0.23 Sun Jan 4 05:36:30 MST 2015 - updated to reflect Draft FIPS 202 -- append domain separation bits to message -- implement SHAKE128 and SHAKE256 Extendable-Output Functions (XOFs) 0.22 Sun Jun 1 00:15:46 MST 2014 - fixed reserved-word clash when compiling with C++ -- use 'classname' instead of 'class' -- ref. SHA3.xs (rt.cpan.org #96090) 0.21 Fri May 16 10:21:46 MST 2014 - restored original 'addfile' for use on opened file handles -- allows callbacks in place of actual files -- ref. IO::Callback (rt.cpan.org #95643) - re-established inheritance from Digest::base -- to pick up future Digest enhancements automatically - cleaned up documentation 0.20 Wed May 7 07:57:10 MST 2014 - consolidated all dynamic memory allocation into XSUBs -- streamlines referencing of SHA3 objects -- simplifies DESTROYing of objects - enhanced Makefile.PL to allow 'use warnings' -- automatically reverts to $^W for early Perls - scrubbed C and Perl code to remove all compiler warnings 0.12 Sat Apr 19 05:14:50 MST 2014 - added universal newlines mode ("U") to addfile and sha3sum -- based on Python Universal Newlines concept -- newlines identical across MacOS, DOS, and UNIX -- will deprecate portable mode ("p") in future -- "U" mode is cleaner and more efficient - enhanced performance -- reduced number of dynamic memory allocations -- sped up addfile method with use of C code -- ref. SHA3.xs (_addfilebin and _addfileuniv) - changed text file test (-T) to act on filehandles -- improves consistency when reading from STDIN -- still must act on filenames for early Perls (< 5.6) - sealed memory leak in SHA3.xs -- arose only with SvPVbyte exceptions during eval - patched inheritence bug (ref: rt.cpan.org #94830) -- use sv_isobject/sv_derived_from instead of sv_isa - added 'allocated' flag to SHA3 structure (ref. src/sha3.h) -- to guard against Perl double frees 0.11 Mon Feb 17 16:42:04 MST 2014 - tightened code in SHA3.xs -- added sv_isa checks when invoking methods 0.10 Thu Jan 30 08:24:30 MST 2014 - improved the performance of hexadecimal output functions -- ref. 'shahex' in src/sha3.c -- thanks to Thomas Drugeon for ideas and test script 0.09 Sun Jan 5 19:08:32 MST 2014 - added a 'squeeze' method for SHA3-0 objects -- to construct SHA3-0 digests of any desired length 0.08 Wed Jun 26 04:32:06 MST 2013 - workaround for repeated calls to shaclose -- ref. Bug #86295 (posted at Digest::SHA) -- need to explicitly reset internal pointer to NULL ref. shaclose() in SHA3.xs - corrected typos in sha3sum script -- ref. Bug #85430 (posted at Digest::SHA) 0.07 Sat Mar 9 17:36:14 MST 2013 - untweaked Makefile.PL to remove dependencies of SHA3.c -- dependencies were breaking builds on VMS -- retaining dependencies provides too little benefit for cost of portable workaround 0.06 Mon Mar 4 08:12:04 MST 2013 - removed code for standalone C operation (no longer used) -- eliminates need for external symbols -- reduces size of object files -- thanks to Marc Lehmann for suggestions - tweaked Makefile.PL to show dependencies of SHA3.c 0.05 Thu Jan 24 04:54:14 MST 2013 - accommodated Unicode string input -- by using SvPVbyte instead of SvPV in SHA3.xs -- provided workaround for Perl 5.6 -- added new test script t/unicode.t - provided documentation to describe Unicode handling - obtained slight speedup on Intel/gcc -- by setting -O1 and -fomit-frame-pointer - adopted (from Digest::SHA) workaround for DEC compiler bug 0.04 Sun Nov 11 19:20:06 MST 2012 - enhanced performance -- typically 10-15% faster than 0.03 -- code is still easy to read and modify - filled in a few documentation omissions 0.03 Mon Oct 29 04:01:06 MST 2012 - attained a 2.5x performance increase through loop unrolling -- code is still easy to follow -- clearly traceable to Keccak pseudo code 0.02 Thu Oct 25 19:18:58 MST 2012 - original version: adapted from Digest::SHA version 5.72 Digest-SHA3-0.24/typemap0000644000175000017500000000011712453204465014664 0ustar mshelormshelorTYPEMAP SHA3 * T_SHA3 PerlIO * T_IN INPUT T_SHA3 $var = getSHA3(aTHX_ $arg) Digest-SHA3-0.24/Makefile.PL0000644000175000017500000000344212454153476015246 0ustar mshelormshelorrequire 5.003000; use strict; use ExtUtils::MakeMaker; use Getopt::Std; use Config qw(%Config); use vars qw($opt_w); my $PM = 'lib/Digest/SHA3.pm'; my $SHA3SUM = 'sha3sum'; # 'use warnings' if possible, but stay portable my($use_warnings, @EDITs); my $warn_1 = 'BEGIN { $^W = 1 }'; my $warn_0 = 'BEGIN { $^W = 0 }'; { eval "require warnings; import warnings"; $use_warnings = $@ ? 0 : 1; local(@ARGV) = ($PM, $SHA3SUM); while (<>) { if ( (!$use_warnings && /^(use|no) warnings\b/) || ( $use_warnings && /^\Q$warn_1\E # use warnings\b/) || ( $use_warnings && /^\Q$warn_0\E # no warnings\b/)) { push @EDITs, $ARGV; close ARGV; } } } if (@EDITs) { local($^I, @ARGV) = ('', @EDITs); while (<>) { if ($use_warnings) { s/^\Q$warn_1\E # (.*)$/$1/; s/^\Q$warn_0\E # (.*)$/$1/; } else { s/^(use warnings\b.*)$/$warn_1 # $1/; s/^(no warnings\b.*)$/$warn_0 # $1/; } print; } } getopts('w'); my @extra = (); # Workaround for DEC compiler bug, adapted from Digest::MD5 if ($^O eq 'VMS') { if (defined($Config{ccname})) { if (grep(/VMS_VAX/, @INC) && ($Config{ccname} eq 'DEC')) { # VAX optimizer, even up to v6.4, gets stuck push(@extra, OPTIMIZE => "/Optimize=(NODISJOINT)"); } } } # Enhance performance on Intel when using gcc if ($Config{archname} =~ /^i[3456]86/ && $Config{ccname} eq 'gcc') { push(@extra, OPTIMIZE => '-O1 -fomit-frame-pointer'); } my $fussy = '-Wall -Wextra -Wconversion -Wcast-align -Wpointer-arith '; push(@extra, CCFLAGS => $fussy . $Config{ccflags}) if $opt_w; my %attr = ( 'NAME' => 'Digest::SHA3', 'VERSION_FROM' => $PM, 'LIBS' => [''], 'INC' => '-I.', 'EXE_FILES' => [ $SHA3SUM ], @extra, ); my $MMversion = $ExtUtils::MakeMaker::VERSION || '0.00_00'; $attr{NO_META} = 1 if $MMversion ge '6.10_03'; WriteMakefile(%attr); Digest-SHA3-0.24/lib/0000755000175000017500000000000012454171765014040 5ustar mshelormshelorDigest-SHA3-0.24/lib/Digest/0000755000175000017500000000000012454171765015257 5ustar mshelormshelorDigest-SHA3-0.24/lib/Digest/SHA3.pm0000644000175000017500000004154112454155405016311 0ustar mshelormshelorpackage Digest::SHA3; require 5.003000; use strict; use warnings; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); use Fcntl; use integer; $VERSION = '0.24'; require Exporter; require DynaLoader; @ISA = qw(Exporter DynaLoader); @EXPORT_OK = qw( shake128 shake128_base64 shake128_hex shake256 shake256_base64 shake256_hex sha3_224 sha3_224_base64 sha3_224_hex sha3_256 sha3_256_base64 sha3_256_hex sha3_384 sha3_384_base64 sha3_384_hex sha3_512 sha3_512_base64 sha3_512_hex); # Inherit from Digest::base if possible eval { require Digest::base; push(@ISA, 'Digest::base'); }; # 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; $alg =~ s/^3?(224|256|384|512|128000|256000)$/$1/ if defined $alg; if (ref($class)) { # instance method if (!defined($alg) || ($alg == $class->algorithm)) { sharewind($class); return($class); } return shainit($class, $alg) ? $class : undef; } $alg = 224 unless defined $alg; return newSHA3($class, $alg); } BEGIN { *reset = \&new } sub add_bits { my($self, $data, $nbits) = @_; unless (defined $nbits) { $nbits = length($data); $data = pack("B*", $data); } $nbits = length($data) * 8 if $nbits > length($data) * 8; if ($nbits % 8) { my @c = unpack("C*", $data); my $b = pop(@c); $b >>= (8 - $nbits % 8); push(@c, $b); $data = pack("C*", @c); } shawrite($data, $nbits, $self); return($self); } sub _bail { my $msg = shift; $msg .= ": $!"; require Carp; Carp::croak($msg); } { my $_can_T_filehandle; sub _istext { local *FH = shift; my $file = shift; if (! defined $_can_T_filehandle) { local $^W = 0; my $istext = eval { -T FH }; $_can_T_filehandle = $@ ? 0 : 1; return $_can_T_filehandle ? $istext : -T $file; } return $_can_T_filehandle ? -T FH : -T $file; } } sub _addfile { my ($self, $handle) = @_; my $n; my $buf = ""; while (($n = read($handle, $buf, 4096))) { $self->add($buf); } _bail("Read failed") unless defined $n; $self; } sub addfile { my ($self, $file, $mode) = @_; return(_addfile($self, $file)) unless ref(\$file) eq 'SCALAR'; $mode = defined($mode) ? $mode : ""; my ($binary, $UNIVERSAL, $BITS, $portable) = map { $_ eq $mode } ("b", "U", "0", "p"); ## Always interpret "-" to mean STDIN; otherwise use ## sysopen to handle full range of POSIX file names local *FH; $file eq '-' and open(FH, '< -') or sysopen(FH, $file, O_RDONLY) or _bail('Open failed'); if ($BITS) { my ($n, $buf) = (0, ""); while (($n = read(FH, $buf, 4096))) { $buf =~ s/[^01]//g; $self->add_bits($buf); } _bail("Read failed") unless defined $n; close(FH); return($self); } binmode(FH) if $binary || $portable || $UNIVERSAL; if ($UNIVERSAL && _istext(*FH, $file)) { $self->_addfileuniv(*FH); } elsif ($portable && _istext(*FH, $file)) { while () { s/\015?\015\012/\012/g; s/\015/\012/g; $self->add($_); } } else { $self->_addfilebin(*FH) } close(FH); $self; } Digest::SHA3->bootstrap($VERSION); 1; __END__ =head1 NAME Digest::SHA3 - Perl extension for SHA-3 =head1 SYNOPSIS In programs: # Functional interface use Digest::SHA3 qw(sha3_224 sha3_256_hex sha3_512_base64 ...); $digest = sha3_224($data); $digest = sha3_256_hex($data); $digest = sha3_384_base64($data); $digest = sha3_512($data); # Object-oriented use Digest::SHA3; $sha3 = Digest::SHA3->new($alg); $sha3->add($data); # feed data into stream $sha3->addfile(*F); $sha3->addfile($filename); $sha3->add_bits($bits); $sha3->add_bits($data, $nbits); $digest = $sha3->digest; # compute digest $digest = $sha3->hexdigest; $digest = $sha3->b64digest; # Compute extendable-length digest $sha3 = Digest::SHA3->new(128000)->add($data); # SHAKE128 $digest = $sha3->squeeze; $digest .= $sha3->squeeze; ... $sha3 = Digest::SHA3->new(256000)->add($data); # SHAKE256 $digest = $sha3->squeeze; $digest .= $sha3->squeeze; ... =head1 ABSTRACT Digest::SHA3 is a complete implementation of the NIST SHA-3 cryptographic hash function, as specified in Draft FIPS 202 (SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions). The module gives Perl programmers a convenient way to calculate SHA3-224, SHA3-256, SHA3-384, and SHA3-512 message digests, as well as variable-length hashes using SHAKE128 and SHAKE256. Digest::SHA3 can handle all types of input, including partial-byte data. =head1 DESCRIPTION Digest::SHA3 is written in C for speed. If your platform lacks a C compiler, perhaps you can find the module in a binary form compatible with your particular processor and operating system. The programming interface is easy to use: it's the same one found in CPAN's L module. So, if your applications currently use L and you'd prefer the newer flavor of the NIST standard, 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 SHA3-256 digest of "hello world" using each approach: use Digest::SHA3 qw(sha3_256_hex); $data = "hello world"; @frags = split(//, $data); # all-at-once (Functional style) $digest1 = sha3_256_hex($data); # in-stages (OOP style) $state = Digest::SHA3->new(256); for (@frags) { $state->add($_) } $digest2 = $state->hexdigest; print $digest1 eq $digest2 ? "that's the ticket!\n" : "oops!\n"; To calculate the digest of an n-bit message where I is not a multiple of 8, use the I 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 SHA3-512 digest: use Digest::SHA3; $bits = "110" x 148 . "11"; $sha3 = Digest::SHA3->new(512)->add_bits($bits); print $sha3->hexdigest, "\n"; Note that for larger bit-strings, it's more efficient to use the two-argument version I, where I<$data> is in the customary packed binary format used for Perl strings. =head1 UNICODE AND SIDE EFFECTS Perl supports Unicode strings as of version 5.6. Such strings may contain wide characters: namely, characters whose ordinal values are greater than 255. This can cause problems for digest algorithms such as SHA-3 that are specified to operate on sequences of bytes. The rule by which Digest::SHA3 handles a Unicode string is easy to state, but potentially confusing to grasp: the string is interpreted as a sequence of byte values, where each byte value is equal to the ordinal value (viz. code point) of its corresponding Unicode character. That way, the Unicode string 'abc' has exactly the same digest value as the ordinary string 'abc'. Since a wide character does not fit into a byte, the Digest::SHA3 routines croak if they encounter one. Whereas if a Unicode string contains no wide characters, the module accepts it quite happily. The following code illustrates the two cases: $str1 = pack('U*', (0..255)); print sha3_224_hex($str1); # ok $str2 = pack('U*', (0..256)); print sha3_224_hex($str2); # croaks Be aware that the digest routines silently convert UTF-8 input into its equivalent byte sequence in the native encoding (cf. utf8::downgrade). This side effect influences only the way Perl stores the data internally, but otherwise leaves the actual value of the data intact. =head1 PADDING OF BASE64 DIGESTS By convention, CPAN Digest modules do B pad their Base64 output. Problems can occur when feeding such digests to other software that expects properly padded Base64 encodings. For the time being, any necessary padding must be done by the user. Fortunately, this is a simple operation: if the length of a Base64-encoded digest isn't a multiple of 4, simply append "=" characters to the end of the digest until it is: while (length($b64_digest) % 4) { $b64_digest .= '='; } To illustrate, I is computed to be Ophdp0/iJbIEXBcta9OQvYVfCG4+nVJbRr/iRRFDFTI which has a length of 43. So, the properly padded version is Ophdp0/iJbIEXBcta9OQvYVfCG4+nVJbRr/iRRFDFTI= =head1 EXPORT None by default. =head1 EXPORTABLE FUNCTIONS Provided your C compiler supports a 64-bit type (e.g. the I 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 any of them. In the interest of simplicity, maintainability, and small code size, it's unlikely that future versions of this module will support a 32-bit implementation. Older platforms using 32-bit-only compilers should continue to favor 32-bit hash implementations such as SHA-1, SHA-224, or SHA-256. The desire to use the SHA-3 hash standard, dating from 2012, should reasonably require that one's compiler adhere to programming language standards dating from at least 1999. I =over 4 =item B =item B =item B =item B =item B =item B Logically joins the arguments into a single string, and returns its SHA3-0/224/256/384/512 digest encoded as a binary string. The digest size for shake128 is 1344 bits (168 bytes); for shake256, it's 1088 bits (136 bytes). To obtain extendable-output from the SHAKE algorithms, use the object-oriented interface with repeated calls to the I method. =item B =item B =item B =item B =item B =item B Logically joins the arguments into a single string, and returns its SHA3-0/224/256/384/512 or SHAKE128/256 digest encoded as a hexadecimal string. =item B =item B =item B =item B =item B =item B Logically joins the arguments into a single string, and returns its SHA3-0/224/256/384/512 or SHAKE128/256 digest encoded as a Base64 string. It's important to note that the resulting string does B contain the padding characters typical of Base64 encodings. This omission is deliberate, and is done to maintain compatibility with the family of CPAN Digest modules. See L for details. =back I =over 4 =item B Returns a new Digest::SHA3 object. Allowed values for I<$alg> are 224, 256, 384, and 512 for the SHA3 algorithms; or 128000 and 256000 for SHAKE128 and SHAKE256, respectively. If the argument is missing, SHA3-224 will be used by default. Invoking I 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 This method has exactly the same effect as I. In fact, I is just an alias for I. =item B Returns the number of digest bits for this object. The values are 224, 256, 384, 512, 1344, and 1088 for SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, and SHAKE256, respectively. =item B Returns the digest algorithm for this object. The values are 224, 256, 384, 512, 128000, and 256000 for SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, and SHAKE256, respectively. =item B Returns a duplicate copy of the object. =item B 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: $sha3->add("a"); $sha3->add("b"); $sha3->add("c"); $sha3->add("a")->add("b")->add("c"); $sha3->add("a", "b", "c"); $sha3->add("abc"); The return value is the updated object itself. =item B =item B 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 $sha3->add_bits(pack("B*", $bits), length($bits)); So, the following two statements do the same thing: $sha3->add_bits("111100001010"); $sha3->add_bits("\xF0\xA0", 12); Note that SHA-3 uses I for its internal state. This means that $sha3->add_bits("110"); is equivalent to $sha3->add_bits("0")->add_bits("1")->add_bits("1"); The fact that SHA-2 and SHA-3 employ opposite bit-ordering schemes has resulted in noticeable confusion, even in the cryptographic community. When programming with bitwise inputs, expect to make blunders, repeatedly: if the Scylla of notation doesn't devour you, the Charybdis of semantics almost certainly will. =item B Reads from I until EOF, and appends that data to the current state. The return value is the updated object itself. =item B Reads the contents of I<$filename>, and appends that data to the current state. The return value is the updated object itself. By default, I<$filename> is simply opened and read; no special modes or I/O disciplines are used. To change this, set the optional I<$mode> argument to one of the following values: "b" read file in binary mode "U" use universal newlines "0" use BITS mode "p" use portable mode (to be deprecated) The "U" mode is modeled on Python's "Universal Newlines" concept, whereby DOS and Mac OS line terminators are converted internally to UNIX newlines before processing. This ensures consistent digest values when working simultaneously across multiple file systems. B, namely those passing Perl's I<-T> test; binary files are processed with no translation whatsoever. The "p" mode differs from "U" only in that it treats "\r\r\n" as a single newline, a quirky feature designed to accommodate legacy applications that occasionally added an extra carriage return before DOS line terminators. The "p" mode will be phased out eventually in favor of the cleaner and more well-established Universal Newlines concept. The BITS mode ("0") interprets the contents of I<$filename> as a logical stream of bits, where each ASCII '0' or '1' character represents a 0 or 1 bit, respectively. All other characters are ignored. This provides a convenient way to calculate the digest values of partial-byte data by using files, rather than having to write programs using the I method. =item B Returns the digest encoded as a binary string. Note that the I method is a read-once operation. Once it has been performed, the Digest::SHA3 object is automatically reset in preparation for calculating another digest value. Call I<$sha-Eclone-Edigest> if it's necessary to preserve the original digest state. =item B Returns the digest encoded as a hexadecimal string. Like I, this method is a read-once operation. Call I<$sha-Eclone-Ehexdigest> if it's necessary to preserve the original digest state. =item B Returns the digest encoded as a Base64 string. Like I, this method is a read-once operation. Call I<$sha-Eclone-Eb64digest> if it's necessary to preserve the original digest state. It's important to note that the resulting string does B contain the padding characters typical of Base64 encodings. This omission is deliberate, and is done to maintain compatibility with the family of CPAN Digest modules. See L for details. =item B Returns the next 168 (136) bytes of the SHAKE128 (SHAKE256) digest encoded as a binary string. The I method may be called repeatedly to construct digests of any desired length. This method is B. =back =head1 SEE ALSO L, L, L The Draft FIPS 202 SHA-3 Standard can be found at: L The Keccak/SHA-3 specifications can be found at: L L =head1 AUTHOR Mark Shelor =head1 ACKNOWLEDGMENTS The author is particularly grateful to Guido Bertoni Joan Daemen Michael Peeters Chris Skiscim Gilles Van Assche "Nothing is more fatiguing nor, in the long run, more exasperating than the daily effort to believe things which daily become more incredible. To be done with this effort is an indispensible condition of secure and lasting happiness." - Bertrand Russell =head1 COPYRIGHT AND LICENSE Copyright (C) 2012-2015 Mark Shelor This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. L =cut Digest-SHA3-0.24/MANIFEST0000644000175000017500000000052012453503442014406 0ustar mshelormshelorChanges Makefile.PL MANIFEST META.yml README SHA3.xs examples/dups3 lib/Digest/SHA3.pm sha3sum src/sdf.c src/sha3.c src/sha3.h t/allfcns.t t/bit-order.t t/bit-sha3-224.t t/bit-sha3-256.t t/bit-sha3-384.t t/bit-sha3-512.t t/bit-shake128.t t/bit-shake256.t t/pod.t t/podcover.t t/sha3-224.t t/sha3-256.t t/sha3-384.t t/sha3-512.t typemap Digest-SHA3-0.24/src/0000755000175000017500000000000012454171765014061 5ustar mshelormshelorDigest-SHA3-0.24/src/sha3.c0000644000175000017500000002457512454154237015073 0ustar mshelormshelor/* * sha3.c: routines to compute SHA-3 digests * * Ref: http://keccak.noekeon.org/specs_summary.html * * Copyright (C) 2012-2015 Mark Shelor, All Rights Reserved * * Version: 0.24 * Sat Jan 10 00:45:34 MST 2015 * */ #include #include #include #include #include "sha3.h" #define UCHR unsigned char /* useful abbreviations */ #define UINT unsigned int #define ULNG unsigned long #define W64 SHA64 #define C64 SHA64_CONST #define SR64 SHA64_SHR #define SL64 SHA64_SHL /* word2mem: write 64-bit value in little-endian order */ static void word2mem(UCHR *mem, W64 w) { int i; UCHR *p = mem; for (i = 0; i < 8; i++, w >>= 8) *p++ = (UCHR) (w & 0xff); } static const W64 RC[] = { /* Keccak round constants */ C64(0x0000000000000001), C64(0x0000000000008082), C64(0x800000000000808a), C64(0x8000000080008000), C64(0x000000000000808b), C64(0x0000000080000001), C64(0x8000000080008081), C64(0x8000000000008009), C64(0x000000000000008a), C64(0x0000000000000088), C64(0x0000000080008009), C64(0x000000008000000a), C64(0x000000008000808b), C64(0x800000000000008b), C64(0x8000000000008089), C64(0x8000000000008003), C64(0x8000000000008002), C64(0x8000000000000080), C64(0x000000000000800a), C64(0x800000008000000a), C64(0x8000000080008081), C64(0x8000000000008080), C64(0x0000000080000001), C64(0x8000000080008008) }; /* ROTL: rotate 64-bit word left by n bit positions */ #define ROTL(w, n) (SR64((w), (64 - (n))) | SL64((w), (n))) /* keccak_f: apply KECCAK-f[1600] permutation for 24 rounds */ static void keccak_f(W64 A[][5]) { int i; const W64 *rc = RC; for (i = 0; i < 24; i++, rc++) { W64 B[5][5], C[5], D[5]; C[0] = A[0][0]^A[0][1]^A[0][2]^A[0][3]^A[0][4]; C[1] = A[1][0]^A[1][1]^A[1][2]^A[1][3]^A[1][4]; C[2] = A[2][0]^A[2][1]^A[2][2]^A[2][3]^A[2][4]; C[3] = A[3][0]^A[3][1]^A[3][2]^A[3][3]^A[3][4]; C[4] = A[4][0]^A[4][1]^A[4][2]^A[4][3]^A[4][4]; D[0] = C[4] ^ ROTL(C[1], 1); D[1] = C[0] ^ ROTL(C[2], 1); D[2] = C[1] ^ ROTL(C[3], 1); D[3] = C[2] ^ ROTL(C[4], 1); D[4] = C[3] ^ ROTL(C[0], 1); A[0][0] ^= D[0]; A[0][1] ^= D[0]; A[0][2] ^= D[0]; A[0][3] ^= D[0]; A[0][4] ^= D[0]; A[1][0] ^= D[1]; A[1][1] ^= D[1]; A[1][2] ^= D[1]; A[1][3] ^= D[1]; A[1][4] ^= D[1]; A[2][0] ^= D[2]; A[2][1] ^= D[2]; A[2][2] ^= D[2]; A[2][3] ^= D[2]; A[2][4] ^= D[2]; A[3][0] ^= D[3]; A[3][1] ^= D[3]; A[3][2] ^= D[3]; A[3][3] ^= D[3]; A[3][4] ^= D[3]; A[4][0] ^= D[4]; A[4][1] ^= D[4]; A[4][2] ^= D[4]; A[4][3] ^= D[4]; A[4][4] ^= D[4]; B[0][0] = A[0][0]; B[1][3] = ROTL(A[0][1], 36); B[2][1] = ROTL(A[0][2], 3); B[3][4] = ROTL(A[0][3], 41); B[4][2] = ROTL(A[0][4], 18); B[0][2] = ROTL(A[1][0], 1); B[1][0] = ROTL(A[1][1], 44); B[2][3] = ROTL(A[1][2], 10); B[3][1] = ROTL(A[1][3], 45); B[4][4] = ROTL(A[1][4], 2); B[0][4] = ROTL(A[2][0], 62); B[1][2] = ROTL(A[2][1], 6); B[2][0] = ROTL(A[2][2], 43); B[3][3] = ROTL(A[2][3], 15); B[4][1] = ROTL(A[2][4], 61); B[0][1] = ROTL(A[3][0], 28); B[1][4] = ROTL(A[3][1], 55); B[2][2] = ROTL(A[3][2], 25); B[3][0] = ROTL(A[3][3], 21); B[4][3] = ROTL(A[3][4], 56); B[0][3] = ROTL(A[4][0], 27); B[1][1] = ROTL(A[4][1], 20); B[2][4] = ROTL(A[4][2], 39); B[3][2] = ROTL(A[4][3], 8); B[4][0] = ROTL(A[4][4], 14); A[0][0] = B[0][0] ^ (~B[1][0] & B[2][0]); A[0][1] = B[0][1] ^ (~B[1][1] & B[2][1]); A[0][2] = B[0][2] ^ (~B[1][2] & B[2][2]); A[0][3] = B[0][3] ^ (~B[1][3] & B[2][3]); A[0][4] = B[0][4] ^ (~B[1][4] & B[2][4]); A[1][0] = B[1][0] ^ (~B[2][0] & B[3][0]); A[1][1] = B[1][1] ^ (~B[2][1] & B[3][1]); A[1][2] = B[1][2] ^ (~B[2][2] & B[3][2]); A[1][3] = B[1][3] ^ (~B[2][3] & B[3][3]); A[1][4] = B[1][4] ^ (~B[2][4] & B[3][4]); A[2][0] = B[2][0] ^ (~B[3][0] & B[4][0]); A[2][1] = B[2][1] ^ (~B[3][1] & B[4][1]); A[2][2] = B[2][2] ^ (~B[3][2] & B[4][2]); A[2][3] = B[2][3] ^ (~B[3][3] & B[4][3]); A[2][4] = B[2][4] ^ (~B[3][4] & B[4][4]); A[3][0] = B[3][0] ^ (~B[4][0] & B[0][0]); A[3][1] = B[3][1] ^ (~B[4][1] & B[0][1]); A[3][2] = B[3][2] ^ (~B[4][2] & B[0][2]); A[3][3] = B[3][3] ^ (~B[4][3] & B[0][3]); A[3][4] = B[3][4] ^ (~B[4][4] & B[0][4]); A[4][0] = B[4][0] ^ (~B[0][0] & B[1][0]); A[4][1] = B[4][1] ^ (~B[0][1] & B[1][1]); A[4][2] = B[4][2] ^ (~B[0][2] & B[1][2]); A[4][3] = B[4][3] ^ (~B[0][3] & B[1][3]); A[4][4] = B[4][4] ^ (~B[0][4] & B[1][4]); A[0][0] ^= *rc; } } /* sha3: update SHA3 state with one block of data */ static void sha3(SHA3 *s, UCHR *block) { unsigned int i, x, y; W64 P0[5][5]; for (i = 0; i < s->blocksize/64; i++, block += 8) MEM2WORD(&P0[i%5][i/5], block); for (x = 0; x < 5; x++) for (y = 0; y < 5; y++) { if (x + y*5 >= s->blocksize/64) break; s->S[x][y] ^= P0[x][y]; } keccak_f(s->S); } /* digcpy: write SHA3 state to digest buffer */ static UCHR *digcpy(SHA3 *s) { unsigned int x, y; UCHR *Z = s->digest; int outbits = s->digestlen*8; while (outbits > 0) { for (y = 0; y < 5; y++) for (x = 0; x < 5; x++, Z += 8) { if (x + y*5 >= s->blocksize/64) break; word2mem(Z, s->S[x][y]); } if ((outbits -= (int) s->blocksize) > 0) keccak_f(s->S); } return(s->digest); } #define BITSET(s, pos) s[(pos) >> 3] & (UCHR) (0x01 << ((pos) % 8)) #define SETBIT(s, pos) s[(pos) >> 3] |= (UCHR) (0x01 << ((pos) % 8)) #define CLRBIT(s, pos) s[(pos) >> 3] &= (UCHR) ~(0x01 << ((pos) % 8)) #define NBYTES(nbits) (((nbits) + 7) >> 3) #define HEXLEN(nbytes) ((nbytes) << 1) #define B64LEN(nbytes) (((nbytes) % 3 == 0) ? ((nbytes) / 3) * 4 \ : ((nbytes) / 3) * 4 + ((nbytes) % 3) + 1) #define SHA3_INIT(s, algo, xof) \ do { \ Zero(s, 1, SHA3); \ s->alg = algo; \ s->shake = xof; \ s->blocksize = algo ## _BLOCK_BITS; \ s->digestlen = algo ## _DIGEST_BITS >> 3; \ } while (0) /* sharewind: resets digest object */ static void sharewind(SHA3 *s) { if (s->alg == SHA3_224) SHA3_INIT(s, SHA3_224, 0); else if (s->alg == SHA3_256) SHA3_INIT(s, SHA3_256, 0); else if (s->alg == SHA3_384) SHA3_INIT(s, SHA3_384, 0); else if (s->alg == SHA3_512) SHA3_INIT(s, SHA3_512, 0); else if (s->alg == SHAKE128) SHA3_INIT(s, SHAKE128, 1); else if (s->alg == SHAKE256) SHA3_INIT(s, SHAKE256, 1); } /* shainit: initializes digest object */ static int shainit(SHA3 *s, int alg) { if (alg != SHA3_224 && alg != SHA3_256 && alg != SHA3_384 && alg != SHA3_512 && alg != SHAKE128 && alg != SHAKE256) return 0; s->alg = alg; sharewind(s); return 1; } /* shadirect: updates state directly (w/o going through s->block) */ static ULNG shadirect(UCHR *bitstr, ULNG bitcnt, SHA3 *s) { ULNG savecnt = bitcnt; while (bitcnt >= s->blocksize) { sha3(s, bitstr); bitstr += (s->blocksize >> 3); bitcnt -= s->blocksize; } if (bitcnt > 0) { Copy(bitstr, s->block, NBYTES(bitcnt), char); s->blockcnt = bitcnt; } return(savecnt); } /* shabytes: updates state for byte-aligned data in s->block */ static ULNG shabytes(UCHR *bitstr, ULNG bitcnt, SHA3 *s) { UINT offset; UINT nbits; ULNG savecnt = bitcnt; offset = s->blockcnt >> 3; if (s->blockcnt + bitcnt >= s->blocksize) { nbits = s->blocksize - s->blockcnt; Copy(bitstr, s->block+offset, nbits>>3, char); bitcnt -= nbits; bitstr += (nbits >> 3); sha3(s, s->block), s->blockcnt = 0; shadirect(bitstr, bitcnt, s); } else { Copy(bitstr, s->block+offset, NBYTES(bitcnt), char); s->blockcnt += bitcnt; } return(savecnt); } /* shabits: updates state for bit-aligned data in s->block */ static ULNG shabits(UCHR *bitstr, ULNG bitcnt, SHA3 *s) { ULNG i; for (i = 0UL; i < bitcnt; i++) { if (BITSET(bitstr, i)) SETBIT(s->block, s->blockcnt), s->blockcnt++; else CLRBIT(s->block, s->blockcnt), s->blockcnt++; if (s->blockcnt == s->blocksize) sha3(s, s->block), s->blockcnt = 0; } return(bitcnt); } /* shawrite: triggers a state update using data in bitstr/bitcnt */ static ULNG shawrite(UCHR *bitstr, ULNG bitcnt, SHA3 *s) { if (!bitcnt) return(0); if (s->blockcnt == 0) return(shadirect(bitstr, bitcnt, s)); else if (s->blockcnt % 8 == 0) return(shabytes(bitstr, bitcnt, s)); else return(shabits(bitstr, bitcnt, s)); } /* shapad: pads byte-aligned block with 0*1 and computes final digest */ static void shapad(SHA3 *s) { while (s->blockcnt < s->blocksize) s->block[s->blockcnt>>3] = 0x00, s->blockcnt += 8; s->block[(s->blocksize>>3)-1] |= 0x80; sha3(s, s->block); } /* shafinish: pads remaining block(s) and computes final digest state */ static void shafinish(SHA3 *s) { UCHR domain = s->shake ? 0x1f : 0x06; if (s->padded) return; s->padded = 1; if (s->blockcnt % 8 == 0) { s->block[s->blockcnt>>3] = domain; s->blockcnt += 8; shapad(s); return; } shawrite((UCHR *) &domain, s->shake ? 5 : 3, s); while (s->blockcnt % 8) CLRBIT(s->block, s->blockcnt), s->blockcnt++; shapad(s); } /* shasqueeze: returns pointer to squeezed digest (binary) */ static UCHR *shasqueeze(SHA3 *s) { if (s->alg != SHAKE128 && s->alg != SHAKE256) return(NULL); digcpy(s); keccak_f(s->S); return(s->digest); } #define shadigest(state) digcpy(state) /* xmap: translation map for hexadecimal encoding */ static const char xmap[] = "0123456789abcdef"; /* shahex: returns pointer to current digest (hexadecimal) */ static char *shahex(SHA3 *s) { int i; char *h; UCHR *d; d = digcpy(s); s->hex[0] = '\0'; if (HEXLEN((size_t) s->digestlen) >= sizeof(s->hex)) return(s->hex); for (i = 0, h = s->hex; i < s->digestlen; i++) { *h++ = xmap[(*d >> 4) & 0x0f]; *h++ = xmap[(*d++ ) & 0x0f]; } *h = '\0'; return(s->hex); } /* bmap: translation map for Base 64 encoding */ static const char bmap[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* encbase64: encodes input (0 to 3 bytes) into Base 64 */ static void encbase64(UCHR *in, int n, char *out) { UCHR byte[3] = {0, 0, 0}; out[0] = '\0'; if (n < 1 || n > 3) return; Copy(in, byte, (unsigned) n, UCHR); out[0] = bmap[byte[0] >> 2]; out[1] = bmap[((byte[0] & 0x03) << 4) | (byte[1] >> 4)]; out[2] = bmap[((byte[1] & 0x0f) << 2) | (byte[2] >> 6)]; out[3] = bmap[byte[2] & 0x3f]; out[n+1] = '\0'; } /* shabase64: returns pointer to current digest (Base 64) */ static char *shabase64(SHA3 *s) { int n; UCHR *q; char out[5]; q = digcpy(s); s->base64[0] = '\0'; if (B64LEN((size_t) s->digestlen) >= sizeof(s->base64)) return(s->base64); for (n = s->digestlen; n > 3; n -= 3, q += 3) { encbase64(q, 3, out); strcat(s->base64, out); } encbase64(q, n, out); strcat(s->base64, out); return(s->base64); } Digest-SHA3-0.24/src/sha3.h0000644000175000017500000000525412454154237015071 0ustar mshelormshelor/* * sha3.h: header file for SHA-3 routines * * Ref: http://keccak.noekeon.org/specs_summary.html * * Copyright (C) 2012-2015 Mark Shelor, All Rights Reserved * * Version: 0.24 * Sat Jan 10 00:45:34 MST 2015 * */ #ifndef _INCLUDE_SHA3_H_ #define _INCLUDE_SHA3_H_ #include #define SHA64_SHR(x, n) ((x) >> (n)) #define SHA64_SHL(x, n) ((x) << (n)) #define SHA64_ALIGNED #if defined(ULONG_LONG_MAX) || defined(ULLONG_MAX) || defined(HAS_LONG_LONG) #define SHA_ULL_EXISTS #endif #if (((ULONG_MAX >> 16) >> 16) >> 16) >> 15 == 1UL #define SHA64 unsigned long #define SHA64_CONST(c) c ## UL #elif defined(SHA_ULL_EXISTS) && defined(LONGLONGSIZE) && LONGLONGSIZE == 8 #define SHA64 unsigned long long #define SHA64_CONST(c) c ## ULL #elif defined(SHA_ULL_EXISTS) #undef SHA64_ALIGNED #undef SHA64_SHR #define SHA64_MAX 18446744073709551615ULL #define SHA64_SHR(x, n) (((x) & SHA64_MAX) >> (n)) #define SHA64 unsigned long long #define SHA64_CONST(c) c ## ULL /* The following cases detect compilers that * support 64-bit types in a non-standard way */ #elif defined(_MSC_VER) /* Microsoft C */ #define SHA64 unsigned __int64 #define SHA64_CONST(c) (SHA64) c #endif #if defined(BYTEORDER) && ((BYTEORDER==0x1234) || (BYTEORDER==0x12345678)) #if defined(SHA64_ALIGNED) #define MEM2WORD(W, m) Copy(m, W, 8, char) #endif #endif #if !defined(MEM2WORD) #define MEM2WORD(W, m) *(W) = \ (SHA64) m[0] << 0 | (SHA64) m[1] << 8 | \ (SHA64) m[2] << 16 | (SHA64) m[3] << 24 | \ (SHA64) m[4] << 32 | (SHA64) m[5] << 40 | \ (SHA64) m[6] << 48 | (SHA64) m[7] << 56 #endif #define SHA3_224 224 #define SHA3_256 256 #define SHA3_384 384 #define SHA3_512 512 #define SHAKE128 128000 #define SHAKE256 256000 #define SHA3_224_BLOCK_BITS 1152 #define SHA3_256_BLOCK_BITS 1088 #define SHA3_384_BLOCK_BITS 832 #define SHA3_512_BLOCK_BITS 576 #define SHAKE128_BLOCK_BITS 1344 #define SHAKE256_BLOCK_BITS 1088 #define SHA3_224_DIGEST_BITS 224 #define SHA3_256_DIGEST_BITS 256 #define SHA3_384_DIGEST_BITS 384 #define SHA3_512_DIGEST_BITS 512 #define SHAKE128_DIGEST_BITS SHAKE128_BLOCK_BITS #define SHAKE256_DIGEST_BITS SHAKE256_BLOCK_BITS #define SHA3_MAX_BLOCK_BITS SHAKE128_BLOCK_BITS #define SHA3_MAX_DIGEST_BITS SHAKE128_DIGEST_BITS #define SHA3_MAX_HEX_LEN (SHA3_MAX_DIGEST_BITS / 4) #define SHA3_MAX_BASE64_LEN (1 + (SHA3_MAX_DIGEST_BITS / 6)) typedef struct SHA3 { int alg; SHA64 S[5][5]; unsigned char block[SHA3_MAX_BLOCK_BITS/8]; unsigned int blockcnt; unsigned int blocksize; unsigned char digest[SHA3_MAX_DIGEST_BITS/8]; int digestlen; char hex[SHA3_MAX_HEX_LEN+1]; char base64[SHA3_MAX_BASE64_LEN+1]; int padded; int shake; } SHA3; #endif /* _INCLUDE_SHA3_H_ */ Digest-SHA3-0.24/src/sdf.c0000644000175000017500000000373412452233267015002 0ustar mshelormshelor/* Extracted from perl-5.004/universal.c, contributed by Graham Barr */ static SV * isa_lookup(stash, name, len, level) HV *stash; char *name; int len; int level; { AV* av; GV* gv; GV** gvp; HV* hv = Nullhv; if (!stash) return &sv_undef; if(strEQ(HvNAME(stash), name)) return &sv_yes; if (level > 100) croak("Recursive inheritance detected"); gvp = (GV**)hv_fetch(stash, "::ISA::CACHE::", 14, FALSE); if (gvp && (gv = *gvp) != (GV*)&sv_undef && (hv = GvHV(gv))) { SV* sv; SV** svp = (SV**)hv_fetch(hv, name, len, FALSE); if (svp && (sv = *svp) != (SV*)&sv_undef) return sv; } gvp = (GV**)hv_fetch(stash,"ISA",3,FALSE); if (gvp && (gv = *gvp) != (GV*)&sv_undef && (av = GvAV(gv))) { if(!hv) { gvp = (GV**)hv_fetch(stash, "::ISA::CACHE::", 14, TRUE); gv = *gvp; if (SvTYPE(gv) != SVt_PVGV) gv_init(gv, stash, "::ISA::CACHE::", 14, TRUE); hv = GvHVn(gv); } if(hv) { SV** svp = AvARRAY(av); I32 items = AvFILL(av) + 1; while (items--) { SV* sv = *svp++; HV* basestash = gv_stashsv(sv, FALSE); if (!basestash) { if (dowarn) warn("Can't locate package %s for @%s::ISA", SvPVX(sv), HvNAME(stash)); continue; } if(&sv_yes == isa_lookup(basestash, name, len, level + 1)) { (void)hv_store(hv,name,len,&sv_yes,0); return &sv_yes; } } (void)hv_store(hv,name,len,&sv_no,0); } } return &sv_no; } static bool sv_derived_from(sv, name) SV * sv ; char * name ; { SV *rv; char *type; HV *stash; stash = Nullhv; type = Nullch; if (SvGMAGICAL(sv)) mg_get(sv) ; if (SvROK(sv)) { sv = SvRV(sv); type = sv_reftype(sv,0); if(SvOBJECT(sv)) stash = SvSTASH(sv); } else { stash = gv_stashsv(sv, FALSE); } return (type && strEQ(type,name)) || (stash && isa_lookup(stash, name, strlen(name), 0) == &sv_yes) ? TRUE : FALSE ; } Digest-SHA3-0.24/README0000644000175000017500000000310112454154237014140 0ustar mshelormshelorDigest::SHA3 version 0.24 ========================= Digest::SHA3 is a complete implementation of the NIST SHA-3 cryptographic hash function, known originally as Keccak. It gives Perl programmers a convenient way to calculate SHA3-224, SHA3-256, SHA3-384, and SHA3-512 message digests, as well as variable-length hashes using SHAKE128 and SHAKE256. The module can handle all types of input, including partial-byte data. Digest::SHA3 is written in C for speed. If your platform lacks a C compiler, perhaps you can find the module in a binary form compatible with your particular processor and operating system. The initial version of Digest::SHA3 was written to emphasize simplicity and correctness. It passed all known-answer-tests for short and long messages. No particular emphasis was placed on performance. However, as the SHA-3 standard matures and achieves 'final' status, versions of this module will endeavor to perform on a par with optimized portable implementations. The module omits all HMAC-SHA-3 functions until such time as official test vectors become available. The tests subdirectory (t/*.t) contains a set of test vectors compiled from both official and informal sources. INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES None COPYRIGHT AND LICENSE Copyright (C) 2012-2015 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