<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">diff --git a/pkgtools/pkg_install/files/admin/check.c b/pkgtools/pkg_install/files/admin/check.c
--- a/pkgtools/pkg_install/files/admin/check.c
+++ b/pkgtools/pkg_install/files/admin/check.c
@@ -53,18 +53,20 @@
 #if HAVE_ERRNO_H
 #include &lt;errno.h&gt;
 #endif
 #if HAVE_FCNTL_H
 #include &lt;fcntl.h&gt;
 #endif
 #ifndef NETBSD
 #include &lt;nbcompat/md5.h&gt;
+#include &lt;nbcompat/sha2.h&gt;
 #else
 #include &lt;md5.h&gt;
+#include &lt;sha2.h&gt;
 #endif
 #if HAVE_LIMITS_H
 #include &lt;limits.h&gt;
 #endif
 #if HAVE_STDIO_H
 #include &lt;stdio.h&gt;
 #endif
 #if HAVE_STRING_H
@@ -108,24 +110,32 @@ check1pkg(const char *pkgdir, int *filec
 				warnx("dirp not initialized, please send-pr!");
 				abort();
 			}
 			
 			(void) snprintf(file, sizeof(file), "%s/%s", dirp, p-&gt;name);
 
 			if (isfile(file) || islinktodir(file)) {
 				if (p-&gt;next &amp;&amp; p-&gt;next-&gt;type == PLIST_COMMENT) {
-					if (strncmp(p-&gt;next-&gt;name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) {
+					if (strncmp(p-&gt;next-&gt;name, MD5_CHECKSUM_HEADER, MD5ChecksumHeaderLen) == 0) {
 						if ((md5file = MD5File(file, NULL)) != NULL) {
 							/* Mismatch? */
-							if (strcmp(md5file, p-&gt;next-&gt;name + ChecksumHeaderLen) != 0)
+							if (strcmp(md5file, p-&gt;next-&gt;name + MD5ChecksumHeaderLen) != 0)
 								printf("%s fails MD5 checksum\n", file);
 
 							free(md5file);
 						}
+					} else if (strncmp(p-&gt;next-&gt;name, COMBO_CHECKSUM_HEADER, ComboChecksumHeaderLen) == 0) {
+						if ((md5file = combo_digest_file(file, NULL)) != NULL) {
+							/* Mismatch? */
+							if (strcmp(md5file, p-&gt;next-&gt;name + ComboChecksumHeaderLen) != 0)
+								printf("%s fails combo checksum\n", file);
+
+							free(md5file);
+						}
 					} else if (strncmp(p-&gt;next-&gt;name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) {
 						char	buf[MaxPathSize + SymlinkHeaderLen];
 						int	cc;
 
 						(void) strlcpy(buf, SYMLINK_HEADER, sizeof(buf));
 						if ((cc = readlink(file, &amp;buf[SymlinkHeaderLen],
 							  sizeof(buf) - SymlinkHeaderLen - 1)) &lt; 0) {
 							warnx("can't readlink `%s'", file);
diff --git a/pkgtools/pkg_install/files/configure b/pkgtools/pkg_install/files/configure
--- a/pkgtools/pkg_install/files/configure
+++ b/pkgtools/pkg_install/files/configure
@@ -4793,17 +4793,17 @@ if eval test \"x\$"$as_ac_Header"\" = x"
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
 fi
 
 done
 
 
-for ac_header in assert.h ctype.h dirent.h err.h errno.h fnctl.h \
+for ac_header in assert.h ctype.h dirent.h err.h errno.h fcntl.h \
 	fnmatch.h glob.h grp.h inttypes.h limits.h pwd.h signal.h \
 	stdarg.h stdio.h stdlib.h string.h time.h unistd.h vis.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
 if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat &gt;&gt;confdefs.h &lt;&lt;_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
diff --git a/pkgtools/pkg_install/files/configure.ac b/pkgtools/pkg_install/files/configure.ac
--- a/pkgtools/pkg_install/files/configure.ac
+++ b/pkgtools/pkg_install/files/configure.ac
@@ -59,17 +59,17 @@ AC_SUBST(bootstrap)
 dnl Checks for large file support.
 AC_SYS_LARGEFILE
 
 dnl Checks for libraries.
 AC_CHECK_LIB(db, __db185_open, , AC_SEARCH_LIBS(dbopen, [db db1]))
 
 dnl Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS([assert.h ctype.h dirent.h err.h errno.h fnctl.h \
+AC_CHECK_HEADERS([assert.h ctype.h dirent.h err.h errno.h fcntl.h \
 	fnmatch.h glob.h grp.h inttypes.h limits.h pwd.h signal.h \
 	stdarg.h stdio.h stdlib.h string.h time.h unistd.h vis.h])
 AC_CHECK_HEADERS([sys/cdefs.h sys/file.h sys/ioctl.h sys/queue.h \
 	sys/stat.h sys/time.h sys/types.h sys/utsname.h sys/wait.h])
 
 # Checks for library functions.
 AC_CHECK_FUNCS([vfork])
 
diff --git a/pkgtools/pkg_install/files/create/pl.c b/pkgtools/pkg_install/files/create/pl.c
--- a/pkgtools/pkg_install/files/create/pl.c
+++ b/pkgtools/pkg_install/files/create/pl.c
@@ -77,17 +77,17 @@ CheckSymlink(char *name, char *prefix, s
  * Check a list for files that require preconversion
  */
 void
 check_list(package_t *pkg, const char *PkgName)
 {
 	struct stat st;
 	plist_t *tmp;
 	plist_t *p;
-	char    buf[ChecksumHeaderLen + LegibleChecksumLen];
+	char    buf[ComboChecksumHeaderLen + LegibleComboChecksumLen];
 	char    target[MaxPathSize + SymlinkHeaderLen];
 	char    name[MaxPathSize];
 	char   *cwd = NULL;
 	char   *pkgname = NULL;
 	int	cc;
 
 	/* Open Package Database for writing */
 	if (update_pkgdb &amp;&amp; !pkgdb_open(ReadWrite))
@@ -178,22 +178,22 @@ check_list(package_t *pkg, const char *P
 				break;
 			case S_IFCHR:
 				warnx("Warning - char special device `%s' in PLIST", name);
 				break;
 			case S_IFBLK:
 				warnx("Warning - block special device `%s' in PLIST", name);
 				break;
 			default:
-				(void) strlcpy(buf, CHECKSUM_HEADER,
+				(void) strlcpy(buf, COMBO_CHECKSUM_HEADER,
 				    sizeof(buf));
-				if (MD5File(name, &amp;buf[ChecksumHeaderLen]) != (char *) NULL) {
+				if (combo_digest_file(name, &amp;buf[ComboChecksumHeaderLen]) != NULL) {
 					tmp = new_plist_entry();
 					tmp-&gt;name = xstrdup(buf);
-					tmp-&gt;type = PLIST_COMMENT;	/* PLIST_MD5 - HF */
+					tmp-&gt;type = PLIST_COMMENT;
 					tmp-&gt;next = p-&gt;next;
 					tmp-&gt;prev = p;
 					if (p == pkg-&gt;tail) {
 						pkg-&gt;tail = tmp;
 					}
 					p-&gt;next = tmp;
 					p = tmp;
 				}
diff --git a/pkgtools/pkg_install/files/lib/Makefile.in b/pkgtools/pkg_install/files/lib/Makefile.in
--- a/pkgtools/pkg_install/files/lib/Makefile.in
+++ b/pkgtools/pkg_install/files/lib/Makefile.in
@@ -24,16 +24,17 @@ CFLAGS=		@CFLAGS@
 
 INSTALL=	@INSTALL@
 
 LIB=	libinstall.a
 
 OBJS=	automatic.o conflicts.o dewey.o fexec.o file.o \
 	global.o iterate.o license.o lpkg.o opattern.o \
 	parse-config.o pkgdb.o plist.o remove.o \
+	sha3.o sha3hl.o keccak.o \
 	str.o var.o version.o vulnerabilities-file.o xwrapper.o
 
 CPPFLAGS+=	-DSYSCONFDIR=\"$(sysconfdir)\"
 
 .if !empty(BOOTSTRAP)
 CPPFLAGS+=	-DBOOTSTRAP
 .else
 OBJS+=	gpgsig.o pkg_io.o pkg_signature.o
diff --git a/pkgtools/pkg_install/files/lib/config.h.in b/pkgtools/pkg_install/files/lib/config.h.in
--- a/pkgtools/pkg_install/files/lib/config.h.in
+++ b/pkgtools/pkg_install/files/lib/config.h.in
@@ -10,18 +10,18 @@
 #undef HAVE_DIRENT_H
 
 /* Define to 1 if you have the &lt;errno.h&gt; header file. */
 #undef HAVE_ERRNO_H
 
 /* Define to 1 if you have the &lt;err.h&gt; header file. */
 #undef HAVE_ERR_H
 
-/* Define to 1 if you have the &lt;fnctl.h&gt; header file. */
-#undef HAVE_FNCTL_H
+/* Define to 1 if you have the &lt;fcntl.h&gt; header file. */
+#undef HAVE_FCNTL_H
 
 /* Define to 1 if you have the &lt;fnmatch.h&gt; header file. */
 #undef HAVE_FNMATCH_H
 
 /* Define to 1 if you have the &lt;glob.h&gt; header file. */
 #undef HAVE_GLOB_H
 
 /* Define to 1 if you have the &lt;grp.h&gt; header file. */
diff --git a/pkgtools/pkg_install/files/lib/keccak.c b/pkgtools/pkg_install/files/lib/keccak.c
new file mode 100644
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/keccak.c
@@ -0,0 +1,178 @@
+/*-
+ * Copyright (c) 2015 Taylor R. Campbell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define	_POSIX_C_SOURCE	200809L
+
+#include &lt;stdint.h&gt;
+
+#include "keccak.h"
+
+#define	secret	/* can't use in variable-time operations, should zero */
+
+#define	FOR5(X, STMT) do						      \
+{									      \
+	(X) = 0; (STMT);						      \
+	(X) = 1; (STMT);						      \
+	(X) = 2; (STMT);						      \
+	(X) = 3; (STMT);						      \
+	(X) = 4; (STMT);						      \
+} while (0)
+
+static inline secret uint64_t
+rol64(secret uint64_t v, unsigned c)
+{
+
+	return ((v &lt;&lt; c) | (v &gt;&gt; (64 - c)));
+}
+
+static inline void
+keccakf1600_theta(secret uint64_t A[25])
+{
+	secret uint64_t C0, C1, C2, C3, C4;
+	unsigned y;
+
+	C0 = C1 = C2 = C3 = C4 = 0;
+	FOR5(y, {
+		C0 ^= A[0 + 5*y];
+		C1 ^= A[1 + 5*y];
+		C2 ^= A[2 + 5*y];
+		C3 ^= A[3 + 5*y];
+		C4 ^= A[4 + 5*y];
+	});
+	FOR5(y, {
+		A[0 + 5*y] ^= C4 ^ rol64(C1, 1);
+		A[1 + 5*y] ^= C0 ^ rol64(C2, 1);
+		A[2 + 5*y] ^= C1 ^ rol64(C3, 1);
+		A[3 + 5*y] ^= C2 ^ rol64(C4, 1);
+		A[4 + 5*y] ^= C3 ^ rol64(C0, 1);
+	});
+}
+
+static inline void
+keccakf1600_rho_pi(secret uint64_t A[25])
+{
+	secret uint64_t T, U;
+
+	/*
+	 * Permute by (x,y) |---&gt; (y, 2x + 3y mod 5) starting at (1,0),
+	 * rotate the ith element by (i + 1)(i + 2)/2 mod 64.
+	 */
+	U = A[ 1];                       T = U;
+	U = A[10]; A[10] = rol64(T,  1); T = U;
+	U = A[ 7]; A[ 7] = rol64(T,  3); T = U;
+	U = A[11]; A[11] = rol64(T,  6); T = U;
+	U = A[17]; A[17] = rol64(T, 10); T = U;
+	U = A[18]; A[18] = rol64(T, 15); T = U;
+	U = A[ 3]; A[ 3] = rol64(T, 21); T = U;
+	U = A[ 5]; A[ 5] = rol64(T, 28); T = U;
+	U = A[16]; A[16] = rol64(T, 36); T = U;
+	U = A[ 8]; A[ 8] = rol64(T, 45); T = U;
+	U = A[21]; A[21] = rol64(T, 55); T = U;
+	U = A[24]; A[24] = rol64(T,  2); T = U;
+	U = A[ 4]; A[ 4] = rol64(T, 14); T = U;
+	U = A[15]; A[15] = rol64(T, 27); T = U;
+	U = A[23]; A[23] = rol64(T, 41); T = U;
+	U = A[19]; A[19] = rol64(T, 56); T = U;
+	U = A[13]; A[13] = rol64(T,  8); T = U;
+	U = A[12]; A[12] = rol64(T, 25); T = U;
+	U = A[ 2]; A[ 2] = rol64(T, 43); T = U;
+	U = A[20]; A[20] = rol64(T, 62); T = U;
+	U = A[14]; A[14] = rol64(T, 18); T = U;
+	U = A[22]; A[22] = rol64(T, 39); T = U;
+	U = A[ 9]; A[ 9] = rol64(T, 61); T = U;
+	U = A[ 6]; A[ 6] = rol64(T, 20); T = U;
+	           A[ 1] = rol64(T, 44);
+}
+
+static inline void
+keccakf1600_chi(secret uint64_t A[25])
+{
+	secret uint64_t B0, B1, B2, B3, B4;
+	unsigned y;
+
+	FOR5(y, {
+		B0 = A[0 + 5*y];
+		B1 = A[1 + 5*y];
+		B2 = A[2 + 5*y];
+		B3 = A[3 + 5*y];
+		B4 = A[4 + 5*y];
+		A[0 + 5*y] ^= ~B1 &amp; B2;
+		A[1 + 5*y] ^= ~B2 &amp; B3;
+		A[2 + 5*y] ^= ~B3 &amp; B4;
+		A[3 + 5*y] ^= ~B4 &amp; B0;
+		A[4 + 5*y] ^= ~B0 &amp; B1;
+	});
+}
+
+static void
+keccakf1600_round(secret uint64_t A[25])
+{
+
+	keccakf1600_theta(A);
+	keccakf1600_rho_pi(A);
+	keccakf1600_chi(A);
+}
+
+void
+keccakf1600(secret uint64_t A[25])
+{
+	/*
+	 * RC[i] = \sum_{j = 0,...,6} rc(j + 7i) 2^(2^j - 1),
+	 * rc(t) = (x^t mod x^8 + x^6 + x^5 + x^4 + 1) mod x in GF(2)[x]
+	 */
+	static const uint64_t RC[24] = {
+		0x0000000000000001ULL,
+		0x0000000000008082ULL,
+		0x800000000000808aULL,
+		0x8000000080008000ULL,
+		0x000000000000808bULL,
+		0x0000000080000001ULL,
+		0x8000000080008081ULL,
+		0x8000000000008009ULL,
+		0x000000000000008aULL,
+		0x0000000000000088ULL,
+		0x0000000080008009ULL,
+		0x000000008000000aULL,
+		0x000000008000808bULL,
+		0x800000000000008bULL,
+		0x8000000000008089ULL,
+		0x8000000000008003ULL,
+		0x8000000000008002ULL,
+		0x8000000000000080ULL,
+		0x000000000000800aULL,
+		0x800000008000000aULL,
+		0x8000000080008081ULL,
+		0x8000000000008080ULL,
+		0x0000000080000001ULL,
+		0x8000000080008008ULL,
+	};
+	unsigned i;
+
+	for (i = 0; i &lt; 24; i++) {
+		keccakf1600_round(A);
+		A[0] ^= RC[i];
+	}
+}
diff --git a/pkgtools/pkg_install/files/lib/keccak.h b/pkgtools/pkg_install/files/lib/keccak.h
new file mode 100644
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/keccak.h
@@ -0,0 +1,34 @@
+/*-
+ * Copyright (c) 2015 Taylor R. Campbell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef	KECCAK_H
+#define	KECCAK_H
+
+#include &lt;stdint.h&gt;
+
+void	keccakf1600(uint64_t A[25]);
+
+#endif	/* KECCAK_H */
diff --git a/pkgtools/pkg_install/files/lib/lib.h b/pkgtools/pkg_install/files/lib/lib.h
--- a/pkgtools/pkg_install/files/lib/lib.h
+++ b/pkgtools/pkg_install/files/lib/lib.h
@@ -196,23 +196,27 @@ typedef struct plist_t {
 
 /* This structure describes a package's complete packing list */
 typedef struct package_t {
 	plist_t *head;		/* head of list */
 	plist_t *tail;		/* tail of list */
 }       package_t;
 
 #define SYMLINK_HEADER	"Symlink:"
-#define CHECKSUM_HEADER	"MD5:"
+#define MD5_CHECKSUM_HEADER	"MD5:"
+#define COMBO_CHECKSUM_HEADER	"SHA3_512+SHA512:"
 
 enum {
-	ChecksumHeaderLen = 4,	/* strlen(CHECKSUM_HEADER) */
-	SymlinkHeaderLen = 8,	/* strlen(SYMLINK_HEADER) */
-	ChecksumLen = 16,
-	LegibleChecksumLen = 33
+	MD5ChecksumHeaderLen = 4,	/* strlen(MD5_CHECKSUM_HEADER) */
+	ComboChecksumHeaderLen = 16,	/* strlen(COMBO_CHECKSUM_HEADER) */
+	SymlinkHeaderLen = 8,		/* strlen(SYMLINK_HEADER) */
+	MD5ChecksumLen = 16,
+	ComboChecksumLen = 64+64,
+	LegibleMD5ChecksumLen = ((MD5ChecksumLen * 2) + 1),
+	LegibleComboChecksumLen = ((ComboChecksumLen * 2) + 1)
 };
 
 /* List of files */
 typedef struct _lfile_t {
         TAILQ_ENTRY(_lfile_t) lf_link;
         char *lf_name;
 } lfile_t;
 TAILQ_HEAD(_lfile_head_t, _lfile_t);
@@ -396,16 +400,19 @@ int easy_pkcs7_verify(const char *, size
 int easy_pkcs7_sign(const char *, size_t, char **, size_t *, const char *,
     const char *);
 #endif
 
 int gpg_verify(const char *, size_t, const char *, const char *, size_t);
 int detached_gpg_sign(const char *, size_t, char **, size_t *, const char *,
     const char *);
 
+/* digest stuff */
+char *combo_digest_file(const char */*file*/, char */*buf*/);
+
 /* License handling */
 int add_licenses(const char *);
 int acceptable_license(const char *);
 int acceptable_pkg_license(const char *);
 void load_license_lists(void);
 
 /* Helper functions for memory allocation */
 char *xstrdup(const char *);
diff --git a/pkgtools/pkg_install/files/lib/plist.c b/pkgtools/pkg_install/files/lib/plist.c
--- a/pkgtools/pkg_install/files/lib/plist.c
+++ b/pkgtools/pkg_install/files/lib/plist.c
@@ -62,20 +62,24 @@
 #if HAVE_ERRNO_H
 #include &lt;errno.h&gt;
 #endif
 #if HAVE_ERR_H
 #include &lt;err.h&gt;
 #endif
 #ifndef NETBSD
 #include &lt;nbcompat/md5.h&gt;
+#include &lt;nbcompat/sha2.h&gt;
 #else
 #include &lt;md5.h&gt;
+#include &lt;sha2.h&gt;
 #endif
 
+#include "sha3.h"
+
 static int     delete_with_parents(const char *, Boolean, Boolean);
 
 /* This struct defines a plist command type */
 typedef struct cmd_t {
 	const char   *c_s;		/* string to recognise */
 	pl_ent_t c_type;	/* type of command */
 	int     c_argc;		/* # of arguments */
 	int     c_subst;	/* can substitute real prefix */
@@ -98,16 +102,37 @@ static const cmd_t cmdv[] = {
 	{"pkgcfl", PLIST_PKGCFL, 1, 0},
 	{"pkgdir", PLIST_PKGDIR, 1, 0},
 	{"dirrm", PLIST_DIR_RM, 1, 0},
 	{"option", PLIST_OPTION, 1, 0},
 	{"blddep", PLIST_BLDDEP, 1, 0},
 	{NULL, FAIL, 0, 0}
 };
 
+/* calculate a combined SHA3_512 and SHA512 digest on the file */
+char *
+combo_digest_file(const char *file, char *buf)
+{
+	int	allocated;
+
+	allocated = 0;
+	if (buf == NULL) {
+		buf = calloc(1, LegibleComboChecksumLen);
+		allocated = 1;
+	}
+	if (SHA3_512_File(file, buf) == NULL ||
+	    SHA512_File(file, &amp;buf[ComboChecksumLen]) == NULL) {
+		if (allocated) {
+			free(buf);
+		}
+		return NULL;
+	}
+	return buf;
+}
+
 /*
  * Add an item to the end of a packing list
  */
 void
 add_plist(package_t *p, pl_ent_t type, const char *arg)
 {
 	plist_t *tmp;
 
@@ -595,30 +620,44 @@ delete_package(Boolean ign_err, package_
 			    prefix, p-&gt;name);
 			if (isdir(tmp)) {
 				warnx("attempting to delete directory `%s' as a file\n"
 				    "this packing list is incorrect - ignoring delete request", tmp);
 			} else {
 				int     restored = 0;	/* restored from preserve? */
 
 				if (p-&gt;next &amp;&amp; p-&gt;next-&gt;type == PLIST_COMMENT) {
-					if (strncmp(p-&gt;next-&gt;name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) {
-						char   *cp, buf[LegibleChecksumLen];
+					if (strncmp(p-&gt;next-&gt;name, MD5_CHECKSUM_HEADER, MD5ChecksumHeaderLen) == 0) {
+						char   *cp, buf[LegibleMD5ChecksumLen];
 
 						if ((cp = MD5File(tmp, buf)) != NULL) {
 							/* Mismatch? */
-							if (strcmp(cp, p-&gt;next-&gt;name + ChecksumHeaderLen) != 0) {
+							if (strcmp(cp, p-&gt;next-&gt;name + MD5ChecksumHeaderLen) != 0) {
 								printf("original MD5 checksum failed, %s: %s\n",
 								    Force ? "deleting anyway" : "not deleting", tmp);
 								if (!Force) {
 									fail = FAIL;
 									goto pkgdb_cleanup;
 								}
 							}
 						}
+					} else if (strncmp(p-&gt;next-&gt;name, COMBO_CHECKSUM_HEADER, ComboChecksumHeaderLen) == 0) {
+						char   *cp, buf[LegibleComboChecksumLen];
+
+						if ((cp = combo_digest_file(tmp, buf)) != NULL) {
+							/* Mismatch? */
+							if (strcmp(cp, p-&gt;next-&gt;name + ComboChecksumHeaderLen) != 0) {
+								printf("original combo checksum failed, %s: %s\n",
+								    Force ? "deleting anyway" : "not deleting", tmp);
+								if (!Force) {
+									fail = FAIL;
+									goto pkgdb_cleanup;
+								}
+							}
+						}
 					} else if (strncmp(p-&gt;next-&gt;name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) {
 						char	buf[MaxPathSize + SymlinkHeaderLen];
 						int	cc;
 
 						(void) strlcpy(buf, SYMLINK_HEADER,
 						    sizeof(buf));
 						if ((cc = readlink(tmp, &amp;buf[SymlinkHeaderLen],
 							  sizeof(buf) - SymlinkHeaderLen - 1)) &lt; 0) {
diff --git a/pkgtools/pkg_install/files/lib/sha3.c b/pkgtools/pkg_install/files/lib/sha3.c
new file mode 100644
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/sha3.c
@@ -0,0 +1,638 @@
+/*-
+ * Copyright (c) 2015 Taylor R. Campbell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * SHA-3: FIPS-202, Permutation-Based Hash and Extendable-Ouptut Functions
+ */
+
+#define	_POSIX_C_SOURCE	200809L
+
+#include &lt;assert.h&gt;
+#include &lt;stddef.h&gt;
+#include &lt;stdint.h&gt;
+#include &lt;string.h&gt;
+
+#include "keccak.h"
+
+#include "sha3.h"
+
+#define	MIN(a,b)	((a) &lt; (b) ? (a) : (b))
+
+void *(*volatile sha3_explicit_memset_impl)(void *, int, size_t) = &amp;memset;
+static void *
+explicit_memset(void *buf, int c, size_t n)
+{
+
+	return (*sha3_explicit_memset_impl)(buf, c, n);
+}
+
+static inline uint64_t
+le64dec(const void *buf)
+{
+	const uint8_t *p = buf;
+
+	return (((uint64_t)p[0]) |
+	    ((uint64_t)p[1] &lt;&lt; 8) |
+	    ((uint64_t)p[2] &lt;&lt; 16) |
+	    ((uint64_t)p[3] &lt;&lt; 24) |
+	    ((uint64_t)p[4] &lt;&lt; 32) |
+	    ((uint64_t)p[5] &lt;&lt; 40) |
+	    ((uint64_t)p[6] &lt;&lt; 48) |
+	    ((uint64_t)p[7] &lt;&lt; 56));
+}
+
+static inline void
+le64enc(void *buf, uint64_t v)
+{
+	uint8_t *p = buf;
+
+	*p++ = v; v &gt;&gt;= 8;
+	*p++ = v; v &gt;&gt;= 8;
+	*p++ = v; v &gt;&gt;= 8;
+	*p++ = v; v &gt;&gt;= 8;
+	*p++ = v; v &gt;&gt;= 8;
+	*p++ = v; v &gt;&gt;= 8;
+	*p++ = v; v &gt;&gt;= 8;
+	*p++ = v;
+}
+
+/*
+ * Common body.  All the SHA-3 functions share code structure.  They
+ * differ only in the size of the chunks they split the message into:
+ * for digest size d, they are split into chunks of 200 - d bytes.
+ */
+
+static inline unsigned
+sha3_rate(unsigned d)
+{
+	const unsigned cw = 2*d/8;	/* capacity in words */
+
+	return 25 - cw;
+}
+
+static void
+sha3_init(struct sha3 *C, unsigned rw)
+{
+	unsigned iw;
+
+	C-&gt;nb = 8*rw;
+	for (iw = 0; iw &lt; 25; iw++)
+		C-&gt;A[iw] = 0;
+}
+
+static void
+sha3_update(struct sha3 *C, const uint8_t *data, size_t len, unsigned rw)
+{
+	uint64_t T;
+	unsigned ib, iw;		/* index of byte/word */
+
+	assert(0 &lt; C-&gt;nb);
+
+	/* If there's a partial word, try to fill it.  */
+	if ((C-&gt;nb % 8) != 0) {
+		T = 0;
+		for (ib = 0; ib &lt; MIN(len, C-&gt;nb % 8); ib++)
+			T |= (uint64_t)data[ib] &lt;&lt; (8*ib);
+		C-&gt;A[rw - (C-&gt;nb + 7)/8] ^= T &lt;&lt; (8*(8 - (C-&gt;nb % 8)));
+		C-&gt;nb -= ib;
+		data += ib;
+		len -= ib;
+
+		/* If we filled the buffer, permute now.  */
+		if (C-&gt;nb == 0) {
+			keccakf1600(C-&gt;A);
+			C-&gt;nb = 8*rw;
+		}
+
+		/* If that exhausted the input, we're done.  */
+		if (len == 0)
+			return;
+	}
+
+	/* At a word boundary.  Fill any partial buffer.  */
+	assert((C-&gt;nb % 8) == 0);
+	if (C-&gt;nb &lt; 8*rw) {
+		for (iw = 0; iw &lt; MIN(len, C-&gt;nb)/8; iw++)
+			C-&gt;A[rw - C-&gt;nb/8 + iw] ^= le64dec(data + 8*iw);
+		C-&gt;nb -= 8*iw;
+		data += 8*iw;
+		len -= 8*iw;
+
+		/* If we filled the buffer, permute now.  */
+		if (C-&gt;nb == 0) {
+			keccakf1600(C-&gt;A);
+			C-&gt;nb = 8*rw;
+		} else {
+			/* Otherwise, less than a word left.  */
+			assert(len &lt; 8);
+			goto partial;
+		}
+	}
+
+	/* At a buffer boundary.  Absorb input one buffer at a time.  */
+	assert(C-&gt;nb == 8*rw);
+	while (8*rw &lt;= len) {
+		for (iw = 0; iw &lt; rw; iw++)
+			C-&gt;A[iw] ^= le64dec(data + 8*iw);
+		keccakf1600(C-&gt;A);
+		data += 8*rw;
+		len -= 8*rw;
+	}
+
+	/* Partially fill the buffer with as many words as we can.  */
+	for (iw = 0; iw &lt; len/8; iw++)
+		C-&gt;A[rw - C-&gt;nb/8 + iw] ^= le64dec(data + 8*iw);
+	C-&gt;nb -= 8*iw;
+	data += 8*iw;
+	len -= 8*iw;
+
+partial:
+	/* Partially fill the last word with as many bytes as we can.  */
+	assert(len &lt; 8);
+	assert(0 &lt; C-&gt;nb);
+	assert((C-&gt;nb % 8) == 0);
+	T = 0;
+	for (ib = 0; ib &lt; len; ib++)
+		T |= (uint64_t)data[ib] &lt;&lt; (8*ib);
+	C-&gt;A[rw - C-&gt;nb/8] ^= T;
+	C-&gt;nb -= ib;
+	assert(0 &lt; C-&gt;nb);
+}
+
+static void
+sha3_final(uint8_t *h, unsigned d, struct sha3 *C, unsigned rw)
+{
+	unsigned nw, iw;
+
+	assert(d &lt;= 8*25);
+	assert(0 &lt; C-&gt;nb);
+
+	/* Append 01, pad with 10*1 up to buffer boundary, LSB first.  */
+	nw = (C-&gt;nb + 7)/8;
+	assert(0 &lt; nw);
+	assert(nw &lt;= rw);
+	C-&gt;A[rw - nw] ^= (uint64_t)0x06 &lt;&lt; (8*(8*nw - C-&gt;nb));
+	C-&gt;A[rw - 1] ^= 0x8000000000000000ULL;
+
+	/* Permute one last time.  */
+	keccakf1600(C-&gt;A);
+
+	/* Reveal the first 8d bits of state, forget 1600-8d of them.  */
+	for (iw = 0; iw &lt; d/8; iw++)
+		le64enc(h + 8*iw, C-&gt;A[iw]);
+	h += 8*iw;
+	d -= 8*iw;
+	if (0 &lt; d) {
+		/* For SHA3-224, we need to expose a partial word.  */
+		uint64_t T = C-&gt;A[iw];
+		do {
+			*h++ = T &amp; 0xff;
+			T &gt;&gt;= 8;
+		} while (--d);
+	}
+	(void)explicit_memset(C-&gt;A, 0, sizeof C-&gt;A);
+	C-&gt;nb = 0;
+}
+
+static void
+shake_final(uint8_t *h, unsigned d, struct sha3 *C, unsigned rw)
+{
+	unsigned nw, iw;
+
+	assert(0 &lt; C-&gt;nb);
+
+	/* Append 1111, pad with 10*1 up to buffer boundary, LSB first.  */
+	nw = (C-&gt;nb + 7)/8;
+	assert(0 &lt; nw);
+	assert(nw &lt;= rw);
+	C-&gt;A[rw - nw] ^= (uint64_t)0x1f &lt;&lt; (8*(8*nw - C-&gt;nb));
+	C-&gt;A[rw - 1] ^= 0x8000000000000000ULL;
+
+	/* Permute, reveal first rw words of state, repeat.  */
+	while (8*rw &lt;= d) {
+		keccakf1600(C-&gt;A);
+		for (iw = 0; iw &lt; rw; iw++)
+			le64enc(h + 8*iw, C-&gt;A[iw]);
+		h += 8*iw;
+		d -= 8*iw;
+	}
+
+	/*
+	 * If 8*rw (the output rate in bytes) does not divide d, more
+	 * words are wanted: permute again and reveal a little more.
+	 */
+	if (0 &lt; d) {
+		keccakf1600(C-&gt;A);
+		for (iw = 0; iw &lt; d/8; iw++)
+			le64enc(h + 8*iw, C-&gt;A[iw]);
+		h += 8*iw;
+		d -= 8*iw;
+
+		/*
+		 * If 8 does not divide d, more bytes are wanted:
+		 * reveal them.
+		 */
+		if (0 &lt; d) {
+			uint64_t T = C-&gt;A[iw];
+			do {
+				*h++ = T &amp; 0xff;
+				T &gt;&gt;= 8;
+			} while (--d);
+		}
+	}
+
+	(void)explicit_memset(C-&gt;A, 0, sizeof C-&gt;A);
+	C-&gt;nb = 0;
+}
+
+void
+SHA3_224_Init(SHA3_224_CTX *C)
+{
+
+	sha3_init(&amp;C-&gt;C224, sha3_rate(SHA3_224_DIGEST_LENGTH));
+}
+
+void
+SHA3_224_Update(SHA3_224_CTX *C, const uint8_t *data, size_t len)
+{
+
+	sha3_update(&amp;C-&gt;C224, data, len, sha3_rate(SHA3_224_DIGEST_LENGTH));
+}
+
+void
+SHA3_224_Final(uint8_t h[SHA3_224_DIGEST_LENGTH], SHA3_224_CTX *C)
+{
+
+	sha3_final(h, SHA3_224_DIGEST_LENGTH, &amp;C-&gt;C224,
+	    sha3_rate(SHA3_224_DIGEST_LENGTH));
+}
+
+void
+SHA3_256_Init(SHA3_256_CTX *C)
+{
+
+	sha3_init(&amp;C-&gt;C256, sha3_rate(SHA3_256_DIGEST_LENGTH));
+}
+
+void
+SHA3_256_Update(SHA3_256_CTX *C, const uint8_t *data, size_t len)
+{
+
+	sha3_update(&amp;C-&gt;C256, data, len, sha3_rate(SHA3_256_DIGEST_LENGTH));
+}
+
+void
+SHA3_256_Final(uint8_t h[SHA3_256_DIGEST_LENGTH], SHA3_256_CTX *C)
+{
+
+	sha3_final(h, SHA3_256_DIGEST_LENGTH, &amp;C-&gt;C256,
+	    sha3_rate(SHA3_256_DIGEST_LENGTH));
+}
+
+void
+SHA3_384_Init(SHA3_384_CTX *C)
+{
+
+	sha3_init(&amp;C-&gt;C384, sha3_rate(SHA3_384_DIGEST_LENGTH));
+}
+
+void
+SHA3_384_Update(SHA3_384_CTX *C, const uint8_t *data, size_t len)
+{
+
+	sha3_update(&amp;C-&gt;C384, data, len, sha3_rate(SHA3_384_DIGEST_LENGTH));
+}
+
+void
+SHA3_384_Final(uint8_t h[SHA3_384_DIGEST_LENGTH], SHA3_384_CTX *C)
+{
+
+	sha3_final(h, SHA3_384_DIGEST_LENGTH, &amp;C-&gt;C384,
+	    sha3_rate(SHA3_384_DIGEST_LENGTH));
+}
+
+void
+SHA3_512_Init(SHA3_512_CTX *C)
+{
+
+	sha3_init(&amp;C-&gt;C512, sha3_rate(SHA3_512_DIGEST_LENGTH));
+}
+
+void
+SHA3_512_Update(SHA3_512_CTX *C, const uint8_t *data, size_t len)
+{
+
+	sha3_update(&amp;C-&gt;C512, data, len, sha3_rate(SHA3_512_DIGEST_LENGTH));
+}
+
+void
+SHA3_512_Final(uint8_t h[SHA3_512_DIGEST_LENGTH], SHA3_512_CTX *C)
+{
+
+	sha3_final(h, SHA3_512_DIGEST_LENGTH, &amp;C-&gt;C512,
+	    sha3_rate(SHA3_512_DIGEST_LENGTH));
+}
+
+void
+SHAKE128_Init(SHAKE128_CTX *C)
+{
+
+	sha3_init(&amp;C-&gt;C128, sha3_rate(128/8));
+}
+
+void
+SHAKE128_Update(SHAKE128_CTX *C, const uint8_t *data, size_t len)
+{
+
+	sha3_update(&amp;C-&gt;C128, data, len, sha3_rate(128/8));
+}
+
+void
+SHAKE128_Final(uint8_t *h, size_t d, SHAKE128_CTX *C)
+{
+
+	shake_final(h, d, &amp;C-&gt;C128, sha3_rate(128/8));
+}
+
+void
+SHAKE256_Init(SHAKE256_CTX *C)
+{
+
+	sha3_init(&amp;C-&gt;C256, sha3_rate(256/8));
+}
+
+void
+SHAKE256_Update(SHAKE256_CTX *C, const uint8_t *data, size_t len)
+{
+
+	sha3_update(&amp;C-&gt;C256, data, len, sha3_rate(256/8));
+}
+
+void
+SHAKE256_Final(uint8_t *h, size_t d, SHAKE256_CTX *C)
+{
+
+	shake_final(h, d, &amp;C-&gt;C256, sha3_rate(256/8));
+}
+
+static void
+sha3_selftest_prng(void *buf, size_t len, uint32_t seed)
+{
+	uint8_t *p = buf;
+	size_t n = len;
+	uint32_t t, a, b;
+
+	a = 0xdead4bad * seed;
+	b = 1;
+
+	while (n--) {
+		t = a + b;
+		*p++ = t &gt;&gt; 24;
+		a = b;
+		b = t;
+	}
+}
+
+int
+SHA3_Selftest(void)
+{
+	const uint8_t d224_0[] = { /* SHA3-224(0-bit) */
+		0x6b,0x4e,0x03,0x42,0x36,0x67,0xdb,0xb7,
+		0x3b,0x6e,0x15,0x45,0x4f,0x0e,0xb1,0xab,
+		0xd4,0x59,0x7f,0x9a,0x1b,0x07,0x8e,0x3f,
+		0x5b,0x5a,0x6b,0xc7,
+	};
+	const uint8_t d256_0[] = { /* SHA3-256(0-bit) */
+		0xa7,0xff,0xc6,0xf8,0xbf,0x1e,0xd7,0x66,
+		0x51,0xc1,0x47,0x56,0xa0,0x61,0xd6,0x62,
+		0xf5,0x80,0xff,0x4d,0xe4,0x3b,0x49,0xfa,
+		0x82,0xd8,0x0a,0x4b,0x80,0xf8,0x43,0x4a,
+	};
+	const uint8_t d384_0[] = { /* SHA3-384(0-bit) */
+		0x0c,0x63,0xa7,0x5b,0x84,0x5e,0x4f,0x7d,
+		0x01,0x10,0x7d,0x85,0x2e,0x4c,0x24,0x85,
+		0xc5,0x1a,0x50,0xaa,0xaa,0x94,0xfc,0x61,
+		0x99,0x5e,0x71,0xbb,0xee,0x98,0x3a,0x2a,
+		0xc3,0x71,0x38,0x31,0x26,0x4a,0xdb,0x47,
+		0xfb,0x6b,0xd1,0xe0,0x58,0xd5,0xf0,0x04,
+	};
+	const uint8_t d512_0[] = { /* SHA3-512(0-bit) */
+		0xa6,0x9f,0x73,0xcc,0xa2,0x3a,0x9a,0xc5,
+		0xc8,0xb5,0x67,0xdc,0x18,0x5a,0x75,0x6e,
+		0x97,0xc9,0x82,0x16,0x4f,0xe2,0x58,0x59,
+		0xe0,0xd1,0xdc,0xc1,0x47,0x5c,0x80,0xa6,
+		0x15,0xb2,0x12,0x3a,0xf1,0xf5,0xf9,0x4c,
+		0x11,0xe3,0xe9,0x40,0x2c,0x3a,0xc5,0x58,
+		0xf5,0x00,0x19,0x9d,0x95,0xb6,0xd3,0xe3,
+		0x01,0x75,0x85,0x86,0x28,0x1d,0xcd,0x26,
+	};
+	const uint8_t shake128_0_41[] = { /* SHAKE128(0-bit, 41) */
+		0x7f,0x9c,0x2b,0xa4,0xe8,0x8f,0x82,0x7d,
+		0x61,0x60,0x45,0x50,0x76,0x05,0x85,0x3e,
+		0xd7,0x3b,0x80,0x93,0xf6,0xef,0xbc,0x88,
+		0xeb,0x1a,0x6e,0xac,0xfa,0x66,0xef,0x26,
+		0x3c,0xb1,0xee,0xa9,0x88,0x00,0x4b,0x93,0x10,
+	};
+	const uint8_t shake256_0_73[] = { /* SHAKE256(0-bit, 73) */
+		0x46,0xb9,0xdd,0x2b,0x0b,0xa8,0x8d,0x13,
+		0x23,0x3b,0x3f,0xeb,0x74,0x3e,0xeb,0x24,
+		0x3f,0xcd,0x52,0xea,0x62,0xb8,0x1b,0x82,
+		0xb5,0x0c,0x27,0x64,0x6e,0xd5,0x76,0x2f,
+		0xd7,0x5d,0xc4,0xdd,0xd8,0xc0,0xf2,0x00,
+		0xcb,0x05,0x01,0x9d,0x67,0xb5,0x92,0xf6,
+		0xfc,0x82,0x1c,0x49,0x47,0x9a,0xb4,0x86,
+		0x40,0x29,0x2e,0xac,0xb3,0xb7,0xc4,0xbe,
+		0x14,0x1e,0x96,0x61,0x6f,0xb1,0x39,0x57,0x69,
+	};
+	const uint8_t d224_1600[] = { /* SHA3-224(200 * 0xa3) */
+		0x93,0x76,0x81,0x6a,0xba,0x50,0x3f,0x72,
+		0xf9,0x6c,0xe7,0xeb,0x65,0xac,0x09,0x5d,
+		0xee,0xe3,0xbe,0x4b,0xf9,0xbb,0xc2,0xa1,
+		0xcb,0x7e,0x11,0xe0,
+	};
+	const uint8_t d256_1600[] = { /* SHA3-256(200 * 0xa3) */
+		0x79,0xf3,0x8a,0xde,0xc5,0xc2,0x03,0x07,
+		0xa9,0x8e,0xf7,0x6e,0x83,0x24,0xaf,0xbf,
+		0xd4,0x6c,0xfd,0x81,0xb2,0x2e,0x39,0x73,
+		0xc6,0x5f,0xa1,0xbd,0x9d,0xe3,0x17,0x87,
+	};
+	const uint8_t d384_1600[] = { /* SHA3-384(200 * 0xa3) */
+		0x18,0x81,0xde,0x2c,0xa7,0xe4,0x1e,0xf9,
+		0x5d,0xc4,0x73,0x2b,0x8f,0x5f,0x00,0x2b,
+		0x18,0x9c,0xc1,0xe4,0x2b,0x74,0x16,0x8e,
+		0xd1,0x73,0x26,0x49,0xce,0x1d,0xbc,0xdd,
+		0x76,0x19,0x7a,0x31,0xfd,0x55,0xee,0x98,
+		0x9f,0x2d,0x70,0x50,0xdd,0x47,0x3e,0x8f,
+	};
+	const uint8_t d512_1600[] = { /* SHA3-512(200 * 0xa3) */
+		0xe7,0x6d,0xfa,0xd2,0x20,0x84,0xa8,0xb1,
+		0x46,0x7f,0xcf,0x2f,0xfa,0x58,0x36,0x1b,
+		0xec,0x76,0x28,0xed,0xf5,0xf3,0xfd,0xc0,
+		0xe4,0x80,0x5d,0xc4,0x8c,0xae,0xec,0xa8,
+		0x1b,0x7c,0x13,0xc3,0x0a,0xdf,0x52,0xa3,
+		0x65,0x95,0x84,0x73,0x9a,0x2d,0xf4,0x6b,
+		0xe5,0x89,0xc5,0x1c,0xa1,0xa4,0xa8,0x41,
+		0x6d,0xf6,0x54,0x5a,0x1c,0xe8,0xba,0x00,
+	};
+	const uint8_t shake128_1600_41[] = { /* SHAKE128(200 * 0xa3, 41) */
+		0x13,0x1a,0xb8,0xd2,0xb5,0x94,0x94,0x6b,
+		0x9c,0x81,0x33,0x3f,0x9b,0xb6,0xe0,0xce,
+		0x75,0xc3,0xb9,0x31,0x04,0xfa,0x34,0x69,
+		0xd3,0x91,0x74,0x57,0x38,0x5d,0xa0,0x37,
+		0xcf,0x23,0x2e,0xf7,0x16,0x4a,0x6d,0x1e,0xb4,
+	};
+	const uint8_t shake256_1600_73[] = { /* SHAKE256(200 * 0xa3, 73) */
+		0xcd,0x8a,0x92,0x0e,0xd1,0x41,0xaa,0x04,
+		0x07,0xa2,0x2d,0x59,0x28,0x86,0x52,0xe9,
+		0xd9,0xf1,0xa7,0xee,0x0c,0x1e,0x7c,0x1c,
+		0xa6,0x99,0x42,0x4d,0xa8,0x4a,0x90,0x4d,
+		0x2d,0x70,0x0c,0xaa,0xe7,0x39,0x6e,0xce,
+		0x96,0x60,0x44,0x40,0x57,0x7d,0xa4,0xf3,
+		0xaa,0x22,0xae,0xb8,0x85,0x7f,0x96,0x1c,
+		0x4c,0xd8,0xe0,0x6f,0x0a,0xe6,0x61,0x0b,
+		0x10,0x48,0xa7,0xf6,0x4e,0x10,0x74,0xcd,0x62,
+	};
+	const uint8_t d0[] = {
+		0x6c,0x02,0x1a,0xc6,0x65,0xaf,0x80,0xfb,
+		0x52,0xe6,0x2d,0x27,0xe5,0x02,0x88,0x84,
+		0xec,0x1c,0x0c,0xe7,0x0b,0x94,0x55,0x83,
+		0x19,0xf2,0xbf,0x09,0x86,0xeb,0x1a,0xbb,
+		0xc3,0x0d,0x1c,0xef,0x22,0xfe,0xc5,0x4c,
+		0x45,0x90,0x66,0x14,0x00,0x6e,0xc8,0x79,
+		0xdf,0x1e,0x02,0xbd,0x75,0xe9,0x60,0xd8,
+		0x60,0x39,0x85,0xc9,0xc4,0xee,0x33,0xab,
+	};
+	const unsigned mlen[6] = { 0, 3, 128, 129, 255, 1024 };
+	uint8_t m[1024], d[73];
+	SHA3_224_CTX sha3224;
+	SHA3_256_CTX sha3256;
+	SHA3_384_CTX sha3384;
+	SHA3_512_CTX sha3512;
+	SHAKE128_CTX shake128;
+	SHAKE256_CTX shake256;
+	SHA3_512_CTX ctx;
+	unsigned mi;
+
+	/*
+	 * NIST test vectors from
+	 * &lt;http://csrc.nist.gov/groups/ST/toolkit/examples.html#aHashing&gt;:
+	 * 0-bit, 1600-bit repeated 0xa3 (= 0b10100011).
+	 */
+	SHA3_224_Init(&amp;sha3224);
+	SHA3_224_Final(d, &amp;sha3224);
+	if (memcmp(d, d224_0, 28) != 0)
+		return -1;
+	SHA3_256_Init(&amp;sha3256);
+	SHA3_256_Final(d, &amp;sha3256);
+	if (memcmp(d, d256_0, 32) != 0)
+		return -1;
+	SHA3_384_Init(&amp;sha3384);
+	SHA3_384_Final(d, &amp;sha3384);
+	if (memcmp(d, d384_0, 48) != 0)
+		return -1;
+	SHA3_512_Init(&amp;sha3512);
+	SHA3_512_Final(d, &amp;sha3512);
+	if (memcmp(d, d512_0, 64) != 0)
+		return -1;
+	SHAKE128_Init(&amp;shake128);
+	SHAKE128_Final(d, 41, &amp;shake128);
+	if (memcmp(d, shake128_0_41, 41) != 0)
+		return -1;
+	SHAKE256_Init(&amp;shake256);
+	SHAKE256_Final(d, 73, &amp;shake256);
+	if (memcmp(d, shake256_0_73, 73) != 0)
+		return -1;
+
+	(void)memset(m, 0xa3, 200);
+	SHA3_224_Init(&amp;sha3224);
+	SHA3_224_Update(&amp;sha3224, m, 200);
+	SHA3_224_Final(d, &amp;sha3224);
+	if (memcmp(d, d224_1600, 28) != 0)
+		return -1;
+	SHA3_256_Init(&amp;sha3256);
+	SHA3_256_Update(&amp;sha3256, m, 200);
+	SHA3_256_Final(d, &amp;sha3256);
+	if (memcmp(d, d256_1600, 32) != 0)
+		return -1;
+	SHA3_384_Init(&amp;sha3384);
+	SHA3_384_Update(&amp;sha3384, m, 200);
+	SHA3_384_Final(d, &amp;sha3384);
+	if (memcmp(d, d384_1600, 48) != 0)
+		return -1;
+	SHA3_512_Init(&amp;sha3512);
+	SHA3_512_Update(&amp;sha3512, m, 200);
+	SHA3_512_Final(d, &amp;sha3512);
+	if (memcmp(d, d512_1600, 64) != 0)
+		return -1;
+	SHAKE128_Init(&amp;shake128);
+	SHAKE128_Update(&amp;shake128, m, 200);
+	SHAKE128_Final(d, 41, &amp;shake128);
+	if (memcmp(d, shake128_1600_41, 41) != 0)
+		return -1;
+	SHAKE256_Init(&amp;shake256);
+	SHAKE256_Update(&amp;shake256, m, 200);
+	SHAKE256_Final(d, 73, &amp;shake256);
+	if (memcmp(d, shake256_1600_73, 73) != 0)
+		return -1;
+
+	/*
+	 * Hand-crufted test vectors with unaligned message lengths.
+	 */
+	SHA3_512_Init(&amp;ctx);
+	for (mi = 0; mi &lt; 6; mi++) {
+		sha3_selftest_prng(m, mlen[mi], (224/8)*mlen[mi]);
+		SHA3_224_Init(&amp;sha3224);
+		SHA3_224_Update(&amp;sha3224, m, mlen[mi]);
+		SHA3_224_Final(d, &amp;sha3224);
+		SHA3_512_Update(&amp;ctx, d, 224/8);
+	}
+	for (mi = 0; mi &lt; 6; mi++) {
+		sha3_selftest_prng(m, mlen[mi], (256/8)*mlen[mi]);
+		SHA3_256_Init(&amp;sha3256);
+		SHA3_256_Update(&amp;sha3256, m, mlen[mi]);
+		SHA3_256_Final(d, &amp;sha3256);
+		SHA3_512_Update(&amp;ctx, d, 256/8);
+	}
+	for (mi = 0; mi &lt; 6; mi++) {
+		sha3_selftest_prng(m, mlen[mi], (384/8)*mlen[mi]);
+		SHA3_384_Init(&amp;sha3384);
+		SHA3_384_Update(&amp;sha3384, m, mlen[mi]);
+		SHA3_384_Final(d, &amp;sha3384);
+		SHA3_512_Update(&amp;ctx, d, 384/8);
+	}
+	for (mi = 0; mi &lt; 6; mi++) {
+		sha3_selftest_prng(m, mlen[mi], (512/8)*mlen[mi]);
+		SHA3_512_Init(&amp;sha3512);
+		SHA3_512_Update(&amp;sha3512, m, mlen[mi]);
+		SHA3_512_Final(d, &amp;sha3512);
+		SHA3_512_Update(&amp;ctx, d, 512/8);
+	}
+	SHA3_512_Final(d, &amp;ctx);
+	if (memcmp(d, d0, 64) != 0)
+		return -1;
+
+	return 0;
+}
diff --git a/pkgtools/pkg_install/files/lib/sha3.h b/pkgtools/pkg_install/files/lib/sha3.h
new file mode 100644
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/sha3.h
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2015 Taylor R. Campbell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef	SHA3_H
+#define	SHA3_H
+
+#include &lt;stddef.h&gt;
+#include &lt;stdint.h&gt;
+
+struct sha3 {
+	uint64_t A[25];
+	unsigned nb;		/* number of bytes remaining to fill buffer */
+};
+
+typedef struct { struct sha3 C224; } SHA3_224_CTX;
+typedef struct { struct sha3 C256; } SHA3_256_CTX;
+typedef struct { struct sha3 C384; } SHA3_384_CTX;
+typedef struct { struct sha3 C512; } SHA3_512_CTX;
+typedef struct { struct sha3 C128; } SHAKE128_CTX;
+typedef struct { struct sha3 C256; } SHAKE256_CTX;
+
+#define	SHA3_224_DIGEST_LENGTH	28
+#define	SHA3_256_DIGEST_LENGTH	32
+#define	SHA3_384_DIGEST_LENGTH	48
+#define	SHA3_512_DIGEST_LENGTH	64
+
+#define	SHA3_224_DIGEST_STRING_LENGTH	((2 * SHA3_224_DIGEST_LENGTH) + 1)
+#define	SHA3_256_DIGEST_STRING_LENGTH	((2 * SHA3_256_DIGEST_LENGTH) + 1)
+#define	SHA3_384_DIGEST_STRING_LENGTH	((2 * SHA3_384_DIGEST_LENGTH) + 1)
+#define	SHA3_512_DIGEST_STRING_LENGTH	((2 * SHA3_512_DIGEST_LENGTH) + 1)
+
+#ifndef __BEGIN_DECLS
+#  if defined(__cplusplus)
+#  define __BEGIN_DECLS           extern "C" {
+#  define __END_DECLS             }
+#  else
+#  define __BEGIN_DECLS
+#  define __END_DECLS
+#  endif
+#endif
+
+__BEGIN_DECLS
+
+#define	SHA3_224_Init	nbcompat_SHA3_224_Init
+#define	SHA3_224_Update	nbcompat_SHA3_224_Update
+#define	SHA3_224_Final	nbcompat_SHA3_224_Final
+#define	SHA3_224_End	nbcompat_SHA3_224_End
+#define	SHA3_224_Data	nbcompat_SHA3_224_Data
+#define	SHA3_224_File	nbcompat_SHA3_224_File
+
+void	SHA3_224_Init(SHA3_224_CTX *);
+void	SHA3_224_Update(SHA3_224_CTX *, const uint8_t *, size_t);
+void	SHA3_224_Final(uint8_t[SHA3_224_DIGEST_LENGTH], SHA3_224_CTX *);
+
+#define	SHA3_256_Init	nbcompat_SHA3_256_Init
+#define	SHA3_256_Update	nbcompat_SHA3_256_Update
+#define	SHA3_256_Final	nbcompat_SHA3_256_Final
+#define	SHA3_256_End	nbcompat_SHA3_256_End
+#define	SHA3_256_Data	nbcompat_SHA3_256_Data
+#define	SHA3_256_File	nbcompat_SHA3_256_File
+
+void	SHA3_256_Init(SHA3_256_CTX *);
+void	SHA3_256_Update(SHA3_256_CTX *, const uint8_t *, size_t);
+void	SHA3_256_Final(uint8_t[SHA3_256_DIGEST_LENGTH], SHA3_256_CTX *);
+
+#define	SHA3_384_Init	nbcompat_SHA3_384_Init
+#define	SHA3_384_Update	nbcompat_SHA3_384_Update
+#define	SHA3_384_Final	nbcompat_SHA3_384_Final
+#define	SHA3_384_End	nbcompat_SHA3_384_End
+#define	SHA3_384_Data	nbcompat_SHA3_384_Data
+#define	SHA3_384_File	nbcompat_SHA3_384_File
+
+void	SHA3_384_Init(SHA3_384_CTX *);
+void	SHA3_384_Update(SHA3_384_CTX *, const uint8_t *, size_t);
+void	SHA3_384_Final(uint8_t[SHA3_384_DIGEST_LENGTH], SHA3_384_CTX *);
+
+#define	SHA3_512_Init	nbcompat_SHA3_512_Init
+#define	SHA3_512_Update	nbcompat_SHA3_512_Update
+#define	SHA3_512_Final	nbcompat_SHA3_512_Final
+#define	SHA3_512_End	nbcompat_SHA3_512_End
+#define	SHA3_512_Data	nbcompat_SHA3_512_Data
+#define	SHA3_512_File	nbcompat_SHA3_512_File
+
+void	SHA3_512_Init(SHA3_512_CTX *);
+void	SHA3_512_Update(SHA3_512_CTX *, const uint8_t *, size_t);
+void	SHA3_512_Final(uint8_t[SHA3_512_DIGEST_LENGTH], SHA3_512_CTX *);
+
+void	SHAKE128_Init(SHAKE128_CTX *);
+void	SHAKE128_Update(SHAKE128_CTX *, const uint8_t *, size_t);
+void	SHAKE128_Final(uint8_t *, size_t, SHAKE128_CTX *);
+
+void	SHAKE256_Init(SHAKE256_CTX *);
+void	SHAKE256_Update(SHAKE256_CTX *, const uint8_t *, size_t);
+void	SHAKE256_Final(uint8_t *, size_t, SHAKE256_CTX *);
+
+int	SHA3_Selftest(void);
+
+char *SHA3_224_End(SHA3_224_CTX*, char[SHA3_224_DIGEST_STRING_LENGTH]);
+char *SHA3_224_Data(const uint8_t*, size_t, unsigned char *);
+char *SHA3_224_File(char *, char *);
+
+char *SHA3_256_End(SHA3_256_CTX*, char[SHA3_256_DIGEST_STRING_LENGTH]);
+char *SHA3_256_Data(const uint8_t*, size_t, unsigned char *);
+char *SHA3_256_File(char *, char *);
+
+char *SHA3_384_End(SHA3_384_CTX*, char[SHA3_384_DIGEST_STRING_LENGTH]);
+char *SHA3_384_Data(const uint8_t*, size_t, unsigned char *);
+char *SHA3_384_File(char *, char *);
+
+char *SHA3_512_End(SHA3_512_CTX*, char[SHA3_512_DIGEST_STRING_LENGTH]);
+char *SHA3_512_Data(const uint8_t*, size_t, unsigned char *);
+char *SHA3_512_File(char *, char *);
+
+__END_DECLS
+
+#endif	/* SHA3_H */
diff --git a/pkgtools/pkg_install/files/lib/sha3hl.c b/pkgtools/pkg_install/files/lib/sha3hl.c
new file mode 100644
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/sha3hl.c
@@ -0,0 +1,316 @@
+/* $NetBSD: sha3hl.c,v 1.8 2011/11/08 18:20:03 joerg Exp $	 */
+
+/*
+ * sha3hl.c
+ * This code includes some functions taken from sha2.c, hence the
+ * following licence reproduction.
+ *
+ * This code is not a verbatim copy, since some routines have been added,
+ * and some bugs have been fixed.
+ *
+ * Version 1.0.0beta1
+ *
+ * Written by Aaron D. Gifford &lt;me@aarongifford.com&gt;
+ *
+ * Copyright 2000 Aaron D. Gifford.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include &lt;errno.h&gt;
+#endif
+#ifdef HAVE_FCNTL_H
+#include &lt;fcntl.h&gt;
+#endif
+#include "sha3.h"
+#include &lt;assert.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;unistd.h&gt;
+
+#ifndef _DIAGASSERT
+#define _DIAGASSERT(cond)	assert(cond)
+#endif
+
+#ifndef MEMSET_BZERO
+#define MEMSET_BZERO(p,l)	memset((p), 0, (l))
+#endif
+
+/*
+ * Constant used by SHA3_224/256/384/512_End() functions for converting the
+ * digest to a readable hexadecimal character string:
+ */
+static const char sha3_hex_digits[] = "0123456789abcdef";
+
+char           *
+SHA3_224_File(char *filename, char *buf)
+{
+	unsigned char          buffer[BUFSIZ * 20];
+	SHA3_224_CTX      ctx;
+	int             fd, num, oerrno;
+
+	_DIAGASSERT(filename != NULL);
+	/* XXX: buf may be NULL ? */
+
+	SHA3_224_Init(&amp;ctx);
+
+	if ((fd = open(filename, O_RDONLY)) &lt; 0)
+		return (0);
+
+	while ((num = read(fd, buffer, sizeof(buffer))) &gt; 0)
+		SHA3_224_Update(&amp;ctx, buffer, (size_t) num);
+
+	oerrno = errno;
+	close(fd);
+	errno = oerrno;
+	return (num &lt; 0 ? 0 : SHA3_224_End(&amp;ctx, buf));
+}
+
+
+char           *
+SHA3_224_End(SHA3_224_CTX *ctx, char buffer[])
+{
+	unsigned char          digest[SHA3_224_DIGEST_LENGTH], *d = digest;
+	unsigned char	       *ret;
+	int             i;
+
+	/* Sanity check: */
+	assert(ctx != NULL);
+
+	if ((ret = buffer) != NULL) {
+		SHA3_224_Final(digest, ctx);
+
+		for (i = 0; i &lt; SHA3_224_DIGEST_LENGTH; i++) {
+			*buffer++ = sha3_hex_digits[(*d &amp; 0xf0) &gt;&gt; 4];
+			*buffer++ = sha3_hex_digits[*d &amp; 0x0f];
+			d++;
+		}
+		*buffer = (char) 0;
+	} else {
+		(void) MEMSET_BZERO(ctx, sizeof(SHA3_224_CTX));
+	}
+	(void) MEMSET_BZERO(digest, SHA3_224_DIGEST_LENGTH);
+	return ret;
+}
+
+char           *
+SHA3_224_Data(const uint8_t * data, size_t len, unsigned char *digest)
+{
+	SHA3_224_CTX      ctx;
+
+	SHA3_224_Init(&amp;ctx);
+	SHA3_224_Update(&amp;ctx, data, len);
+	return SHA3_224_End(&amp;ctx, digest);
+}
+
+char           *
+SHA3_256_File(char *filename, char *buf)
+{
+	unsigned char          buffer[BUFSIZ * 20];
+	SHA3_256_CTX      ctx;
+	int             fd, num, oerrno;
+
+	_DIAGASSERT(filename != NULL);
+	/* XXX: buf may be NULL ? */
+
+	SHA3_256_Init(&amp;ctx);
+
+	if ((fd = open(filename, O_RDONLY)) &lt; 0)
+		return (0);
+
+	while ((num = read(fd, buffer, sizeof(buffer))) &gt; 0)
+		SHA3_256_Update(&amp;ctx, buffer, (size_t) num);
+
+	oerrno = errno;
+	close(fd);
+	errno = oerrno;
+	return (num &lt; 0 ? 0 : SHA3_256_End(&amp;ctx, buf));
+}
+
+
+char           *
+SHA3_256_End(SHA3_256_CTX *ctx, char buffer[])
+{
+	unsigned char          digest[SHA3_256_DIGEST_LENGTH], *d = digest;
+	unsigned char	       *ret;
+	int             i;
+
+	/* Sanity check: */
+	assert(ctx != NULL);
+
+	if ((ret = buffer) != NULL) {
+		SHA3_256_Final(digest, ctx);
+
+		for (i = 0; i &lt; SHA3_256_DIGEST_LENGTH; i++) {
+			*buffer++ = sha3_hex_digits[(*d &amp; 0xf0) &gt;&gt; 4];
+			*buffer++ = sha3_hex_digits[*d &amp; 0x0f];
+			d++;
+		}
+		*buffer = (char) 0;
+	} else {
+		(void) MEMSET_BZERO(ctx, sizeof(SHA3_256_CTX));
+	}
+	(void) MEMSET_BZERO(digest, SHA3_256_DIGEST_LENGTH);
+	return ret;
+}
+
+char           *
+SHA3_256_Data(const uint8_t * data, size_t len, unsigned char *digest)
+{
+	SHA3_256_CTX      ctx;
+
+	SHA3_256_Init(&amp;ctx);
+	SHA3_256_Update(&amp;ctx, data, len);
+	return SHA3_256_End(&amp;ctx, digest);
+}
+
+char           *
+SHA3_384_File(char *filename, char *buf)
+{
+	unsigned char          buffer[BUFSIZ * 20];
+	SHA3_384_CTX      ctx;
+	int             fd, num, oerrno;
+
+	_DIAGASSERT(filename != NULL);
+	/* XXX: buf may be NULL ? */
+
+	SHA3_384_Init(&amp;ctx);
+
+	if ((fd = open(filename, O_RDONLY)) &lt; 0)
+		return (0);
+
+	while ((num = read(fd, buffer, sizeof(buffer))) &gt; 0)
+		SHA3_384_Update(&amp;ctx, buffer, (size_t) num);
+
+	oerrno = errno;
+	close(fd);
+	errno = oerrno;
+	return (num &lt; 0 ? 0 : SHA3_384_End(&amp;ctx, buf));
+}
+
+
+char           *
+SHA3_384_End(SHA3_384_CTX *ctx, char buffer[])
+{
+	unsigned char          digest[SHA3_384_DIGEST_LENGTH], *d = digest;
+	unsigned char	       *ret;
+	int             i;
+
+	/* Sanity check: */
+	assert(ctx != NULL);
+
+	if ((ret = buffer) != NULL) {
+		SHA3_384_Final(digest, ctx);
+
+		for (i = 0; i &lt; SHA3_384_DIGEST_LENGTH; i++) {
+			*buffer++ = sha3_hex_digits[(*d &amp; 0xf0) &gt;&gt; 4];
+			*buffer++ = sha3_hex_digits[*d &amp; 0x0f];
+			d++;
+		}
+		*buffer = (char) 0;
+	} else {
+		(void) MEMSET_BZERO(ctx, sizeof(SHA3_384_CTX));
+	}
+	(void) MEMSET_BZERO(digest, SHA3_384_DIGEST_LENGTH);
+	return ret;
+}
+
+char           *
+SHA3_384_Data(const uint8_t * data, size_t len, unsigned char *digest)
+{
+	SHA3_384_CTX      ctx;
+
+	SHA3_384_Init(&amp;ctx);
+	SHA3_384_Update(&amp;ctx, data, len);
+	return SHA3_384_End(&amp;ctx, digest);
+}
+
+char           *
+SHA3_512_File(char *filename, char *buf)
+{
+	unsigned char          buffer[BUFSIZ * 20];
+	SHA3_512_CTX      ctx;
+	int             fd, num, oerrno;
+
+	_DIAGASSERT(filename != NULL);
+	/* XXX: buf may be NULL ? */
+
+	SHA3_512_Init(&amp;ctx);
+
+	if ((fd = open(filename, O_RDONLY)) &lt; 0)
+		return (0);
+
+	while ((num = read(fd, buffer, sizeof(buffer))) &gt; 0)
+		SHA3_512_Update(&amp;ctx, buffer, (size_t) num);
+
+	oerrno = errno;
+	close(fd);
+	errno = oerrno;
+	return (num &lt; 0 ? 0 : SHA3_512_End(&amp;ctx, buf));
+}
+
+
+char           *
+SHA3_512_End(SHA3_512_CTX *ctx, char buffer[])
+{
+	unsigned char          digest[SHA3_512_DIGEST_LENGTH], *d = digest;
+	unsigned char	       *ret;
+	int             i;
+
+	/* Sanity check: */
+	assert(ctx != NULL);
+
+	if ((ret = buffer) != NULL) {
+		SHA3_512_Final(digest, ctx);
+
+		for (i = 0; i &lt; SHA3_512_DIGEST_LENGTH; i++) {
+			*buffer++ = sha3_hex_digits[(*d &amp; 0xf0) &gt;&gt; 4];
+			*buffer++ = sha3_hex_digits[*d &amp; 0x0f];
+			d++;
+		}
+		*buffer = (char) 0;
+	} else {
+		(void) MEMSET_BZERO(ctx, sizeof(SHA3_512_CTX));
+	}
+	(void) MEMSET_BZERO(digest, SHA3_512_DIGEST_LENGTH);
+	return ret;
+}
+
+char           *
+SHA3_512_Data(const uint8_t * data, size_t len, unsigned char *digest)
+{
+	SHA3_512_CTX      ctx;
+
+	SHA3_512_Init(&amp;ctx);
+	SHA3_512_Update(&amp;ctx, data, len);
+	return SHA3_512_End(&amp;ctx, digest);
+}
+
</pre></body></html>