[RFC PATCH 1/2] Base test implementation for short BLAKE2b support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Test the implementation of a second hash algorithm with "short"
(160-bit) BLAKE2b support.  Simply add an additional algorithm to the
codebase without changing the use of any hash function and add a test
helper.

BLAKE2b was chosen simply because it provides a readily accessible hash
algorithm with arbitrary length support.  A 160-bit (20-byte) hash was
chosen to allow identification of tests that depend on the hash
algorithm in use while not causing buffer overflows, since parts of the
codebase still assume a 20-byte hash.

This is a preliminary commit for test purposes only and should not be
used in production in any way.
---
 Makefile                 |  3 +++
 cache.h                  | 16 ++++++++++++++
 hash.h                   |  9 +++++++-
 sha1_file.c              | 33 ++++++++++++++++++++++++++++
 t/helper/test-sblake2b.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 t/helper/test-sblake2b.c

diff --git a/Makefile b/Makefile
index 1a9b23b679..d46247586b 100644
--- a/Makefile
+++ b/Makefile
@@ -677,6 +677,7 @@ TEST_PROGRAMS_NEED_X += test-ref-store
 TEST_PROGRAMS_NEED_X += test-regex
 TEST_PROGRAMS_NEED_X += test-revision-walking
 TEST_PROGRAMS_NEED_X += test-run-command
+TEST_PROGRAMS_NEED_X += test-sblake2b
 TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
 TEST_PROGRAMS_NEED_X += test-sha1
 TEST_PROGRAMS_NEED_X += test-sha1-array
@@ -1539,6 +1540,8 @@ endif
 endif
 endif
 
+EXTLIBS += -lb2
+
 ifdef SHA1_MAX_BLOCK_SIZE
 	LIB_OBJS += compat/sha1-chunked.o
 	BASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE="$(SHA1_MAX_BLOCK_SIZE)"
diff --git a/cache.h b/cache.h
index bfde6f757a..638d832350 100644
--- a/cache.h
+++ b/cache.h
@@ -45,6 +45,10 @@ unsigned long git_deflate_bound(git_zstream *, unsigned long);
 #define GIT_SHA1_RAWSZ 20
 #define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
 
+/* The length in bytes and in hex digits of an object name (short BLAKE2b value). */
+#define GIT_SBLAKE2B_RAWSZ 20
+#define GIT_SBLAKE2B_HEXSZ (2 * GIT_SBLAKE2B_RAWSZ)
+
 /* The length in byte and in hex digits of the largest possible hash value. */
 #define GIT_MAX_RAWSZ GIT_SHA1_RAWSZ
 #define GIT_MAX_HEXSZ GIT_SHA1_HEXSZ
@@ -1013,7 +1017,13 @@ static inline void oidclr(struct object_id *oid)
 #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_SBLAKE2B_HEX \
+	"f44422a644bfa5212387098f253a1e89eba94548"
+#define EMPTY_TREE_SBLAKE2B_BIN_LITERAL \
+	"\xf4\x44\x22\xa6\x44\xbf\xa5\x21\x23\x87" \
+	"\x09\x8f\x25\x3a\x1e\x89\xeb\xa9\x45\x48"
 extern const struct object_id empty_tree_oid;
+const struct object_id empty_tree_oid_sblake2b;
 #define EMPTY_TREE_SHA1_BIN (empty_tree_oid.hash)
 
 #define EMPTY_BLOB_SHA1_HEX \
@@ -1021,7 +1031,13 @@ extern const struct object_id empty_tree_oid;
 #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_SBLAKE2B_HEX \
+	"a706650a477f63b9b00eba41272bf36ef5a7dfa2"
+#define EMPTY_BLOB_SBLAKE2B_BIN_LITERAL \
+	"\xa7\x06\x65\x0a\x47\x7f\x63\xb9\xb0\x0e" \
+	"\xba\x41\x27\x2b\xf3\x6e\xf5\xa7\xdf\xa2"
 extern const struct object_id empty_blob_oid;
+const struct object_id empty_blob_oid_sblake2b;
 #define EMPTY_BLOB_SHA1_BIN (empty_blob_oid.hash)
 
 
diff --git a/hash.h b/hash.h
index 365846a6b5..ef510bd51a 100644
--- a/hash.h
+++ b/hash.h
@@ -15,6 +15,8 @@
 #include "block-sha1/sha1.h"
 #endif
 
+#include <blake2.h>
+
 #ifndef platform_SHA_CTX
 /*
  * platform's underlying implementation of SHA-1; could be OpenSSL,
@@ -40,6 +42,8 @@
 #define git_SHA1_Update		git_SHA1_Update_Chunked
 #endif
 
+#define git_BLAKE2B_CTX		blake2b_state
+
 /*
  * Note that these constants are suitable for indexing the hash_algos array and
  * comparing against each other, but are otherwise arbitrary, so they should not
@@ -52,12 +56,15 @@
 #define GIT_HASH_UNKNOWN 0
 /* SHA-1 */
 #define GIT_HASH_SHA1 1
