Digest-SHA3-1.04/0000755000175000017500000000000013266475421013267 5ustar mshelormshelorDigest-SHA3-1.04/sha3sum0000755000175000017500000002263113266473664014613 0ustar mshelormshelor#!perl ## sha3sum: filter for computing SHA-3 digests (ref. shasum) ## ## Copyright (C) 2012-2018 Mark Shelor, All Rights Reserved ## ## Version: 1.04 ## Fri Apr 20 16:25:30 MST 2018 ## sha3sum SYNOPSIS adapted from GNU Coreutils sha1sum. Add ## "-a" option for algorithm selection, ## "-U" option for Universal Newlines support, and ## "-0" option for reading bit strings. BEGIN { pop @INC if $INC[-1] eq '.' } use strict; use warnings; use Fcntl; use Getopt::Long; use Digest::SHA3 qw($errmsg); 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 --tag create a BSD-style checksum -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 The following five options are useful only when verifying checksums: --ignore-missing don't fail or report status for missing files -q, --quiet don't print OK for each successfully verified file -s, --status don't output anything, status code shows success --strict exit non-zero for improperly formatted checksum lines -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), and name for each FILE. The line starts with a `\' character if the FILE name contains either newlines or backslashes, which are then replaced by the two-character sequences `\n' and `\\' respectively. 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-2018 Mark Shelor . =head1 SEE ALSO I is implemented using the Perl module L. =cut END_OF_POD my $VERSION = "1.04"; 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(.+?)^=/sm; $USAGE =~ s/^\s*//; $USAGE =~ s/\s*$//; $USAGE =~ s/^ //gm; print $USAGE, "\n"; 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, $quiet, $warn, $help); my ($version, $BITS, $UNIVERSAL, $tag, $strict, $ignore_missing); 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, 'q|quiet' => \$quiet, 'h|help' => \$help, 'v|version' => \$version, 'U|UNIVERSAL' => \$UNIVERSAL, '0|01' => \$BITS, 'tag' => \$tag, 'strict' => \$strict, 'ignore-missing' => \$ignore_missing, ) 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, $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; usage(1, "sha3sum: --quiet option used only when verifying checksums\n") if $quiet && !$check; usage(1, "sha3sum: --ignore-missing option used only when verifying checksums\n") if $ignore_missing && !$check; usage(1, "sha3sum: --strict option used only when verifying checksums\n") if $strict && !$check; usage(1, "sha3sum: --tag does not support --text mode\n") if $tag && $text; usage(1, "sha3sum: --tag does not support Universal Newlines mode\n") if $tag && $UNIVERSAL; usage(1, "sha3sum: --tag does not support BITS mode\n") if $tag && $BITS; ## Default to SHA3-224 unless overridden by command line option my %isAlg = map { $_ => 1 } (224, 256, 384, 512, 128000, 256000); $alg = 224 unless defined $alg; usage(1, "sha3sum: Unrecognized algorithm\n") unless $isAlg{$alg}; my %Tag = map { $_ => "SHA3-$_" } (224, 256, 384, 512); $Tag{128000} = "SHAKE128"; $Tag{256000} = "SHAKE256"; ## 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" options. my $isDOSish = ($^O =~ /^(MSWin\d\d|os2|dos|mint|cygwin)$/); if ($isDOSish) { $binary = 1 unless $text || $UNIVERSAL } my $modesym = $binary ? '*' : ($UNIVERSAL ? 'U' : ($BITS ? '^' : ' ')); ## 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' : '')); my $digest = eval { Digest::SHA3->new($alg)->addfile($file, $mode) }; if ($@) { warn "sha3sum: $file: $errmsg\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; 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_fmt_OK, $num_OK) = (0, 0); my ($bslash, $fcn, $sum, $fname, $rsp, $digest, $isOK); 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 /^#/; if (/^[ \t]*\\?(SHA3-|SHAKE)/) { $modesym = '*'; ($bslash, $fcn, $alg, $fname, $sum) = /^[ \t]*(\\?)(SHA3-|SHAKE)(\d+) \((.+)\) = ([\da-fA-F]+)/; if (defined $fcn and $fcn eq 'SHAKE') { $alg *= 1000 if defined $alg; } } else { ($bslash, $sum, $modesym, $fname) = /^[ \t]*(\\?)([\da-fA-F]+)[ \t]([ *^U])(.+)/; $alg = defined $sum ? $len2alg{length($sum)} : undef; } if (grep { ! defined $_ } ($alg, $sum, $modesym, $fname) or ! $isAlg{$alg}) { warn("sha3sum: $checkfile: $.: improperly formatted" . " SHA3 checksum line\n") if $warn; $fmt_errs++; $err = 1 if $strict; next; } $num_fmt_OK++; $fname = unescape($fname) if $bslash; next if $ignore_missing && ! -e $fname; $rsp = "$fname: "; ($binary, $text, $UNIVERSAL, $BITS) = map { $_ eq $modesym } ('*', ' ', 'U', '^'); $isOK = 0; unless ($digest = sumfile($fname)) { $rsp .= "FAILED open or read\n"; $err = 1; $read_errs++; } elsif (lc($sum) eq $digest) { $rsp .= "OK\n"; $isOK = 1; $num_OK++; } else { $rsp .= "FAILED\n"; $err = 1; $match_errs++ } print $rsp unless ($status || ($quiet && $isOK)); } close(FH); if (! $num_fmt_OK) { warn("sha3sum: $checkfile: no properly formatted " . "SHA3 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; } if ($ignore_missing && ! $num_OK && $num_fmt_OK) { warn("sha3sum: $checkfile: no file was verified\n") unless $status; $err = 1; } 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; print "\\"; } unless ($tag) { print "$digest $modesym$file\n" } else { print "$Tag{$alg} ($file) = $digest\n" } } else { $STATUS = 1 } } exit($STATUS); Digest-SHA3-1.04/src/0000755000175000017500000000000013266475421014056 5ustar mshelormshelorDigest-SHA3-1.04/src/sdf.c0000644000175000017500000000373413220125134014764 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-1.04/src/sha3.c0000644000175000017500000002454113266473352015067 0ustar mshelormshelor/* * sha3.c: routines to compute SHA-3 digests * * Ref: http://keccak.noekeon.org/specs_summary.html * * Copyright (C) 2012-2018 Mark Shelor, All Rights Reserved * * Version: 1.04 * Fri Apr 20 16:25:30 MST 2018 * */ #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); else CLRBIT(s->block, 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-1.04/src/sha3.h0000644000175000017500000000525413266473352015074 0ustar mshelormshelor/* * sha3.h: header file for SHA-3 routines * * Ref: http://keccak.noekeon.org/specs_summary.html * * Copyright (C) 2012-2018 Mark Shelor, All Rights Reserved * * Version: 1.04 * Fri Apr 20 16:25:30 MST 2018 * */ #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-1.04/lib/0000755000175000017500000000000013266475421014035 5ustar mshelormshelorDigest-SHA3-1.04/lib/Digest/0000755000175000017500000000000013266475421015254 5ustar mshelormshelorDigest-SHA3-1.04/lib/Digest/SHA3.pm0000644000175000017500000004233213266473664016323 0ustar mshelormshelorpackage Digest::SHA3; require 5.003000; use strict; use warnings; use vars qw($VERSION @ISA @EXPORT_OK $errmsg); use Fcntl qw(O_RDONLY O_RDWR); use integer; $VERSION = '1.04'; require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw( $errmsg 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, $lsb) = @_; if (defined $nbits) { my $max = length($data) * 8; $nbits = $max if $nbits > $max; } if ($lsb) { shawrite($data, $nbits, $self); return($self); } unless (defined $nbits) { $nbits = length($data); $data = pack("B*", $data); } if ($nbits % 8) { my $b = unpack("C", substr($data, -1)); $b >>= (8 - $nbits % 8); substr($data, -1) = pack("C", $b); } shawrite($data, $nbits, $self); return($self); } sub _bail { my $msg = shift; $errmsg = $!; $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) = map { $_ eq $mode } ("b", "U", "0"); ## Always interpret "-" to mean STDIN; otherwise use ## sysopen to handle full range of POSIX file names. ## If $file is a directory, force an EISDIR error ## by attempting to open with mode O_RDWR local *FH; $file eq '-' and open(FH, '< -') or sysopen(FH, $file, -d $file ? O_RDWR : O_RDONLY) or _bail('Open failed'); if ($BITS) { my ($n, $buf, $bits) = (0, "", ""); while (($n = read(FH, $buf, 4096))) { $buf =~ tr/01//cd; $bits .= $buf; if (length($bits) >= 4096) { $self->add_bits(substr($bits, 0, 4096)); $bits = substr($bits, 4096); } } $self->add_bits($bits) if length($bits) > 0; _bail("Read failed") unless defined $n; close(FH); return($self); } binmode(FH) if $binary || $UNIVERSAL; if ($UNIVERSAL && _istext(*FH, $file)) { $self->_addfileuniv(*FH); } else { $self->_addfilebin(*FH) } close(FH); $self; } eval { require XSLoader; XSLoader::load('Digest::SHA3', $VERSION); 1; } or do { require DynaLoader; push @ISA, 'DynaLoader'; 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 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 2015, 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. Setting the optional I<$lsb> flag to a true value indicates that the final (partial) byte of I<$data> is aligned with the least-significant bit; by default it's aligned with the most-significant bit, as required by the parent L module. 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 three statements do the same thing: $sha3->add_bits("111100001010"); $sha3->add_bits("\xF0\xA0", 12); $sha3->add_bits("\xF0\x0A", 12, 1); SHA-3 uses least-significant-bit ordering for its internal operation. This means that $sha3->add_bits("110"); is equivalent to $sha3->add_bits("0")->add_bits("1")->add_bits("1"); Many public test vectors for SHA-3, such as the Keccak known-answer tests, are delivered in least-significant-bit format. Using the optional I<$lsb> flag in these cases allows your code to be simpler and more efficient. See the test directory for examples. The fact that SHA-2 and SHA-3 employ opposite bit-ordering schemes has caused noticeable confusion in the programming community. Exercise caution if your code examines individual bits in data streams. =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 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 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 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-2018 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-1.04/README0000644000175000017500000000304513266473352014152 0ustar mshelormshelorDigest::SHA3 version 1.04 ========================= 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, 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-2018 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 Digest-SHA3-1.04/SHA3.xs0000644000175000017500000001274713244400124014334 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, (ULNG) 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, (ULNG) 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 = (int) 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 = (int) 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-1.04/t/0000755000175000017500000000000013266475421013532 5ustar mshelormshelorDigest-SHA3-1.04/t/bit-shake256.t0000644000175000017500000000640513220125134016007 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); $sha3->add_bits($Msg, $Len, 1); 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-1.04/t/bitorder.t0000644000175000017500000000112513220125134015507 0ustar mshelormsheloruse strict; use Digest::SHA3; my $numtests = 3; print "1..$numtests\n"; my $testnum = 1; 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; print "not " unless $d1 eq $d2; print "ok ", $testnum++, "\n"; $d1 = $s1->add_bits("111100001010")->hexdigest; $d2 = $s2->add_bits("\xF0\xA0", 12)->hexdigest; print "not " unless $d1 eq $d2; print "ok ", $testnum++, "\n"; $d2 = $s2->add_bits("\xF0\x0A", 12, 1)->hexdigest; print "not " unless $d1 eq $d2; print "ok ", $testnum++, "\n"; Digest-SHA3-1.04/t/bit-shake128.t0000644000175000017500000000640513220125134016005 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); $sha3->add_bits($Msg, $Len, 1); 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-1.04/t/sha3-256.t0000644000175000017500000000111013220125134015037 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-1.04/t/sha3-224.t0000644000175000017500000000114613220125134015043 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-1.04/t/bit-sha3-512.t0000644000175000017500000000325613220125134015623 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); my $MD = shift @vecs; my $computed = $sha3->add_bits($Msg, $Len, 1)->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-1.04/t/sha3-384.t0000644000175000017500000000125013220125134015046 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-1.04/t/allfcns.t0000644000175000017500000000046413220125134015324 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-1.04/t/pod.t0000644000175000017500000000053213220125134014460 0ustar mshelormsheloruse strict; my $skip; BEGIN { eval "use Test::More"; $skip = $@ ? 1 : 0; unless ($skip) { eval "use Test::Pod 1.00"; $skip = 2 if $@; } } if ($skip == 1) { print "1..0 # Skipped: Test::More not installed\n"; exit; } if ($skip == 2) { print "1..0 # Skipped: Test::Pod 1.00 required for testing POD\n"; exit; } all_pod_files_ok(); Digest-SHA3-1.04/t/podcover.t0000644000175000017500000000072113220125134015517 0ustar mshelormsheloruse strict; use Digest::SHA3; my $skip; BEGIN { eval "use Test::More"; $skip = $@ ? 1 : 0; unless ($skip) { eval "use Test::Pod::Coverage 0.08"; $skip = 2 if $@; } } if ($skip == 1) { print "1..0 # Skipped: Test::More not installed\n"; exit; } if ($skip == 2) { print "1..0 # Skipped: Test::Pod::Coverage 0.08 required\n"; exit; } my @privfcns = qw( newSHA3 shainit sharewind shawrite ); all_pod_coverage_ok( { also_private => \@privfcns } ); Digest-SHA3-1.04/t/sha3-512.t0000644000175000017500000000141013220125134015035 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-1.04/t/bit-sha3-224.t0000644000175000017500000000317513220125134015623 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); my $MD = shift @vecs; my $computed = $sha3->add_bits($Msg, $Len, 1)->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-1.04/t/bit-sha3-384.t0000644000175000017500000000321513220125134015625 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); my $MD = shift @vecs; my $computed = $sha3->add_bits($Msg, $Len, 1)->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-1.04/t/bit-sha3-256.t0000644000175000017500000000315713220125134015630 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); my $MD = shift @vecs; my $computed = $sha3->add_bits($Msg, $Len, 1)->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-1.04/typemap0000644000175000017500000000011713220125134014647 0ustar mshelormshelorTYPEMAP SHA3 * T_SHA3 PerlIO * T_IN INPUT T_SHA3 $var = getSHA3(aTHX_ $arg) Digest-SHA3-1.04/examples/0000755000175000017500000000000013266475421015105 5ustar mshelormshelorDigest-SHA3-1.04/examples/dups30000755000175000017500000000233313220125134016051 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-1.04/Makefile.PL0000644000175000017500000000344213220125134015223 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-1.04/META.yml0000644000175000017500000000053513266473352014544 0ustar mshelormshelor--- #YAML:1.0 name: Digest-SHA3 version: 1.04 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: 1.04 meta-spec: version: 1.3 url: http://module-build.sourceforge.net/META-spec-v1.3.html generated_by: Mark Shelor Digest-SHA3-1.04/MANIFEST0000644000175000017500000000051713220125134014402 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/bitorder.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-1.04/Changes0000644000175000017500000001447013266473352014571 0ustar mshelormshelorRevision history for Perl extension Digest::SHA3. 1.04 Fri Apr 20 16:25:30 MST 2018 - silenced compiler warnings from VS2017 -- ref. rt.cpan.org #124477 -- thanks to Sergey Aleynikov for diagnostics - modified addfile to return error when given a directory name -- makes behavior consistent with GNU coreutils shaXsum -- thanks to Scott Baker for pointing this out 1.03 Mon Dec 25 00:08:10 MST 2017 - added "--ignore-missing" and "--strict" options to sha3sum -- consistent with GNU coreutils -- ref. rt.cpan.org #123897 1.02 Fri Dec 8 22:44:46 MST 2017 - added "tag" option (BSD-style checksums) to sha3sum -- consistent with GNU sha1sum, sha224sum, etc. -- thanks to Christopher Tubbs for suggestion - modified SHA3.pm to use XSLoader -- falls back to DynaLoader if necessary 1.01 Sun Oct 22 16:04:22 MST 2017 - added optional $lsb argument for add_bits() method -- many public vectors in least-significant-bit format -- using $lsb flag results in simpler test code - further minor optimizations in add_bits() and tests 1.00 Sat Oct 14 18:08:10 MST 2017 - promoted to major release version 1.0 -- module stable enough not to be considered draft - fixed alignment issue in BITS mode of addfile -- surfaced only for large non-aligned inputs 0.27 Wed Oct 4 00:40:04 MST 2017 - removed "portable" mode from sha3sum and addfile -- rarely used, mostly in outdated systems -- potentially confusing features (e.g. \r\r\n -> \n) -- Universal Newlines mode (-U) a much cleaner approach -- mimics Universal Newlines in Python - sha3sum now depends explicitly on Digest::SHA3 -- eliminates runtime loading of modules -- no future plans to write Digest::SHA3::PurePerl 0.26 Wed Sep 6 02:23:08 MST 2017 - added 'quiet' option to sha3sum -- thanks to Chris David for suggestion and initial patch -- ref. rt.cpan.org #122750 - expanded sha3sum --help message -- to explain use of escaped FILE names 0.25 Wed Jul 27 20:04:40 MST 2016 - prevented sha3sum from possibly running malicious code -- remove '.' from @INC before module loading -- ref. rt.cpan.org #116513 - namespace cleanup (ref. rt.cpan.org #105371 and #105372) - minor code and documentation tweaks 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