{"thread":{"id":"40727","subject":"[PATCH v4 2/3] Limit the size of the data block passed to SHA1_Update()","startedAt":"2015-11-05T06:38:41Z","lastAt":"2015-11-11T23:46:51Z","messageCount":7,"participants":["atousa.p@gmail.com","Junio C Hamano","Atousa Duprat"],"isPatch":true,"patchVersion":4,"patchTotal":3},"messages":[{"id":"272945","messageId":"1446705523-30701-1-git-send-email-apahlevan@ieee.org","threadId":"40727","inReplyTo":"CAPig+cS7NktyhveQUiBFkRtJH1D-Aif861e9qshL2R=ZNg2+Lw@mail.gmail.com","subject":"[PATCH v4 1/3] Provide another level of abstraction for the SHA1 utilities.","fromName":"","fromEmail":"atousa.p@gmail.com","sentAt":"2015-11-05T06:38:41Z","receivedAt":"2015-11-05T06:38:41Z","isPatch":true,"sender":{"key":"atousa.p@gmail.com","avatar":"https://gravatar.com/avatar/b5b7b70553497c4ce08a835c156ff3b245366eba956fbceff99553b1ccdc4e42?d=mp&s=160"},"body":"From: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n\nThe git source uses git_SHA1_Update() and friends to call\ninto the code that computes the hashes.  This is can then be\nmapped directly to an implementation that computes the hash,\nsuch as platform_SHA1_Update(); or as we will do in a subsequent\npatch, it can be mapped to something more complex that will in turn call\ninto the platform's SHA implementation.\n\nSigned-off-by: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n---\n cache.h | 19 +++++++++++++++----\n 1 file changed, 15 insertions(+), 4 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex a9aaa03..a934a2e 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -12,10 +12,21 @@\n \n #include SHA1_HEADER\n #ifndef git_SHA_CTX\n-#define git_SHA_CTX\tSHA_CTX\n-#define git_SHA1_Init\tSHA1_Init\n-#define git_SHA1_Update\tSHA1_Update\n-#define git_SHA1_Final\tSHA1_Final\n+\n+/* platform's underlying implementation of SHA1, could be OpenSSL,\n+   blk_SHA, Apple CommonCrypto, etc...  */\n+#define platform_SHA_CTX\tSHA_CTX\n+#define platform_SHA1_Init\tSHA1_Init\n+#define platform_SHA1_Update\tSHA1_Update\n+#define platform_SHA1_Final    \tSHA1_Final\n+\n+/* git may call platform's underlying implementation of SHA1 directly,\n+   or may call it through a wrapper */\n+#define git_SHA_CTX\t\tplatform_SHA_CTX\n+#define git_SHA1_Init\t\tplatform_SHA1_Init\n+#define git_SHA1_Update\t\tplatform_SHA1_Update\n+#define git_SHA1_Final\t\tplatform_SHA1_Final\n+\n #endif\n \n #include <zlib.h>\n-- \n2.4.9 (Apple Git-60)\n"},{"id":"272944","messageId":"1446705523-30701-2-git-send-email-apahlevan@ieee.org","threadId":"40727","inReplyTo":"1446705523-30701-1-git-send-email-apahlevan@ieee.org","subject":"[PATCH v4 2/3] Limit the size of the data block passed to SHA1_Update()","fromName":"","fromEmail":"atousa.p@gmail.com","sentAt":"2015-11-05T06:38:42Z","receivedAt":"2015-11-05T06:38:42Z","isPatch":true,"sender":{"key":"atousa.p@gmail.com","avatar":"https://gravatar.com/avatar/b5b7b70553497c4ce08a835c156ff3b245366eba956fbceff99553b1ccdc4e42?d=mp&s=160"},"body":"From: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n\nUse the previous commit's abstraction mechanism for SHA1 to\nsupport a chunked implementation of SHA1_Update() which limits\nthe amount of data in the chunk passed to SHA1_Update().\n\nThis is enabled by using the SHA1_MAX_BLOCK_SIZE envvar to\nspecify chunk size.  When using Apple's CommonCrypto library\nthis is enable and set to 1GiB.\n\nSigned-off-by: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n---\n Makefile                     | 13 +++++++++++++\n cache.h                      | 17 +++++++++++++++--\n compat/apple-common-crypto.h |  4 ++++\n compat/sha1-chunked.c        | 19 +++++++++++++++++++\n compat/sha1-chunked.h        |  2 ++\n 5 files changed, 53 insertions(+), 2 deletions(-)\n create mode 100644 compat/sha1-chunked.c\n create mode 100644 compat/sha1-chunked.h\n\ndiff --git a/Makefile b/Makefile\nindex 04c2231..6a4ca59 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -141,6 +141,10 @@ all::\n # Define PPC_SHA1 environment variable when running make to make use of\n # a bundled SHA1 routine optimized for PowerPC.\n #\n+# Define SHA1_MAX_BLOCK_SIZE to limit the amount of data that will be hashed\n+# in one call to the platform's SHA1_Update(). e.g. APPLE_COMMON_CRYPTO\n+# wants 'SHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' defined.\n+#\n # Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).\n #\n # Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).\n@@ -1335,6 +1339,11 @@ ifdef NO_POSIX_GOODIES\n \tBASIC_CFLAGS += -DNO_POSIX_GOODIES\n endif\n \n+ifdef APPLE_COMMON_CRYPTO\n+\t# Apple CommonCrypto requires chunking\n+\tSHA1_MAX_BLOCK_SIZE = 1024L*1024L*1024L\n+endif\n+\n ifdef BLK_SHA1\n \tSHA1_HEADER = \"block-sha1/sha1.h\"\n \tLIB_OBJS += block-sha1/sha1.o\n@@ -1353,6 +1362,10 @@ endif\n endif\n endif\n \n+ifdef SHA1_MAX_BLOCK_SIZE\n+\tLIB_OBJS += compat/sha1-chunked.o\n+\tBASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE=\"$(SHA1_MAX_BLOCK_SIZE)\"\n+endif\n ifdef NO_PERL_MAKEMAKER\n \texport NO_PERL_MAKEMAKER\n endif\ndiff --git a/cache.h b/cache.h\nindex a934a2e..182ac62 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -11,7 +11,7 @@\n #include \"string-list.h\"\n \n #include SHA1_HEADER\n-#ifndef git_SHA_CTX\n+#ifndef platform_SHA_CTX\n \n /* platform's underlying implementation of SHA1, could be OpenSSL,\n    blk_SHA, Apple CommonCrypto, etc...  */\n@@ -20,15 +20,28 @@\n #define platform_SHA1_Update\tSHA1_Update\n #define platform_SHA1_Final    \tSHA1_Final\n \n+#endif\n+\n /* git may call platform's underlying implementation of SHA1 directly,\n    or may call it through a wrapper */\n+\n+#ifndef git_SHA_CTX\n+\n+#ifdef SHA1_MAX_BLOCK_SIZE\n+#include \"compat/sha1-chunked.h\"\n+#define git_SHA_CTX\t\tplatform_SHA_CTX\n+#define git_SHA1_Init\t\tplatform_SHA1_Init\n+#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n+#define git_SHA1_Final\t\tplatform_SHA1_Final\n+#else\n #define git_SHA_CTX\t\tplatform_SHA_CTX\n #define git_SHA1_Init\t\tplatform_SHA1_Init\n #define git_SHA1_Update\t\tplatform_SHA1_Update\n #define git_SHA1_Final\t\tplatform_SHA1_Final\n-\n #endif\n \n+#endif \n+\n #include <zlib.h>\n typedef struct git_zstream {\n \tz_stream z;\ndiff --git a/compat/apple-common-crypto.h b/compat/apple-common-crypto.h\nindex c8b9b0e..d3fb264 100644\n--- a/compat/apple-common-crypto.h\n+++ b/compat/apple-common-crypto.h\n@@ -16,6 +16,10 @@\n #undef TYPE_BOOL\n #endif\n \n+#ifndef SHA1_MAX_BLOCK_SIZE\n+#error Using Apple Common Crypto library requires setting SHA1_MAX_BLOCK_SIZE\n+#endif\n+\n #ifdef APPLE_LION_OR_NEWER\n #define git_CC_error_check(pattern, err) \\\n \tdo { \\\ndiff --git a/compat/sha1-chunked.c b/compat/sha1-chunked.c\nnew file mode 100644\nindex 0000000..6adfcfd\n--- /dev/null\n+++ b/compat/sha1-chunked.c\n@@ -0,0 +1,19 @@\n+#include \"cache.h\"\n+\n+int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)\n+{\n+\tsize_t nr;\n+\tsize_t total = 0;\n+\tconst char *cdata = (const char*)data;\n+\n+\twhile (len) {\n+\t\tnr = len;\n+\t\tif (nr > SHA1_MAX_BLOCK_SIZE)\n+\t\t\tnr = SHA1_MAX_BLOCK_SIZE;\n+\t\tplatform_SHA1_Update(c, cdata, nr);\n+\t\ttotal += nr;\n+\t\tcdata += nr;\n+\t\tlen -= nr;\n+\t}\n+\treturn total;\n+}\ndiff --git a/compat/sha1-chunked.h b/compat/sha1-chunked.h\nnew file mode 100644\nindex 0000000..7b2df28\n--- /dev/null\n+++ b/compat/sha1-chunked.h\n@@ -0,0 +1,2 @@\n+\n+int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len);\n-- \n2.4.9 (Apple Git-60)\n"},{"id":"272946","messageId":"1446705523-30701-3-git-send-email-apahlevan@ieee.org","threadId":"40727","inReplyTo":"1446705523-30701-1-git-send-email-apahlevan@ieee.org","subject":"[PATCH v4 3/3] Move all the SHA1 implementations into one directory","fromName":"","fromEmail":"atousa.p@gmail.com","sentAt":"2015-11-05T06:38:43Z","receivedAt":"2015-11-05T06:38:43Z","isPatch":true,"sender":{"key":"atousa.p@gmail.com","avatar":"https://gravatar.com/avatar/b5b7b70553497c4ce08a835c156ff3b245366eba956fbceff99553b1ccdc4e42?d=mp&s=160"},"body":"From: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n\nThe various SHA1 implementations were spread around in 3 directories.\nThis makes it easier to understand what implementations are\navailable at a glance.\n\nSigned-off-by: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n---\n Makefile              |  10 +-\n block-sha1/sha1.c     | 251 --------------------------------------------------\n block-sha1/sha1.h     |  22 -----\n cache.h               |   2 +-\n compat/sha1-chunked.c |  19 ----\n compat/sha1-chunked.h |   2 -\n ppc/sha1.c            |  72 ---------------\n ppc/sha1.h            |  25 -----\n ppc/sha1ppc.S         | 224 --------------------------------------------\n sha1/blk-sha1.c       | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++\n sha1/blk-sha1.h       |  22 +++++\n sha1/chk-sha1.c       |  19 ++++\n sha1/chk-sha1.h       |   2 +\n sha1/ppc-sha1.c       |  72 +++++++++++++++\n sha1/ppc-sha1.h       |  25 +++++\n sha1/ppc-sha1asm.S    | 224 ++++++++++++++++++++++++++++++++++++++++++++\n 16 files changed, 621 insertions(+), 621 deletions(-)\n delete mode 100644 block-sha1/sha1.c\n delete mode 100644 block-sha1/sha1.h\n delete mode 100644 compat/sha1-chunked.c\n delete mode 100644 compat/sha1-chunked.h\n delete mode 100644 ppc/sha1.c\n delete mode 100644 ppc/sha1.h\n delete mode 100644 ppc/sha1ppc.S\n create mode 100644 sha1/blk-sha1.c\n create mode 100644 sha1/blk-sha1.h\n create mode 100644 sha1/chk-sha1.c\n create mode 100644 sha1/chk-sha1.h\n create mode 100644 sha1/ppc-sha1.c\n create mode 100644 sha1/ppc-sha1.h\n create mode 100644 sha1/ppc-sha1asm.S\n\ndiff --git a/Makefile b/Makefile\nindex 6a4ca59..94f74d7 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1345,12 +1345,12 @@ ifdef APPLE_COMMON_CRYPTO\n endif\n \n ifdef BLK_SHA1\n-\tSHA1_HEADER = \"block-sha1/sha1.h\"\n-\tLIB_OBJS += block-sha1/sha1.o\n+\tSHA1_HEADER = \"sha1/blk-sha1.h\"\n+\tLIB_OBJS += sha1/blk-sha1.o\n else\n ifdef PPC_SHA1\n-\tSHA1_HEADER = \"ppc/sha1.h\"\n-\tLIB_OBJS += ppc/sha1.o ppc/sha1ppc.o\n+\tSHA1_HEADER = \"sha1/ppc-sha1.h\"\n+\tLIB_OBJS += sha1/ppc-sha1.o sha1/ppc-sha1asm.o\n else\n ifdef APPLE_COMMON_CRYPTO\n \tCOMPAT_CFLAGS += -DCOMMON_DIGEST_FOR_OPENSSL\n@@ -1363,7 +1363,7 @@ endif\n endif\n \n ifdef SHA1_MAX_BLOCK_SIZE\n-\tLIB_OBJS += compat/sha1-chunked.o\n+\tLIB_OBJS += sha1/chk-sha1.o\n \tBASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE=\"$(SHA1_MAX_BLOCK_SIZE)\"\n endif\n ifdef NO_PERL_MAKEMAKER\ndiff --git a/block-sha1/sha1.c b/block-sha1/sha1.c\ndeleted file mode 100644\nindex 22b125c..0000000\n--- a/block-sha1/sha1.c\n+++ /dev/null\n@@ -1,251 +0,0 @@\n-/*\n- * SHA1 routine optimized to do word accesses rather than byte accesses,\n- * and to avoid unnecessary copies into the context array.\n- *\n- * This was initially based on the Mozilla SHA1 implementation, although\n- * none of the original Mozilla code remains.\n- */\n-\n-/* this is only to get definitions for memcpy(), ntohl() and htonl() */\n-#include \"../git-compat-util.h\"\n-\n-#include \"sha1.h\"\n-\n-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))\n-\n-/*\n- * Force usage of rol or ror by selecting the one with the smaller constant.\n- * It _can_ generate slightly smaller code (a constant of 1 is special), but\n- * perhaps more importantly it's possibly faster on any uarch that does a\n- * rotate with a loop.\n- */\n-\n-#define SHA_ASM(op, x, n) ({ unsigned int __res; __asm__(op \" %1,%0\":\"=r\" (__res):\"i\" (n), \"0\" (x)); __res; })\n-#define SHA_ROL(x,n)\tSHA_ASM(\"rol\", x, n)\n-#define SHA_ROR(x,n)\tSHA_ASM(\"ror\", x, n)\n-\n-#else\n-\n-#define SHA_ROT(X,l,r)\t(((X) << (l)) | ((X) >> (r)))\n-#define SHA_ROL(X,n)\tSHA_ROT(X,n,32-(n))\n-#define SHA_ROR(X,n)\tSHA_ROT(X,32-(n),n)\n-\n-#endif\n-\n-/*\n- * If you have 32 registers or more, the compiler can (and should)\n- * try to change the array[] accesses into registers. However, on\n- * machines with less than ~25 registers, that won't really work,\n- * and at least gcc will make an unholy mess of it.\n- *\n- * So to avoid that mess which just slows things down, we force\n- * the stores to memory to actually happen (we might be better off\n- * with a 'W(t)=(val);asm(\"\":\"+m\" (W(t))' there instead, as\n- * suggested by Artur Skawina - that will also make gcc unable to\n- * try to do the silly \"optimize away loads\" part because it won't\n- * see what the value will be).\n- *\n- * Ben Herrenschmidt reports that on PPC, the C version comes close\n- * to the optimized asm with this (ie on PPC you don't want that\n- * 'volatile', since there are lots of registers).\n- *\n- * On ARM we get the best code generation by forcing a full memory barrier\n- * between each SHA_ROUND, otherwise gcc happily get wild with spilling and\n- * the stack frame size simply explode and performance goes down the drain.\n- */\n-\n-#if defined(__i386__) || defined(__x86_64__)\n-  #define setW(x, val) (*(volatile unsigned int *)&W(x) = (val))\n-#elif defined(__GNUC__) && defined(__arm__)\n-  #define setW(x, val) do { W(x) = (val); __asm__(\"\":::\"memory\"); } while (0)\n-#else\n-  #define setW(x, val) (W(x) = (val))\n-#endif\n-\n-/* This \"rolls\" over the 512-bit array */\n-#define W(x) (array[(x)&15])\n-\n-/*\n- * Where do we get the source from? The first 16 iterations get it from\n- * the input data, the next mix it from the 512-bit array.\n- */\n-#define SHA_SRC(t) get_be32((unsigned char *) block + (t)*4)\n-#define SHA_MIX(t) SHA_ROL(W((t)+13) ^ W((t)+8) ^ W((t)+2) ^ W(t), 1);\n-\n-#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \\\n-\tunsigned int TEMP = input(t); setW(t, TEMP); \\\n-\tE += TEMP + SHA_ROL(A,5) + (fn) + (constant); \\\n-\tB = SHA_ROR(B, 2); } while (0)\n-\n-#define T_0_15(t, A, B, C, D, E)  SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )\n-#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )\n-#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )\n-#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )\n-#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) ,  0xca62c1d6, A, B, C, D, E )\n-\n-static void blk_SHA1_Block(blk_SHA_CTX *ctx, const void *block)\n-{\n-\tunsigned int A,B,C,D,E;\n-\tunsigned int array[16];\n-\n-\tA = ctx->H[0];\n-\tB = ctx->H[1];\n-\tC = ctx->H[2];\n-\tD = ctx->H[3];\n-\tE = ctx->H[4];\n-\n-\t/* Round 1 - iterations 0-16 take their input from 'block' */\n-\tT_0_15( 0, A, B, C, D, E);\n-\tT_0_15( 1, E, A, B, C, D);\n-\tT_0_15( 2, D, E, A, B, C);\n-\tT_0_15( 3, C, D, E, A, B);\n-\tT_0_15( 4, B, C, D, E, A);\n-\tT_0_15( 5, A, B, C, D, E);\n-\tT_0_15( 6, E, A, B, C, D);\n-\tT_0_15( 7, D, E, A, B, C);\n-\tT_0_15( 8, C, D, E, A, B);\n-\tT_0_15( 9, B, C, D, E, A);\n-\tT_0_15(10, A, B, C, D, E);\n-\tT_0_15(11, E, A, B, C, D);\n-\tT_0_15(12, D, E, A, B, C);\n-\tT_0_15(13, C, D, E, A, B);\n-\tT_0_15(14, B, C, D, E, A);\n-\tT_0_15(15, A, B, C, D, E);\n-\n-\t/* Round 1 - tail. Input from 512-bit mixing array */\n-\tT_16_19(16, E, A, B, C, D);\n-\tT_16_19(17, D, E, A, B, C);\n-\tT_16_19(18, C, D, E, A, B);\n-\tT_16_19(19, B, C, D, E, A);\n-\n-\t/* Round 2 */\n-\tT_20_39(20, A, B, C, D, E);\n-\tT_20_39(21, E, A, B, C, D);\n-\tT_20_39(22, D, E, A, B, C);\n-\tT_20_39(23, C, D, E, A, B);\n-\tT_20_39(24, B, C, D, E, A);\n-\tT_20_39(25, A, B, C, D, E);\n-\tT_20_39(26, E, A, B, C, D);\n-\tT_20_39(27, D, E, A, B, C);\n-\tT_20_39(28, C, D, E, A, B);\n-\tT_20_39(29, B, C, D, E, A);\n-\tT_20_39(30, A, B, C, D, E);\n-\tT_20_39(31, E, A, B, C, D);\n-\tT_20_39(32, D, E, A, B, C);\n-\tT_20_39(33, C, D, E, A, B);\n-\tT_20_39(34, B, C, D, E, A);\n-\tT_20_39(35, A, B, C, D, E);\n-\tT_20_39(36, E, A, B, C, D);\n-\tT_20_39(37, D, E, A, B, C);\n-\tT_20_39(38, C, D, E, A, B);\n-\tT_20_39(39, B, C, D, E, A);\n-\n-\t/* Round 3 */\n-\tT_40_59(40, A, B, C, D, E);\n-\tT_40_59(41, E, A, B, C, D);\n-\tT_40_59(42, D, E, A, B, C);\n-\tT_40_59(43, C, D, E, A, B);\n-\tT_40_59(44, B, C, D, E, A);\n-\tT_40_59(45, A, B, C, D, E);\n-\tT_40_59(46, E, A, B, C, D);\n-\tT_40_59(47, D, E, A, B, C);\n-\tT_40_59(48, C, D, E, A, B);\n-\tT_40_59(49, B, C, D, E, A);\n-\tT_40_59(50, A, B, C, D, E);\n-\tT_40_59(51, E, A, B, C, D);\n-\tT_40_59(52, D, E, A, B, C);\n-\tT_40_59(53, C, D, E, A, B);\n-\tT_40_59(54, B, C, D, E, A);\n-\tT_40_59(55, A, B, C, D, E);\n-\tT_40_59(56, E, A, B, C, D);\n-\tT_40_59(57, D, E, A, B, C);\n-\tT_40_59(58, C, D, E, A, B);\n-\tT_40_59(59, B, C, D, E, A);\n-\n-\t/* Round 4 */\n-\tT_60_79(60, A, B, C, D, E);\n-\tT_60_79(61, E, A, B, C, D);\n-\tT_60_79(62, D, E, A, B, C);\n-\tT_60_79(63, C, D, E, A, B);\n-\tT_60_79(64, B, C, D, E, A);\n-\tT_60_79(65, A, B, C, D, E);\n-\tT_60_79(66, E, A, B, C, D);\n-\tT_60_79(67, D, E, A, B, C);\n-\tT_60_79(68, C, D, E, A, B);\n-\tT_60_79(69, B, C, D, E, A);\n-\tT_60_79(70, A, B, C, D, E);\n-\tT_60_79(71, E, A, B, C, D);\n-\tT_60_79(72, D, E, A, B, C);\n-\tT_60_79(73, C, D, E, A, B);\n-\tT_60_79(74, B, C, D, E, A);\n-\tT_60_79(75, A, B, C, D, E);\n-\tT_60_79(76, E, A, B, C, D);\n-\tT_60_79(77, D, E, A, B, C);\n-\tT_60_79(78, C, D, E, A, B);\n-\tT_60_79(79, B, C, D, E, A);\n-\n-\tctx->H[0] += A;\n-\tctx->H[1] += B;\n-\tctx->H[2] += C;\n-\tctx->H[3] += D;\n-\tctx->H[4] += E;\n-}\n-\n-void blk_SHA1_Init(blk_SHA_CTX *ctx)\n-{\n-\tctx->size = 0;\n-\n-\t/* Initialize H with the magic constants (see FIPS180 for constants) */\n-\tctx->H[0] = 0x67452301;\n-\tctx->H[1] = 0xefcdab89;\n-\tctx->H[2] = 0x98badcfe;\n-\tctx->H[3] = 0x10325476;\n-\tctx->H[4] = 0xc3d2e1f0;\n-}\n-\n-void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)\n-{\n-\tunsigned int lenW = ctx->size & 63;\n-\n-\tctx->size += len;\n-\n-\t/* Read the data into W and process blocks as they get full */\n-\tif (lenW) {\n-\t\tunsigned int left = 64 - lenW;\n-\t\tif (len < left)\n-\t\t\tleft = len;\n-\t\tmemcpy(lenW + (char *)ctx->W, data, left);\n-\t\tlenW = (lenW + left) & 63;\n-\t\tlen -= left;\n-\t\tdata = ((const char *)data + left);\n-\t\tif (lenW)\n-\t\t\treturn;\n-\t\tblk_SHA1_Block(ctx, ctx->W);\n-\t}\n-\twhile (len >= 64) {\n-\t\tblk_SHA1_Block(ctx, data);\n-\t\tdata = ((const char *)data + 64);\n-\t\tlen -= 64;\n-\t}\n-\tif (len)\n-\t\tmemcpy(ctx->W, data, len);\n-}\n-\n-void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)\n-{\n-\tstatic const unsigned char pad[64] = { 0x80 };\n-\tunsigned int padlen[2];\n-\tint i;\n-\n-\t/* Pad with a binary 1 (ie 0x80), then zeroes, then length */\n-\tpadlen[0] = htonl((uint32_t)(ctx->size >> 29));\n-\tpadlen[1] = htonl((uint32_t)(ctx->size << 3));\n-\n-\ti = ctx->size & 63;\n-\tblk_SHA1_Update(ctx, pad, 1 + (63 & (55 - i)));\n-\tblk_SHA1_Update(ctx, padlen, 8);\n-\n-\t/* Output hash */\n-\tfor (i = 0; i < 5; i++)\n-\t\tput_be32(hashout + i * 4, ctx->H[i]);\n-}\ndiff --git a/block-sha1/sha1.h b/block-sha1/sha1.h\ndeleted file mode 100644\nindex b864df6..0000000\n--- a/block-sha1/sha1.h\n+++ /dev/null\n@@ -1,22 +0,0 @@\n-/*\n- * SHA1 routine optimized to do word accesses rather than byte accesses,\n- * and to avoid unnecessary copies into the context array.\n- *\n- * This was initially based on the Mozilla SHA1 implementation, although\n- * none of the original Mozilla code remains.\n- */\n-\n-typedef struct {\n-\tunsigned long long size;\n-\tunsigned int H[5];\n-\tunsigned int W[16];\n-} blk_SHA_CTX;\n-\n-void blk_SHA1_Init(blk_SHA_CTX *ctx);\n-void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);\n-void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);\n-\n-#define git_SHA_CTX\tblk_SHA_CTX\n-#define git_SHA1_Init\tblk_SHA1_Init\n-#define git_SHA1_Update\tblk_SHA1_Update\n-#define git_SHA1_Final\tblk_SHA1_Final\ndiff --git a/cache.h b/cache.h\nindex 182ac62..961da4e 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -28,7 +28,7 @@\n #ifndef git_SHA_CTX\n \n #ifdef SHA1_MAX_BLOCK_SIZE\n-#include \"compat/sha1-chunked.h\"\n+#include \"sha1/chk-sha1.h\"\n #define git_SHA_CTX\t\tplatform_SHA_CTX\n #define git_SHA1_Init\t\tplatform_SHA1_Init\n #define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\ndiff --git a/compat/sha1-chunked.c b/compat/sha1-chunked.c\ndeleted file mode 100644\nindex 6adfcfd..0000000\n--- a/compat/sha1-chunked.c\n+++ /dev/null\n@@ -1,19 +0,0 @@\n-#include \"cache.h\"\n-\n-int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)\n-{\n-\tsize_t nr;\n-\tsize_t total = 0;\n-\tconst char *cdata = (const char*)data;\n-\n-\twhile (len) {\n-\t\tnr = len;\n-\t\tif (nr > SHA1_MAX_BLOCK_SIZE)\n-\t\t\tnr = SHA1_MAX_BLOCK_SIZE;\n-\t\tplatform_SHA1_Update(c, cdata, nr);\n-\t\ttotal += nr;\n-\t\tcdata += nr;\n-\t\tlen -= nr;\n-\t}\n-\treturn total;\n-}\ndiff --git a/compat/sha1-chunked.h b/compat/sha1-chunked.h\ndeleted file mode 100644\nindex 7b2df28..0000000\n--- a/compat/sha1-chunked.h\n+++ /dev/null\n@@ -1,2 +0,0 @@\n-\n-int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len);\ndiff --git a/ppc/sha1.c b/ppc/sha1.c\ndeleted file mode 100644\nindex ec6a192..0000000\n--- a/ppc/sha1.c\n+++ /dev/null\n@@ -1,72 +0,0 @@\n-/*\n- * SHA-1 implementation.\n- *\n- * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>\n- *\n- * This version assumes we are running on a big-endian machine.\n- * It calls an external sha1_core() to process blocks of 64 bytes.\n- */\n-#include <stdio.h>\n-#include <string.h>\n-#include \"sha1.h\"\n-\n-extern void ppc_sha1_core(uint32_t *hash, const unsigned char *p,\n-\t\t\t  unsigned int nblocks);\n-\n-int ppc_SHA1_Init(ppc_SHA_CTX *c)\n-{\n-\tc->hash[0] = 0x67452301;\n-\tc->hash[1] = 0xEFCDAB89;\n-\tc->hash[2] = 0x98BADCFE;\n-\tc->hash[3] = 0x10325476;\n-\tc->hash[4] = 0xC3D2E1F0;\n-\tc->len = 0;\n-\tc->cnt = 0;\n-\treturn 0;\n-}\n-\n-int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *ptr, unsigned long n)\n-{\n-\tunsigned long nb;\n-\tconst unsigned char *p = ptr;\n-\n-\tc->len += (uint64_t) n << 3;\n-\twhile (n != 0) {\n-\t\tif (c->cnt || n < 64) {\n-\t\t\tnb = 64 - c->cnt;\n-\t\t\tif (nb > n)\n-\t\t\t\tnb = n;\n-\t\t\tmemcpy(&c->buf.b[c->cnt], p, nb);\n-\t\t\tif ((c->cnt += nb) == 64) {\n-\t\t\t\tppc_sha1_core(c->hash, c->buf.b, 1);\n-\t\t\t\tc->cnt = 0;\n-\t\t\t}\n-\t\t} else {\n-\t\t\tnb = n >> 6;\n-\t\t\tppc_sha1_core(c->hash, p, nb);\n-\t\t\tnb <<= 6;\n-\t\t}\n-\t\tn -= nb;\n-\t\tp += nb;\n-\t}\n-\treturn 0;\n-}\n-\n-int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c)\n-{\n-\tunsigned int cnt = c->cnt;\n-\n-\tc->buf.b[cnt++] = 0x80;\n-\tif (cnt > 56) {\n-\t\tif (cnt < 64)\n-\t\t\tmemset(&c->buf.b[cnt], 0, 64 - cnt);\n-\t\tppc_sha1_core(c->hash, c->buf.b, 1);\n-\t\tcnt = 0;\n-\t}\n-\tif (cnt < 56)\n-\t\tmemset(&c->buf.b[cnt], 0, 56 - cnt);\n-\tc->buf.l[7] = c->len;\n-\tppc_sha1_core(c->hash, c->buf.b, 1);\n-\tmemcpy(hash, c->hash, 20);\n-\treturn 0;\n-}\ndiff --git a/ppc/sha1.h b/ppc/sha1.h\ndeleted file mode 100644\nindex c405f73..0000000\n--- a/ppc/sha1.h\n+++ /dev/null\n@@ -1,25 +0,0 @@\n-/*\n- * SHA-1 implementation.\n- *\n- * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>\n- */\n-#include <stdint.h>\n-\n-typedef struct {\n-\tuint32_t hash[5];\n-\tuint32_t cnt;\n-\tuint64_t len;\n-\tunion {\n-\t\tunsigned char b[64];\n-\t\tuint64_t l[8];\n-\t} buf;\n-} ppc_SHA_CTX;\n-\n-int ppc_SHA1_Init(ppc_SHA_CTX *c);\n-int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *p, unsigned long n);\n-int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c);\n-\n-#define git_SHA_CTX\tppc_SHA_CTX\n-#define git_SHA1_Init\tppc_SHA1_Init\n-#define git_SHA1_Update\tppc_SHA1_Update\n-#define git_SHA1_Final\tppc_SHA1_Final\ndiff --git a/ppc/sha1ppc.S b/ppc/sha1ppc.S\ndeleted file mode 100644\nindex 1711eef..0000000\n--- a/ppc/sha1ppc.S\n+++ /dev/null\n@@ -1,224 +0,0 @@\n-/*\n- * SHA-1 implementation for PowerPC.\n- *\n- * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>\n- */\n-\n-/*\n- * PowerPC calling convention:\n- * %r0 - volatile temp\n- * %r1 - stack pointer.\n- * %r2 - reserved\n- * %r3-%r12 - Incoming arguments & return values; volatile.\n- * %r13-%r31 - Callee-save registers\n- * %lr - Return address, volatile\n- * %ctr - volatile\n- *\n- * Register usage in this routine:\n- * %r0 - temp\n- * %r3 - argument (pointer to 5 words of SHA state)\n- * %r4 - argument (pointer to data to hash)\n- * %r5 - Constant K in SHA round (initially number of blocks to hash)\n- * %r6-%r10 - Working copies of SHA variables A..E (actually E..A order)\n- * %r11-%r26 - Data being hashed W[].\n- * %r27-%r31 - Previous copies of A..E, for final add back.\n- * %ctr - loop count\n- */\n-\n-\n-/*\n- * We roll the registers for A, B, C, D, E around on each\n- * iteration; E on iteration t is D on iteration t+1, and so on.\n- * We use registers 6 - 10 for this.  (Registers 27 - 31 hold\n- * the previous values.)\n- */\n-#define RA(t)\t(((t)+4)%5+6)\n-#define RB(t)\t(((t)+3)%5+6)\n-#define RC(t)\t(((t)+2)%5+6)\n-#define RD(t)\t(((t)+1)%5+6)\n-#define RE(t)\t(((t)+0)%5+6)\n-\n-/* We use registers 11 - 26 for the W values */\n-#define W(t)\t((t)%16+11)\n-\n-/* Register 5 is used for the constant k */\n-\n-/*\n- * The basic SHA-1 round function is:\n- * E += ROTL(A,5) + F(B,C,D) + W[i] + K;  B = ROTL(B,30)\n- * Then the variables are renamed: (A,B,C,D,E) = (E,A,B,C,D).\n- *\n- * Every 20 rounds, the function F() and the constant K changes:\n- * - 20 rounds of f0(b,c,d) = \"bit wise b ? c : d\" =  (^b & d) + (b & c)\n- * - 20 rounds of f1(b,c,d) = b^c^d = (b^d)^c\n- * - 20 rounds of f2(b,c,d) = majority(b,c,d) = (b&d) + ((b^d)&c)\n- * - 20 more rounds of f1(b,c,d)\n- *\n- * These are all scheduled for near-optimal performance on a G4.\n- * The G4 is a 3-issue out-of-order machine with 3 ALUs, but it can only\n- * *consider* starting the oldest 3 instructions per cycle.  So to get\n- * maximum performance out of it, you have to treat it as an in-order\n- * machine.  Which means interleaving the computation round t with the\n- * computation of W[t+4].\n- *\n- * The first 16 rounds use W values loaded directly from memory, while the\n- * remaining 64 use values computed from those first 16.  We preload\n- * 4 values before starting, so there are three kinds of rounds:\n- * - The first 12 (all f0) also load the W values from memory.\n- * - The next 64 compute W(i+4) in parallel. 8*f0, 20*f1, 20*f2, 16*f1.\n- * - The last 4 (all f1) do not do anything with W.\n- *\n- * Therefore, we have 6 different round functions:\n- * STEPD0_LOAD(t,s) - Perform round t and load W(s).  s < 16\n- * STEPD0_UPDATE(t,s) - Perform round t and compute W(s).  s >= 16.\n- * STEPD1_UPDATE(t,s)\n- * STEPD2_UPDATE(t,s)\n- * STEPD1(t) - Perform round t with no load or update.\n- *\n- * The G5 is more fully out-of-order, and can find the parallelism\n- * by itself.  The big limit is that it has a 2-cycle ALU latency, so\n- * even though it's 2-way, the code has to be scheduled as if it's\n- * 4-way, which can be a limit.  To help it, we try to schedule the\n- * read of RA(t) as late as possible so it doesn't stall waiting for\n- * the previous round's RE(t-1), and we try to rotate RB(t) as early\n- * as possible while reading RC(t) (= RB(t-1)) as late as possible.\n- */\n-\n-/* the initial loads. */\n-#define LOADW(s) \\\n-\tlwz\tW(s),(s)*4(%r4)\n-\n-/*\n- * Perform a step with F0, and load W(s).  Uses W(s) as a temporary\n- * before loading it.\n- * This is actually 10 instructions, which is an awkward fit.\n- * It can execute grouped as listed, or delayed one instruction.\n- * (If delayed two instructions, there is a stall before the start of the\n- * second line.)  Thus, two iterations take 7 cycles, 3.5 cycles per round.\n- */\n-#define STEPD0_LOAD(t,s) \\\n-add RE(t),RE(t),W(t); andc   %r0,RD(t),RB(t);  and    W(s),RC(t),RB(t); \\\n-add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;      rotlwi RB(t),RB(t),30;   \\\n-add RE(t),RE(t),W(s); add    %r0,%r0,%r5;      lwz    W(s),(s)*4(%r4);  \\\n-add RE(t),RE(t),%r0\n-\n-/*\n- * This is likewise awkward, 13 instructions.  However, it can also\n- * execute starting with 2 out of 3 possible moduli, so it does 2 rounds\n- * in 9 cycles, 4.5 cycles/round.\n- */\n-#define STEPD0_UPDATE(t,s,loadk...) \\\n-add RE(t),RE(t),W(t); andc   %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \\\n-add RE(t),RE(t),%r0;  and    %r0,RC(t),RB(t); xor    W(s),W(s),W((s)-8);      \\\n-add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     xor    W(s),W(s),W((s)-14);     \\\n-add RE(t),RE(t),%r5;  loadk; rotlwi RB(t),RB(t),30;  rotlwi W(s),W(s),1;     \\\n-add RE(t),RE(t),%r0\n-\n-/* Nicely optimal.  Conveniently, also the most common. */\n-#define STEPD1_UPDATE(t,s,loadk...) \\\n-add RE(t),RE(t),W(t); xor    %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \\\n-add RE(t),RE(t),%r5;  loadk; xor %r0,%r0,RC(t);  xor W(s),W(s),W((s)-8);      \\\n-add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     xor    W(s),W(s),W((s)-14);     \\\n-add RE(t),RE(t),%r0;  rotlwi RB(t),RB(t),30;  rotlwi W(s),W(s),1\n-\n-/*\n- * The naked version, no UPDATE, for the last 4 rounds.  3 cycles per.\n- * We could use W(s) as a temp register, but we don't need it.\n- */\n-#define STEPD1(t) \\\n-                        add   RE(t),RE(t),W(t); xor    %r0,RD(t),RB(t); \\\n-rotlwi RB(t),RB(t),30;  add   RE(t),RE(t),%r5;  xor    %r0,%r0,RC(t);   \\\n-add    RE(t),RE(t),%r0; rotlwi %r0,RA(t),5;     /* spare slot */        \\\n-add    RE(t),RE(t),%r0\n-\n-/*\n- * 14 instructions, 5 cycles per.  The majority function is a bit\n- * awkward to compute.  This can execute with a 1-instruction delay,\n- * but it causes a 2-instruction delay, which triggers a stall.\n- */\n-#define STEPD2_UPDATE(t,s,loadk...) \\\n-add RE(t),RE(t),W(t); and    %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \\\n-add RE(t),RE(t),%r0;  xor    %r0,RD(t),RB(t); xor    W(s),W(s),W((s)-8);      \\\n-add RE(t),RE(t),%r5;  loadk; and %r0,%r0,RC(t);  xor W(s),W(s),W((s)-14);     \\\n-add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     rotlwi W(s),W(s),1;             \\\n-add RE(t),RE(t),%r0;  rotlwi RB(t),RB(t),30\n-\n-#define STEP0_LOAD4(t,s)\t\t\\\n-\tSTEPD0_LOAD(t,s);\t\t\\\n-\tSTEPD0_LOAD((t+1),(s)+1);\t\\\n-\tSTEPD0_LOAD((t)+2,(s)+2);\t\\\n-\tSTEPD0_LOAD((t)+3,(s)+3)\n-\n-#define STEPUP4(fn, t, s, loadk...)\t\t\\\n-\tSTEP##fn##_UPDATE(t,s,);\t\t\\\n-\tSTEP##fn##_UPDATE((t)+1,(s)+1,);\t\\\n-\tSTEP##fn##_UPDATE((t)+2,(s)+2,);\t\\\n-\tSTEP##fn##_UPDATE((t)+3,(s)+3,loadk)\n-\n-#define STEPUP20(fn, t, s, loadk...)\t\\\n-\tSTEPUP4(fn, t, s,);\t\t\\\n-\tSTEPUP4(fn, (t)+4, (s)+4,);\t\\\n-\tSTEPUP4(fn, (t)+8, (s)+8,);\t\\\n-\tSTEPUP4(fn, (t)+12, (s)+12,);\t\\\n-\tSTEPUP4(fn, (t)+16, (s)+16, loadk)\n-\n-\t.globl\tppc_sha1_core\n-ppc_sha1_core:\n-\tstwu\t%r1,-80(%r1)\n-\tstmw\t%r13,4(%r1)\n-\n-\t/* Load up A - E */\n-\tlmw\t%r27,0(%r3)\n-\n-\tmtctr\t%r5\n-\n-1:\n-\tLOADW(0)\n-\tlis\t%r5,0x5a82\n-\tmr\tRE(0),%r31\n-\tLOADW(1)\n-\tmr\tRD(0),%r30\n-\tmr\tRC(0),%r29\n-\tLOADW(2)\n-\tori\t%r5,%r5,0x7999\t/* K0-19 */\n-\tmr\tRB(0),%r28\n-\tLOADW(3)\n-\tmr\tRA(0),%r27\n-\n-\tSTEP0_LOAD4(0, 4)\n-\tSTEP0_LOAD4(4, 8)\n-\tSTEP0_LOAD4(8, 12)\n-\tSTEPUP4(D0, 12, 16,)\n-\tSTEPUP4(D0, 16, 20, lis %r5,0x6ed9)\n-\n-\tori\t%r5,%r5,0xeba1\t/* K20-39 */\n-\tSTEPUP20(D1, 20, 24, lis %r5,0x8f1b)\n-\n-\tori\t%r5,%r5,0xbcdc\t/* K40-59 */\n-\tSTEPUP20(D2, 40, 44, lis %r5,0xca62)\n-\n-\tori\t%r5,%r5,0xc1d6\t/* K60-79 */\n-\tSTEPUP4(D1, 60, 64,)\n-\tSTEPUP4(D1, 64, 68,)\n-\tSTEPUP4(D1, 68, 72,)\n-\tSTEPUP4(D1, 72, 76,)\n-\taddi\t%r4,%r4,64\n-\tSTEPD1(76)\n-\tSTEPD1(77)\n-\tSTEPD1(78)\n-\tSTEPD1(79)\n-\n-\t/* Add results to original values */\n-\tadd\t%r31,%r31,RE(0)\n-\tadd\t%r30,%r30,RD(0)\n-\tadd\t%r29,%r29,RC(0)\n-\tadd\t%r28,%r28,RB(0)\n-\tadd\t%r27,%r27,RA(0)\n-\n-\tbdnz\t1b\n-\n-\t/* Save final hash, restore registers, and return */\n-\tstmw\t%r27,0(%r3)\n-\tlmw\t%r13,4(%r1)\n-\taddi\t%r1,%r1,80\n-\tblr\ndiff --git a/sha1/blk-sha1.c b/sha1/blk-sha1.c\nnew file mode 100644\nindex 0000000..abacf05\n--- /dev/null\n+++ b/sha1/blk-sha1.c\n@@ -0,0 +1,251 @@\n+/*\n+ * SHA1 routine optimized to do word accesses rather than byte accesses,\n+ * and to avoid unnecessary copies into the context array.\n+ *\n+ * This was initially based on the Mozilla SHA1 implementation, although\n+ * none of the original Mozilla code remains.\n+ */\n+\n+/* this is only to get definitions for memcpy(), ntohl() and htonl() */\n+#include \"../git-compat-util.h\"\n+\n+#include \"blk-sha1.h\"\n+\n+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))\n+\n+/*\n+ * Force usage of rol or ror by selecting the one with the smaller constant.\n+ * It _can_ generate slightly smaller code (a constant of 1 is special), but\n+ * perhaps more importantly it's possibly faster on any uarch that does a\n+ * rotate with a loop.\n+ */\n+\n+#define SHA_ASM(op, x, n) ({ unsigned int __res; __asm__(op \" %1,%0\":\"=r\" (__res):\"i\" (n), \"0\" (x)); __res; })\n+#define SHA_ROL(x,n)\tSHA_ASM(\"rol\", x, n)\n+#define SHA_ROR(x,n)\tSHA_ASM(\"ror\", x, n)\n+\n+#else\n+\n+#define SHA_ROT(X,l,r)\t(((X) << (l)) | ((X) >> (r)))\n+#define SHA_ROL(X,n)\tSHA_ROT(X,n,32-(n))\n+#define SHA_ROR(X,n)\tSHA_ROT(X,32-(n),n)\n+\n+#endif\n+\n+/*\n+ * If you have 32 registers or more, the compiler can (and should)\n+ * try to change the array[] accesses into registers. However, on\n+ * machines with less than ~25 registers, that won't really work,\n+ * and at least gcc will make an unholy mess of it.\n+ *\n+ * So to avoid that mess which just slows things down, we force\n+ * the stores to memory to actually happen (we might be better off\n+ * with a 'W(t)=(val);asm(\"\":\"+m\" (W(t))' there instead, as\n+ * suggested by Artur Skawina - that will also make gcc unable to\n+ * try to do the silly \"optimize away loads\" part because it won't\n+ * see what the value will be).\n+ *\n+ * Ben Herrenschmidt reports that on PPC, the C version comes close\n+ * to the optimized asm with this (ie on PPC you don't want that\n+ * 'volatile', since there are lots of registers).\n+ *\n+ * On ARM we get the best code generation by forcing a full memory barrier\n+ * between each SHA_ROUND, otherwise gcc happily get wild with spilling and\n+ * the stack frame size simply explode and performance goes down the drain.\n+ */\n+\n+#if defined(__i386__) || defined(__x86_64__)\n+  #define setW(x, val) (*(volatile unsigned int *)&W(x) = (val))\n+#elif defined(__GNUC__) && defined(__arm__)\n+  #define setW(x, val) do { W(x) = (val); __asm__(\"\":::\"memory\"); } while (0)\n+#else\n+  #define setW(x, val) (W(x) = (val))\n+#endif\n+\n+/* This \"rolls\" over the 512-bit array */\n+#define W(x) (array[(x)&15])\n+\n+/*\n+ * Where do we get the source from? The first 16 iterations get it from\n+ * the input data, the next mix it from the 512-bit array.\n+ */\n+#define SHA_SRC(t) get_be32((unsigned char *) block + (t)*4)\n+#define SHA_MIX(t) SHA_ROL(W((t)+13) ^ W((t)+8) ^ W((t)+2) ^ W(t), 1);\n+\n+#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \\\n+\tunsigned int TEMP = input(t); setW(t, TEMP); \\\n+\tE += TEMP + SHA_ROL(A,5) + (fn) + (constant); \\\n+\tB = SHA_ROR(B, 2); } while (0)\n+\n+#define T_0_15(t, A, B, C, D, E)  SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )\n+#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )\n+#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )\n+#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )\n+#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) ,  0xca62c1d6, A, B, C, D, E )\n+\n+static void blk_SHA1_Block(blk_SHA_CTX *ctx, const void *block)\n+{\n+\tunsigned int A,B,C,D,E;\n+\tunsigned int array[16];\n+\n+\tA = ctx->H[0];\n+\tB = ctx->H[1];\n+\tC = ctx->H[2];\n+\tD = ctx->H[3];\n+\tE = ctx->H[4];\n+\n+\t/* Round 1 - iterations 0-16 take their input from 'block' */\n+\tT_0_15( 0, A, B, C, D, E);\n+\tT_0_15( 1, E, A, B, C, D);\n+\tT_0_15( 2, D, E, A, B, C);\n+\tT_0_15( 3, C, D, E, A, B);\n+\tT_0_15( 4, B, C, D, E, A);\n+\tT_0_15( 5, A, B, C, D, E);\n+\tT_0_15( 6, E, A, B, C, D);\n+\tT_0_15( 7, D, E, A, B, C);\n+\tT_0_15( 8, C, D, E, A, B);\n+\tT_0_15( 9, B, C, D, E, A);\n+\tT_0_15(10, A, B, C, D, E);\n+\tT_0_15(11, E, A, B, C, D);\n+\tT_0_15(12, D, E, A, B, C);\n+\tT_0_15(13, C, D, E, A, B);\n+\tT_0_15(14, B, C, D, E, A);\n+\tT_0_15(15, A, B, C, D, E);\n+\n+\t/* Round 1 - tail. Input from 512-bit mixing array */\n+\tT_16_19(16, E, A, B, C, D);\n+\tT_16_19(17, D, E, A, B, C);\n+\tT_16_19(18, C, D, E, A, B);\n+\tT_16_19(19, B, C, D, E, A);\n+\n+\t/* Round 2 */\n+\tT_20_39(20, A, B, C, D, E);\n+\tT_20_39(21, E, A, B, C, D);\n+\tT_20_39(22, D, E, A, B, C);\n+\tT_20_39(23, C, D, E, A, B);\n+\tT_20_39(24, B, C, D, E, A);\n+\tT_20_39(25, A, B, C, D, E);\n+\tT_20_39(26, E, A, B, C, D);\n+\tT_20_39(27, D, E, A, B, C);\n+\tT_20_39(28, C, D, E, A, B);\n+\tT_20_39(29, B, C, D, E, A);\n+\tT_20_39(30, A, B, C, D, E);\n+\tT_20_39(31, E, A, B, C, D);\n+\tT_20_39(32, D, E, A, B, C);\n+\tT_20_39(33, C, D, E, A, B);\n+\tT_20_39(34, B, C, D, E, A);\n+\tT_20_39(35, A, B, C, D, E);\n+\tT_20_39(36, E, A, B, C, D);\n+\tT_20_39(37, D, E, A, B, C);\n+\tT_20_39(38, C, D, E, A, B);\n+\tT_20_39(39, B, C, D, E, A);\n+\n+\t/* Round 3 */\n+\tT_40_59(40, A, B, C, D, E);\n+\tT_40_59(41, E, A, B, C, D);\n+\tT_40_59(42, D, E, A, B, C);\n+\tT_40_59(43, C, D, E, A, B);\n+\tT_40_59(44, B, C, D, E, A);\n+\tT_40_59(45, A, B, C, D, E);\n+\tT_40_59(46, E, A, B, C, D);\n+\tT_40_59(47, D, E, A, B, C);\n+\tT_40_59(48, C, D, E, A, B);\n+\tT_40_59(49, B, C, D, E, A);\n+\tT_40_59(50, A, B, C, D, E);\n+\tT_40_59(51, E, A, B, C, D);\n+\tT_40_59(52, D, E, A, B, C);\n+\tT_40_59(53, C, D, E, A, B);\n+\tT_40_59(54, B, C, D, E, A);\n+\tT_40_59(55, A, B, C, D, E);\n+\tT_40_59(56, E, A, B, C, D);\n+\tT_40_59(57, D, E, A, B, C);\n+\tT_40_59(58, C, D, E, A, B);\n+\tT_40_59(59, B, C, D, E, A);\n+\n+\t/* Round 4 */\n+\tT_60_79(60, A, B, C, D, E);\n+\tT_60_79(61, E, A, B, C, D);\n+\tT_60_79(62, D, E, A, B, C);\n+\tT_60_79(63, C, D, E, A, B);\n+\tT_60_79(64, B, C, D, E, A);\n+\tT_60_79(65, A, B, C, D, E);\n+\tT_60_79(66, E, A, B, C, D);\n+\tT_60_79(67, D, E, A, B, C);\n+\tT_60_79(68, C, D, E, A, B);\n+\tT_60_79(69, B, C, D, E, A);\n+\tT_60_79(70, A, B, C, D, E);\n+\tT_60_79(71, E, A, B, C, D);\n+\tT_60_79(72, D, E, A, B, C);\n+\tT_60_79(73, C, D, E, A, B);\n+\tT_60_79(74, B, C, D, E, A);\n+\tT_60_79(75, A, B, C, D, E);\n+\tT_60_79(76, E, A, B, C, D);\n+\tT_60_79(77, D, E, A, B, C);\n+\tT_60_79(78, C, D, E, A, B);\n+\tT_60_79(79, B, C, D, E, A);\n+\n+\tctx->H[0] += A;\n+\tctx->H[1] += B;\n+\tctx->H[2] += C;\n+\tctx->H[3] += D;\n+\tctx->H[4] += E;\n+}\n+\n+void blk_SHA1_Init(blk_SHA_CTX *ctx)\n+{\n+\tctx->size = 0;\n+\n+\t/* Initialize H with the magic constants (see FIPS180 for constants) */\n+\tctx->H[0] = 0x67452301;\n+\tctx->H[1] = 0xefcdab89;\n+\tctx->H[2] = 0x98badcfe;\n+\tctx->H[3] = 0x10325476;\n+\tctx->H[4] = 0xc3d2e1f0;\n+}\n+\n+void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)\n+{\n+\tunsigned int lenW = ctx->size & 63;\n+\n+\tctx->size += len;\n+\n+\t/* Read the data into W and process blocks as they get full */\n+\tif (lenW) {\n+\t\tunsigned int left = 64 - lenW;\n+\t\tif (len < left)\n+\t\t\tleft = len;\n+\t\tmemcpy(lenW + (char *)ctx->W, data, left);\n+\t\tlenW = (lenW + left) & 63;\n+\t\tlen -= left;\n+\t\tdata = ((const char *)data + left);\n+\t\tif (lenW)\n+\t\t\treturn;\n+\t\tblk_SHA1_Block(ctx, ctx->W);\n+\t}\n+\twhile (len >= 64) {\n+\t\tblk_SHA1_Block(ctx, data);\n+\t\tdata = ((const char *)data + 64);\n+\t\tlen -= 64;\n+\t}\n+\tif (len)\n+\t\tmemcpy(ctx->W, data, len);\n+}\n+\n+void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)\n+{\n+\tstatic const unsigned char pad[64] = { 0x80 };\n+\tunsigned int padlen[2];\n+\tint i;\n+\n+\t/* Pad with a binary 1 (ie 0x80), then zeroes, then length */\n+\tpadlen[0] = htonl((uint32_t)(ctx->size >> 29));\n+\tpadlen[1] = htonl((uint32_t)(ctx->size << 3));\n+\n+\ti = ctx->size & 63;\n+\tblk_SHA1_Update(ctx, pad, 1 + (63 & (55 - i)));\n+\tblk_SHA1_Update(ctx, padlen, 8);\n+\n+\t/* Output hash */\n+\tfor (i = 0; i < 5; i++)\n+\t\tput_be32(hashout + i * 4, ctx->H[i]);\n+}\ndiff --git a/sha1/blk-sha1.h b/sha1/blk-sha1.h\nnew file mode 100644\nindex 0000000..b864df6\n--- /dev/null\n+++ b/sha1/blk-sha1.h\n@@ -0,0 +1,22 @@\n+/*\n+ * SHA1 routine optimized to do word accesses rather than byte accesses,\n+ * and to avoid unnecessary copies into the context array.\n+ *\n+ * This was initially based on the Mozilla SHA1 implementation, although\n+ * none of the original Mozilla code remains.\n+ */\n+\n+typedef struct {\n+\tunsigned long long size;\n+\tunsigned int H[5];\n+\tunsigned int W[16];\n+} blk_SHA_CTX;\n+\n+void blk_SHA1_Init(blk_SHA_CTX *ctx);\n+void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);\n+void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);\n+\n+#define git_SHA_CTX\tblk_SHA_CTX\n+#define git_SHA1_Init\tblk_SHA1_Init\n+#define git_SHA1_Update\tblk_SHA1_Update\n+#define git_SHA1_Final\tblk_SHA1_Final\ndiff --git a/sha1/chk-sha1.c b/sha1/chk-sha1.c\nnew file mode 100644\nindex 0000000..6adfcfd\n--- /dev/null\n+++ b/sha1/chk-sha1.c\n@@ -0,0 +1,19 @@\n+#include \"cache.h\"\n+\n+int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)\n+{\n+\tsize_t nr;\n+\tsize_t total = 0;\n+\tconst char *cdata = (const char*)data;\n+\n+\twhile (len) {\n+\t\tnr = len;\n+\t\tif (nr > SHA1_MAX_BLOCK_SIZE)\n+\t\t\tnr = SHA1_MAX_BLOCK_SIZE;\n+\t\tplatform_SHA1_Update(c, cdata, nr);\n+\t\ttotal += nr;\n+\t\tcdata += nr;\n+\t\tlen -= nr;\n+\t}\n+\treturn total;\n+}\ndiff --git a/sha1/chk-sha1.h b/sha1/chk-sha1.h\nnew file mode 100644\nindex 0000000..7b2df28\n--- /dev/null\n+++ b/sha1/chk-sha1.h\n@@ -0,0 +1,2 @@\n+\n+int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len);\ndiff --git a/sha1/ppc-sha1.c b/sha1/ppc-sha1.c\nnew file mode 100644\nindex 0000000..2ca9a5a\n--- /dev/null\n+++ b/sha1/ppc-sha1.c\n@@ -0,0 +1,72 @@\n+/*\n+ * SHA-1 implementation.\n+ *\n+ * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>\n+ *\n+ * This version assumes we are running on a big-endian machine.\n+ * It calls an external sha1_core() to process blocks of 64 bytes.\n+ */\n+#include <stdio.h>\n+#include <string.h>\n+#include \"ppc-sha1.h\"\n+\n+extern void ppc_sha1_core(uint32_t *hash, const unsigned char *p,\n+\t\t\t  unsigned int nblocks);\n+\n+int ppc_SHA1_Init(ppc_SHA_CTX *c)\n+{\n+\tc->hash[0] = 0x67452301;\n+\tc->hash[1] = 0xEFCDAB89;\n+\tc->hash[2] = 0x98BADCFE;\n+\tc->hash[3] = 0x10325476;\n+\tc->hash[4] = 0xC3D2E1F0;\n+\tc->len = 0;\n+\tc->cnt = 0;\n+\treturn 0;\n+}\n+\n+int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *ptr, unsigned long n)\n+{\n+\tunsigned long nb;\n+\tconst unsigned char *p = ptr;\n+\n+\tc->len += (uint64_t) n << 3;\n+\twhile (n != 0) {\n+\t\tif (c->cnt || n < 64) {\n+\t\t\tnb = 64 - c->cnt;\n+\t\t\tif (nb > n)\n+\t\t\t\tnb = n;\n+\t\t\tmemcpy(&c->buf.b[c->cnt], p, nb);\n+\t\t\tif ((c->cnt += nb) == 64) {\n+\t\t\t\tppc_sha1_core(c->hash, c->buf.b, 1);\n+\t\t\t\tc->cnt = 0;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tnb = n >> 6;\n+\t\t\tppc_sha1_core(c->hash, p, nb);\n+\t\t\tnb <<= 6;\n+\t\t}\n+\t\tn -= nb;\n+\t\tp += nb;\n+\t}\n+\treturn 0;\n+}\n+\n+int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c)\n+{\n+\tunsigned int cnt = c->cnt;\n+\n+\tc->buf.b[cnt++] = 0x80;\n+\tif (cnt > 56) {\n+\t\tif (cnt < 64)\n+\t\t\tmemset(&c->buf.b[cnt], 0, 64 - cnt);\n+\t\tppc_sha1_core(c->hash, c->buf.b, 1);\n+\t\tcnt = 0;\n+\t}\n+\tif (cnt < 56)\n+\t\tmemset(&c->buf.b[cnt], 0, 56 - cnt);\n+\tc->buf.l[7] = c->len;\n+\tppc_sha1_core(c->hash, c->buf.b, 1);\n+\tmemcpy(hash, c->hash, 20);\n+\treturn 0;\n+}\ndiff --git a/sha1/ppc-sha1.h b/sha1/ppc-sha1.h\nnew file mode 100644\nindex 0000000..c405f73\n--- /dev/null\n+++ b/sha1/ppc-sha1.h\n@@ -0,0 +1,25 @@\n+/*\n+ * SHA-1 implementation.\n+ *\n+ * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>\n+ */\n+#include <stdint.h>\n+\n+typedef struct {\n+\tuint32_t hash[5];\n+\tuint32_t cnt;\n+\tuint64_t len;\n+\tunion {\n+\t\tunsigned char b[64];\n+\t\tuint64_t l[8];\n+\t} buf;\n+} ppc_SHA_CTX;\n+\n+int ppc_SHA1_Init(ppc_SHA_CTX *c);\n+int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *p, unsigned long n);\n+int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c);\n+\n+#define git_SHA_CTX\tppc_SHA_CTX\n+#define git_SHA1_Init\tppc_SHA1_Init\n+#define git_SHA1_Update\tppc_SHA1_Update\n+#define git_SHA1_Final\tppc_SHA1_Final\ndiff --git a/sha1/ppc-sha1asm.S b/sha1/ppc-sha1asm.S\nnew file mode 100644\nindex 0000000..1711eef\n--- /dev/null\n+++ b/sha1/ppc-sha1asm.S\n@@ -0,0 +1,224 @@\n+/*\n+ * SHA-1 implementation for PowerPC.\n+ *\n+ * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>\n+ */\n+\n+/*\n+ * PowerPC calling convention:\n+ * %r0 - volatile temp\n+ * %r1 - stack pointer.\n+ * %r2 - reserved\n+ * %r3-%r12 - Incoming arguments & return values; volatile.\n+ * %r13-%r31 - Callee-save registers\n+ * %lr - Return address, volatile\n+ * %ctr - volatile\n+ *\n+ * Register usage in this routine:\n+ * %r0 - temp\n+ * %r3 - argument (pointer to 5 words of SHA state)\n+ * %r4 - argument (pointer to data to hash)\n+ * %r5 - Constant K in SHA round (initially number of blocks to hash)\n+ * %r6-%r10 - Working copies of SHA variables A..E (actually E..A order)\n+ * %r11-%r26 - Data being hashed W[].\n+ * %r27-%r31 - Previous copies of A..E, for final add back.\n+ * %ctr - loop count\n+ */\n+\n+\n+/*\n+ * We roll the registers for A, B, C, D, E around on each\n+ * iteration; E on iteration t is D on iteration t+1, and so on.\n+ * We use registers 6 - 10 for this.  (Registers 27 - 31 hold\n+ * the previous values.)\n+ */\n+#define RA(t)\t(((t)+4)%5+6)\n+#define RB(t)\t(((t)+3)%5+6)\n+#define RC(t)\t(((t)+2)%5+6)\n+#define RD(t)\t(((t)+1)%5+6)\n+#define RE(t)\t(((t)+0)%5+6)\n+\n+/* We use registers 11 - 26 for the W values */\n+#define W(t)\t((t)%16+11)\n+\n+/* Register 5 is used for the constant k */\n+\n+/*\n+ * The basic SHA-1 round function is:\n+ * E += ROTL(A,5) + F(B,C,D) + W[i] + K;  B = ROTL(B,30)\n+ * Then the variables are renamed: (A,B,C,D,E) = (E,A,B,C,D).\n+ *\n+ * Every 20 rounds, the function F() and the constant K changes:\n+ * - 20 rounds of f0(b,c,d) = \"bit wise b ? c : d\" =  (^b & d) + (b & c)\n+ * - 20 rounds of f1(b,c,d) = b^c^d = (b^d)^c\n+ * - 20 rounds of f2(b,c,d) = majority(b,c,d) = (b&d) + ((b^d)&c)\n+ * - 20 more rounds of f1(b,c,d)\n+ *\n+ * These are all scheduled for near-optimal performance on a G4.\n+ * The G4 is a 3-issue out-of-order machine with 3 ALUs, but it can only\n+ * *consider* starting the oldest 3 instructions per cycle.  So to get\n+ * maximum performance out of it, you have to treat it as an in-order\n+ * machine.  Which means interleaving the computation round t with the\n+ * computation of W[t+4].\n+ *\n+ * The first 16 rounds use W values loaded directly from memory, while the\n+ * remaining 64 use values computed from those first 16.  We preload\n+ * 4 values before starting, so there are three kinds of rounds:\n+ * - The first 12 (all f0) also load the W values from memory.\n+ * - The next 64 compute W(i+4) in parallel. 8*f0, 20*f1, 20*f2, 16*f1.\n+ * - The last 4 (all f1) do not do anything with W.\n+ *\n+ * Therefore, we have 6 different round functions:\n+ * STEPD0_LOAD(t,s) - Perform round t and load W(s).  s < 16\n+ * STEPD0_UPDATE(t,s) - Perform round t and compute W(s).  s >= 16.\n+ * STEPD1_UPDATE(t,s)\n+ * STEPD2_UPDATE(t,s)\n+ * STEPD1(t) - Perform round t with no load or update.\n+ *\n+ * The G5 is more fully out-of-order, and can find the parallelism\n+ * by itself.  The big limit is that it has a 2-cycle ALU latency, so\n+ * even though it's 2-way, the code has to be scheduled as if it's\n+ * 4-way, which can be a limit.  To help it, we try to schedule the\n+ * read of RA(t) as late as possible so it doesn't stall waiting for\n+ * the previous round's RE(t-1), and we try to rotate RB(t) as early\n+ * as possible while reading RC(t) (= RB(t-1)) as late as possible.\n+ */\n+\n+/* the initial loads. */\n+#define LOADW(s) \\\n+\tlwz\tW(s),(s)*4(%r4)\n+\n+/*\n+ * Perform a step with F0, and load W(s).  Uses W(s) as a temporary\n+ * before loading it.\n+ * This is actually 10 instructions, which is an awkward fit.\n+ * It can execute grouped as listed, or delayed one instruction.\n+ * (If delayed two instructions, there is a stall before the start of the\n+ * second line.)  Thus, two iterations take 7 cycles, 3.5 cycles per round.\n+ */\n+#define STEPD0_LOAD(t,s) \\\n+add RE(t),RE(t),W(t); andc   %r0,RD(t),RB(t);  and    W(s),RC(t),RB(t); \\\n+add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;      rotlwi RB(t),RB(t),30;   \\\n+add RE(t),RE(t),W(s); add    %r0,%r0,%r5;      lwz    W(s),(s)*4(%r4);  \\\n+add RE(t),RE(t),%r0\n+\n+/*\n+ * This is likewise awkward, 13 instructions.  However, it can also\n+ * execute starting with 2 out of 3 possible moduli, so it does 2 rounds\n+ * in 9 cycles, 4.5 cycles/round.\n+ */\n+#define STEPD0_UPDATE(t,s,loadk...) \\\n+add RE(t),RE(t),W(t); andc   %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \\\n+add RE(t),RE(t),%r0;  and    %r0,RC(t),RB(t); xor    W(s),W(s),W((s)-8);      \\\n+add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     xor    W(s),W(s),W((s)-14);     \\\n+add RE(t),RE(t),%r5;  loadk; rotlwi RB(t),RB(t),30;  rotlwi W(s),W(s),1;     \\\n+add RE(t),RE(t),%r0\n+\n+/* Nicely optimal.  Conveniently, also the most common. */\n+#define STEPD1_UPDATE(t,s,loadk...) \\\n+add RE(t),RE(t),W(t); xor    %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \\\n+add RE(t),RE(t),%r5;  loadk; xor %r0,%r0,RC(t);  xor W(s),W(s),W((s)-8);      \\\n+add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     xor    W(s),W(s),W((s)-14);     \\\n+add RE(t),RE(t),%r0;  rotlwi RB(t),RB(t),30;  rotlwi W(s),W(s),1\n+\n+/*\n+ * The naked version, no UPDATE, for the last 4 rounds.  3 cycles per.\n+ * We could use W(s) as a temp register, but we don't need it.\n+ */\n+#define STEPD1(t) \\\n+                        add   RE(t),RE(t),W(t); xor    %r0,RD(t),RB(t); \\\n+rotlwi RB(t),RB(t),30;  add   RE(t),RE(t),%r5;  xor    %r0,%r0,RC(t);   \\\n+add    RE(t),RE(t),%r0; rotlwi %r0,RA(t),5;     /* spare slot */        \\\n+add    RE(t),RE(t),%r0\n+\n+/*\n+ * 14 instructions, 5 cycles per.  The majority function is a bit\n+ * awkward to compute.  This can execute with a 1-instruction delay,\n+ * but it causes a 2-instruction delay, which triggers a stall.\n+ */\n+#define STEPD2_UPDATE(t,s,loadk...) \\\n+add RE(t),RE(t),W(t); and    %r0,RD(t),RB(t); xor    W(s),W((s)-16),W((s)-3); \\\n+add RE(t),RE(t),%r0;  xor    %r0,RD(t),RB(t); xor    W(s),W(s),W((s)-8);      \\\n+add RE(t),RE(t),%r5;  loadk; and %r0,%r0,RC(t);  xor W(s),W(s),W((s)-14);     \\\n+add RE(t),RE(t),%r0;  rotlwi %r0,RA(t),5;     rotlwi W(s),W(s),1;             \\\n+add RE(t),RE(t),%r0;  rotlwi RB(t),RB(t),30\n+\n+#define STEP0_LOAD4(t,s)\t\t\\\n+\tSTEPD0_LOAD(t,s);\t\t\\\n+\tSTEPD0_LOAD((t+1),(s)+1);\t\\\n+\tSTEPD0_LOAD((t)+2,(s)+2);\t\\\n+\tSTEPD0_LOAD((t)+3,(s)+3)\n+\n+#define STEPUP4(fn, t, s, loadk...)\t\t\\\n+\tSTEP##fn##_UPDATE(t,s,);\t\t\\\n+\tSTEP##fn##_UPDATE((t)+1,(s)+1,);\t\\\n+\tSTEP##fn##_UPDATE((t)+2,(s)+2,);\t\\\n+\tSTEP##fn##_UPDATE((t)+3,(s)+3,loadk)\n+\n+#define STEPUP20(fn, t, s, loadk...)\t\\\n+\tSTEPUP4(fn, t, s,);\t\t\\\n+\tSTEPUP4(fn, (t)+4, (s)+4,);\t\\\n+\tSTEPUP4(fn, (t)+8, (s)+8,);\t\\\n+\tSTEPUP4(fn, (t)+12, (s)+12,);\t\\\n+\tSTEPUP4(fn, (t)+16, (s)+16, loadk)\n+\n+\t.globl\tppc_sha1_core\n+ppc_sha1_core:\n+\tstwu\t%r1,-80(%r1)\n+\tstmw\t%r13,4(%r1)\n+\n+\t/* Load up A - E */\n+\tlmw\t%r27,0(%r3)\n+\n+\tmtctr\t%r5\n+\n+1:\n+\tLOADW(0)\n+\tlis\t%r5,0x5a82\n+\tmr\tRE(0),%r31\n+\tLOADW(1)\n+\tmr\tRD(0),%r30\n+\tmr\tRC(0),%r29\n+\tLOADW(2)\n+\tori\t%r5,%r5,0x7999\t/* K0-19 */\n+\tmr\tRB(0),%r28\n+\tLOADW(3)\n+\tmr\tRA(0),%r27\n+\n+\tSTEP0_LOAD4(0, 4)\n+\tSTEP0_LOAD4(4, 8)\n+\tSTEP0_LOAD4(8, 12)\n+\tSTEPUP4(D0, 12, 16,)\n+\tSTEPUP4(D0, 16, 20, lis %r5,0x6ed9)\n+\n+\tori\t%r5,%r5,0xeba1\t/* K20-39 */\n+\tSTEPUP20(D1, 20, 24, lis %r5,0x8f1b)\n+\n+\tori\t%r5,%r5,0xbcdc\t/* K40-59 */\n+\tSTEPUP20(D2, 40, 44, lis %r5,0xca62)\n+\n+\tori\t%r5,%r5,0xc1d6\t/* K60-79 */\n+\tSTEPUP4(D1, 60, 64,)\n+\tSTEPUP4(D1, 64, 68,)\n+\tSTEPUP4(D1, 68, 72,)\n+\tSTEPUP4(D1, 72, 76,)\n+\taddi\t%r4,%r4,64\n+\tSTEPD1(76)\n+\tSTEPD1(77)\n+\tSTEPD1(78)\n+\tSTEPD1(79)\n+\n+\t/* Add results to original values */\n+\tadd\t%r31,%r31,RE(0)\n+\tadd\t%r30,%r30,RD(0)\n+\tadd\t%r29,%r29,RC(0)\n+\tadd\t%r28,%r28,RB(0)\n+\tadd\t%r27,%r27,RA(0)\n+\n+\tbdnz\t1b\n+\n+\t/* Save final hash, restore registers, and return */\n+\tstmw\t%r27,0(%r3)\n+\tlmw\t%r13,4(%r1)\n+\taddi\t%r1,%r1,80\n+\tblr\n-- \n2.4.9 (Apple Git-60)\n"},{"id":"272965","messageId":"xmqq8u6c711m.fsf@gitster.mtv.corp.google.com","threadId":"40727","inReplyTo":"1446705523-30701-3-git-send-email-apahlevan@ieee.org","subject":"Re: [PATCH v4 3/3] Move all the SHA1 implementations into one directory","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-11-05T18:29:09Z","receivedAt":"2015-11-05T18:29:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"atousa.p@gmail.com writes:\n\n> From: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n>\n> The various SHA1 implementations were spread around in 3 directories.\n> This makes it easier to understand what implementations are\n> available at a glance.\n>\n> Signed-off-by: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n> ---\n\nI am not strongly opposed to moving block and ppc (I am not strongly\nfor the movement, either, though).\n\nI however think the chunked one should not be mixed together with\nthem--it is not a full SHA-1 hash implementation but belongs to a\ndifferent layer of abstration (and that is the reason why we\nintroduced a new layer of indirection in 1/3).\n"},{"id":"272966","messageId":"xmqq1tc47117.fsf@gitster.mtv.corp.google.com","threadId":"40727","inReplyTo":"1446705523-30701-1-git-send-email-apahlevan@ieee.org","subject":"Re: [PATCH v4 1/3] Provide another level of abstraction for the SHA1 utilities.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-11-05T18:29:24Z","receivedAt":"2015-11-05T18:29:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"atousa.p@gmail.com writes:\n\n> From: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n>\n> The git source uses git_SHA1_Update() and friends to call\n> into the code that computes the hashes.  This is can then be\n> mapped directly to an implementation that computes the hash,\n> such as platform_SHA1_Update(); or as we will do in a subsequent\n> patch, it can be mapped to something more complex that will in turn call\n> into the platform's SHA implementation.\n>\n> Signed-off-by: Atousa Pahlevan Duprat <apahlevan@ieee.org>\n> ---\n>  cache.h | 19 +++++++++++++++----\n>  1 file changed, 15 insertions(+), 4 deletions(-)\n>\n> diff --git a/cache.h b/cache.h\n> index a9aaa03..a934a2e 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -12,10 +12,21 @@\n>  \n>  #include SHA1_HEADER\n>  #ifndef git_SHA_CTX\n> -#define git_SHA_CTX\tSHA_CTX\n> -#define git_SHA1_Init\tSHA1_Init\n> -#define git_SHA1_Update\tSHA1_Update\n> -#define git_SHA1_Final\tSHA1_Final\n> +\n> +/* platform's underlying implementation of SHA1, could be OpenSSL,\n> +   blk_SHA, Apple CommonCrypto, etc...  */\n> +#define platform_SHA_CTX\tSHA_CTX\n> +#define platform_SHA1_Init\tSHA1_Init\n> +#define platform_SHA1_Update\tSHA1_Update\n> +#define platform_SHA1_Final    \tSHA1_Final\n> +\n> +/* git may call platform's underlying implementation of SHA1 directly,\n> +   or may call it through a wrapper */\n> +#define git_SHA_CTX\t\tplatform_SHA_CTX\n> +#define git_SHA1_Init\t\tplatform_SHA1_Init\n> +#define git_SHA1_Update\t\tplatform_SHA1_Update\n> +#define git_SHA1_Final\t\tplatform_SHA1_Final\n> +\n>  #endif\n>  \n>  #include <zlib.h>\n\nThis is not quite correct, I am afraid.  Our own implementations\nstill define git_SHA* macros, but they should be considered the\n\"platform\" ones in the new world order with another level of\nindirection.\n\nI think the attached is closer to what we want.  The implementations\nmay give us platform_SHA*() in which case cache.h does not have to\ngive the fallback mapping from them to the OpenSSL compatible\ninterface used by OpenSSL and CommonCrypto.  Regardless of the\nplatform SHA-1 implementations, by default they are the ones used by\nthe rest of the system via git_SHA*().\n\nAnd in the second step, git_SHA1_Update() may map to the Chunked\none, whose implementation would use platform_SHA1_Update().\n\n-- >8 ---\nFrom: Atousa Pahlevan Duprat <apahlevan@ieee.org>\nSubject: sha1: provide another level of indirection for the SHA-1 functions\n\nThe git source uses git_SHA1_Update() and friends to call into the\ncode that computes the hashes.  Traditionally, we used to map these\ndirectly to underlying implementation of the SHA-1 hash (e.g.\nSHA1_Update() from OpenSSL or blk_SHA1_Update() from block-sha1/).\n\nThis arrangement however makes it hard to tweak behaviour of the\nunderlying implementation without fully replacing.  If we want to\nintroduce a tweaked_SHA1_Update() wrapper to implement the \"Update\"\nin a slightly different way, for example, the implementation of the\nwrapper still would want to call into the underlying implementation,\nbut tweaked_SHA1_Update() cannot call git_SHA1_Update() to get to\nthe underlying implementation (often but not always SHA1_Update()).\n\nAdd another level of indirection that maps platform_SHA1_Update()\nand friends to their underlying implementations, and by default make\ngit_SHA1_Update() and friends map to platform_SHA1_* functions.\n\nDoing it this way will later allow us to map git_SHA1_Update() to\ntweaked_SHA1_Update(), and the latter can use platform_SHA1_Update()\nin its implementation.\n\nSigned-off-by: Atousa Pahlevan Duprat <apahlevan@ieee.org>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n block-sha1/sha1.h |  8 ++++----\n cache.h           | 22 +++++++++++++++++-----\n ppc/sha1.h        |  8 ++++----\n 3 files changed, 25 insertions(+), 13 deletions(-)\n\ndiff --git a/block-sha1/sha1.h b/block-sha1/sha1.h\nindex b864df6..4df6747 100644\n--- a/block-sha1/sha1.h\n+++ b/block-sha1/sha1.h\n@@ -16,7 +16,7 @@ void blk_SHA1_Init(blk_SHA_CTX *ctx);\n void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);\n void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);\n \n-#define git_SHA_CTX\tblk_SHA_CTX\n-#define git_SHA1_Init\tblk_SHA1_Init\n-#define git_SHA1_Update\tblk_SHA1_Update\n-#define git_SHA1_Final\tblk_SHA1_Final\n+#define platform_SHA_CTX\tblk_SHA_CTX\n+#define platform_SHA1_Init\tblk_SHA1_Init\n+#define platform_SHA1_Update\tblk_SHA1_Update\n+#define platform_SHA1_Final\tblk_SHA1_Final\ndiff --git a/cache.h b/cache.h\nindex a9aaa03..2f697c4 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -11,13 +11,25 @@\n #include \"string-list.h\"\n \n #include SHA1_HEADER\n-#ifndef git_SHA_CTX\n-#define git_SHA_CTX\tSHA_CTX\n-#define git_SHA1_Init\tSHA1_Init\n-#define git_SHA1_Update\tSHA1_Update\n-#define git_SHA1_Final\tSHA1_Final\n+#ifndef platform_SHA_CTX\n+/*\n+ * platform's underlying implementation of SHA-1; could be OpenSSL,\n+ * blk_SHA, Apple CommonCrypto, etc...  Note that including\n+ * SHA1_HEADER may have already defined platform_SHA_CTX for our\n+ * own implementations like block-sha1 and ppc-sha1, so we list\n+ * the default for OpenSSL compatible SHA-1 implementations here.\n+ */\n+#define platform_SHA_CTX\tSHA_CTX\n+#define platform_SHA1_Init\tSHA1_Init\n+#define platform_SHA1_Update\tSHA1_Update\n+#define platform_SHA1_Final    \tSHA1_Final\n #endif\n \n+#define git_SHA_CTX\t\tplatform_SHA_CTX\n+#define git_SHA1_Init\t\tplatform_SHA1_Init\n+#define git_SHA1_Update\t\tplatform_SHA1_Update\n+#define git_SHA1_Final\t\tplatform_SHA1_Final\n+\n #include <zlib.h>\n typedef struct git_zstream {\n \tz_stream z;\ndiff --git a/ppc/sha1.h b/ppc/sha1.h\nindex c405f73..9b24b32 100644\n--- a/ppc/sha1.h\n+++ b/ppc/sha1.h\n@@ -19,7 +19,7 @@ int ppc_SHA1_Init(ppc_SHA_CTX *c);\n int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *p, unsigned long n);\n int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c);\n \n-#define git_SHA_CTX\tppc_SHA_CTX\n-#define git_SHA1_Init\tppc_SHA1_Init\n-#define git_SHA1_Update\tppc_SHA1_Update\n-#define git_SHA1_Final\tppc_SHA1_Final\n+#define platform_SHA_CTX\tppc_SHA_CTX\n+#define platform_SHA1_Init\tppc_SHA1_Init\n+#define platform_SHA1_Update\tppc_SHA1_Update\n+#define platform_SHA1_Final\tppc_SHA1_Final\n-- \n2.6.2-535-ga9e37b0\n"},{"id":"272967","messageId":"xmqqtwp05mgn.fsf@gitster.mtv.corp.google.com","threadId":"40727","inReplyTo":"1446705523-30701-2-git-send-email-apahlevan@ieee.org","subject":"Re: [PATCH v4 2/3] Limit the size of the data block passed to SHA1_Update()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-11-05T18:29:28Z","receivedAt":"2015-11-05T18:29:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"atousa.p@gmail.com writes:\n\n> +#ifndef git_SHA_CTX\n> +\n> +#ifdef SHA1_MAX_BLOCK_SIZE\n> +#include \"compat/sha1-chunked.h\"\n> +#define git_SHA_CTX\t\tplatform_SHA_CTX\n> +#define git_SHA1_Init\t\tplatform_SHA1_Init\n> +#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n> +#define git_SHA1_Final\t\tplatform_SHA1_Final\n> +#else\n>  #define git_SHA_CTX\t\tplatform_SHA_CTX\n>  #define git_SHA1_Init\t\tplatform_SHA1_Init\n>  #define git_SHA1_Update\t\tplatform_SHA1_Update\n>  #define git_SHA1_Final\t\tplatform_SHA1_Final\n> -\n>  #endif\n>  \n> +#endif \n> +\n\nAdjusting to the proposed change to 1/3, this step would become the\nattached patch.  Note that I thought the above would not scale well\nso I did it a bit differently.\n\n-- >8 --\nFrom: Atousa Pahlevan Duprat <apahlevan@ieee.org>\nSubject: sha1: allow limiting the size of the data passed to SHA1_Update()\n\nUsing the previous commit's inredirection mechanism for SHA1,\nsupport a chunked implementation of SHA1_Update() that limits the\namount of data in the chunk passed to SHA1_Update().\n\nThis is enabled by using the Makefile variable SHA1_MAX_BLOCK_SIZE\nto specify chunk size.  When using Apple's CommonCrypto library this\nis set to 1GiB (the implementation cannot handle more 4GiB).\n\nSigned-off-by: Atousa Pahlevan Duprat <apahlevan@ieee.org>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Makefile                     | 13 +++++++++++++\n cache.h                      |  6 ++++++\n compat/apple-common-crypto.h |  4 ++++\n compat/sha1-chunked.c        | 19 +++++++++++++++++++\n compat/sha1-chunked.h        |  2 ++\n 5 files changed, 44 insertions(+)\n create mode 100644 compat/sha1-chunked.c\n create mode 100644 compat/sha1-chunked.h\n\ndiff --git a/Makefile b/Makefile\nindex 04c2231..6a4ca59 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -141,6 +141,10 @@ all::\n # Define PPC_SHA1 environment variable when running make to make use of\n # a bundled SHA1 routine optimized for PowerPC.\n #\n+# Define SHA1_MAX_BLOCK_SIZE to limit the amount of data that will be hashed\n+# in one call to the platform's SHA1_Update(). e.g. APPLE_COMMON_CRYPTO\n+# wants 'SHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' defined.\n+#\n # Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).\n #\n # Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).\n@@ -1335,6 +1339,11 @@ ifdef NO_POSIX_GOODIES\n \tBASIC_CFLAGS += -DNO_POSIX_GOODIES\n endif\n \n+ifdef APPLE_COMMON_CRYPTO\n+\t# Apple CommonCrypto requires chunking\n+\tSHA1_MAX_BLOCK_SIZE = 1024L*1024L*1024L\n+endif\n+\n ifdef BLK_SHA1\n \tSHA1_HEADER = \"block-sha1/sha1.h\"\n \tLIB_OBJS += block-sha1/sha1.o\n@@ -1353,6 +1362,10 @@ endif\n endif\n endif\n \n+ifdef SHA1_MAX_BLOCK_SIZE\n+\tLIB_OBJS += compat/sha1-chunked.o\n+\tBASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE=\"$(SHA1_MAX_BLOCK_SIZE)\"\n+endif\n ifdef NO_PERL_MAKEMAKER\n \texport NO_PERL_MAKEMAKER\n endif\ndiff --git a/cache.h b/cache.h\nindex 2f697c4..19c966d 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -30,6 +30,12 @@\n #define git_SHA1_Update\t\tplatform_SHA1_Update\n #define git_SHA1_Final\t\tplatform_SHA1_Final\n \n+#ifdef SHA1_MAX_BLOCK_SIZE\n+#include \"compat/sha1-chunked.h\"\n+#undef git_SHA1_Update\n+#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n+#endif\n+\n #include <zlib.h>\n typedef struct git_zstream {\n \tz_stream z;\ndiff --git a/compat/apple-common-crypto.h b/compat/apple-common-crypto.h\nindex c8b9b0e..d3fb264 100644\n--- a/compat/apple-common-crypto.h\n+++ b/compat/apple-common-crypto.h\n@@ -16,6 +16,10 @@\n #undef TYPE_BOOL\n #endif\n \n+#ifndef SHA1_MAX_BLOCK_SIZE\n+#error Using Apple Common Crypto library requires setting SHA1_MAX_BLOCK_SIZE\n+#endif\n+\n #ifdef APPLE_LION_OR_NEWER\n #define git_CC_error_check(pattern, err) \\\n \tdo { \\\ndiff --git a/compat/sha1-chunked.c b/compat/sha1-chunked.c\nnew file mode 100644\nindex 0000000..6adfcfd\n--- /dev/null\n+++ b/compat/sha1-chunked.c\n@@ -0,0 +1,19 @@\n+#include \"cache.h\"\n+\n+int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)\n+{\n+\tsize_t nr;\n+\tsize_t total = 0;\n+\tconst char *cdata = (const char*)data;\n+\n+\twhile (len) {\n+\t\tnr = len;\n+\t\tif (nr > SHA1_MAX_BLOCK_SIZE)\n+\t\t\tnr = SHA1_MAX_BLOCK_SIZE;\n+\t\tplatform_SHA1_Update(c, cdata, nr);\n+\t\ttotal += nr;\n+\t\tcdata += nr;\n+\t\tlen -= nr;\n+\t}\n+\treturn total;\n+}\ndiff --git a/compat/sha1-chunked.h b/compat/sha1-chunked.h\nnew file mode 100644\nindex 0000000..7b2df28\n--- /dev/null\n+++ b/compat/sha1-chunked.h\n@@ -0,0 +1,2 @@\n+\n+int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len);\n-- \n2.6.2-535-ga9e37b0\n"},{"id":"273235","messageId":"CA+izobv=PUf+6WWfQNEO+bwfzLRQ3V-TKQdUS0-qNJ0aCSkJzA@mail.gmail.com","threadId":"40727","inReplyTo":"xmqqtwp05mgn.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v4 2/3] Limit the size of the data block passed to SHA1_Update()","fromName":"Atousa Duprat","fromEmail":"atousa.p@gmail.com","sentAt":"2015-11-11T23:46:51Z","receivedAt":"2015-11-11T23:46:51Z","isPatch":true,"sender":{"key":"atousa.p@gmail.com","avatar":"https://gravatar.com/avatar/b5b7b70553497c4ce08a835c156ff3b245366eba956fbceff99553b1ccdc4e42?d=mp&s=160"},"body":"> Adjusting to the proposed change to 1/3, this step would become the\n> attached patch.  Note that I thought the above would not scale well\n> so I did it a bit differently.\n\nThank you, I understand now the changes that you made.\nLet me know if this can be improved any further.\n\nAtousa\n"}]}