+/* 20-byte BLAKE2b ("short" BLAKE2b) */
+#define GIT_HASH_SBLAKE2 2
 /* Number of algorithms supported (including unknown). */
-#define GIT_HASH_NALGOS (GIT_HASH_SHA1 + 1)
+#define GIT_HASH_NALGOS (GIT_HASH_SBLAKE2 + 1)
 
 /* A suitably aligned type for stack allocations of hash contexts. */
 union git_hash_ctx {
 	git_SHA_CTX sha1;
+	git_BLAKE2B_CTX blake2b;
 };
 typedef union git_hash_ctx git_hash_ctx;
 
diff --git a/sha1_file.c b/sha1_file.c
index d9e2b1f285..5067b22a30 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -38,6 +38,12 @@ const struct object_id empty_tree_oid = {
 const struct object_id empty_blob_oid = {
 	EMPTY_BLOB_SHA1_BIN_LITERAL
 };
+const struct object_id empty_tree_oid_sblake2b = {
+	EMPTY_TREE_SBLAKE2B_BIN_LITERAL
+};
+const struct object_id empty_blob_oid_sblake2b = {
+	EMPTY_BLOB_SBLAKE2B_BIN_LITERAL
+};
 
 static void git_hash_sha1_init(void *ctx)
 {
@@ -54,6 +60,21 @@ static void git_hash_sha1_final(unsigned char *hash, void *ctx)
 	git_SHA1_Final(hash, (git_SHA_CTX *)ctx);
 }
 
+static void git_hash_sblake2b_init(void *ctx)
+{
+	blake2b_init((git_BLAKE2B_CTX *)ctx, GIT_SBLAKE2B_RAWSZ);
+}
+
+static void git_hash_sblake2b_update(void *ctx, const void *data, size_t len)
+{
+	blake2b_update((git_BLAKE2B_CTX *)ctx, data, len);
+}
+
+static void git_hash_sblake2b_final(unsigned char *hash, void *ctx)
+{
+	blake2b_final((git_BLAKE2B_CTX *)ctx, hash, GIT_SBLAKE2B_RAWSZ);
+}
+
 static void git_hash_unknown_init(void *ctx)
 {
 	die("trying to init unknown hash");
@@ -93,6 +114,18 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
 		&empty_tree_oid,
 		&empty_blob_oid,
 	},
+	{
+		"sblake2b",
+		/* "sb2b", big-endian */
+		0x73623262,
+		GIT_SBLAKE2B_RAWSZ,
+		GIT_SBLAKE2B_HEXSZ,
+		git_hash_sblake2b_init,
+		git_hash_sblake2b_update,
+		git_hash_sblake2b_final,
+		&empty_tree_oid_sblake2b,
+		&empty_blob_oid_sblake2b,
+	}
 };
 
 /*
diff --git a/t/helper/test-sblake2b.c b/t/helper/test-sblake2b.c
new file mode 100644
index 0000000000..6623aaa4d5
--- /dev/null
+++ b/t/helper/test-sblake2b.c
@@ -0,0 +1,56 @@
+#include "cache.h"
+
+int cmd_main(int ac, const char **av)
+{
+	git_hash_ctx ctx;
+	unsigned char hash[GIT_MAX_RAWSZ];
+	unsigned bufsz = 8192;
+	int binary = 0;
+	char *buffer;
+
+	if (ac == 2) {
+		if (!strcmp(av[1], "-b"))
+			binary = 1;
+		else
+			bufsz = strtoul(av[1], NULL, 10) * 1024 * 1024;
+	}
+
+	if (!bufsz)
+		bufsz = 8192;
+
+	while ((buffer = malloc(bufsz)) == NULL) {
+		fprintf(stderr, "bufsz %u is too big, halving...\n", bufsz);
+		bufsz /= 2;
+		if (bufsz < 1024)
+			die("OOPS");
+	}
+
+	hash_algos[GIT_HASH_SBLAKE2].init_fn(&ctx);
+
+	while (1) {
+		ssize_t sz, this_sz;
+		char *cp = buffer;
+		unsigned room = bufsz;
+		this_sz = 0;
+		while (room) {
+			sz = xread(0, cp, room);
+			if (sz == 0)
+				break;
+			if (sz < 0)
+				die_errno("test-sha1");
+			this_sz += sz;
+			cp += sz;
+			room -= sz;
+		}
+		if (this_sz == 0)
+			break;
+		hash_algos[GIT_HASH_SBLAKE2].update_fn(&ctx, buffer, this_sz);
+	}
+	hash_algos[GIT_HASH_SBLAKE2].final_fn(hash, &ctx);
+
+	if (binary)
+		fwrite(hash, 1, hash_algos[GIT_HASH_SBLAKE2].rawsz, stdout);
+	else
+		puts(sha1_to_hex(hash));
+	exit(0);
+}



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux