summaryrefslogtreecommitdiff
path: root/arm/sha1.c
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2005-09-20 12:27:13 -0400
committerJunio C Hamano <junkio@cox.net>2005-09-20 18:10:00 -0700
commit7c6ef2f2142f0a4c22b5505d95553cac17867a21 (patch)
tree5eff144d174355bd17dc7b12d77af58202c46ea5 /arm/sha1.c
parentf1f0d0889e5557bc467490fdbd53f7b912503a33 (diff)
downloadgit-7c6ef2f2142f0a4c22b5505d95553cac17867a21.tar.gz
[PATCH] ARM optimized SHA1 implementation
This is my ARM assembly SHA1 implementation for GIT. It is approximately 50% faster than the generic C version. On an XScale processor running at 400MHz: generic C version: 9.8 MB/s my version: 14.5 MB/s It's not that I expect a lot of big GIT users on ARM, but I stillknow about one important ARM user that might benefit from it, and writing that code was fun. I also reworked the makefile a bit so any optimized SHA1 implementations is used regardless of whether NO_OPENSSL is defined or not. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'arm/sha1.c')
-rw-r--r--arm/sha1.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/arm/sha1.c b/arm/sha1.c
new file mode 100644
index 0000000000..11b1a048b4
--- /dev/null
+++ b/arm/sha1.c
@@ -0,0 +1,82 @@
+/*
+ * SHA-1 implementation optimized for ARM
+ *
+ * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
+ * Created: September 17, 2005
+ */
+
+#include <string.h>
+#include "sha1.h"
+
+extern void sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W);
+
+void SHA1_Init(SHA_CTX *c)
+{
+ c->len = 0;
+ c->hash[0] = 0x67452301;
+ c->hash[1] = 0xefcdab89;
+ c->hash[2] = 0x98badcfe;
+ c->hash[3] = 0x10325476;
+ c->hash[4] = 0xc3d2e1f0;
+}
+
+void SHA1_Update(SHA_CTX *c, const void *p, unsigned long n)
+{
+ uint32_t workspace[80];
+ unsigned int partial;
+ unsigned long done;
+
+ partial = c->len & 0x3f;
+ c->len += n;
+ if ((partial + n) >= 64) {
+ if (partial) {
+ done = 64 - partial;
+ memcpy(c->buffer + partial, p, done);
+ sha_transform(c->hash, c->buffer, workspace);
+ partial = 0;
+ } else
+ done = 0;
+ while (n >= done + 64) {
+ sha_transform(c->hash, p + done, workspace);
+ done += 64;
+ }
+ } else
+ done = 0;
+ if (n - done)
+ memcpy(c->buffer + partial, p + done, n - done);
+}
+
+void SHA1_Final(unsigned char *hash, SHA_CTX *c)
+{
+ uint64_t bitlen;
+ uint32_t bitlen_hi, bitlen_lo;
+ unsigned int i, offset, padlen;
+ unsigned char bits[8];
+ static const unsigned char padding[64] = { 0x80, };
+
+ bitlen = c->len << 3;
+ offset = c->len & 0x3f;
+ padlen = ((offset < 56) ? 56 : (64 + 56)) - offset;
+ SHA1_Update(c, padding, padlen);
+
+ bitlen_hi = bitlen >> 32;
+ bitlen_lo = bitlen & 0xffffffff;
+ bits[0] = bitlen_hi >> 24;
+ bits[1] = bitlen_hi >> 16;
+ bits[2] = bitlen_hi >> 8;
+ bits[3] = bitlen_hi;
+ bits[4] = bitlen_lo >> 24;
+ bits[5] = bitlen_lo >> 16;
+ bits[6] = bitlen_lo >> 8;
+ bits[7] = bitlen_lo;
+ SHA1_Update(c, bits, 8);
+
+ for (i = 0; i < 5; i++) {
+ uint32_t v = c->hash[i];
+ hash[0] = v >> 24;
+ hash[1] = v >> 16;
+ hash[2] = v >> 8;
+ hash[3] = v;
+ hash += 4;
+ }
+}