Git fork

sha256: add support for Nettle

For SHA-256, we currently have support for OpenSSL and libgcrypt because
these two libraries contain optimized implementations that can take
advantage of native processor instructions. However, OpenSSL is not
suitable for linking against for Linux distros due to licensing
incompatibilities with the GPLv2, and libgcrypt has been less favored by
cryptographers due to some security-related implementation issues,
which, while not affecting our use of hash algorithms, has affected its
reputation.

Let's add another option that's compatible with the GPLv2, which is
Nettle. This is an option which is generally better than libgcrypt
because on many distros GnuTLS (which uses Nettle) is used for HTTPS and
therefore as a practical matter it will be available on most systems.
As a result, prefer it over libgcrypt and our built-in implementation.

Nettle also has recently gained support for Intel's SHA-NI instructions,
which compare very favorably to other implementations, as well as
assembly implementations for when SHA-NI is not available.

A git gc on git.git sees a 12% performance improvement with Nettle over
our block SHA-256 implementation due to general assembly improvements.
With SHA-NI, the performance of raw SHA-256 on a 2 GiB file goes from
7.296 seconds with block SHA-256 to 1.523 seconds with Nettle.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

brian m. carlson and committed by
Junio C Hamano
e5557358 e4a4b315

+44 -1
+10
Makefile
··· 182 182 # 183 183 # Define BLK_SHA256 to use the built-in SHA-256 routines. 184 184 # 185 + # Define NETTLE_SHA256 to use the SHA-256 routines in libnettle. 186 + # 185 187 # Define GCRYPT_SHA256 to use the SHA-256 routines in libgcrypt. 186 188 # 187 189 # Define OPENSSL_SHA256 to use the SHA-256 routines in OpenSSL. ··· 1842 1844 EXTLIBS += $(LIB_4_CRYPTO) 1843 1845 BASIC_CFLAGS += -DSHA256_OPENSSL 1844 1846 else 1847 + ifdef NETTLE_SHA256 1848 + BASIC_CFLAGS += -DSHA256_NETTLE 1849 + EXTLIBS += -lnettle 1850 + else 1845 1851 ifdef GCRYPT_SHA256 1846 1852 BASIC_CFLAGS += -DSHA256_GCRYPT 1847 1853 EXTLIBS += -lgcrypt 1848 1854 else 1849 1855 LIB_OBJS += sha256/block/sha256.o 1850 1856 BASIC_CFLAGS += -DSHA256_BLK 1857 + endif 1851 1858 endif 1852 1859 endif 1853 1860 ··· 3091 3098 sparse: $(SP_OBJ) 3092 3099 3093 3100 EXCEPT_HDRS := $(GENERATED_H) unicode-width.h compat/% xdiff/% 3101 + ifndef NETTLE_SHA256 3102 + EXCEPT_HDRS += sha256/nettle.h 3103 + endif 3094 3104 ifndef GCRYPT_SHA256 3095 3105 EXCEPT_HDRS += sha256/gcrypt.h 3096 3106 endif
+3 -1
hash.h
··· 16 16 #include "block-sha1/sha1.h" 17 17 #endif 18 18 19 - #if defined(SHA256_GCRYPT) 19 + #if defined(SHA256_NETTLE) 20 + #include "sha256/nettle.h" 21 + #elif defined(SHA256_GCRYPT) 20 22 #define SHA256_NEEDS_CLONE_HELPER 21 23 #include "sha256/gcrypt.h" 22 24 #elif defined(SHA256_OPENSSL)
+31
sha256/nettle.h
··· 1 + #ifndef SHA256_NETTLE_H 2 + #define SHA256_NETTLE_H 3 + 4 + #include <nettle/sha2.h> 5 + 6 + typedef struct sha256_ctx nettle_SHA256_CTX; 7 + 8 + static inline void nettle_SHA256_Init(nettle_SHA256_CTX *ctx) 9 + { 10 + sha256_init(ctx); 11 + } 12 + 13 + static inline void nettle_SHA256_Update(nettle_SHA256_CTX *ctx, 14 + const void *data, 15 + size_t len) 16 + { 17 + sha256_update(ctx, len, data); 18 + } 19 + 20 + static inline void nettle_SHA256_Final(unsigned char *digest, 21 + nettle_SHA256_CTX *ctx) 22 + { 23 + sha256_digest(ctx, SHA256_DIGEST_SIZE, digest); 24 + } 25 + 26 + #define platform_SHA256_CTX nettle_SHA256_CTX 27 + #define platform_SHA256_Init nettle_SHA256_Init 28 + #define platform_SHA256_Update nettle_SHA256_Update 29 + #define platform_SHA256_Final nettle_SHA256_Final 30 + 31 + #endif