sha256: add an SHA-256 implementation using libgcrypt

Generally, one gets better performance out of cryptographic routines written in assembly than C, and this is also true for SHA-256. In addition, most Linux distributions cannot distribute Git linked against OpenSSL for licensing reasons. Most systems with GnuPG will also have libgcrypt, since it is a dependency of GnuPG. libgcrypt is also faster than the SHA1DC implementation for messages of a few KiB and larger. For comparison, on a Core i7-6600U, this implementation processes 16 KiB chunks at 355 MiB/s while SHA1DC processes equivalent chunks at 337 MiB/s. In addition, libgcrypt is licensed under the LGPL 2.1, which is compatible with the GPL. Add an implementation of SHA-256 that uses libgcrypt. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

brian m. carlson committed Nov 14, 2018 at 04:09 UTC 27dc04c54506967fcaa87b2d560547ee5633040c
3 files changed +45 -2
Makefile
+11 -2
@@ -179,6 +179,10 @@ all::
179 # in one call to the platform's SHA1_Update(). e.g. APPLE_COMMON_CRYPTO
180 # wants 'SHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' defined.
181 #
182 +# Define BLK_SHA256 to use the built-in SHA-256 routines.
183 +#
184 +# Define GCRYPT_SHA256 to use the SHA-256 routines in libgcrypt.
185 +#
186 # Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).
187 #
188 # Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
@@ -1634,8 +1638,13 @@ endif
1638 endif
1639 endif
1640
1637 -LIB_OBJS += sha256/block/sha256.o
1638 -BASIC_CFLAGS += -DSHA256_BLK
1641 +ifdef GCRYPT_SHA256
1642 + BASIC_CFLAGS += -DSHA256_GCRYPT
1643 + EXTLIBS += -lgcrypt
1644 +else
1645 + LIB_OBJS += sha256/block/sha256.o
1646 + BASIC_CFLAGS += -DSHA256_BLK
1647 +endif
1648
1649 ifdef SHA1_MAX_BLOCK_SIZE
1650 LIB_OBJS += compat/sha1-chunked.o
hash.h
+4
@@ -15,7 +15,11 @@
15 #include "block-sha1/sha1.h"
16 #endif
17
18 +#if defined(SHA256_GCRYPT)
19 +#include "sha256/gcrypt.h"
20 +#else
21 #include "sha256/block/sha256.h"
22 +#endif
23
24 #ifndef platform_SHA_CTX
25 /*
sha256/gcrypt.h new
+30
@@ -0,0 +1,30 @@
1 +#ifndef SHA256_GCRYPT_H
2 +#define SHA256_GCRYPT_H
3 +
4 +#include <gcrypt.h>
5 +
6 +#define SHA256_DIGEST_SIZE 32
7 +
8 +typedef gcry_md_hd_t gcrypt_SHA256_CTX;
9 +
10 +inline void gcrypt_SHA256_Init(gcrypt_SHA256_CTX *ctx)
11 +{
12 + gcry_md_open(ctx, GCRY_MD_SHA256, 0);
13 +}
14 +
15 +inline void gcrypt_SHA256_Update(gcrypt_SHA256_CTX *ctx, const void *data, size_t len)
16 +{
17 + gcry_md_write(*ctx, data, len);
18 +}
19 +
20 +inline void gcrypt_SHA256_Final(unsigned char *digest, gcrypt_SHA256_CTX *ctx)
21 +{
22 + memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA256), SHA256_DIGEST_SIZE);
23 +}
24 +
25 +#define platform_SHA256_CTX gcrypt_SHA256_CTX
26 +#define platform_SHA256_Init gcrypt_SHA256_Init
27 +#define platform_SHA256_Update gcrypt_SHA256_Update
28 +#define platform_SHA256_Final gcrypt_SHA256_Final
29 +
30 +#endif