From ac8bc20b27e8ae5274eebfce633cb809230f38cf Mon Sep 17 00:00:00 2001
From: stateless <stateless@archlinux.us>
Date: Wed, 19 Jun 2013 09:54:52 +0100
Subject: [PATCH] Add md5sum

No support for -c at the moment.
---
 LICENSE.lpl     |  236 ++++++++++++++++++++++++++++++++++++++++++++++++
 Makefile        |    3 +
 md5.h           |   17 ++++
 md5sum.1        |    8 ++
 md5sum.c        |   67 ++++++++++++++
 util/md5.c      |  149 ++++++++++++++++++++++++++++++
 util/md5block.c |  270 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 750 insertions(+)
 create mode 100644 LICENSE.lpl
 create mode 100644 md5.h
 create mode 100644 md5sum.1
 create mode 100644 md5sum.c
 create mode 100644 util/md5.c
 create mode 100644 util/md5block.c

diff --git a/LICENSE.lpl b/LICENSE.lpl
new file mode 100644
index 0000000..a2905eb
--- /dev/null
+++ b/LICENSE.lpl
@@ -0,0 +1,236 @@
+Lucent Public License Version 1.02
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE
+PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+  a. in the case of Lucent Technologies Inc. ("LUCENT"), the Original
+     Program, and
+  b. in the case of each Contributor,
+
+     i. changes to the Program, and
+    ii. additions to the Program;
+
+    where such changes and/or additions to the Program were added to the
+    Program by such Contributor itself or anyone acting on such
+    Contributor's behalf, and the Contributor explicitly consents, in
+    accordance with Section 3C, to characterization of the changes and/or
+    additions as Contributions.
+
+"Contributor" means LUCENT and any other entity that has Contributed a
+Contribution to the Program.
+
+"Distributor" means a Recipient that distributes the Program,
+modifications to the Program, or any part thereof.
+
+"Licensed Patents" mean patent claims licensable by a Contributor
+which are necessarily infringed by the use or sale of its Contribution
+alone or when combined with the Program.
+
+"Original Program" means the original version of the software
+accompanying this Agreement as released by LUCENT, including source
+code, object code and documentation, if any.
+
+"Program" means the Original Program and Contributions or any part
+thereof
+
+"Recipient" means anyone who receives the Program under this
+Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+ a. Subject to the terms of this Agreement, each Contributor hereby
+    grants Recipient a non-exclusive, worldwide, royalty-free copyright
+    license to reproduce, prepare derivative works of, publicly display,
+    publicly perform, distribute and sublicense the Contribution of such
+    Contributor, if any, and such derivative works, in source code and
+    object code form.
+
+ b. Subject to the terms of this Agreement, each Contributor hereby
+    grants Recipient a non-exclusive, worldwide, royalty-free patent
+    license under Licensed Patents to make, use, sell, offer to sell,
+    import and otherwise transfer the Contribution of such Contributor, if
+    any, in source code and object code form. The patent license granted
+    by a Contributor shall also apply to the combination of the
+    Contribution of that Contributor and the Program if, at the time the
+    Contribution is added by the Contributor, such addition of the
+    Contribution causes such combination to be covered by the Licensed
+    Patents. The patent license granted by a Contributor shall not apply
+    to (i) any other combinations which include the Contribution, nor to
+    (ii) Contributions of other Contributors. No hardware per se is
+    licensed hereunder.
+
+ c. Recipient understands that although each Contributor grants the
+    licenses to its Contributions set forth herein, no assurances are
+    provided by any Contributor that the Program does not infringe the
+    patent or other intellectual property rights of any other entity. Each
+    Contributor disclaims any liability to Recipient for claims brought by
+    any other entity based on infringement of intellectual property rights
+    or otherwise. As a condition to exercising the rights and licenses
+    granted hereunder, each Recipient hereby assumes sole responsibility
+    to secure any other intellectual property rights needed, if any. For
+    example, if a third party patent license is required to allow
+    Recipient to distribute the Program, it is Recipient's responsibility
+    to acquire that license before distributing the Program.
+
+ d. Each Contributor represents that to its knowledge it has sufficient
+    copyright rights in its Contribution, if any, to grant the copyright
+    license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A. Distributor may choose to distribute the Program in any form under
+this Agreement or under its own license agreement, provided that:
+
+ a. it complies with the terms and conditions of this Agreement;
+
+ b. if the Program is distributed in source code or other tangible
+    form, a copy of this Agreement or Distributor's own license agreement
+    is included with each copy of the Program; and
+
+ c. if distributed under Distributor's own license agreement, such
+    license agreement:
+
+      i. effectively disclaims on behalf of all Contributors all warranties
+         and conditions, express and implied, including warranties or
+         conditions of title and non-infringement, and implied warranties or
+         conditions of merchantability and fitness for a particular purpose;
+     ii. effectively excludes on behalf of all Contributors all liability
+         for damages, including direct, indirect, special, incidental and
+         consequential damages, such as lost profits; and
+    iii. states that any provisions which differ from this Agreement are
+         offered by that Contributor alone and not by any other party.
+
+B. Each Distributor must include the following in a conspicuous
+   location in the Program:
+
+   Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights
+   Reserved.
+
+C. In addition, each Contributor must identify itself as the
+originator of its Contribution in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution.
+Also, each Contributor must agree that the additions and/or changes
+are intended to be a Contribution. Once a Contribution is contributed,
+it may not thereafter be revoked.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use
+of the Program, the Distributor who includes the Program in a
+commercial product offering should do so in a manner which does not
+create potential liability for Contributors. Therefore, if a
+Distributor includes the Program in a commercial product offering,
+such Distributor ("Commercial Distributor") hereby agrees to defend
+and indemnify every Contributor ("Indemnified Contributor") against
+any losses, damages and costs (collectively"Losses") arising from
+claims, lawsuits and other legal actions brought by a third party
+against the Indemnified Contributor to the extent caused by the acts
+or omissions of such Commercial Distributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement.
+In order to qualify, an Indemnified Contributor must: a) promptly
+notify the Commercial Distributor in writing of such claim, and b)
+allow the Commercial Distributor to control, and cooperate with the
+Commercial Distributor in, the defense and any related settlement
+negotiations. The Indemnified Contributor may participate in any such
+claim at its own expense.
+
+For example, a Distributor might include the Program in a commercial
+product offering, Product X. That Distributor is then a Commercial
+Distributor. If that Commercial Distributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Distributor's responsibility
+alone. Under this section, the Commercial Distributor would have to
+defend claims against the Contributors related to those performance
+claims and warranties, and if a court requires any Contributor to pay
+any damages as a result, the Commercial Distributor must pay those
+damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement, including but not limited to
+the risks and costs of program errors, compliance with applicable
+laws, damage to or loss of data, programs or equipment, and
+unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
+ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), 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 OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. EXPORT CONTROL
+
+Recipient agrees that Recipient alone is responsible for compliance
+with the United States export administration regulations (and the
+export control laws and regulation of any other countries).
+
+8. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against a Contributor with
+respect to a patent applicable to software (including a cross-claim or
+counterclaim in a lawsuit), then any patent licenses granted by that
+Contributor to such Recipient under this Agreement shall terminate as
+of the date such litigation is filed. In addition, if Recipient
+institutes patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Program
+itself (excluding combinations of the Program with other software or
+hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably practicable.
+However, Recipient's obligations under this Agreement and any licenses
+granted by Recipient relating to the Program shall continue and
+survive.
+
+LUCENT may publish new versions (including revisions) of this
+Agreement from time to time. Each new version of the Agreement will be
+given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new
+version of the Agreement is published, Contributor may elect to
+distribute the Program (including its Contributions) under the new
+version. No one other than LUCENT has the right to modify this
+Agreement. Except as expressly stated in Sections 2(a) and 2(b) above,
+Recipient receives no rights or licenses to the intellectual property
+of any Contributor under this Agreement, whether expressly, by
+implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and
+the intellectual property laws of the United States of America. No
+party to this Agreement will bring a legal action under this Agreement
+more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.
diff --git a/Makefile b/Makefile
index 9aeb5c4..7db585a 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,8 @@ LIB = \
 	util/estrtol.o   \
 	util/fnck.o      \
 	util/getlines.o  \
+	util/md5.o       \
+	util/md5block.o  \
 	util/putword.o   \
 	util/recurse.o   \
 	util/rm.o
@@ -45,6 +47,7 @@ SRC = \
 	ln.c       \
 	ls.c       \
 	mc.c       \
+	md5sum.c   \
 	mkdir.c    \
 	mkfifo.c   \
 	mv.c       \
diff --git a/md5.h b/md5.h
new file mode 100644
index 0000000..c52f58d
--- /dev/null
+++ b/md5.h
@@ -0,0 +1,17 @@
+/* See LICENSE.lpl file for copyright and license details. */
+enum { MD5dlen = 16 };
+
+typedef struct DigestState DigestState;
+struct DigestState
+{
+	unsigned long len;
+	uint32_t state[5];
+	unsigned char buf[128];
+	int blen;
+	char malloced;
+	char seeded;
+};
+typedef struct DigestState MD5state;
+
+DigestState *md5(unsigned char *, unsigned long, unsigned char *,
+		 DigestState *);
diff --git a/md5sum.1 b/md5sum.1
new file mode 100644
index 0000000..93ecb2f
--- /dev/null
+++ b/md5sum.1
@@ -0,0 +1,8 @@
+.TH MD5SUM 1 sbase\-VERSION
+.SH NAME
+md5sum \- compute MD5 message digest
+.SH SYNOPSIS
+.B md5sum
+.RI [ file ...]
+.SH DESCRIPTION
+Print MD5 (128-bit) checksums. With no file, read standard input.
diff --git a/md5sum.c b/md5sum.c
new file mode 100644
index 0000000..f0e35f2
--- /dev/null
+++ b/md5sum.c
@@ -0,0 +1,67 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "util.h"
+#include "md5.h"
+
+static void md5sum(int fd, const char *s);
+
+static void
+usage(void)
+{
+	eprintf("usage: %s [file...]\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int fd;
+
+	ARGBEGIN {
+	default:
+		usage();
+	} ARGEND;
+
+	if (argc == 0) {
+		md5sum(STDIN_FILENO, "<stdin>");
+	} else {
+		for (; argc > 0; argc--) {
+			if ((fd = open(*argv, O_RDONLY)) < 0)
+				eprintf("open %s:", *argv);
+			md5sum(fd, *argv);
+			close(fd);
+			argv++;
+		}
+	}
+
+	return 0;
+}
+
+static void
+md5sum(int fd, const char *s)
+{
+	unsigned char buf[BUFSIZ];
+	unsigned char digest[MD5dlen];
+	DigestState *ds;
+	ssize_t n;
+	int i;
+
+	ds = md5(NULL, 0, NULL, NULL);
+	while ((n = read(fd, buf, sizeof buf)) > 0)
+		md5(buf, n, NULL, ds);
+	if (n < 0) {
+		eprintf("%s: read error:", s);
+		return;
+	}
+
+	md5(NULL, 0, digest, ds);
+
+	for (i = 0; i < MD5dlen; i++)
+		printf("%02x", digest[i]);
+	printf("  %s\n", s);
+}
diff --git a/util/md5.c b/util/md5.c
new file mode 100644
index 0000000..dbfd7f4
--- /dev/null
+++ b/util/md5.c
@@ -0,0 +1,149 @@
+/* See LICENSE.lpl file for copyright and license details. */
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include "../md5.h"
+
+/*
+ *  rfc1321 requires that I include this.  The code is new.  The constants
+ *  all come from the rfc (hence the copyright).  We trade a table for the
+ *  macros in rfc.  The total size is a lot less. -- presotto
+ *
+ *	Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ *	rights reserved.
+ *
+ *	License to copy and use this software is granted provided that it
+ *	is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ *	Algorithm" in all material mentioning or referencing this software
+ *	or this function.
+ *
+ *	License is also granted to make and use derivative works provided
+ *	that such works are identified as "derived from the RSA Data
+ *	Security, Inc. MD5 Message-Digest Algorithm" in all material
+ *	mentioning or referencing the derived work.
+ *
+ *	RSA Data Security, Inc. makes no representations concerning either
+ *	the merchantability of this software or the suitability of this
+ *	software forany particular purpose. It is provided "as is"
+ *	without express or implied warranty of any kind.
+ *	These notices must be retained in any copies of any part of this
+ *	documentation and/or software.
+ */
+
+static void encode(unsigned char *, uint32_t *, unsigned long);
+extern void _md5block(unsigned char *, unsigned long, uint32_t *);
+
+MD5state*
+md5(unsigned char *p, unsigned long len, unsigned char *digest, MD5state *s)
+{
+	uint32_t x[16];
+	unsigned char buf[128];
+	int i;
+	unsigned char *e;
+
+	if(s == NULL){
+		s = malloc(sizeof(*s));
+		if(s == NULL)
+			return NULL;
+		memset(s, 0, sizeof(*s));
+		s->malloced = 1;
+	}
+
+	if(s->seeded == 0){
+		/* seed the state, these constants would look nicer big-endian */
+		s->state[0] = 0x67452301;
+		s->state[1] = 0xefcdab89;
+		s->state[2] = 0x98badcfe;
+		s->state[3] = 0x10325476;
+		s->seeded = 1;
+	}
+
+	/* fill out the partial 64 byte block from previous calls */
+	if(s->blen){
+		i = 64 - s->blen;
+		if(len < i)
+			i = len;
+		memmove(s->buf + s->blen, p, i);
+		len -= i;
+		s->blen += i;
+		p += i;
+		if(s->blen == 64){
+			_md5block(s->buf, s->blen, s->state);
+			s->len += s->blen;
+			s->blen = 0;
+		}
+	}
+
+	/* do 64 byte blocks */
+	i = len & ~0x3f;
+	if(i){
+		_md5block(p, i, s->state);
+		s->len += i;
+		len -= i;
+		p += i;
+	}
+
+	/* save the left overs if not last call */
+	if(digest == 0){
+		if(len){
+			memmove(s->buf, p, len);
+			s->blen += len;
+		}
+		return s;
+	}
+
+	/*
+	 *  this is the last time through, pad what's left with 0x80,
+	 *  0's, and the input count to create a multiple of 64 bytes
+	 */
+	if(s->blen){
+		p = s->buf;
+		len = s->blen;
+	} else {
+		memmove(buf, p, len);
+		p = buf;
+	}
+	s->len += len;
+	e = p + len;
+	if(len < 56)
+		i = 56 - len;
+	else
+		i = 120 - len;
+	memset(e, 0, i);
+	*e = 0x80;
+	len += i;
+
+	/* append the count */
+	x[0] = s->len<<3;
+	x[1] = s->len>>29;
+	encode(p+len, x, 8);
+
+	/* digest the last part */
+	_md5block(p, len+8, s->state);
+	s->len += len;
+
+	/* return result and free state */
+	encode(digest, s->state, MD5dlen);
+	if(s->malloced == 1)
+		free(s);
+	return NULL;
+}
+
+/*
+ *	encodes input (uint32_t) into output (unsigned char). Assumes len is
+ *	a multiple of 4.
+ */
+static void
+encode(unsigned char *output, uint32_t *input, unsigned long len)
+{
+	uint32_t x;
+	unsigned char *e;
+
+	for(e = output + len; output < e;) {
+		x = *input++;
+		*output++ = x;
+		*output++ = x >> 8;
+		*output++ = x >> 16;
+		*output++ = x >> 24;
+	}
+}
diff --git a/util/md5block.c b/util/md5block.c
new file mode 100644
index 0000000..250bcea
--- /dev/null
+++ b/util/md5block.c
@@ -0,0 +1,270 @@
+/* See LICENSE.lpl file for copyright and license details. */
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include "../md5.h"
+
+/*
+ *  rfc1321 requires that I include this.  The code is new.  The constants
+ *  all come from the rfc (hence the copyright).  We trade a table for the
+ *  macros in rfc.  The total size is a lot less. -- presotto
+ *
+ *	Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ *	rights reserved.
+ *
+ *	License to copy and use this software is granted provided that it
+ *	is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ *	Algorithm" in all material mentioning or referencing this software
+ *	or this function.
+ *
+ *	License is also granted to make and use derivative works provided
+ *	that such works are identified as "derived from the RSA Data
+ *	Security, Inc. MD5 Message-Digest Algorithm" in all material
+ *	mentioning or referencing the derived work.
+ *
+ *	RSA Data Security, Inc. makes no representations concerning either
+ *	the merchantability of this software or the suitability of this
+ *	software forany particular purpose. It is provided "as is"
+ *	without express or implied warranty of any kind.
+ *	These notices must be retained in any copies of any part of this
+ *	documentation and/or software.
+ */
+
+/*
+ *	Rotate ammounts used in the algorithm
+ */
+enum
+{
+	S11=	7,
+	S12=	12,
+	S13=	17,
+	S14=	22,
+
+	S21=	5,
+	S22=	9,
+	S23=	14,
+	S24=	20,
+
+	S31=	4,
+	S32=	11,
+	S33=	16,
+	S34=	23,
+
+	S41=	6,
+	S42=	10,
+	S43=	15,
+	S44=	21
+};
+
+static uint32_t md5tab[] =
+{
+	/* round 1 */
+/*[0]*/	0xd76aa478,
+	0xe8c7b756,
+	0x242070db,
+	0xc1bdceee,
+	0xf57c0faf,
+	0x4787c62a,
+	0xa8304613,
+	0xfd469501,
+	0x698098d8,
+	0x8b44f7af,
+	0xffff5bb1,
+	0x895cd7be,
+	0x6b901122,
+	0xfd987193,
+	0xa679438e,
+	0x49b40821,
+
+	/* round 2 */
+/*[16]*/0xf61e2562,
+	0xc040b340,
+	0x265e5a51,
+	0xe9b6c7aa,
+	0xd62f105d,
+	 0x2441453,
+	0xd8a1e681,
+	0xe7d3fbc8,
+	0x21e1cde6,
+	0xc33707d6,
+	0xf4d50d87,
+	0x455a14ed,
+	0xa9e3e905,
+	0xfcefa3f8,
+	0x676f02d9,
+	0x8d2a4c8a,
+
+	/* round 3 */
+/*[32]*/0xfffa3942,
+	0x8771f681,
+	0x6d9d6122,
+	0xfde5380c,
+	0xa4beea44,
+	0x4bdecfa9,
+	0xf6bb4b60,
+	0xbebfbc70,
+	0x289b7ec6,
+	0xeaa127fa,
+	0xd4ef3085,
+	 0x4881d05,
+	0xd9d4d039,
+	0xe6db99e5,
+	0x1fa27cf8,
+	0xc4ac5665,
+
+	/* round 4 */
+/*[48]*/0xf4292244,
+	0x432aff97,
+	0xab9423a7,
+	0xfc93a039,
+	0x655b59c3,
+	0x8f0ccc92,
+	0xffeff47d,
+	0x85845dd1,
+	0x6fa87e4f,
+	0xfe2ce6e0,
+	0xa3014314,
+	0x4e0811a1,
+	0xf7537e82,
+	0xbd3af235,
+	0x2ad7d2bb,
+	0xeb86d391,
+};
+
+static void decode(uint32_t *, unsigned char *, unsigned long);
+extern void _md5block(unsigned char *p, unsigned long len, uint32_t *s);
+
+void
+_md5block(unsigned char *p, unsigned long len, uint32_t *s)
+{
+	uint32_t a, b, c, d, sh;
+	uint32_t *t;
+	unsigned char *end;
+	uint32_t x[16];
+
+	for(end = p+len; p < end; p += 64){
+		a = s[0];
+		b = s[1];
+		c = s[2];
+		d = s[3];
+
+		decode(x, p, 64);
+
+		t = md5tab;
+		sh = 0;
+		for(; sh != 16; t += 4){
+			a += ((c ^ d) & b) ^ d;
+			a += x[sh] + t[0];
+			a = (a << S11) | (a >> (32 - S11));
+			a += b;
+
+			d += ((b ^ c) & a) ^ c;
+			d += x[sh + 1] + t[1];
+			d = (d << S12) | (d >> (32 - S12));
+			d += a;
+
+			c += ((a ^ b) & d) ^ b;
+			c += x[sh + 2] + t[2];
+			c = (c << S13) | (c >> (32 - S13));
+			c += d;
+
+			b += ((d ^ a) & c) ^ a;
+			b += x[sh + 3] + t[3];
+			b = (b << S14) | (b >> (32 - S14));
+			b += c;
+
+			sh += 4;
+		}
+		sh = 1;
+		for(; sh != 1+20*4; t += 4){
+			a += ((b ^ c) & d) ^ c;
+			a += x[sh & 0xf] + t[0];
+			a = (a << S21) | (a >> (32 - S21));
+			a += b;
+
+			d += ((a ^ b) & c) ^ b;
+			d += x[(sh + 5) & 0xf] + t[1];
+			d = (d << S22) | (d >> (32 - S22));
+			d += a;
+
+			c += ((d ^ a) & b) ^ a;
+			c += x[(sh + 10) & 0xf] + t[2];
+			c = (c << S23) | (c >> (32 - S23));
+			c += d;
+
+			b += ((c ^ d) & a) ^ d;
+			b += x[(sh + 15) & 0xf] + t[3];
+			b = (b << S24) | (b >> (32 - S24));
+			b += c;
+
+			sh += 20;
+		}
+		sh = 5;
+		for(; sh != 5+12*4; t += 4){
+			a += b ^ c ^ d;
+			a += x[sh & 0xf] + t[0];
+			a = (a << S31) | (a >> (32 - S31));
+			a += b;
+
+			d += a ^ b ^ c;
+			d += x[(sh + 3) & 0xf] + t[1];
+			d = (d << S32) | (d >> (32 - S32));
+			d += a;
+
+			c += d ^ a ^ b;
+			c += x[(sh + 6) & 0xf] + t[2];
+			c = (c << S33) | (c >> (32 - S33));
+			c += d;
+
+			b += c ^ d ^ a;
+			b += x[(sh + 9) & 0xf] + t[3];
+			b = (b << S34) | (b >> (32 - S34));
+			b += c;
+
+			sh += 12;
+		}
+		sh = 0;
+		for(; sh != 28*4; t += 4){
+			a += c ^ (b | ~d);
+			a += x[sh & 0xf] + t[0];
+			a = (a << S41) | (a >> (32 - S41));
+			a += b;
+
+			d += b ^ (a | ~c);
+			d += x[(sh + 7) & 0xf] + t[1];
+			d = (d << S42) | (d >> (32 - S42));
+			d += a;
+
+			c += a ^ (d | ~b);
+			c += x[(sh + 14) & 0xf] + t[2];
+			c = (c << S43) | (c >> (32 - S43));
+			c += d;
+
+			b += d ^ (c | ~a);
+			b += x[(sh + 21) & 0xf] + t[3];
+			b = (b << S44) | (b >> (32 - S44));
+			b += c;
+
+			sh += 28;
+		}
+
+		s[0] += a;
+		s[1] += b;
+		s[2] += c;
+		s[3] += d;
+	}
+}
+
+/*
+ *	decodes input (unsigned char) into output (uint32_t). Assumes len is
+ *	a multiple of 4.
+ */
+static void
+decode(uint32_t *output, unsigned char *input, unsigned long len)
+{
+	unsigned char *e;
+
+	for(e = input+len; input < e; input += 4)
+		*output++ = input[0] | (input[1] << 8) |
+			(input[2] << 16) | (input[3] << 24);
+}
-- 
1.7.10.4

