From 7c6ef2f2142f0a4c22b5505d95553cac17867a21 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Tue, 20 Sep 2005 12:27:13 -0400 Subject: [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 Signed-off-by: Junio C Hamano --- arm/sha1.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 arm/sha1.c (limited to 'arm/sha1.c') 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 + * Created: September 17, 2005 + */ + +#include +#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; + } +} -- cgit v1.2.3