Merge branch 'bc/sha-256'
Add sha-256 hash and plug it through the code to allow building Git with the "NewHash". * bc/sha-256: hash: add an SHA-256 implementation using OpenSSL sha256: add an SHA-256 implementation using libgcrypt Add a base implementation of SHA-256 support commit-graph: convert to using the_hash_algo t/helper: add a test helper to compute hash speed sha1-file: add a constant for hash block size t: make the sha1 test-tool helper generic t: add basic tests for our SHA-1 implementation cache: make hashcmp and hasheq work with larger hashes hex: introduce functions to print arbitrary hashes sha1-file: provide functions to look up hash algorithms sha1-file: rename algorithm to "sha1"
This commit is contained in:
51
cache.h
51
cache.h
@ -45,10 +45,20 @@ unsigned long git_deflate_bound(git_zstream *, unsigned long);
|
||||
/* The length in bytes and in hex digits of an object name (SHA-1 value). */
|
||||
#define GIT_SHA1_RAWSZ 20
|
||||
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
|
||||
/* The block size of SHA-1. */
|
||||
#define GIT_SHA1_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)
|
||||
/* The block size of SHA-256. */
|
||||
#define GIT_SHA256_BLKSZ 64
|
||||
|
||||
/* 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
|
||||
#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
|
||||
#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
|
||||
/* The largest possible block size for any supported hash. */
|
||||
#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
|
||||
|
||||
struct object_id {
|
||||
unsigned char hash[GIT_MAX_RAWSZ];
|
||||
@ -1028,16 +1038,12 @@ extern const struct object_id null_oid;
|
||||
static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
|
||||
{
|
||||
/*
|
||||
* This is a temporary optimization hack. By asserting the size here,
|
||||
* we let the compiler know that it's always going to be 20, which lets
|
||||
* it turn this fixed-size memcmp into a few inline instructions.
|
||||
*
|
||||
* This will need to be extended or ripped out when we learn about
|
||||
* hashes of different sizes.
|
||||
* Teach the compiler that there are only two possibilities of hash size
|
||||
* here, so that it can optimize for this case as much as possible.
|
||||
*/
|
||||
if (the_hash_algo->rawsz != 20)
|
||||
BUG("hash size not yet supported by hashcmp");
|
||||
return memcmp(sha1, sha2, the_hash_algo->rawsz);
|
||||
if (the_hash_algo->rawsz == GIT_MAX_RAWSZ)
|
||||
return memcmp(sha1, sha2, GIT_MAX_RAWSZ);
|
||||
return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
|
||||
}
|
||||
|
||||
static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)
|
||||
@ -1047,7 +1053,13 @@ static inline int oidcmp(const struct object_id *oid1, const struct object_id *o
|
||||
|
||||
static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2)
|
||||
{
|
||||
return !hashcmp(sha1, sha2);
|
||||
/*
|
||||
* We write this here instead of deferring to hashcmp so that the
|
||||
* compiler can properly inline it and avoid calling memcmp.
|
||||
*/
|
||||
if (the_hash_algo->rawsz == GIT_MAX_RAWSZ)
|
||||
return !memcmp(sha1, sha2, GIT_MAX_RAWSZ);
|
||||
return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
|
||||
}
|
||||
|
||||
static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)
|
||||
@ -1365,9 +1377,9 @@ extern int get_oid_hex(const char *hex, struct object_id *sha1);
|
||||
extern int hex_to_bytes(unsigned char *binary, const char *hex, size_t len);
|
||||
|
||||
/*
|
||||
* Convert a binary sha1 to its hex equivalent. The `_r` variant is reentrant,
|
||||
* Convert a binary hash to its hex equivalent. The `_r` variant is reentrant,
|
||||
* and writes the NUL-terminated output to the buffer `out`, which must be at
|
||||
* least `GIT_SHA1_HEXSZ + 1` bytes, and returns a pointer to out for
|
||||
* least `GIT_MAX_HEXSZ + 1` bytes, and returns a pointer to out for
|
||||
* convenience.
|
||||
*
|
||||
* The non-`_r` variant returns a static buffer, but uses a ring of 4
|
||||
@ -1375,10 +1387,13 @@ extern int hex_to_bytes(unsigned char *binary, const char *hex, size_t len);
|
||||
*
|
||||
* printf("%s -> %s", sha1_to_hex(one), sha1_to_hex(two));
|
||||
*/
|
||||
extern char *sha1_to_hex_r(char *out, const unsigned char *sha1);
|
||||
extern char *oid_to_hex_r(char *out, const struct object_id *oid);
|
||||
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
|
||||
extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as sha1_to_hex */
|
||||
char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash, const struct git_hash_algo *);
|
||||
char *sha1_to_hex_r(char *out, const unsigned char *sha1);
|
||||
char *oid_to_hex_r(char *out, const struct object_id *oid);
|
||||
char *hash_to_hex_algop(const unsigned char *hash, const struct git_hash_algo *); /* static buffer result! */
|
||||
char *sha1_to_hex(const unsigned char *sha1); /* same static buffer */
|
||||
char *hash_to_hex(const unsigned char *hash); /* same static buffer */
|
||||
char *oid_to_hex(const struct object_id *oid); /* same static buffer */
|
||||
|
||||
/*
|
||||
* Parse a 40-character hexadecimal object ID starting from hex, updating the
|
||||
|
Reference in New Issue
Block a user