* [PATCH 1/6] Move all SHA algorithm variants into sha/ directory
2019-12-22 6:48 [PATCH 0/6] Additional SHA implementations Michael Clark
@ 2019-12-22 6:48 ` Michael Clark
2019-12-22 6:48 ` [PATCH 2/6] Add an implementation of the SHA-512 hash algorithm Michael Clark
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Michael Clark @ 2019-12-22 6:48 UTC (permalink / raw)
To: git; +Cc: Michael Clark
This is a tidy up before we add additional hash agorithms.
This patch does not change code. It only contains renames.
After this patch, all hash algorithm implementations are in sha/.
---
Makefile | 16 ++++++++--------
hash.h | 6 +++---
{block-sha1 => sha/sha1}/sha1.c | 2 +-
{block-sha1 => sha/sha1}/sha1.h | 0
{sha1dc => sha/sha1dc}/.gitattributes | 0
{sha1dc => sha/sha1dc}/LICENSE.txt | 0
{sha1dc => sha/sha1dc}/sha1.c | 0
{sha1dc => sha/sha1dc}/sha1.h | 0
{sha1dc => sha/sha1dc}/ubc_check.c | 0
{sha1dc => sha/sha1dc}/ubc_check.h | 0
sha1dc_git.c => sha/sha1dc_git.c | 0
sha1dc_git.h => sha/sha1dc_git.h | 2 +-
{ppc => sha/sha1ppc}/sha1.c | 0
{ppc => sha/sha1ppc}/sha1.h | 0
{ppc => sha/sha1ppc}/sha1ppc.S | 0
{sha256 => sha/sha256}/gcrypt.h | 0
{sha256/block => sha/sha256}/sha256.c | 0
{sha256/block => sha/sha256}/sha256.h | 0
18 files changed, 13 insertions(+), 13 deletions(-)
rename {block-sha1 => sha/sha1}/sha1.c (99%)
rename {block-sha1 => sha/sha1}/sha1.h (100%)
rename {sha1dc => sha/sha1dc}/.gitattributes (100%)
rename {sha1dc => sha/sha1dc}/LICENSE.txt (100%)
rename {sha1dc => sha/sha1dc}/sha1.c (100%)
rename {sha1dc => sha/sha1dc}/sha1.h (100%)
rename {sha1dc => sha/sha1dc}/ubc_check.c (100%)
rename {sha1dc => sha/sha1dc}/ubc_check.h (100%)
rename sha1dc_git.c => sha/sha1dc_git.c (100%)
rename sha1dc_git.h => sha/sha1dc_git.h (95%)
rename {ppc => sha/sha1ppc}/sha1.c (100%)
rename {ppc => sha/sha1ppc}/sha1.h (100%)
rename {ppc => sha/sha1ppc}/sha1ppc.S (100%)
rename {sha256 => sha/sha256}/gcrypt.h (100%)
rename {sha256/block => sha/sha256}/sha256.c (100%)
rename {sha256/block => sha/sha256}/sha256.h (100%)
diff --git a/Makefile b/Makefile
index 42a061d3fb75..bac1b30b2f1f 100644
--- a/Makefile
+++ b/Makefile
@@ -1158,7 +1158,7 @@ THIRD_PARTY_SOURCES += compat/obstack.%
THIRD_PARTY_SOURCES += compat/poll/%
THIRD_PARTY_SOURCES += compat/regex/%
THIRD_PARTY_SOURCES += sha1collisiondetection/%
-THIRD_PARTY_SOURCES += sha1dc/%
+THIRD_PARTY_SOURCES += sha/sha1dc/%
GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB)
EXTLIBS =
@@ -1657,11 +1657,11 @@ ifdef OPENSSL_SHA1
BASIC_CFLAGS += -DSHA1_OPENSSL
else
ifdef BLK_SHA1
- LIB_OBJS += block-sha1/sha1.o
+ LIB_OBJS += sha/sha1/sha1.o
BASIC_CFLAGS += -DSHA1_BLK
else
ifdef PPC_SHA1
- LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
+ LIB_OBJS += sha/sha1ppc/sha1.o sha/sha1ppc/sha1ppc.o
BASIC_CFLAGS += -DSHA1_PPC
else
ifdef APPLE_COMMON_CRYPTO
@@ -1670,7 +1670,7 @@ ifdef APPLE_COMMON_CRYPTO
else
DC_SHA1 := YesPlease
BASIC_CFLAGS += -DSHA1_DC
- LIB_OBJS += sha1dc_git.o
+ LIB_OBJS += sha/sha1dc_git.o
ifdef DC_SHA1_EXTERNAL
ifdef DC_SHA1_SUBMODULE
ifneq ($(DC_SHA1_SUBMODULE),auto)
@@ -1685,8 +1685,8 @@ ifdef DC_SHA1_SUBMODULE
LIB_OBJS += sha1collisiondetection/lib/ubc_check.o
BASIC_CFLAGS += -DDC_SHA1_SUBMODULE
else
- LIB_OBJS += sha1dc/sha1.o
- LIB_OBJS += sha1dc/ubc_check.o
+ LIB_OBJS += sha/sha1dc/sha1.o
+ LIB_OBJS += sha/sha1dc/ubc_check.o
endif
BASIC_CFLAGS += \
-DSHA1DC_NO_STANDARD_INCLUDES \
@@ -1707,7 +1707,7 @@ ifdef GCRYPT_SHA256
BASIC_CFLAGS += -DSHA256_GCRYPT
EXTLIBS += -lgcrypt
else
- LIB_OBJS += sha256/block/sha256.o
+ LIB_OBJS += sha/sha256/sha256.o
BASIC_CFLAGS += -DSHA256_BLK
endif
endif
@@ -2782,7 +2782,7 @@ sparse: $(SP_OBJ)
GEN_HDRS := command-list.h unicode-width.h
EXCEPT_HDRS := $(GEN_HDRS) compat/% xdiff/%
ifndef GCRYPT_SHA256
- EXCEPT_HDRS += sha256/gcrypt.h
+ EXCEPT_HDRS += sha/sha256/gcrypt.h
endif
CHK_HDRS = $(filter-out $(EXCEPT_HDRS),$(LIB_H))
HCO = $(patsubst %.h,%.hco,$(CHK_HDRS))
diff --git a/hash.h b/hash.h
index 52a4f1a3f430..f1b941218dc8 100644
--- a/hash.h
+++ b/hash.h
@@ -10,9 +10,9 @@
#elif defined(SHA1_OPENSSL)
#include <openssl/sha.h>
#elif defined(SHA1_DC)
-#include "sha1dc_git.h"
+#include "sha/sha1dc_git.h"
#else /* SHA1_BLK */
-#include "block-sha1/sha1.h"
+#include "sha/sha1/sha1.h"
#endif
#if defined(SHA256_GCRYPT)
@@ -20,7 +20,7 @@
#elif defined(SHA256_OPENSSL)
#include <openssl/sha.h>
#else
-#include "sha256/block/sha256.h"
+#include "sha/sha256/sha256.h"
#endif
#ifndef platform_SHA_CTX
diff --git a/block-sha1/sha1.c b/sha/sha1/sha1.c
similarity index 99%
rename from block-sha1/sha1.c
rename to sha/sha1/sha1.c
index 22b125cf8c12..ad9f7e50a395 100644
--- a/block-sha1/sha1.c
+++ b/sha/sha1/sha1.c
@@ -7,7 +7,7 @@
*/
/* this is only to get definitions for memcpy(), ntohl() and htonl() */
-#include "../git-compat-util.h"
+#include "git-compat-util.h"
#include "sha1.h"
diff --git a/block-sha1/sha1.h b/sha/sha1/sha1.h
similarity index 100%
rename from block-sha1/sha1.h
rename to sha/sha1/sha1.h
diff --git a/sha1dc/.gitattributes b/sha/sha1dc/.gitattributes
similarity index 100%
rename from sha1dc/.gitattributes
rename to sha/sha1dc/.gitattributes
diff --git a/sha1dc/LICENSE.txt b/sha/sha1dc/LICENSE.txt
similarity index 100%
rename from sha1dc/LICENSE.txt
rename to sha/sha1dc/LICENSE.txt
diff --git a/sha1dc/sha1.c b/sha/sha1dc/sha1.c
similarity index 100%
rename from sha1dc/sha1.c
rename to sha/sha1dc/sha1.c
diff --git a/sha1dc/sha1.h b/sha/sha1dc/sha1.h
similarity index 100%
rename from sha1dc/sha1.h
rename to sha/sha1dc/sha1.h
diff --git a/sha1dc/ubc_check.c b/sha/sha1dc/ubc_check.c
similarity index 100%
rename from sha1dc/ubc_check.c
rename to sha/sha1dc/ubc_check.c
diff --git a/sha1dc/ubc_check.h b/sha/sha1dc/ubc_check.h
similarity index 100%
rename from sha1dc/ubc_check.h
rename to sha/sha1dc/ubc_check.h
diff --git a/sha1dc_git.c b/sha/sha1dc_git.c
similarity index 100%
rename from sha1dc_git.c
rename to sha/sha1dc_git.c
diff --git a/sha1dc_git.h b/sha/sha1dc_git.h
similarity index 95%
rename from sha1dc_git.h
rename to sha/sha1dc_git.h
index 41e1c3fd3f78..100a7cc9d641 100644
--- a/sha1dc_git.h
+++ b/sha/sha1dc_git.h
@@ -5,7 +5,7 @@
#elif defined(DC_SHA1_SUBMODULE)
#include "sha1collisiondetection/lib/sha1.h"
#else
-#include "sha1dc/sha1.h"
+#include "sha/sha1dc/sha1.h"
#endif
#ifdef DC_SHA1_EXTERNAL
diff --git a/ppc/sha1.c b/sha/sha1ppc/sha1.c
similarity index 100%
rename from ppc/sha1.c
rename to sha/sha1ppc/sha1.c
diff --git a/ppc/sha1.h b/sha/sha1ppc/sha1.h
similarity index 100%
rename from ppc/sha1.h
rename to sha/sha1ppc/sha1.h
diff --git a/ppc/sha1ppc.S b/sha/sha1ppc/sha1ppc.S
similarity index 100%
rename from ppc/sha1ppc.S
rename to sha/sha1ppc/sha1ppc.S
diff --git a/sha256/gcrypt.h b/sha/sha256/gcrypt.h
similarity index 100%
rename from sha256/gcrypt.h
rename to sha/sha256/gcrypt.h
diff --git a/sha256/block/sha256.c b/sha/sha256/sha256.c
similarity index 100%
rename from sha256/block/sha256.c
rename to sha/sha256/sha256.c
diff --git a/sha256/block/sha256.h b/sha/sha256/sha256.h
similarity index 100%
rename from sha256/block/sha256.h
rename to sha/sha256/sha256.h
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/6] Add an implementation of the SHA-512 hash algorithm
2019-12-22 6:48 [PATCH 0/6] Additional SHA implementations Michael Clark
2019-12-22 6:48 ` [PATCH 1/6] Move all SHA algorithm variants into sha/ directory Michael Clark
@ 2019-12-22 6:48 ` Michael Clark
2019-12-22 6:48 ` [PATCH 3/6] Add an implementation of the SHA-3 " Michael Clark
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Michael Clark @ 2019-12-22 6:48 UTC (permalink / raw)
To: git; +Cc: Michael Clark
- Add SHA-512 hash algorithm implementation derived from the
SHA-256 implementation translated to 64-bit and 80 rounds.
- Add configuration machinery to select builtin impl or gcrypt.
- Add sha512-224, sha512-256 and sha512 commands to test-tool.
- Add sha512 hash tests to t/t0015-hash.sh
---
Makefile | 14 +++
hash.h | 46 ++++++-
sha/sha512/gcrypt.h | 43 +++++++
sha/sha512/sha512.c | 206 +++++++++++++++++++++++++++++++
sha/sha512/sha512.h | 31 +++++
sha1-file.c | 268 +++++++++++++++++++++++++++++++++++++++++
t/helper/test-sha512.c | 17 +++
t/helper/test-tool.c | 3 +
t/helper/test-tool.h | 3 +
t/t0015-hash.sh | 80 ++++++++++++
10 files changed, 707 insertions(+), 4 deletions(-)
create mode 100644 sha/sha512/gcrypt.h
create mode 100644 sha/sha512/sha512.c
create mode 100644 sha/sha512/sha512.h
create mode 100644 t/helper/test-sha512.c
diff --git a/Makefile b/Makefile
index bac1b30b2f1f..2cd505b21ebb 100644
--- a/Makefile
+++ b/Makefile
@@ -183,6 +183,8 @@ all::
#
# Define BLK_SHA256 to use the built-in SHA-256 routines.
#
+# Define BLK_SHA512 to use the built-in SHA-512 routines.
+#
# Define GCRYPT_SHA256 to use the SHA-256 routines in libgcrypt.
#
# Define OPENSSL_SHA256 to use the SHA-256 routines in OpenSSL.
@@ -739,6 +741,7 @@ TEST_BUILTINS_OBJS += test-serve-v2.o
TEST_BUILTINS_OBJS += test-sha1.o
TEST_BUILTINS_OBJS += test-sha1-array.o
TEST_BUILTINS_OBJS += test-sha256.o
+TEST_BUILTINS_OBJS += test-sha512.o
TEST_BUILTINS_OBJS += test-sigchain.o
TEST_BUILTINS_OBJS += test-strcmp-offset.o
TEST_BUILTINS_OBJS += test-string-list.o
@@ -1712,6 +1715,14 @@ else
endif
endif
+ifdef GCRYPT_SHA512
+ BASIC_CFLAGS += -DSHA512_GCRYPT
+ EXTLIBS += -lgcrypt
+else
+ LIB_OBJS += sha/sha512/sha512.o
+ BASIC_CFLAGS += -DSHA512_BLK
+endif
+
ifdef SHA1_MAX_BLOCK_SIZE
LIB_OBJS += compat/sha1-chunked.o
BASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE="$(SHA1_MAX_BLOCK_SIZE)"
@@ -2784,6 +2795,9 @@ EXCEPT_HDRS := $(GEN_HDRS) compat/% xdiff/%
ifndef GCRYPT_SHA256
EXCEPT_HDRS += sha/sha256/gcrypt.h
endif
+ifndef GCRYPT_SHA512
+ EXCEPT_HDRS += sha/sha512/gcrypt.h
+endif
CHK_HDRS = $(filter-out $(EXCEPT_HDRS),$(LIB_H))
HCO = $(patsubst %.h,%.hco,$(CHK_HDRS))
HCC = $(HCO:hco=hcc)
diff --git a/hash.h b/hash.h
index f1b941218dc8..ea96fccce0c8 100644
--- a/hash.h
+++ b/hash.h
@@ -23,6 +23,12 @@
#include "sha/sha256/sha256.h"
#endif
+#if defined(SHA512_GCRYPT)
+#include "sha/sha512/gcrypt.h"
+#else
+#include "sha/sha512/sha512.h"
+#endif
+
#ifndef platform_SHA_CTX
/*
* platform's underlying implementation of SHA-1; could be OpenSSL,
@@ -54,6 +60,13 @@
#define git_SHA256_Update platform_SHA256_Update
#define git_SHA256_Final platform_SHA256_Final
+#define git_SHA512_CTX platform_SHA512_CTX
+#define git_SHA512_Init platform_SHA512_Init
+#define git_SHA512_224_Init platform_SHA512_224_Init
+#define git_SHA512_256_Init platform_SHA512_256_Init
+#define git_SHA512_Update platform_SHA512_Update
+#define git_SHA512_Final platform_SHA512_Final
+
#ifdef SHA1_MAX_BLOCK_SIZE
#include "compat/sha1-chunked.h"
#undef git_SHA1_Update
@@ -74,13 +87,20 @@
#define GIT_HASH_SHA1 1
/* SHA-256 */
#define GIT_HASH_SHA256 2
+/* SHA-512 */
+#define GIT_HASH_SHA512 3
+/* SHA-512-224 */
+#define GIT_HASH_SHA512_224 4
+/* SHA-512-256 */
+#define GIT_HASH_SHA512_256 5
/* Number of algorithms supported (including unknown). */
-#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)
+#define GIT_HASH_NALGOS (GIT_HASH_SHA512_256 + 1)
/* A suitably aligned type for stack allocations of hash contexts. */
union git_hash_ctx {
git_SHA_CTX sha1;
git_SHA256_CTX sha256;
+ git_SHA512_CTX sha512;
};
typedef union git_hash_ctx git_hash_ctx;
@@ -151,11 +171,29 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
/* The block size of SHA-256. */
#define GIT_SHA256_BLKSZ 64
+/* The length in bytes and in hex digits of an object name (SHA-512 value). */
+#define GIT_SHA512_RAWSZ 64
+#define GIT_SHA512_HEXSZ (2 * GIT_SHA512_RAWSZ)
+/* The block size of SHA-512. */
+#define GIT_SHA512_BLKSZ 128
+
+/* The length in bytes and in hex digits of an object name (SHA-512-224 value). */
+#define GIT_SHA512_224_RAWSZ 28
+#define GIT_SHA512_224_HEXSZ (2 * GIT_SHA512_224_RAWSZ)
+/* The block size of SHA-512-224. */
+#define GIT_SHA512_224_BLKSZ 128
+
+/* The length in bytes and in hex digits of an object name (SHA-512-256 value). */
+#define GIT_SHA512_256_RAWSZ 32
+#define GIT_SHA512_256_HEXSZ (2 * GIT_SHA512_256_RAWSZ)
+/* The block size of SHA-512-256. */
+#define GIT_SHA512_256_BLKSZ 128
+
/* The length in byte and in hex digits of the largest possible hash value. */
-#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
-#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
+#define GIT_MAX_RAWSZ GIT_SHA512_RAWSZ
+#define GIT_MAX_HEXSZ GIT_SHA512_HEXSZ
/* The largest possible block size for any supported hash. */
-#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
+#define GIT_MAX_BLKSZ GIT_SHA512_BLKSZ
struct object_id {
unsigned char hash[GIT_MAX_RAWSZ];
diff --git a/sha/sha512/gcrypt.h b/sha/sha512/gcrypt.h
new file mode 100644
index 000000000000..fdc0097d0777
--- /dev/null
+++ b/sha/sha512/gcrypt.h
@@ -0,0 +1,43 @@
+#ifndef SHA512_GCRYPT_H
+#define SHA512_GCRYPT_H
+
+#include <gcrypt.h>
+
+#define SHA512_DIGEST_SIZE 64
+
+typedef gcry_md_hd_t gcrypt_SHA512_CTX;
+
+inline void gcrypt_SHA512_Init(gcrypt_SHA512_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA512, 0);
+}
+
+inline void gcrypt_SHA512_224_Init(gcrypt_SHA512_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA512_224, 0);
+}
+
+inline void gcrypt_SHA512_256_Init(gcrypt_SHA512_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA512_256, 0);
+}
+
+inline void gcrypt_SHA512_Update(gcrypt_SHA512_CTX *ctx, const void *data, size_t len)
+{
+ gcry_md_write(*ctx, data, len);
+}
+
+inline void gcrypt_SHA512_Final(unsigned char *digest, gcrypt_SHA512_CTX *ctx)
+{
+ int algo = gcry_md_get_algo(ctx);
+ unsigned int dlen = gcry_md_get_algo_dlen(algo);
+ memcpy(digest, gcry_md_read(*ctx, algo), dlen);
+}
+
+#define platform_SHA512_CTX gcrypt_SHA512_CTX
+#define platform_SHA512_Init gcrypt_SHA512_Init
+#define platform_SHA512_256_Init gcrypt_SHA512_256_Init
+#define platform_SHA512_Update gcrypt_SHA512_Update
+#define platform_SHA512_Final gcrypt_SHA512_Final
+
+#endif
diff --git a/sha/sha512/sha512.c b/sha/sha512/sha512.c
new file mode 100644
index 000000000000..8c1955627648
--- /dev/null
+++ b/sha/sha512/sha512.c
@@ -0,0 +1,206 @@
+#include "git-compat-util.h"
+#include "./sha512.h"
+
+static const uint64_t SHA_512_K[80] = {
+ 0x428a2f98d728ae22ull, 0x7137449123ef65cdull,
+ 0xb5c0fbcfec4d3b2full, 0xe9b5dba58189dbbcull,
+ 0x3956c25bf348b538ull, 0x59f111f1b605d019ull,
+ 0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull,
+ 0xd807aa98a3030242ull, 0x12835b0145706fbeull,
+ 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull,
+ 0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull,
+ 0x9bdc06a725c71235ull, 0xc19bf174cf692694ull,
+ 0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull,
+ 0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull,
+ 0x2de92c6f592b0275ull, 0x4a7484aa6ea6e483ull,
+ 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull,
+ 0x983e5152ee66dfabull, 0xa831c66d2db43210ull,
+ 0xb00327c898fb213full, 0xbf597fc7beef0ee4ull,
+ 0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull,
+ 0x06ca6351e003826full, 0x142929670a0e6e70ull,
+ 0x27b70a8546d22ffcull, 0x2e1b21385c26c926ull,
+ 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull,
+ 0x650a73548baf63deull, 0x766a0abb3c77b2a8ull,
+ 0x81c2c92e47edaee6ull, 0x92722c851482353bull,
+ 0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull,
+ 0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull,
+ 0xd192e819d6ef5218ull, 0xd69906245565a910ull,
+ 0xf40e35855771202aull, 0x106aa07032bbd1b8ull,
+ 0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull,
+ 0x2748774cdf8eeb99ull, 0x34b0bcb5e19b48a8ull,
+ 0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull,
+ 0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull,
+ 0x748f82ee5defb2fcull, 0x78a5636f43172f60ull,
+ 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull,
+ 0x90befffa23631e28ull, 0xa4506cebde82bde9ull,
+ 0xbef9a3f7b2c67915ull, 0xc67178f2e372532bull,
+ 0xca273eceea26619cull, 0xd186b8c721c0c207ull,
+ 0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull,
+ 0x06f067aa72176fbaull, 0x0a637dc5a2c898a6ull,
+ 0x113f9804bef90daeull, 0x1b710b35131c471bull,
+ 0x28db77f523047d84ull, 0x32caab7b40c72493ull,
+ 0x3c9ebe0a15c9bebcull, 0x431d67c49c100d4cull,
+ 0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull,
+ 0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull
+};
+
+void blk_SHA512_224_Init(blk_SHA512_CTX *ctx)
+{
+ ctx->size = 0;
+ ctx->digestlen = blk_SHA512_224_HASHSIZE;
+ ctx->state[0] = 0x8c3d37c819544da2ull;
+ ctx->state[1] = 0x73e1996689dcd4d6ull;
+ ctx->state[2] = 0x1dfab7ae32ff9c82ull;
+ ctx->state[3] = 0x679dd514582f9fcfull;
+ ctx->state[4] = 0x0f6d2b697bd44da8ull;
+ ctx->state[5] = 0x77e36f7304c48942ull;
+ ctx->state[6] = 0x3f9d85a86a1d36c8ull;
+ ctx->state[7] = 0x1112e6ad91d692a1ull;
+}
+
+void blk_SHA512_256_Init(blk_SHA512_CTX *ctx)
+{
+ ctx->size = 0;
+ ctx->digestlen = blk_SHA512_256_HASHSIZE;
+ ctx->state[0] = 0x22312194fc2bf72cull;
+ ctx->state[1] = 0x9f555fa3c84c64c2ull;
+ ctx->state[2] = 0x2393b86b6f53b151ull;
+ ctx->state[3] = 0x963877195940eabdull;
+ ctx->state[4] = 0x96283ee2a88effe3ull;
+ ctx->state[5] = 0xbe5e1e2553863992ull;
+ ctx->state[6] = 0x2b0199fc2c85b8aaull;
+ ctx->state[7] = 0x0eb72ddc81c52ca2ull;
+}
+
+void blk_SHA512_Init(blk_SHA512_CTX *ctx)
+{
+ ctx->size = 0;
+ ctx->digestlen = blk_SHA512_HASHSIZE;
+ ctx->state[0] = 0x6a09e667f3bcc908ull;
+ ctx->state[1] = 0xbb67ae8584caa73bull;
+ ctx->state[2] = 0x3c6ef372fe94f82bull;
+ ctx->state[3] = 0xa54ff53a5f1d36f1ull;
+ ctx->state[4] = 0x510e527fade682d1ull;
+ ctx->state[5] = 0x9b05688c2b3e6c1full;
+ ctx->state[6] = 0x1f83d9abfb41bd6bull;
+ ctx->state[7] = 0x5be0cd19137e2179ull;
+}
+
+static inline uint64_t ror(uint64_t x, unsigned n)
+{
+ return (x >> n) | (x << (64 - n));
+}
+
+static inline uint64_t ch(uint64_t x, uint64_t y, uint64_t z)
+{
+ return z ^ (x & (y ^ z));
+}
+
+static inline uint64_t maj(uint64_t x, uint64_t y, uint64_t z)
+{
+ return ((x | y) & z) | (x & y);
+}
+
+static inline uint64_t sigma0(uint64_t x)
+{
+ return ror(x, 28) ^ ror(x, 34) ^ ror(x, 39);
+}
+
+static inline uint64_t sigma1(uint64_t x)
+{
+ return ror(x, 14) ^ ror(x, 18) ^ ror(x, 41);
+}
+
+static inline uint64_t gamma0(uint64_t x)
+{
+ return ror(x, 1) ^ ror(x, 8) ^ (x >> 7);
+}
+
+static inline uint64_t gamma1(uint64_t x)
+{
+ return ror(x, 19) ^ ror(x, 61) ^ (x >> 6);
+}
+
+static void blk_SHA512_Transform(blk_SHA512_CTX *ctx, const unsigned char *buf)
+{
+ uint64_t S[8], W[80], t0, t1;
+ int i;
+
+ /* copy state into S */
+ for (i = 0; i < 8; i++)
+ S[i] = ctx->state[i];
+
+ /* copy the state into 1024-bits into W[0..15] */
+ for (i=0; i<16; i++, buf += sizeof(uint64_t)) {
+ W[i] = get_be64(buf);
+ }
+
+ /* fill W[16..80] */
+ for (; i<80; i++) {
+ W[i] = gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16];
+ }
+
+ /* compute SHA rounds */
+ for (i=0; i<80; i++) {
+ t0 = W[i] + S[7] + sigma1(S[4]) + ch(S[4], S[5], S[6]) + SHA_512_K[i];
+ t1 = maj(S[0], S[1], S[2]) + sigma0(S[0]);
+ S[7] = S[6];
+ S[6] = S[5];
+ S[5] = S[4];
+ S[4] = S[3] + t0;
+ S[3] = S[2];
+ S[2] = S[1];
+ S[1] = S[0];
+ S[0] = t0 + t1;
+ }
+
+ for (i = 0; i < 8; i++)
+ ctx->state[i] += S[i];
+}
+
+void blk_SHA512_Update(blk_SHA512_CTX *ctx, const void *data, size_t len)
+{
+ unsigned int len_buf = ctx->size & 127;
+
+ ctx->size += len;
+
+ /* Read the data into buf and process blocks as they get full */
+ if (len_buf) {
+ unsigned int left = 128 - len_buf;
+ if (len < left)
+ left = len;
+ memcpy(len_buf + ctx->buf, data, left);
+ len_buf = (len_buf + left) & 127;
+ len -= left;
+ data = ((const char *)data + left);
+ if (len_buf)
+ return;
+ blk_SHA512_Transform(ctx, ctx->buf);
+ }
+ while (len >= 128) {
+ blk_SHA512_Transform(ctx, data);
+ data = ((const char *)data + 128);
+ len -= 128;
+ }
+ if (len)
+ memcpy(ctx->buf, data, len);
+}
+
+void blk_SHA512_Final(uint8_t *digest, blk_SHA512_CTX *ctx)
+{
+ static const unsigned char pad[128] = { 0x80 };
+ unsigned int padlen[2];
+ int i;
+
+ /* Pad with a binary 1 (ie 0x80), then zeroes, then length */
+ padlen[0] = htonl((uint32_t)(ctx->size >> 29));
+ padlen[1] = htonl((uint32_t)(ctx->size << 3));
+
+ i = ctx->size & 127;
+ blk_SHA512_Update(ctx, pad, 1 + (127 & (119 - i)));
+ blk_SHA512_Update(ctx, padlen, 8);
+
+ /* copy output */
+ for (i = 0; i < 8; i++, digest += sizeof(uint64_t))
+ put_be64(digest, ctx->state[i]);
+}
diff --git a/sha/sha512/sha512.h b/sha/sha512/sha512.h
new file mode 100644
index 000000000000..bc063f0af868
--- /dev/null
+++ b/sha/sha512/sha512.h
@@ -0,0 +1,31 @@
+#ifndef SHA512_BLOCK_SHA512_H
+#define SHA512_BLOCK_SHA512_H
+
+#define blk_SHA512_BLKSIZE 128
+#define blk_SHA512_224_HASHSIZE 28
+#define blk_SHA512_256_HASHSIZE 32
+#define blk_SHA512_HASHSIZE 64
+
+struct blk_SHA512_CTX {
+ uint64_t state[8];
+ uint64_t size;
+ uint64_t digestlen;
+ uint8_t buf[blk_SHA512_BLKSIZE];
+};
+
+typedef struct blk_SHA512_CTX blk_SHA512_CTX;
+
+void blk_SHA512_Init(blk_SHA512_CTX *ctx);
+void blk_SHA512_224_Init(blk_SHA512_CTX *ctx);
+void blk_SHA512_256_Init(blk_SHA512_CTX *ctx);
+void blk_SHA512_Update(blk_SHA512_CTX *ctx, const void *data, size_t len);
+void blk_SHA512_Final(unsigned char *digest, blk_SHA512_CTX *ctx);
+
+#define platform_SHA512_CTX blk_SHA512_CTX
+#define platform_SHA512_Init blk_SHA512_Init
+#define platform_SHA512_224_Init blk_SHA512_224_Init
+#define platform_SHA512_256_Init blk_SHA512_256_Init
+#define platform_SHA512_Update blk_SHA512_Update
+#define platform_SHA512_Final blk_SHA512_Final
+
+#endif
diff --git a/sha1-file.c b/sha1-file.c
index 188de57634bb..1f5b835a9f24 100644
--- a/sha1-file.c
+++ b/sha1-file.c
@@ -45,6 +45,46 @@
"\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \
"\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \
"\x53\x21"
+#define EMPTY_TREE_SHA512_224_BIN_LITERAL \
+ "\xaa\xff\x3a\xb0\x67\xb1\x51\xd0\xbc\x31" \
+ "\x30\x27\x7d\x64\xa1\x1e\xb2\x57\xe0\xfe" \
+ "\xca\x74\xe0\xdc\xb7\xe3\x83\x03"
+#define EMPTY_TREE_SHA512_256_BIN_LITERAL \
+ "\x2c\xfe\x78\xf8\xea\x2f\xa9\xd2\x19\x37" \
+ "\x48\x68\xe7\xaa\x1f\xe4\x91\x62\x2b\xcb" \
+ "\x58\x15\xdc\xf3\xad\x12\xf3\x08\xbe\x79" \
+ "\x59\xdb"
+#define EMPTY_TREE_SHA512_BIN_LITERAL \
+ "\xd5\x1f\xd9\x2f\xdd\x8b\x29\xd0\x8f\x5c" \
+ "\xba\x26\x1a\xbb\x22\x15\x29\xe6\xff\xb1" \
+ "\x26\x4c\x51\x1b\xe2\x16\xd2\xf5\x30\x6e" \
+ "\xcd\xcc\x38\xe2\x39\x2d\xe4\xf6\x2c\x74" \
+ "\x56\x07\xa9\x76\x80\xfc\x7c\xcb\xbe\x73" \
+ "\x04\x4d\xfc\x03\xd8\x9e\xd9\x5b\xa5\x49" \
+ "\x67\x90\x91\x95"
+#define EMPTY_TREE_SHA3_224_BIN_LITERAL \
+ "\x1e\x04\xf2\x3d\xe0\xb2\xb7\xd1\xb8\x5e" \
+ "\x67\x68\xfa\x99\x7a\x99\xbd\x01\x19\xde" \
+ "\xc8\x15\x8a\xe0\xad\x07\xe1\x83"
+#define EMPTY_TREE_SHA3_256_BIN_LITERAL \
+ "\x30\x21\x1e\xd4\x85\xc9\x12\xe5\xbc\x28" \
+ "\x5b\xd0\xbd\x89\x59\xdd\xbf\xb5\x87\x5c" \
+ "\xaf\xb0\xae\x28\xe0\xab\xfa\x10\x77\xb2" \
+ "\xb2\x14"
+#define EMPTY_TREE_SHA3_384_BIN_LITERAL \
+ "\x92\xe9\x9a\xe9\x28\x1a\x89\xdc\x33\x2c" \
+ "\x9c\xe8\xf2\x83\x1d\xb5\x0e\xcc\x54\x78" \
+ "\x4d\x51\xc3\xeb\xd5\xc1\x15\x1e\x8f\xd6" \
+ "\x03\xfb\x40\x8a\xbb\xbb\x9d\xcf\x57\x13" \
+ "\xed\x21\x56\x67\x89\xce\x80\x59"
+#define EMPTY_TREE_SHA3_512_BIN_LITERAL \
+ "\x8f\x86\xcb\x67\xce\x0a\x8b\xc8\x65\xb3" \
+ "\x00\x73\x3c\x27\xda\xde\x0e\xa8\xfe\x66" \
+ "\x29\x9b\x4b\xc6\x36\x8e\xc8\x4f\x53\x13" \
+ "\x4c\x36\x7c\x66\xf0\xe3\x37\x62\x61\xab" \
+ "\x5a\x86\xd7\x22\xad\x0d\x98\x39\x1a\x3c" \
+ "\x1c\x47\x2d\x67\x91\xda\x46\x4a\x78\x36" \
+ "\x00\x6d\xe1\x2c"
#define EMPTY_BLOB_SHA1_BIN_LITERAL \
"\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
@@ -54,6 +94,46 @@
"\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43" \
"\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
"\x18\x13"
+#define EMPTY_BLOB_SHA512_224_BIN_LITERAL \
+ "\xa8\x6d\x3c\x63\x33\x98\x60\x44\x56\x07" \
+ "\xd6\xcf\xd3\x55\x12\x92\xa6\xfb\x04\x9f" \
+ "\x0f\xaa\x22\x2a\x7c\x10\x02\x7b"
+#define EMPTY_BLOB_SHA512_256_BIN_LITERAL \
+ "\x65\x76\x66\x8d\x3a\xcf\x02\x2c\x9c\x77" \
+ "\x92\x0c\x83\x49\xed\x6c\xcd\x8f\xc5\x96" \
+ "\x84\x5e\x87\xc3\x8b\x9e\x74\x90\x16\xc9" \
+ "\x84\xb3"
+#define EMPTY_BLOB_SHA512_BIN_LITERAL \
+ "\xba\x4d\x0b\xb3\xec\x89\x0f\xdc\x47\xa1" \
+ "\x0d\xf5\x3a\x59\x1a\x79\x85\x22\x37\xd5" \
+ "\xe6\x35\x45\x5d\xa9\x0a\x37\x42\xd7\x48" \
+ "\x27\x08\xb5\x7d\xe2\xff\xab\xc7\x58\x1f" \
+ "\x58\x1e\xe8\x07\x5f\xba\xb3\x47\x62\x70" \
+ "\x94\x2c\xdf\x87\xfa\x7d\xd6\x89\x5d\xaa" \
+ "\x65\x09\x89\x6c"
+#define EMPTY_BLOB_SHA3_224_BIN_LITERAL \
+ "\xf1\xe7\x29\x35\xac\x5c\x52\xd5\xc0\x9b" \
+ "\x40\x88\x42\xe2\x07\xc4\x2e\x54\x34\x42" \
+ "\x40\x07\x36\x4f\xdb\x46\x80\x63"
+#define EMPTY_BLOB_SHA3_256_BIN_LITERAL \
+ "\x5a\xad\xde\x7d\x8c\xa5\xb9\xb3\x52\xc2" \
+ "\x50\xce\x9b\x79\x9f\x5d\x81\x88\x93\xfe" \
+ "\x89\xdc\x52\xb4\x9f\x43\x8c\x8a\x9b\xa0" \
+ "\xa5\x45"
+#define EMPTY_BLOB_SHA3_384_BIN_LITERAL \
+ "\xa5\x3e\x08\x8a\xbe\x90\x8d\x8c\x94\x58" \
+ "\xa8\xba\x95\x56\x90\xc4\x17\xf7\x68\x03" \
+ "\x1e\xcf\x15\x6a\x16\x62\x44\x1f\xae\xda" \
+ "\x50\x2e\x83\x8f\x26\x60\x16\x4b\x61\xa7" \
+ "\x8b\x15\xac\x75\xe0\xf8\xde\xd4"
+#define EMPTY_BLOB_SHA3_512_BIN_LITERAL \
+ "\x43\x53\xa5\x0d\x0d\x3d\x8e\xdd\x23\x17" \
+ "\x63\xfb\x01\x02\x11\x62\x86\xaa\x6d\x76" \
+ "\x0a\x77\x21\x33\xe3\x2c\x12\x4a\x99\x8a" \
+ "\x19\x46\x7d\x78\x90\x64\xdd\x76\x3e\x57" \
+ "\xb5\x47\xff\x3a\x31\x88\x2d\xa3\xd2\x03" \
+ "\x13\x78\xcf\xe0\xfa\x57\x74\xc1\x2e\xea" \
+ "\x51\x05\x5a\x51"
const struct object_id null_oid;
static const struct object_id empty_tree_oid = {
@@ -68,6 +148,48 @@ static const struct object_id empty_tree_oid_sha256 = {
static const struct object_id empty_blob_oid_sha256 = {
EMPTY_BLOB_SHA256_BIN_LITERAL
};
+static const struct object_id empty_tree_oid_sha512 = {
+ EMPTY_TREE_SHA512_BIN_LITERAL
+};
+static const struct object_id empty_blob_oid_sha512 = {
+ EMPTY_BLOB_SHA512_BIN_LITERAL
+};
+static const struct object_id empty_tree_oid_sha512_224 = {
+ EMPTY_TREE_SHA512_224_BIN_LITERAL
+};
+static const struct object_id empty_blob_oid_sha512_224 = {
+ EMPTY_BLOB_SHA512_224_BIN_LITERAL
+};
+static const struct object_id empty_tree_oid_sha512_256 = {
+ EMPTY_TREE_SHA512_256_BIN_LITERAL
+};
+static const struct object_id empty_blob_oid_sha512_256 = {
+ EMPTY_BLOB_SHA512_256_BIN_LITERAL
+};
+static const struct object_id empty_tree_oid_sha3_224 = {
+ EMPTY_TREE_SHA3_224_BIN_LITERAL
+};
+static const struct object_id empty_blob_oid_sha3_224 = {
+ EMPTY_BLOB_SHA3_224_BIN_LITERAL
+};
+static const struct object_id empty_tree_oid_sha3_256 = {
+ EMPTY_TREE_SHA3_256_BIN_LITERAL
+};
+static const struct object_id empty_blob_oid_sha3_256 = {
+ EMPTY_BLOB_SHA3_256_BIN_LITERAL
+};
+static const struct object_id empty_tree_oid_sha3_384 = {
+ EMPTY_TREE_SHA3_384_BIN_LITERAL
+};
+static const struct object_id empty_blob_oid_sha3_384 = {
+ EMPTY_BLOB_SHA3_384_BIN_LITERAL
+};
+static const struct object_id empty_tree_oid_sha3_512 = {
+ EMPTY_TREE_SHA3_512_BIN_LITERAL
+};
+static const struct object_id empty_blob_oid_sha3_512 = {
+ EMPTY_BLOB_SHA3_512_BIN_LITERAL
+};
static void git_hash_sha1_init(git_hash_ctx *ctx)
{
@@ -100,6 +222,61 @@ static void git_hash_sha256_final(unsigned char *hash, git_hash_ctx *ctx)
git_SHA256_Final(hash, &ctx->sha256);
}
+static void git_hash_sha512_init(git_hash_ctx *ctx)
+{
+ git_SHA512_Init(&ctx->sha512);
+}
+
+static void git_hash_sha512_224_init(git_hash_ctx *ctx)
+{
+ git_SHA512_224_Init(&ctx->sha512);
+}
+
+static void git_hash_sha512_256_init(git_hash_ctx *ctx)
+{
+ git_SHA512_256_Init(&ctx->sha512);
+}
+
+static void git_hash_sha512_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+ git_SHA512_Update(&ctx->sha512, data, len);
+}
+
+static void git_hash_sha512_final(unsigned char *hash, git_hash_ctx *ctx)
+{
+ git_SHA512_Final(hash, &ctx->sha512);
+}
+
+static void git_hash_sha3_224_init(git_hash_ctx *ctx)
+{
+ git_SHA3_224_Init(&ctx->sha3);
+}
+
+static void git_hash_sha3_256_init(git_hash_ctx *ctx)
+{
+ git_SHA3_256_Init(&ctx->sha3);
+}
+
+static void git_hash_sha3_384_init(git_hash_ctx *ctx)
+{
+ git_SHA3_384_Init(&ctx->sha3);
+}
+
+static void git_hash_sha3_512_init(git_hash_ctx *ctx)
+{
+ git_SHA3_512_Init(&ctx->sha3);
+}
+
+static void git_hash_sha3_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+ git_SHA3_Update(&ctx->sha3, data, len);
+}
+
+static void git_hash_sha3_final(unsigned char *hash, git_hash_ctx *ctx)
+{
+ git_SHA3_Final(hash, &ctx->sha3);
+}
+
static void git_hash_unknown_init(git_hash_ctx *ctx)
{
BUG("trying to init unknown hash");
@@ -153,6 +330,97 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
git_hash_sha256_final,
&empty_tree_oid_sha256,
&empty_blob_oid_sha256,
+ },
+ {
+ "sha512",
+ /* "s512", big-endian */
+ 0x73353132,
+ GIT_SHA512_RAWSZ,
+ GIT_SHA512_HEXSZ,
+ GIT_SHA512_BLKSZ,
+ git_hash_sha512_init,
+ git_hash_sha512_update,
+ git_hash_sha512_final,
+ &empty_tree_oid_sha512,
+ &empty_blob_oid_sha512,
+ },
+ {
+ "sha512/224",
+ /* "s226", big-endian */
+ 0x73323236,
+ GIT_SHA512_224_RAWSZ,
+ GIT_SHA512_224_HEXSZ,
+ GIT_SHA512_224_BLKSZ,
+ git_hash_sha512_224_init,
+ git_hash_sha512_update,
+ git_hash_sha512_final,
+ &empty_tree_oid_sha512_224,
+ &empty_blob_oid_sha512_224,
+ },
+ {
+ "sha512/256",
+ /* "s228", big-endian */
+ 0x73323238,
+ GIT_SHA512_256_RAWSZ,
+ GIT_SHA512_256_HEXSZ,
+ GIT_SHA512_256_BLKSZ,
+ git_hash_sha512_256_init,
+ git_hash_sha512_update,
+ git_hash_sha512_final,
+ &empty_tree_oid_sha512_256,
+ &empty_blob_oid_sha512_256,
+ },
+ {
+ "sha3-224",
+ /* "s388", big-endian */
+ 0x73333838,
+ GIT_SHA3_224_RAWSZ,
+ GIT_SHA3_224_HEXSZ,
+ GIT_SHA3_224_BLKSZ,
+ git_hash_sha3_224_init,
+ git_hash_sha3_update,
+ git_hash_sha3_final,
+ &empty_tree_oid_sha3_224,
+ &empty_blob_oid_sha3_224,
+ },
+ {
+ "sha3-256",
+ /* "s398", big-endian */
+ 0x73333938,
+ GIT_SHA3_256_RAWSZ,
+ GIT_SHA3_256_HEXSZ,
+ GIT_SHA3_256_BLKSZ,
+ git_hash_sha3_256_init,
+ git_hash_sha3_update,
+ git_hash_sha3_final,
+ &empty_tree_oid_sha3_256,
+ &empty_blob_oid_sha3_256,
+ },
+ {
+ "sha3-384",
+ /* "s3a8", big-endian */
+ 0x73336138,
+ GIT_SHA3_384_RAWSZ,
+ GIT_SHA3_384_HEXSZ,
+ GIT_SHA3_384_BLKSZ,
+ git_hash_sha3_384_init,
+ git_hash_sha3_update,
+ git_hash_sha3_final,
+ &empty_tree_oid_sha3_384,
+ &empty_blob_oid_sha3_384,
+ },
+ {
+ "sha3-512",
+ /* "s3b8", big-endian */
+ 0x73336238,
+ GIT_SHA3_512_RAWSZ,
+ GIT_SHA3_512_HEXSZ,
+ GIT_SHA3_512_BLKSZ,
+ git_hash_sha3_512_init,
+ git_hash_sha3_update,
+ git_hash_sha3_final,
+ &empty_tree_oid_sha3_512,
+ &empty_blob_oid_sha3_512,
}
};
diff --git a/t/helper/test-sha512.c b/t/helper/test-sha512.c
new file mode 100644
index 000000000000..c80941a2a595
--- /dev/null
+++ b/t/helper/test-sha512.c
@@ -0,0 +1,17 @@
+#include "test-tool.h"
+#include "cache.h"
+
+int cmd__sha512(int ac, const char **av)
+{
+ return cmd_hash_impl(ac, av, GIT_HASH_SHA512);
+}
+
+int cmd__sha512_224(int ac, const char **av)
+{
+ return cmd_hash_impl(ac, av, GIT_HASH_SHA512_224);
+}
+
+int cmd__sha512_256(int ac, const char **av)
+{
+ return cmd_hash_impl(ac, av, GIT_HASH_SHA512_256);
+}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index f20989d4497b..47deff9c6ef4 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -57,6 +57,9 @@ static struct test_cmd cmds[] = {
{ "sha1", cmd__sha1 },
{ "sha1-array", cmd__sha1_array },
{ "sha256", cmd__sha256 },
+ { "sha512", cmd__sha512 },
+ { "sha512-224", cmd__sha512_224 },
+ { "sha512-256", cmd__sha512_256 },
{ "sigchain", cmd__sigchain },
{ "strcmp-offset", cmd__strcmp_offset },
{ "string-list", cmd__string_list },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 8ed2af71d1b2..927540dff7dd 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -47,6 +47,9 @@ int cmd__serve_v2(int argc, const char **argv);
int cmd__sha1(int argc, const char **argv);
int cmd__sha1_array(int argc, const char **argv);
int cmd__sha256(int argc, const char **argv);
+int cmd__sha512(int argc, const char **argv);
+int cmd__sha512_224(int argc, const char **argv);
+int cmd__sha512_256(int argc, const char **argv);
int cmd__sigchain(int argc, const char **argv);
int cmd__strcmp_offset(int argc, const char **argv);
int cmd__string_list(int argc, const char **argv);
diff --git a/t/t0015-hash.sh b/t/t0015-hash.sh
index 291e9061f39d..4735befe1c72 100755
--- a/t/t0015-hash.sh
+++ b/t/t0015-hash.sh
@@ -52,4 +52,84 @@ test_expect_success 'test basic SHA-256 hash values' '
grep 6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321 actual
'
+test_expect_success 'test basic SHA-512/224 hash values' '
+ test-tool sha512-224 </dev/null >actual &&
+ grep 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4 actual &&
+ printf "a" | test-tool sha512-224 >actual &&
+ grep d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327 actual &&
+ printf "abc" | test-tool sha512-224 >actual &&
+ grep 4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa actual &&
+ printf "message digest" | test-tool sha512-224 >actual &&
+ grep ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564 actual &&
+ printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha512-224 >actual &&
+ grep ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8 actual &&
+ # Try to exercise the chunking code by turning autoflush on.
+ perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \
+ test-tool sha512-224 >actual &&
+ grep 37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287 actual &&
+ perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \
+ test-tool sha512-224 >actual &&
+ grep 6a312ce7c451ef28bf9ad33f5ce85ddf2d9f07097660160dbcb5c4c4 actual &&
+ printf "blob 0\0" | test-tool sha512-224 >actual &&
+ grep a86d3c63339860445607d6cfd3551292a6fb049f0faa222a7c10027b actual &&
+ printf "blob 3\0abc" | test-tool sha512-224 >actual &&
+ grep 9d6948b51bccf6b9814288d3e8cbca42f5e31b825ec613b23a45a546 actual &&
+ printf "tree 0\0" | test-tool sha512-224 >actual &&
+ grep aaff3ab067b151d0bc3130277d64a11eb257e0feca74e0dcb7e38303 actual
+'
+
+test_expect_success 'test basic SHA-512/256 hash values' '
+ test-tool sha512-256 </dev/null >actual &&
+ grep c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a actual &&
+ printf "a" | test-tool sha512-256 >actual &&
+ grep 455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8 actual &&
+ printf "abc" | test-tool sha512-256 >actual &&
+ grep 53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23 actual &&
+ printf "message digest" | test-tool sha512-256 >actual &&
+ grep 0cf471fd17ed69d990daf3433c89b16d63dec1bb9cb42a6094604ee5d7b4e9fb actual &&
+ printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha512-256 >actual &&
+ grep fc3189443f9c268f626aea08a756abe7b726b05f701cb08222312ccfd6710a26 actual &&
+ # Try to exercise the chunking code by turning autoflush on.
+ perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \
+ test-tool sha512-256 >actual &&
+ grep 9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21 actual &&
+ perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \
+ test-tool sha512-256 >actual &&
+ grep b8803f7dc283e57eeb6340a3ba9d9a2098125500008b5bfdfeeb6ddd0582d2b8 actual &&
+ printf "blob 0\0" | test-tool sha512-256 >actual &&
+ grep 6576668d3acf022c9c77920c8349ed6ccd8fc596845e87c38b9e749016c984b3 actual &&
+ printf "blob 3\0abc" | test-tool sha512-256 >actual &&
+ grep 815d5a4e692c971eea251f5e8d86b42953640027d8f1163d9f33adeb5e1f7a7a actual &&
+ printf "tree 0\0" | test-tool sha512-256 >actual &&
+ grep 2cfe78f8ea2fa9d219374868e7aa1fe491622bcb5815dcf3ad12f308be7959db actual
+
+'
+
+test_expect_success 'test basic SHA-512 hash values' '
+ test-tool sha512 </dev/null >actual &&
+ grep cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e actual &&
+ printf "a" | test-tool sha512 >actual &&
+ grep 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75 actual &&
+ printf "abc" | test-tool sha512 >actual &&
+ grep ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f actual &&
+ printf "message digest" | test-tool sha512 >actual &&
+ grep 107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c actual &&
+ printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha512 >actual &&
+ grep 4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1 actual &&
+ # Try to exercise the chunking code by turning autoflush on.
+ perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \
+ test-tool sha512 >actual &&
+ grep e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b actual &&
+ perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \
+ test-tool sha512 >actual &&
+ grep daeddbe45570b154876086f66464a1a1ea6b623bd6bf53132a92f3326e0edb5cb8bf3eef58fe0b15c87526a226bd3242cad65f1f2025f1dbde0c30e41a9f8253 actual &&
+ printf "blob 0\0" | test-tool sha512 >actual &&
+ grep ba4d0bb3ec890fdc47a10df53a591a79852237d5e635455da90a3742d7482708b57de2ffabc7581f581ee8075fbab3476270942cdf87fa7dd6895daa6509896c actual &&
+ printf "blob 3\0abc" | test-tool sha512 >actual &&
+ grep 55abbe2a993e9d900dcd5e1315dbf5bc634af92500bf4242fd9c5bba38090ee043fc886018aab7fa7d855abf41162a1fcb49ef7bd56778fd6c0b9d1a7ba00a71 actual &&
+ printf "tree 0\0" | test-tool sha512 >actual &&
+ grep d51fd92fdd8b29d08f5cba261abb221529e6ffb1264c511be216d2f5306ecdcc38e2392de4f62c745607a97680fc7ccbbe73044dfc03d89ed95ba54967909195 actual
+
+'
+
test_done
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/6] Add an implementation of the SHA-3 hash algorithm
2019-12-22 6:48 [PATCH 0/6] Additional SHA implementations Michael Clark
2019-12-22 6:48 ` [PATCH 1/6] Move all SHA algorithm variants into sha/ directory Michael Clark
2019-12-22 6:48 ` [PATCH 2/6] Add an implementation of the SHA-512 hash algorithm Michael Clark
@ 2019-12-22 6:48 ` Michael Clark
2019-12-22 6:48 ` [PATCH 4/6] Add an implementation of the SHA224 truncated " Michael Clark
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Michael Clark @ 2019-12-22 6:48 UTC (permalink / raw)
To: git; +Cc: Michael Clark
- Add SHA3-224, SHA3-256, SHA3-384 and SHA3-512 hash algorithms
derived from the Keccak SHA-3 submission to NIST (Round 3), 2011
by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche
- Add configuration machinery to select builtin impl or gcrypt.
- Add sha3-224, sha3-256, sha3-384 and sha3-512 commands to test-tool.
- Add sha3 hash tests to t/t0015-hash.sh
---
Makefile | 9 ++
hash.h | 49 +++++++-
sha/sha3/gcrypt.h | 53 +++++++++
sha/sha3/sha3.c | 271 +++++++++++++++++++++++++++++++++++++++++++
sha/sha3/sha3.h | 34 ++++++
t/helper/test-sha3.c | 22 ++++
t/helper/test-tool.c | 4 +
t/helper/test-tool.h | 4 +
t/t0015-hash.sh | 108 +++++++++++++++++
9 files changed, 553 insertions(+), 1 deletion(-)
create mode 100644 sha/sha3/gcrypt.h
create mode 100644 sha/sha3/sha3.c
create mode 100644 sha/sha3/sha3.h
create mode 100644 t/helper/test-sha3.c
diff --git a/Makefile b/Makefile
index 2cd505b21ebb..6bf9900291cb 100644
--- a/Makefile
+++ b/Makefile
@@ -742,6 +742,7 @@ TEST_BUILTINS_OBJS += test-sha1.o
TEST_BUILTINS_OBJS += test-sha1-array.o
TEST_BUILTINS_OBJS += test-sha256.o
TEST_BUILTINS_OBJS += test-sha512.o
+TEST_BUILTINS_OBJS += test-sha3.o
TEST_BUILTINS_OBJS += test-sigchain.o
TEST_BUILTINS_OBJS += test-strcmp-offset.o
TEST_BUILTINS_OBJS += test-string-list.o
@@ -1723,6 +1724,14 @@ else
BASIC_CFLAGS += -DSHA512_BLK
endif
+ifdef GCRYPT_SHA3
+ BASIC_CFLAGS += -DSHA3_GCRYPT
+ EXTLIBS += -lgcrypt
+else
+ LIB_OBJS += sha/sha3/sha3.o
+ BASIC_CFLAGS += -DSHA3_BLK
+endif
+
ifdef SHA1_MAX_BLOCK_SIZE
LIB_OBJS += compat/sha1-chunked.o
BASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE="$(SHA1_MAX_BLOCK_SIZE)"
diff --git a/hash.h b/hash.h
index ea96fccce0c8..4826de3c80d4 100644
--- a/hash.h
+++ b/hash.h
@@ -29,6 +29,12 @@
#include "sha/sha512/sha512.h"
#endif
+#if defined(SHA3_GCRYPT)
+#include "sha/sha3/gcrypt.h"
+#else
+#include "sha/sha3/sha3.h"
+#endif
+
#ifndef platform_SHA_CTX
/*
* platform's underlying implementation of SHA-1; could be OpenSSL,
@@ -67,6 +73,14 @@
#define git_SHA512_Update platform_SHA512_Update
#define git_SHA512_Final platform_SHA512_Final
+#define git_SHA3_CTX platform_SHA3_CTX
+#define git_SHA3_224_Init platform_SHA3_224_Init
+#define git_SHA3_256_Init platform_SHA3_256_Init
+#define git_SHA3_384_Init platform_SHA3_384_Init
+#define git_SHA3_512_Init platform_SHA3_512_Init
+#define git_SHA3_Update platform_SHA3_Update
+#define git_SHA3_Final platform_SHA3_Final
+
#ifdef SHA1_MAX_BLOCK_SIZE
#include "compat/sha1-chunked.h"
#undef git_SHA1_Update
@@ -93,14 +107,23 @@
#define GIT_HASH_SHA512_224 4
/* SHA-512-256 */
#define GIT_HASH_SHA512_256 5
+/* SHA-3-224 */
+#define GIT_HASH_SHA3_224 6
+/* SHA-3-256 */
+#define GIT_HASH_SHA3_256 7
+/* SHA-3-384 */
+#define GIT_HASH_SHA3_384 8
+/* SHA-3-512 */
+#define GIT_HASH_SHA3_512 9
/* Number of algorithms supported (including unknown). */
-#define GIT_HASH_NALGOS (GIT_HASH_SHA512_256 + 1)
+#define GIT_HASH_NALGOS (GIT_HASH_SHA3_512 + 1)
/* A suitably aligned type for stack allocations of hash contexts. */
union git_hash_ctx {
git_SHA_CTX sha1;
git_SHA256_CTX sha256;
git_SHA512_CTX sha512;
+ git_SHA3_CTX sha3;
};
typedef union git_hash_ctx git_hash_ctx;
@@ -189,6 +212,30 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
/* The block size of SHA-512-256. */
#define GIT_SHA512_256_BLKSZ 128
+/* The length in bytes and in hex digits of an object name (SHA-3-224 value). */
+#define GIT_SHA3_224_RAWSZ 28
+#define GIT_SHA3_224_HEXSZ (2 * GIT_SHA3_224_RAWSZ)
+/* The block size of SHA-3-224. */
+#define GIT_SHA3_224_BLKSZ 128
+
+/* The length in bytes and in hex digits of an object name (SHA-3-256 value). */
+#define GIT_SHA3_256_RAWSZ 32
+#define GIT_SHA3_256_HEXSZ (2 * GIT_SHA3_256_RAWSZ)
+/* The block size of SHA-3-256. */
+#define GIT_SHA3_256_BLKSZ 128
+
+/* The length in bytes and in hex digits of an object name (SHA-3-384 value). */
+#define GIT_SHA3_384_RAWSZ 48
+#define GIT_SHA3_384_HEXSZ (2 * GIT_SHA3_384_RAWSZ)
+/* The block size of SHA-3-384. */
+#define GIT_SHA3_384_BLKSZ 128
+
+/* The length in bytes and in hex digits of an object name (SHA-3-512 value). */
+#define GIT_SHA3_512_RAWSZ 64
+#define GIT_SHA3_512_HEXSZ (2 * GIT_SHA3_512_RAWSZ)
+/* The block size of SHA-3-512. */
+#define GIT_SHA3_512_BLKSZ 128
+
/* The length in byte and in hex digits of the largest possible hash value. */
#define GIT_MAX_RAWSZ GIT_SHA512_RAWSZ
#define GIT_MAX_HEXSZ GIT_SHA512_HEXSZ
diff --git a/sha/sha3/gcrypt.h b/sha/sha3/gcrypt.h
new file mode 100644
index 000000000000..47a1482d65bc
--- /dev/null
+++ b/sha/sha3/gcrypt.h
@@ -0,0 +1,53 @@
+#ifndef SHA3_GCRYPT_H
+#define SHA3_GCRYPT_H
+
+#include <gcrypt.h>
+
+#define SHA3_224_DIGEST_SIZE 28
+#define SHA3_256_DIGEST_SIZE 32
+#define SHA3_384_DIGEST_SIZE 48
+#define SHA3_512_DIGEST_SIZE 64
+
+typedef gcry_md_hd_t gcrypt_SHA3_CTX;
+
+inline void gcrypt_SHA3_224_Init(gcrypt_SHA3_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA3_224, 0);
+}
+
+inline void gcrypt_SHA3_256_Init(gcrypt_SHA3_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA3_256, 0);
+}
+
+inline void gcrypt_SHA3_384_Init(gcrypt_SHA3_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA3_384, 0);
+}
+
+inline void gcrypt_SHA3_512_Init(gcrypt_SHA3_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA3_512, 0);
+}
+
+inline void gcrypt_SHA3_Update(gcrypt_SHA3_CTX *ctx, const void *data, size_t len)
+{
+ gcry_md_write(*ctx, data, len);
+}
+
+inline void gcrypt_SHA3_Final(unsigned char *digest, gcrypt_SHA3_CTX *ctx)
+{
+ int algo = gcry_md_get_algo(ctx);
+ unsigned int dlen = gcry_md_get_algo_dlen(algo);
+ memcpy(digest, gcry_md_read(*ctx, algo), dlen);
+}
+
+#define platform_SHA3_CTX gcrypt_SHA3_CTX
+#define platform_SHA3_224_Init gcrypt_SHA3_224_Init
+#define platform_SHA3_256_Init gcrypt_SHA3_256_Init
+#define platform_SHA3_384_Init gcrypt_SHA3_384_Init
+#define platform_SHA3_512_Init gcrypt_SHA3_512_Init
+#define platform_SHA3_Update gcrypt_SHA3_Update
+#define platform_SHA3_Final gcrypt_SHA3_Final
+
+#endif
diff --git a/sha/sha3/sha3.c b/sha/sha3/sha3.c
new file mode 100644
index 000000000000..572cbf88f163
--- /dev/null
+++ b/sha/sha3/sha3.c
@@ -0,0 +1,271 @@
+/*
+ * sha3.c
+ *
+ * an implementation of Secure Hash Algorithm 3 (Keccak) based on:
+ * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
+ * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche
+ *
+ * portions derived from RHash/sha3.c
+ *
+ * Copyright (c) 2013, Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2019, Michael Clark <michaeljclark@mac.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "git-compat-util.h"
+#include "sha3.h"
+
+/*
+ * macro to expand Keccak 7-term GF(2) round constant:
+ *
+ * (ax^63 + bx^31 + cx^15 + dx^7 + ex^3 + fx + g)
+ *
+ * K(c) -> forall (b in 0...6) |= c[b] << (1 << b) ;
+ */
+#define T(c,b) 0b##c##ull>>b<<63>>(64-(1 << b))
+#define K(c) T(c,0)|T(c,1)|T(c,2)|T(c,3)|T(c,4)|T(c,5)|T(c,6)
+
+/*
+ * expand SHA3 (Keccak) constants for 24 rounds
+ */
+static uint64_t keccak_round_constants[24] = {
+ K(0000001), K(0011010), K(1011110), K(1110000),
+ K(0011111), K(0100001), K(1111001), K(1010101),
+ K(0001110), K(0001100), K(0110101), K(0100110),
+ K(0111111), K(1001111), K(1011101), K(1010011),
+ K(1010010), K(1001000), K(0010110), K(1100110),
+ K(1111001), K(1011000), K(0100001), K(1110100),
+};
+
+static inline uint64_t rol(uint64_t x, int d)
+{
+ return (x << d) | (x >> (64-d));
+}
+
+/* Keccak theta() transformation */
+static void keccak_theta(uint64_t A[25])
+{
+ uint64_t C[5] = {
+ A[0] ^ A[5] ^ A[10] ^ A[15] ^ A[20],
+ A[1] ^ A[6] ^ A[11] ^ A[16] ^ A[21],
+ A[2] ^ A[7] ^ A[12] ^ A[17] ^ A[22],
+ A[3] ^ A[8] ^ A[13] ^ A[18] ^ A[23],
+ A[4] ^ A[9] ^ A[14] ^ A[19] ^ A[24]
+ };
+
+ uint64_t D[5] = {
+ rol(C[1], 1) ^ C[4],
+ rol(C[2], 1) ^ C[0],
+ rol(C[3], 1) ^ C[1],
+ rol(C[4], 1) ^ C[2],
+ rol(C[0], 1) ^ C[3]
+ };
+
+ for (size_t i = 0; i < 25; i += 5) {
+ A[i + 0] ^= D[0];
+ A[i + 1] ^= D[1];
+ A[i + 2] ^= D[2];
+ A[i + 3] ^= D[3];
+ A[i + 4] ^= D[4];
+ }
+}
+
+/* Keccak pi() transformation */
+static void keccak_pi(uint64_t A[25])
+{
+ uint64_t A1;
+ A1 = A[1];
+ A[ 1] = A[ 6];
+ A[ 6] = A[ 9];
+ A[ 9] = A[22];
+ A[22] = A[14];
+ A[14] = A[20];
+ A[20] = A[ 2];
+ A[ 2] = A[12];
+ A[12] = A[13];
+ A[13] = A[19];
+ A[19] = A[23];
+ A[23] = A[15];
+ A[15] = A[ 4];
+ A[ 4] = A[24];
+ A[24] = A[21];
+ A[21] = A[ 8];
+ A[ 8] = A[16];
+ A[16] = A[ 5];
+ A[ 5] = A[ 3];
+ A[ 3] = A[18];
+ A[18] = A[17];
+ A[17] = A[11];
+ A[11] = A[ 7];
+ A[ 7] = A[10];
+ A[10] = A1;
+ /* note: A[ 0] is left as is */
+}
+
+static inline void ChiStep(uint64_t A[25], size_t i)
+{
+ uint64_t C[5];
+ C[0] = A[0 + i] ^ ~A[1 + i] & A[2 + i];
+ C[1] = A[1 + i] ^ ~A[2 + i] & A[3 + i];
+ C[2] = A[2 + i] ^ ~A[3 + i] & A[4 + i];
+ C[3] = A[3 + i] ^ ~A[4 + i] & A[0 + i];
+ C[4] = A[4 + i] ^ ~A[0 + i] & A[1 + i];
+ A[0 + i] = C[0];
+ A[1 + i] = C[1];
+ A[2 + i] = C[2];
+ A[3 + i] = C[3];
+ A[4 + i] = C[4];
+}
+
+/* Keccak chi() transformation */
+static void keccak_chi(uint64_t A[25])
+{
+ ChiStep(A,0);
+ ChiStep(A,5);
+ ChiStep(A,10);
+ ChiStep(A,15);
+ ChiStep(A,20);
+}
+
+static void keccak_rho(uint64_t A[25])
+{
+ /* apply Keccak rho() transformation */
+ A[ 1] = rol(A[ 1], 1);
+ A[ 2] = rol(A[ 2], 62);
+ A[ 3] = rol(A[ 3], 28);
+ A[ 4] = rol(A[ 4], 27);
+ A[ 5] = rol(A[ 5], 36);
+ A[ 6] = rol(A[ 6], 44);
+ A[ 7] = rol(A[ 7], 6);
+ A[ 8] = rol(A[ 8], 55);
+ A[ 9] = rol(A[ 9], 20);
+ A[10] = rol(A[10], 3);
+ A[11] = rol(A[11], 10);
+ A[12] = rol(A[12], 43);
+ A[13] = rol(A[13], 25);
+ A[14] = rol(A[14], 39);
+ A[15] = rol(A[15], 41);
+ A[16] = rol(A[16], 45);
+ A[17] = rol(A[17], 15);
+ A[18] = rol(A[18], 21);
+ A[19] = rol(A[19], 8);
+ A[20] = rol(A[20], 18);
+ A[21] = rol(A[21], 2);
+ A[22] = rol(A[22], 61);
+ A[23] = rol(A[23], 56);
+ A[24] = rol(A[24], 14);
+}
+
+static void keccak_iota(uint64_t A[25], size_t round)
+{
+ /* apply iota(state, round) */
+ A[0] ^= keccak_round_constants[round];
+}
+
+static void keccak_permutation(uint64_t A[25])
+{
+ for (size_t round = 0; round < 24; round++)
+ {
+ keccak_theta(A);
+ keccak_rho(A);
+ keccak_pi(A);
+ keccak_chi(A);
+ keccak_iota(A, round);
+ }
+}
+
+static void blk_SHA3_Transform(blk_SHA3_CTX* ctx, const unsigned char *buf)
+{
+ size_t block_size = ctx->block_size;
+ for (size_t i = 0; i < block_size/8; i++)
+ {
+ ctx->state[i] ^= le64toh(((uint64_t*)buf)[i]);
+ }
+ keccak_permutation(ctx->state);
+}
+
+static void blk_SHA3_Init(blk_SHA3_CTX* ctx, unsigned bits)
+{
+ /* NB: The Keccak capacity parameter = bits * 2 */
+ unsigned rate = 1600 - bits * 2;
+
+ memset(ctx, 0, sizeof(blk_SHA3_CTX));
+ ctx->block_size = rate / 8;
+ assert(rate <= 1600 && (rate % 64) == 0);
+}
+
+void blk_SHA3_224_Init(blk_SHA3_CTX* ctx) { blk_SHA3_Init(ctx, 224); }
+void blk_SHA3_256_Init(blk_SHA3_CTX* ctx) { blk_SHA3_Init(ctx, 256); }
+void blk_SHA3_384_Init(blk_SHA3_CTX* ctx) { blk_SHA3_Init(ctx, 384); }
+void blk_SHA3_512_Init(blk_SHA3_CTX* ctx) { blk_SHA3_Init(ctx, 512); }
+
+void blk_SHA3_Update(blk_SHA3_CTX* ctx, const void *data, size_t len)
+{
+ unsigned int block_size = ctx->block_size;
+ unsigned int len_buf = ctx->size % block_size;
+
+ ctx->size += len;
+
+ /* Read the data into buf and process blocks as they get full */
+ if (len_buf) {
+ unsigned int left = block_size - len_buf;
+ if (len < left)
+ left = len;
+ memcpy(len_buf + ctx->buf, data, left);
+ len_buf = (len_buf + left) % block_size;
+ len -= left;
+ data = ((const char *)data + left);
+ if (len_buf)
+ return;
+ blk_SHA3_Transform(ctx, ctx->buf);
+ }
+ while (len >= block_size) {
+ blk_SHA3_Transform(ctx, data);
+ data = ((const char *)data + block_size);
+ len -= block_size;
+ }
+ if (len)
+ memcpy(ctx->buf, data, len);
+}
+
+static inline void put_le64(void *ptr, uint64_t value)
+{
+ unsigned char *p = ptr;
+ p[0] = value >> 0;
+ p[1] = value >> 8;
+ p[2] = value >> 16;
+ p[3] = value >> 24;
+ p[4] = value >> 32;
+ p[5] = value >> 40;
+ p[6] = value >> 48;
+ p[7] = value >> 56;
+}
+
+void blk_SHA3_Final(unsigned char* digest, blk_SHA3_CTX* ctx)
+{
+ unsigned int digest_length = 100 - ctx->block_size / 2;
+ unsigned int block_size = ctx->block_size;
+ unsigned int len = ctx->size % block_size, i;
+
+ /* Pad with 0x06, then zeroes, then 0x80 */
+ memset((char*)ctx->buf + len, 0, block_size - len);
+ ((char*)ctx->buf)[len] |= 0x06;
+ ((char*)ctx->buf)[block_size - 1] |= 0x80;
+
+ /* process final block */
+ blk_SHA3_Transform(ctx, ctx->buf);
+
+ /* copy output */
+ for (i = 0; i < (digest_length+7)/8; i++, digest += sizeof(uint64_t))
+ put_le64(digest, ctx->state[i]);
+}
diff --git a/sha/sha3/sha3.h b/sha/sha3/sha3.h
new file mode 100644
index 000000000000..eb974d69d2b8
--- /dev/null
+++ b/sha/sha3/sha3.h
@@ -0,0 +1,34 @@
+#ifndef SHA3_BLOCK_H
+#define SHA3_BLOCK_H
+
+#define blk_SHA3_224_hash_size 28
+#define blk_SHA3_256_hash_size 32
+#define blk_SHA3_384_hash_size 48
+#define blk_SHA3_512_hash_size 64
+#define blk_SHA3_max_permutation_size 200
+
+typedef struct blk_SHA3_CTX
+{
+ uint64_t state[blk_SHA3_max_permutation_size];
+ uint64_t size;
+ uint64_t block_size;
+ uint8_t buf[blk_SHA3_max_permutation_size];
+} blk_SHA3_CTX;
+
+void blk_SHA3_224_Init(blk_SHA3_CTX* ctx);
+void blk_SHA3_256_Init(blk_SHA3_CTX* ctx);
+void blk_SHA3_384_Init(blk_SHA3_CTX* ctx);
+void blk_SHA3_512_Init(blk_SHA3_CTX* ctx);
+void blk_SHA3_Update(blk_SHA3_CTX* ctx, const void *data, size_t len);
+void blk_SHA3_Final(unsigned char* digest, blk_SHA3_CTX* ctx);
+
+#define platform_SHA3_CTX blk_SHA3_CTX
+#define platform_SHA3_Init blk_SHA3_Init
+#define platform_SHA3_224_Init blk_SHA3_224_Init
+#define platform_SHA3_256_Init blk_SHA3_256_Init
+#define platform_SHA3_384_Init blk_SHA3_384_Init
+#define platform_SHA3_512_Init blk_SHA3_512_Init
+#define platform_SHA3_Update blk_SHA3_Update
+#define platform_SHA3_Final blk_SHA3_Final
+
+#endif
\ No newline at end of file
diff --git a/t/helper/test-sha3.c b/t/helper/test-sha3.c
new file mode 100644
index 000000000000..323936d1bc2e
--- /dev/null
+++ b/t/helper/test-sha3.c
@@ -0,0 +1,22 @@
+#include "test-tool.h"
+#include "cache.h"
+
+int cmd__sha3_224(int ac, const char **av)
+{
+ return cmd_hash_impl(ac, av, GIT_HASH_SHA3_224);
+}
+
+int cmd__sha3_256(int ac, const char **av)
+{
+ return cmd_hash_impl(ac, av, GIT_HASH_SHA3_256);
+}
+
+int cmd__sha3_384(int ac, const char **av)
+{
+ return cmd_hash_impl(ac, av, GIT_HASH_SHA3_384);
+}
+
+int cmd__sha3_512(int ac, const char **av)
+{
+ return cmd_hash_impl(ac, av, GIT_HASH_SHA3_512);
+}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 47deff9c6ef4..7acae78e9b87 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -60,6 +60,10 @@ static struct test_cmd cmds[] = {
{ "sha512", cmd__sha512 },
{ "sha512-224", cmd__sha512_224 },
{ "sha512-256", cmd__sha512_256 },
+ { "sha3-224", cmd__sha3_224 },
+ { "sha3-256", cmd__sha3_256 },
+ { "sha3-384", cmd__sha3_384 },
+ { "sha3-512", cmd__sha3_512 },
{ "sigchain", cmd__sigchain },
{ "strcmp-offset", cmd__strcmp_offset },
{ "string-list", cmd__string_list },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 927540dff7dd..8aa5cee7710b 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -50,6 +50,10 @@ int cmd__sha256(int argc, const char **argv);
int cmd__sha512(int argc, const char **argv);
int cmd__sha512_224(int argc, const char **argv);
int cmd__sha512_256(int argc, const char **argv);
+int cmd__sha3_224(int argc, const char **argv);
+int cmd__sha3_256(int argc, const char **argv);
+int cmd__sha3_384(int argc, const char **argv);
+int cmd__sha3_512(int argc, const char **argv);
int cmd__sigchain(int argc, const char **argv);
int cmd__strcmp_offset(int argc, const char **argv);
int cmd__string_list(int argc, const char **argv);
diff --git a/t/t0015-hash.sh b/t/t0015-hash.sh
index 4735befe1c72..c68a9ef2145c 100755
--- a/t/t0015-hash.sh
+++ b/t/t0015-hash.sh
@@ -132,4 +132,112 @@ test_expect_success 'test basic SHA-512 hash values' '
'
+test_expect_success 'test basic SHA3-224 hash values' '
+ test-tool sha3-224 </dev/null >actual &&
+ grep 6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7 actual &&
+ printf "a" | test-tool sha3-224 >actual &&
+ grep 9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b actual &&
+ printf "abc" | test-tool sha3-224 >actual &&
+ grep e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf actual &&
+ printf "message digest" | test-tool sha3-224 >actual &&
+ grep 18768bb4c48eb7fc88e5ddb17efcf2964abd7798a39d86a4b4a1e4c8 actual &&
+ printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha3-224 >actual &&
+ grep 5cdeca81e123f87cad96b9cba999f16f6d41549608d4e0f4681b8239 actual &&
+ # Try to exercise the chunking code by turning autoflush on.
+ perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \
+ test-tool sha3-224 >actual &&
+ grep d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c actual &&
+ perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \
+ test-tool sha3-224 >actual &&
+ grep 165efebf793f03c7610d6d5e79462c5f9b7fbcb903f4448038eb35a2 actual &&
+ printf "blob 0\0" | test-tool sha3-224 >actual &&
+ grep f1e72935ac5c52d5c09b408842e207c42e5434424007364fdb468063 actual &&
+ printf "blob 3\0abc" | test-tool sha3-224 >actual &&
+ grep f83c608c9d424b858f66ec80a67ab42409bdc1aae8d7867e6b595e2a actual &&
+ printf "tree 0\0" | test-tool sha3-224 >actual &&
+ grep 1e04f23de0b2b7d1b85e6768fa997a99bd0119dec8158ae0ad07e183 actual
+
+'
+
+test_expect_success 'test basic SHA3-256 hash values' '
+ test-tool sha3-256 </dev/null >actual &&
+ grep a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a actual &&
+ printf "a" | test-tool sha3-256 >actual &&
+ grep 80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b actual &&
+ printf "abc" | test-tool sha3-256 >actual &&
+ grep 3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532 actual &&
+ printf "message digest" | test-tool sha3-256 >actual &&
+ grep edcdb2069366e75243860c18c3a11465eca34bce6143d30c8665cefcfd32bffd actual &&
+ printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha3-256 >actual &&
+ grep 7cab2dc765e21b241dbc1c255ce620b29f527c6d5e7f5f843e56288f0d707521 actual &&
+ # Try to exercise the chunking code by turning autoflush on.
+ perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \
+ test-tool sha3-256 >actual &&
+ grep 5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1 actual &&
+ perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \
+ test-tool sha3-256 >actual &&
+ grep 529a361bd6ebbb28deea5a78db2fd714c5b415499d608e37123c4ca130770e6d actual &&
+ printf "blob 0\0" | test-tool sha3-256 >actual &&
+ grep 5aadde7d8ca5b9b352c250ce9b799f5d818893fe89dc52b49f438c8a9ba0a545 actual &&
+ printf "blob 3\0abc" | test-tool sha3-256 >actual &&
+ grep 1a6437dda2a94af5c38246520fd1461886dc46b97ced88b04d43537c603cde6d actual &&
+ printf "tree 0\0" | test-tool sha3-256 >actual &&
+ grep 30211ed485c912e5bc285bd0bd8959ddbfb5875cafb0ae28e0abfa1077b2b214 actual
+
+'
+
+test_expect_success 'test basic SHA3-384 hash values' '
+ test-tool sha3-384 </dev/null >actual &&
+ grep 0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004 actual &&
+ printf "a" | test-tool sha3-384 >actual &&
+ grep 1815f774f320491b48569efec794d249eeb59aae46d22bf77dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9 actual &&
+ printf "abc" | test-tool sha3-384 >actual &&
+ grep ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25 actual &&
+ printf "message digest" | test-tool sha3-384 >actual &&
+ grep d9519709f44af73e2c8e291109a979de3d61dc02bf69def7fbffdfffe662751513f19ad57e17d4b93ba1e484fc1980d5 actual &&
+ printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha3-384 >actual &&
+ grep fed399d2217aaf4c717ad0c5102c15589e1c990cc2b9a5029056a7f7485888d6ab65db2370077a5cadb53fc9280d278f actual &&
+ # Try to exercise the chunking code by turning autoflush on.
+ perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \
+ test-tool sha3-384 >actual &&
+ grep eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340 actual &&
+ perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \
+ test-tool sha3-384 >actual &&
+ grep 62c16d1d4366dd40a4c6995168c1e7b35e8e8103403274151a34c5838845a0f3d1a192dadbb0964af7d6941c50f0eb97 actual &&
+ printf "blob 0\0" | test-tool sha3-384 >actual &&
+ grep a53e088abe908d8c9458a8ba955690c417f768031ecf156a1662441faeda502e838f2660164b61a78b15ac75e0f8ded4 actual &&
+ printf "blob 3\0abc" | test-tool sha3-384 >actual &&
+ grep ba0eda34a4b47f9ec8ed996a260efadeb576e4f682b7d0d7d84b4781a210771da519e48f2542431882499fbd21d16935 actual &&
+ printf "tree 0\0" | test-tool sha3-384 >actual &&
+ grep 92e99ae9281a89dc332c9ce8f2831db50ecc54784d51c3ebd5c1151e8fd603fb408abbbb9dcf5713ed21566789ce8059 actual
+
+'
+
+test_expect_success 'test basic SHA3-512 hash values' '
+ test-tool sha3-512 </dev/null >actual &&
+ grep a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26 actual &&
+ printf "a" | test-tool sha3-512 >actual &&
+ grep 697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa803f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a actual &&
+ printf "abc" | test-tool sha3-512 >actual &&
+ grep b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0 actual &&
+ printf "message digest" | test-tool sha3-512 >actual &&
+ grep 3444e155881fa15511f57726c7d7cfe80302a7433067b29d59a71415ca9dd141ac892d310bc4d78128c98fda839d18d7f0556f2fe7acb3c0cda4bff3a25f5f59 actual &&
+ printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha3-512 >actual &&
+ grep af328d17fa28753a3c9f5cb72e376b90440b96f0289e5703b729324a975ab384eda565fc92aaded143669900d761861687acdc0a5ffa358bd0571aaad80aca68 actual &&
+ # Try to exercise the chunking code by turning autoflush on.
+ perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \
+ test-tool sha3-512 >actual &&
+ grep 3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87 actual &&
+ perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \
+ test-tool sha3-512 >actual &&
+ grep 06b2e52cc7595712651351cdc6726acdebba682844c7983f66089158433975e4d2caf6c0efc4c7018cd2da73df53047f19a79935941025db4aaf1bd876c49ad6 actual &&
+ printf "blob 0\0" | test-tool sha3-512 >actual &&
+ grep 4353a50d0d3d8edd231763fb0102116286aa6d760a772133e32c124a998a19467d789064dd763e57b547ff3a31882da3d2031378cfe0fa5774c12eea51055a51 actual &&
+ printf "blob 3\0abc" | test-tool sha3-512 >actual &&
+ grep 89de02c66a3beca3411b5a72699fe8389d574b7d59ca17d42cba7a83cd03423388b1c4248cd8a3cce73a0768948fe1a800c155c24378334f6ae2bb8c5bf48284 actual &&
+ printf "tree 0\0" | test-tool sha3-512 >actual &&
+ grep 8f86cb67ce0a8bc865b300733c27dade0ea8fe66299b4bc6368ec84f53134c367c66f0e3376261ab5a86d722ad0d98391a3c1c472d6791da464a7836006de12c actual
+
+'
+
test_done
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/6] Add an implementation of the SHA224 truncated hash algorithm
2019-12-22 6:48 [PATCH 0/6] Additional SHA implementations Michael Clark
` (2 preceding siblings ...)
2019-12-22 6:48 ` [PATCH 3/6] Add an implementation of the SHA-3 " Michael Clark
@ 2019-12-22 6:48 ` Michael Clark
2019-12-22 6:48 ` [PATCH 5/6] Add OpenSSL EVP interface for SHA-3 and SHA-512 algorithms Michael Clark
2019-12-22 6:48 ` [PATCH 6/6] Add sha/README.md with table of SHA algorithm details Michael Clark
5 siblings, 0 replies; 7+ messages in thread
From: Michael Clark @ 2019-12-22 6:48 UTC (permalink / raw)
To: git; +Cc: Michael Clark
- Update existing SHA256 implementation adding initialization
vector for SHA224 and add algorithm to list of hash algos.
- Add sha224 commands to test-tool.
- Add sha224 hash tests to t/t0015-hash.sh
---
hash.h | 34 +++++++++++++++++++++++++++-------
sha/sha256/gcrypt.h | 15 ++++++++++++++-
sha/sha256/sha256.c | 18 +++++++++++++++++-
sha/sha256/sha256.h | 9 +++++++++
sha1-file.c | 41 +++++++++++++++++++++++++++++++++++++++++
t/helper/test-sha256.c | 5 +++++
t/helper/test-tool.c | 1 +
t/helper/test-tool.h | 1 +
t/t0015-hash.sh | 26 ++++++++++++++++++++++++++
9 files changed, 141 insertions(+), 9 deletions(-)
diff --git a/hash.h b/hash.h
index 4826de3c80d4..16924203d035 100644
--- a/hash.h
+++ b/hash.h
@@ -54,6 +54,18 @@
#define git_SHA1_Update platform_SHA1_Update
#define git_SHA1_Final platform_SHA1_Final
+#ifndef platform_SHA224_CTX
+#define platform_SHA224_CTX SHA224_CTX
+#define platform_SHA224_Init SHA224_Init
+#define platform_SHA224_Update SHA224_Update
+#define platform_SHA224_Final SHA224_Final
+#endif
+
+#define git_SHA224_CTX platform_SHA224_CTX
+#define git_SHA224_Init platform_SHA224_Init
+#define git_SHA224_Update platform_SHA224_Update
+#define git_SHA224_Final platform_SHA224_Final
+
#ifndef platform_SHA256_CTX
#define platform_SHA256_CTX SHA256_CTX
#define platform_SHA256_Init SHA256_Init
@@ -101,20 +113,22 @@
#define GIT_HASH_SHA1 1
/* SHA-256 */
#define GIT_HASH_SHA256 2
+/* SHA-224 */
+#define GIT_HASH_SHA224 3
/* SHA-512 */
-#define GIT_HASH_SHA512 3
+#define GIT_HASH_SHA512 4
/* SHA-512-224 */
-#define GIT_HASH_SHA512_224 4
+#define GIT_HASH_SHA512_224 5
/* SHA-512-256 */
-#define GIT_HASH_SHA512_256 5
+#define GIT_HASH_SHA512_256 6
/* SHA-3-224 */
-#define GIT_HASH_SHA3_224 6
+#define GIT_HASH_SHA3_224 7
/* SHA-3-256 */
-#define GIT_HASH_SHA3_256 7
+#define GIT_HASH_SHA3_256 8
/* SHA-3-384 */
-#define GIT_HASH_SHA3_384 8
+#define GIT_HASH_SHA3_384 9
/* SHA-3-512 */
-#define GIT_HASH_SHA3_512 9
+#define GIT_HASH_SHA3_512 10
/* Number of algorithms supported (including unknown). */
#define GIT_HASH_NALGOS (GIT_HASH_SHA3_512 + 1)
@@ -188,6 +202,12 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
/* The block size of SHA-1. */
#define GIT_SHA1_BLKSZ 64
+/* The length in bytes and in hex digits of an object name (SHA-224 value). */
+#define GIT_SHA224_RAWSZ 28
+#define GIT_SHA224_HEXSZ (2 * GIT_SHA224_RAWSZ)
+/* The block size of SHA-224. */
+#define GIT_SHA224_BLKSZ 64
+
/* The length in bytes and in hex digits of an object name (SHA-256 value). */
#define GIT_SHA256_RAWSZ 32
#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
diff --git a/sha/sha256/gcrypt.h b/sha/sha256/gcrypt.h
index 09bd8bb20062..3de8614eb1d8 100644
--- a/sha/sha256/gcrypt.h
+++ b/sha/sha256/gcrypt.h
@@ -3,10 +3,16 @@
#include <gcrypt.h>
+#define SHA224_DIGEST_SIZE 28
#define SHA256_DIGEST_SIZE 32
typedef gcry_md_hd_t gcrypt_SHA256_CTX;
+inline void gcrypt_SHA224_Init(gcrypt_SHA256_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA224, 0);
+}
+
inline void gcrypt_SHA256_Init(gcrypt_SHA256_CTX *ctx)
{
gcry_md_open(ctx, GCRY_MD_SHA256, 0);
@@ -19,7 +25,9 @@ inline void gcrypt_SHA256_Update(gcrypt_SHA256_CTX *ctx, const void *data, size_
inline void gcrypt_SHA256_Final(unsigned char *digest, gcrypt_SHA256_CTX *ctx)
{
- memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA256), SHA256_DIGEST_SIZE);
+ int algo = gcry_md_get_algo(ctx);
+ unsigned int dlen = gcry_md_get_algo_dlen(algo);
+ memcpy(digest, gcry_md_read(*ctx, algo), dlen);
}
#define platform_SHA256_CTX gcrypt_SHA256_CTX
@@ -27,4 +35,9 @@ inline void gcrypt_SHA256_Final(unsigned char *digest, gcrypt_SHA256_CTX *ctx)
#define platform_SHA256_Update gcrypt_SHA256_Update
#define platform_SHA256_Final gcrypt_SHA256_Final
+#define platform_SHA224_CTX gcrypt_SHA256_CTX
+#define platform_SHA224_Init gcrypt_SHA224_Init
+#define platform_SHA224_Update gcrypt_SHA256_Update
+#define platform_SHA224_Final gcrypt_SHA256_Final
+
#endif
diff --git a/sha/sha256/sha256.c b/sha/sha256/sha256.c
index 37850b4e52e0..a774d7562d6e 100644
--- a/sha/sha256/sha256.c
+++ b/sha/sha256/sha256.c
@@ -6,8 +6,24 @@
#define BLKSIZE blk_SHA256_BLKSIZE
+void blk_SHA224_Init(blk_SHA256_CTX *ctx)
+{
+ ctx->digestlen = blk_SHA224_HASHSIZE;
+ ctx->offset = 0;
+ ctx->size = 0;
+ ctx->state[0] = 0xc1059ed8ul;
+ ctx->state[1] = 0x367cd507ul;
+ ctx->state[2] = 0x3070dd17ul;
+ ctx->state[3] = 0xf70e5939ul;
+ ctx->state[4] = 0xffc00b31ul;
+ ctx->state[5] = 0x68581511ul;
+ ctx->state[6] = 0x64f98fa7ul;
+ ctx->state[7] = 0xbefa4fa4ul;
+}
+
void blk_SHA256_Init(blk_SHA256_CTX *ctx)
{
+ ctx->digestlen = blk_SHA256_HASHSIZE;
ctx->offset = 0;
ctx->size = 0;
ctx->state[0] = 0x6a09e667ul;
@@ -191,6 +207,6 @@ void blk_SHA256_Final(unsigned char *digest, blk_SHA256_CTX *ctx)
blk_SHA256_Update(ctx, padlen, 8);
/* copy output */
- for (i = 0; i < 8; i++, digest += sizeof(uint32_t))
+ for (i = 0; i < (ctx->digestlen >> 2); i++, digest += sizeof(uint32_t))
put_be32(digest, ctx->state[i]);
}
diff --git a/sha/sha256/sha256.h b/sha/sha256/sha256.h
index 5099d6421d37..e513eafa8199 100644
--- a/sha/sha256/sha256.h
+++ b/sha/sha256/sha256.h
@@ -2,16 +2,20 @@
#define SHA256_BLOCK_SHA256_H
#define blk_SHA256_BLKSIZE 64
+#define blk_SHA224_HASHSIZE 28
+#define blk_SHA256_HASHSIZE 32
struct blk_SHA256_CTX {
uint32_t state[8];
uint64_t size;
uint32_t offset;
+ uint32_t digestlen;
uint8_t buf[blk_SHA256_BLKSIZE];
};
typedef struct blk_SHA256_CTX blk_SHA256_CTX;
+void blk_SHA224_Init(blk_SHA256_CTX *ctx);
void blk_SHA256_Init(blk_SHA256_CTX *ctx);
void blk_SHA256_Update(blk_SHA256_CTX *ctx, const void *data, size_t len);
void blk_SHA256_Final(unsigned char *digest, blk_SHA256_CTX *ctx);
@@ -21,4 +25,9 @@ void blk_SHA256_Final(unsigned char *digest, blk_SHA256_CTX *ctx);
#define platform_SHA256_Update blk_SHA256_Update
#define platform_SHA256_Final blk_SHA256_Final
+#define platform_SHA224_CTX blk_SHA256_CTX
+#define platform_SHA224_Init blk_SHA224_Init
+#define platform_SHA224_Update blk_SHA256_Update
+#define platform_SHA224_Final blk_SHA256_Final
+
#endif
diff --git a/sha1-file.c b/sha1-file.c
index 1f5b835a9f24..b73847bea5d2 100644
--- a/sha1-file.c
+++ b/sha1-file.c
@@ -40,6 +40,10 @@
#define EMPTY_TREE_SHA1_BIN_LITERAL \
"\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
"\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
+#define EMPTY_TREE_SHA224_BIN_LITERAL \
+ "\xc8\x24\x29\x25\x0d\x41\x1b\x49\x91\xa3" \
+ "\xde\x9b\x42\xf5\x00\x90\x8a\x4a\x24\x2a" \
+ "\x8d\x3b\x34\x85\xe5\xe3\xbf\x71"
#define EMPTY_TREE_SHA256_BIN_LITERAL \
"\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
"\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \
@@ -89,6 +93,10 @@
#define EMPTY_BLOB_SHA1_BIN_LITERAL \
"\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
"\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91"
+#define EMPTY_BLOB_SHA224_BIN_LITERAL \
+ "\xfc\xdd\x1b\x16\x6d\xde\x80\x33\x06\xa4" \
+ "\x48\x52\xe0\xb7\xdc\xdf\x73\xba\xd0\xde" \
+ "\xc5\x6f\x00\x1f\xeb\x39\xea\x89"
#define EMPTY_BLOB_SHA256_BIN_LITERAL \
"\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \
"\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43" \
@@ -142,6 +150,12 @@ static const struct object_id empty_tree_oid = {
static const struct object_id empty_blob_oid = {
EMPTY_BLOB_SHA1_BIN_LITERAL
};
+static const struct object_id empty_tree_oid_sha224 = {
+ EMPTY_TREE_SHA224_BIN_LITERAL
+};
+static const struct object_id empty_blob_oid_sha224 = {
+ EMPTY_BLOB_SHA224_BIN_LITERAL
+};
static const struct object_id empty_tree_oid_sha256 = {
EMPTY_TREE_SHA256_BIN_LITERAL
};
@@ -206,6 +220,20 @@ static void git_hash_sha1_final(unsigned char *hash, git_hash_ctx *ctx)
git_SHA1_Final(hash, &ctx->sha1);
}
+static void git_hash_sha224_init(git_hash_ctx *ctx)
+{
+ git_SHA224_Init(&ctx->sha256);
+}
+
+static void git_hash_sha224_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+ git_SHA224_Update(&ctx->sha256, data, len);
+}
+
+static void git_hash_sha224_final(unsigned char *hash, git_hash_ctx *ctx)
+{
+ git_SHA224_Final(hash, &ctx->sha256);
+}
static void git_hash_sha256_init(git_hash_ctx *ctx)
{
@@ -331,6 +359,19 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
&empty_tree_oid_sha256,
&empty_blob_oid_sha256,
},
+ {
+ "sha224",
+ /* "s224", big-endian */
+ 0x73323234,
+ GIT_SHA224_RAWSZ,
+ GIT_SHA224_HEXSZ,
+ GIT_SHA224_BLKSZ,
+ git_hash_sha224_init,
+ git_hash_sha224_update,
+ git_hash_sha224_final,
+ &empty_tree_oid_sha224,
+ &empty_blob_oid_sha224,
+ },
{
"sha512",
/* "s512", big-endian */
diff --git a/t/helper/test-sha256.c b/t/helper/test-sha256.c
index 0ac6a99d5f2a..f79aca916128 100644
--- a/t/helper/test-sha256.c
+++ b/t/helper/test-sha256.c
@@ -1,6 +1,11 @@
#include "test-tool.h"
#include "cache.h"
+int cmd__sha224(int ac, const char **av)
+{
+ return cmd_hash_impl(ac, av, GIT_HASH_SHA224);
+}
+
int cmd__sha256(int ac, const char **av)
{
return cmd_hash_impl(ac, av, GIT_HASH_SHA256);
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 7acae78e9b87..762c4cb01d19 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -56,6 +56,7 @@ static struct test_cmd cmds[] = {
{ "serve-v2", cmd__serve_v2 },
{ "sha1", cmd__sha1 },
{ "sha1-array", cmd__sha1_array },
+ { "sha224", cmd__sha224 },
{ "sha256", cmd__sha256 },
{ "sha512", cmd__sha512 },
{ "sha512-224", cmd__sha512_224 },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 8aa5cee7710b..e4f63baef948 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -46,6 +46,7 @@ int cmd__scrap_cache_tree(int argc, const char **argv);
int cmd__serve_v2(int argc, const char **argv);
int cmd__sha1(int argc, const char **argv);
int cmd__sha1_array(int argc, const char **argv);
+int cmd__sha224(int argc, const char **argv);
int cmd__sha256(int argc, const char **argv);
int cmd__sha512(int argc, const char **argv);
int cmd__sha512_224(int argc, const char **argv);
diff --git a/t/t0015-hash.sh b/t/t0015-hash.sh
index c68a9ef2145c..225145d52653 100755
--- a/t/t0015-hash.sh
+++ b/t/t0015-hash.sh
@@ -52,6 +52,32 @@ test_expect_success 'test basic SHA-256 hash values' '
grep 6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321 actual
'
+test_expect_success 'test basic SHA-224 hash values' '
+ test-tool sha224 </dev/null >actual &&
+ grep d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f actual &&
+ printf "a" | test-tool sha224 >actual &&
+ grep abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5 actual &&
+ printf "abc" | test-tool sha224 >actual &&
+ grep 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7 actual &&
+ printf "message digest" | test-tool sha224 >actual &&
+ grep 2cb21c83ae2f004de7e81c3c7019cbcb65b71ab656b22d6d0c39b8eb actual &&
+ printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha224 >actual &&
+ grep 45a5f72c39c5cff2522eb3429799e49e5f44b356ef926bcf390dccc2 actual &&
+ # Try to exercise the chunking code by turning autoflush on.
+ perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \
+ test-tool sha224 >actual &&
+ grep 20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67 actual &&
+ perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \
+ test-tool sha224 >actual &&
+ grep 22c732697633e465ba836e11c7829ee185a72b53fbf35fde511bfbcd actual &&
+ printf "blob 0\0" | test-tool sha224 >actual &&
+ grep fcdd1b166dde803306a44852e0b7dcdf73bad0dec56f001feb39ea89 actual &&
+ printf "blob 3\0abc" | test-tool sha224 >actual &&
+ grep 22d78642a42d232e5b21911de160bed5b033badbecb8fc8b693e6ffe actual &&
+ printf "tree 0\0" | test-tool sha224 >actual &&
+ grep c82429250d411b4991a3de9b42f500908a4a242a8d3b3485e5e3bf71 actual
+'
+
test_expect_success 'test basic SHA-512/224 hash values' '
test-tool sha512-224 </dev/null >actual &&
grep 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4 actual &&
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/6] Add OpenSSL EVP interface for SHA-3 and SHA-512 algorithms
2019-12-22 6:48 [PATCH 0/6] Additional SHA implementations Michael Clark
` (3 preceding siblings ...)
2019-12-22 6:48 ` [PATCH 4/6] Add an implementation of the SHA224 truncated " Michael Clark
@ 2019-12-22 6:48 ` Michael Clark
2019-12-22 6:48 ` [PATCH 6/6] Add sha/README.md with table of SHA algorithm details Michael Clark
5 siblings, 0 replies; 7+ messages in thread
From: Michael Clark @ 2019-12-22 6:48 UTC (permalink / raw)
To: git; +Cc: Michael Clark
- Add OpenSSL EVP context wrapper and interface.
- Add configuration machinery to select SHA-3 and SHA-512 impls
from OpenSSL using the EVP interface.
- Use `make OPENSSL_EVP=1` to build using the OpenSSL EVP impls
for all SHA-3 and SHA-512 algos.
---
Makefile | 9 +++-
hash.h | 6 +++
sha/sha_evp/sha_evp.c | 99 +++++++++++++++++++++++++++++++++++++++++++
sha/sha_evp/sha_evp.h | 51 ++++++++++++++++++++++
4 files changed, 164 insertions(+), 1 deletion(-)
create mode 100644 sha/sha_evp/sha_evp.c
create mode 100644 sha/sha_evp/sha_evp.h
diff --git a/Makefile b/Makefile
index 6bf9900291cb..e065630e24fa 100644
--- a/Makefile
+++ b/Makefile
@@ -189,6 +189,8 @@ all::
#
# Define OPENSSL_SHA256 to use the SHA-256 routines in OpenSSL.
#
+# Define OPENSSL_EVP to use the SHA-3 and SHA-512 routines in OpenSSL.
+#
# Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).
#
# Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
@@ -1716,6 +1718,11 @@ else
endif
endif
+ifdef OPENSSL_EVP
+ EXTLIBS += $(LIB_4_CRYPTO)
+ BASIC_CFLAGS += -DSHA_EVP_OPENSSL
+ LIB_OBJS += sha/sha_evp/sha_evp.o
+else
ifdef GCRYPT_SHA512
BASIC_CFLAGS += -DSHA512_GCRYPT
EXTLIBS += -lgcrypt
@@ -1723,7 +1730,6 @@ else
LIB_OBJS += sha/sha512/sha512.o
BASIC_CFLAGS += -DSHA512_BLK
endif
-
ifdef GCRYPT_SHA3
BASIC_CFLAGS += -DSHA3_GCRYPT
EXTLIBS += -lgcrypt
@@ -1731,6 +1737,7 @@ else
LIB_OBJS += sha/sha3/sha3.o
BASIC_CFLAGS += -DSHA3_BLK
endif
+endif
ifdef SHA1_MAX_BLOCK_SIZE
LIB_OBJS += compat/sha1-chunked.o
diff --git a/hash.h b/hash.h
index 16924203d035..38e691fe8961 100644
--- a/hash.h
+++ b/hash.h
@@ -25,12 +25,18 @@
#if defined(SHA512_GCRYPT)
#include "sha/sha512/gcrypt.h"
+#elif defined(SHA_EVP_OPENSSL)
+#include <openssl/evp.h>
+#include "sha/sha_evp/sha_evp.h"
#else
#include "sha/sha512/sha512.h"
#endif
#if defined(SHA3_GCRYPT)
#include "sha/sha3/gcrypt.h"
+#elif defined(SHA_EVP_OPENSSL)
+#include <openssl/evp.h>
+#include "sha/sha_evp/sha_evp.h"
#else
#include "sha/sha3/sha3.h"
#endif
diff --git a/sha/sha_evp/sha_evp.c b/sha/sha_evp/sha_evp.c
new file mode 100644
index 000000000000..6871f9744a71
--- /dev/null
+++ b/sha/sha_evp/sha_evp.c
@@ -0,0 +1,99 @@
+#include "git-compat-util.h"
+#include "sha_evp.h"
+
+void evp_SHA2_224_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha224();
+}
+
+void evp_SHA2_256_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha256();
+}
+
+void evp_SHA2_512_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha512();
+}
+
+void evp_SHA2_512_224_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha512_224();
+}
+
+void evp_SHA2_512_256_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha512_256();
+}
+
+void evp_SHA3_224_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha3_224();
+}
+
+void evp_SHA3_256_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha3_256();
+}
+
+void evp_SHA3_384_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha3_384();
+}
+
+void evp_SHA3_512_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha3_512();
+}
+
+static void evp_SHA_Lazy_Init(SHA_EVP_CTX *ctx)
+{
+ /*
+ * The OpenSSL EVP digest API requires a dynamically sized context to be
+ * allocated and destroyed, however, the digest API we are emulating uses
+ * static structures and thus has no allocation or deallocation API.
+ *
+ * Due to this, we must call EVP_MD_CTX_destroy in Final to free up
+ * dynamically allocated memory. Context creation is thus done lazily in
+ * either Update or Final to handle cases where the context is reused
+ * after Final has been called.
+ */
+ if (ctx->digest_ctx) return;
+ if ((ctx->digest_ctx = EVP_MD_CTX_create()) == NULL)
+ abort();
+ if (EVP_DigestInit_ex(ctx->digest_ctx, ctx->digest_md, NULL) != 1)
+ abort();
+}
+
+void evp_SHA_Update(SHA_EVP_CTX *ctx, const void *data, size_t len)
+{
+ /* handle late Init as well as being called again after Final */
+ evp_SHA_Lazy_Init(ctx);
+
+ if (EVP_DigestUpdate(ctx->digest_ctx, data, len) != 1)
+ abort();
+}
+
+void evp_SHA_Final(unsigned char *result, SHA_EVP_CTX *ctx)
+{
+ unsigned int len;
+
+ /* handle case where Final is called without Update (empty hash) */
+ evp_SHA_Lazy_Init(ctx);
+
+ if (EVP_DigestFinal_ex(ctx->digest_ctx, result, &len) != 1)
+ abort();
+ assert(EVP_MD_size(ctx->digest_md) == len);
+
+ EVP_MD_CTX_destroy(ctx->digest_ctx);
+ ctx->digest_ctx = NULL;
+}
diff --git a/sha/sha_evp/sha_evp.h b/sha/sha_evp/sha_evp.h
new file mode 100644
index 000000000000..8757f77f4c13
--- /dev/null
+++ b/sha/sha_evp/sha_evp.h
@@ -0,0 +1,51 @@
+#ifndef SHAEVP_BLOCK_H
+#define SHAEVP_BLOCK_H
+
+#include <openssl/evp.h>
+
+#define evp_SHA2_256_hash_size 32
+#define evp_SHA2_512_224_hash_size 28
+#define evp_SHA2_512_256_hash_size 32
+#define evp_SHA2_512_hash_size 64
+#define evp_SHA3_224_hash_size 28
+#define evp_SHA3_256_hash_size 32
+#define evp_SHA3_384_hash_size 48
+#define evp_SHA3_512_hash_size 64
+
+struct SHA_EVP_CTX {
+ EVP_MD_CTX *digest_ctx;
+ const EVP_MD* digest_md;
+};
+
+typedef struct SHA_EVP_CTX SHA_EVP_CTX;
+
+void evp_SHA2_224_Init(SHA_EVP_CTX *ctx);
+void evp_SHA2_256_Init(SHA_EVP_CTX *ctx);
+void evp_SHA2_512_Init(SHA_EVP_CTX *ctx);
+void evp_SHA2_512_224_Init(SHA_EVP_CTX *ctx);
+void evp_SHA2_512_256_Init(SHA_EVP_CTX *ctx);
+void evp_SHA3_224_Init(SHA_EVP_CTX *ctx);
+void evp_SHA3_256_Init(SHA_EVP_CTX *ctx);
+void evp_SHA3_384_Init(SHA_EVP_CTX *ctx);
+void evp_SHA3_512_Init(SHA_EVP_CTX *ctx);
+
+void evp_SHA_Update(SHA_EVP_CTX *ctx, const void *data, size_t len);
+void evp_SHA_Final(unsigned char *result, SHA_EVP_CTX *ctx);
+
+#define platform_SHA512_CTX SHA_EVP_CTX
+#define platform_SHA512_Init evp_SHA2_512_Init
+#define platform_SHA512_224_Init evp_SHA2_512_224_Init
+#define platform_SHA512_256_Init evp_SHA2_512_256_Init
+#define platform_SHA512_Update evp_SHA_Update
+#define platform_SHA512_Final evp_SHA_Final
+
+#define platform_SHA3_CTX SHA_EVP_CTX
+#define platform_SHA3_Init evp_SHA3_256_Init
+#define platform_SHA3_224_Init evp_SHA3_224_Init
+#define platform_SHA3_256_Init evp_SHA3_256_Init
+#define platform_SHA3_384_Init evp_SHA3_384_Init
+#define platform_SHA3_512_Init evp_SHA3_512_Init
+#define platform_SHA3_Update evp_SHA_Update
+#define platform_SHA3_Final evp_SHA_Final
+
+#endif
\ No newline at end of file
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6/6] Add sha/README.md with table of SHA algorithm details
2019-12-22 6:48 [PATCH 0/6] Additional SHA implementations Michael Clark
` (4 preceding siblings ...)
2019-12-22 6:48 ` [PATCH 5/6] Add OpenSSL EVP interface for SHA-3 and SHA-512 algorithms Michael Clark
@ 2019-12-22 6:48 ` Michael Clark
5 siblings, 0 replies; 7+ messages in thread
From: Michael Clark @ 2019-12-22 6:48 UTC (permalink / raw)
To: git; +Cc: Michael Clark
- Add table showing algorith name, mnemonic, type-code, wdith,
and library implementation (builtin, gcrypt, OpenSSL, EVP).
---
sha/README.md | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 sha/README.md
diff --git a/sha/README.md b/sha/README.md
new file mode 100644
index 000000000000..0e24049e4cc7
--- /dev/null
+++ b/sha/README.md
@@ -0,0 +1,23 @@
+# SHA algorithms
+
+### Algorithms
+
+Table showing details of the SHA algorithms:
+
+| algorithm | mnemonic | type-code | width | extension | builtin | gcrypt | OpenSSL| EVP |
+|:---------------|:---------|:-------------|------:|----------:|:-------------|:-------|:-------|:-------|
+| `sha1` | `sha1` | `0x73686131` | 160 | yes | `sha/sha1` | yes | yes | - |
+| `sha256` | `s256` | `0x73323536` | 256 | yes | `sha/sha256` | yes | yes | - |
+| `sha224` | `s224` | `0x73323234` | 224 | no | `sha/sha256` | yes | yes | - |
+| `sha512` | `s512` | `0x73353132` | 512 | yes | `sha/sha512` | yes | yes | yes |
+| `sha512/224` | `s226` | `0x73323236` | 224 | no | `sha/sha512` | yes | yes | yes |
+| `sha512/256` | `s228` | `0x73323238` | 256 | no | `sha/sha512` | yes | yes | yes |
+| `sha3-224` | `s388` | `0x73333838` | 224 | no | `sha/sha3` | yes | - | yes |
+| `sha3-256` | `s398` | `0x73333938` | 256 | no | `sha/sha3` | yes | - | yes |
+| `sha3-384` | `s3a8` | `0x73336138` | 384 | no | `sha/sha3` | yes | - | yes |
+| `sha3-512` | `s3b8` | `0x73336238` | 512 | no | `sha/sha3` | yes | - | yes |
+
+#### Notes
+
+- The _'extension'_ column refers to whether the algorithm is vulnerable to the
+ [length extension attack](https://en.wikipedia.org/wiki/Length_extension_attack).
\ No newline at end of file
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread