t0410: make test description clearer
[git/gitster.git] / hash.h
blob756166ce5e8e1d0e1a87c087936361bac6e66479
1 #ifndef HASH_H
2 #define HASH_H
4 #if defined(SHA1_APPLE)
5 #include <CommonCrypto/CommonDigest.h>
6 #elif defined(SHA1_OPENSSL)
7 # include <openssl/sha.h>
8 # if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
9 # define SHA1_NEEDS_CLONE_HELPER
10 # include "sha1/openssl.h"
11 # endif
12 #elif defined(SHA1_DC)
13 #include "sha1dc_git.h"
14 #else /* SHA1_BLK */
15 #include "block-sha1/sha1.h"
16 #endif
18 #if defined(SHA1_APPLE_UNSAFE)
19 # include <CommonCrypto/CommonDigest.h>
20 # define platform_SHA_CTX_unsafe CC_SHA1_CTX
21 # define platform_SHA1_Init_unsafe CC_SHA1_Init
22 # define platform_SHA1_Update_unsafe CC_SHA1_Update
23 # define platform_SHA1_Final_unsafe CC_SHA1_Final
24 #elif defined(SHA1_OPENSSL_UNSAFE)
25 # include <openssl/sha.h>
26 # if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
27 # define SHA1_NEEDS_CLONE_HELPER_UNSAFE
28 # include "sha1/openssl.h"
29 # define platform_SHA_CTX_unsafe openssl_SHA1_CTX
30 # define platform_SHA1_Init_unsafe openssl_SHA1_Init
31 # define platform_SHA1_Clone_unsafe openssl_SHA1_Clone
32 # define platform_SHA1_Update_unsafe openssl_SHA1_Update
33 # define platform_SHA1_Final_unsafe openssl_SHA1_Final
34 # else
35 # define platform_SHA_CTX_unsafe SHA_CTX
36 # define platform_SHA1_Init_unsafe SHA1_Init
37 # define platform_SHA1_Update_unsafe SHA1_Update
38 # define platform_SHA1_Final_unsafe SHA1_Final
39 # endif
40 #elif defined(SHA1_BLK_UNSAFE)
41 # include "block-sha1/sha1.h"
42 # define platform_SHA_CTX_unsafe blk_SHA_CTX
43 # define platform_SHA1_Init_unsafe blk_SHA1_Init
44 # define platform_SHA1_Update_unsafe blk_SHA1_Update
45 # define platform_SHA1_Final_unsafe blk_SHA1_Final
46 #endif
48 #if defined(SHA256_NETTLE)
49 #include "sha256/nettle.h"
50 #elif defined(SHA256_GCRYPT)
51 #define SHA256_NEEDS_CLONE_HELPER
52 #include "sha256/gcrypt.h"
53 #elif defined(SHA256_OPENSSL)
54 # include <openssl/sha.h>
55 # if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
56 # define SHA256_NEEDS_CLONE_HELPER
57 # include "sha256/openssl.h"
58 # endif
59 #else
60 #include "sha256/block/sha256.h"
61 #endif
63 #ifndef platform_SHA_CTX
65 * platform's underlying implementation of SHA-1; could be OpenSSL,
66 * blk_SHA, Apple CommonCrypto, etc... Note that the relevant
67 * SHA-1 header may have already defined platform_SHA_CTX for our
68 * own implementations like block-sha1, so we list
69 * the default for OpenSSL compatible SHA-1 implementations here.
71 #define platform_SHA_CTX SHA_CTX
72 #define platform_SHA1_Init SHA1_Init
73 #define platform_SHA1_Update SHA1_Update
74 #define platform_SHA1_Final SHA1_Final
75 #endif
77 #ifndef platform_SHA_CTX_unsafe
78 # define platform_SHA_CTX_unsafe platform_SHA_CTX
79 # define platform_SHA1_Init_unsafe platform_SHA1_Init
80 # define platform_SHA1_Update_unsafe platform_SHA1_Update
81 # define platform_SHA1_Final_unsafe platform_SHA1_Final
82 # ifdef platform_SHA1_Clone
83 # define platform_SHA1_Clone_unsafe platform_SHA1_Clone
84 # endif
85 # ifdef SHA1_NEEDS_CLONE_HELPER
86 # define SHA1_NEEDS_CLONE_HELPER_UNSAFE
87 # endif
88 #endif
90 #define git_SHA_CTX platform_SHA_CTX
91 #define git_SHA1_Init platform_SHA1_Init
92 #define git_SHA1_Update platform_SHA1_Update
93 #define git_SHA1_Final platform_SHA1_Final
95 #define git_SHA_CTX_unsafe platform_SHA_CTX_unsafe
96 #define git_SHA1_Init_unsafe platform_SHA1_Init_unsafe
97 #define git_SHA1_Update_unsafe platform_SHA1_Update_unsafe
98 #define git_SHA1_Final_unsafe platform_SHA1_Final_unsafe
100 #ifdef platform_SHA1_Clone
101 #define git_SHA1_Clone platform_SHA1_Clone
102 #endif
103 #ifdef platform_SHA1_Clone_unsafe
104 # define git_SHA1_Clone_unsafe platform_SHA1_Clone_unsafe
105 #endif
107 #ifndef platform_SHA256_CTX
108 #define platform_SHA256_CTX SHA256_CTX
109 #define platform_SHA256_Init SHA256_Init
110 #define platform_SHA256_Update SHA256_Update
111 #define platform_SHA256_Final SHA256_Final
112 #endif
114 #define git_SHA256_CTX platform_SHA256_CTX
115 #define git_SHA256_Init platform_SHA256_Init
116 #define git_SHA256_Update platform_SHA256_Update
117 #define git_SHA256_Final platform_SHA256_Final
119 #ifdef platform_SHA256_Clone
120 #define git_SHA256_Clone platform_SHA256_Clone
121 #endif
123 #ifdef SHA1_MAX_BLOCK_SIZE
124 #include "compat/sha1-chunked.h"
125 #undef git_SHA1_Update
126 #define git_SHA1_Update git_SHA1_Update_Chunked
127 #endif
129 #ifndef SHA1_NEEDS_CLONE_HELPER
130 static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)
132 memcpy(dst, src, sizeof(*dst));
134 #endif
135 #ifndef SHA1_NEEDS_CLONE_HELPER_UNSAFE
136 static inline void git_SHA1_Clone_unsafe(git_SHA_CTX_unsafe *dst,
137 const git_SHA_CTX_unsafe *src)
139 memcpy(dst, src, sizeof(*dst));
141 #endif
143 #ifndef SHA256_NEEDS_CLONE_HELPER
144 static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)
146 memcpy(dst, src, sizeof(*dst));
148 #endif
151 * Note that these constants are suitable for indexing the hash_algos array and
152 * comparing against each other, but are otherwise arbitrary, so they should not
153 * be exposed to the user or serialized to disk. To know whether a
154 * git_hash_algo struct points to some usable hash function, test the format_id
155 * field for being non-zero. Use the name field for user-visible situations and
156 * the format_id field for fixed-length fields on disk.
158 /* An unknown hash function. */
159 #define GIT_HASH_UNKNOWN 0
160 /* SHA-1 */
161 #define GIT_HASH_SHA1 1
162 /* SHA-256 */
163 #define GIT_HASH_SHA256 2
164 /* Number of algorithms supported (including unknown). */
165 #define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)
167 /* "sha1", big-endian */
168 #define GIT_SHA1_FORMAT_ID 0x73686131
170 /* The length in bytes and in hex digits of an object name (SHA-1 value). */
171 #define GIT_SHA1_RAWSZ 20
172 #define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
173 /* The block size of SHA-1. */
174 #define GIT_SHA1_BLKSZ 64
176 /* "s256", big-endian */
177 #define GIT_SHA256_FORMAT_ID 0x73323536
179 /* The length in bytes and in hex digits of an object name (SHA-256 value). */
180 #define GIT_SHA256_RAWSZ 32
181 #define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
182 /* The block size of SHA-256. */
183 #define GIT_SHA256_BLKSZ 64
185 /* The length in byte and in hex digits of the largest possible hash value. */
186 #define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
187 #define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
188 /* The largest possible block size for any supported hash. */
189 #define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
191 struct object_id {
192 unsigned char hash[GIT_MAX_RAWSZ];
193 int algo; /* XXX requires 4-byte alignment */
196 #define GET_OID_QUIETLY 01
197 #define GET_OID_COMMIT 02
198 #define GET_OID_COMMITTISH 04
199 #define GET_OID_TREE 010
200 #define GET_OID_TREEISH 020
201 #define GET_OID_BLOB 040
202 #define GET_OID_FOLLOW_SYMLINKS 0100
203 #define GET_OID_RECORD_PATH 0200
204 #define GET_OID_ONLY_TO_DIE 04000
205 #define GET_OID_REQUIRE_PATH 010000
206 #define GET_OID_HASH_ANY 020000
208 #define GET_OID_DISAMBIGUATORS \
209 (GET_OID_COMMIT | GET_OID_COMMITTISH | \
210 GET_OID_TREE | GET_OID_TREEISH | \
211 GET_OID_BLOB)
213 enum get_oid_result {
214 FOUND = 0,
215 MISSING_OBJECT = -1, /* The requested object is missing */
216 SHORT_NAME_AMBIGUOUS = -2,
217 /* The following only apply when symlinks are followed */
218 DANGLING_SYMLINK = -4, /*
219 * The initial symlink is there, but
220 * (transitively) points to a missing
221 * in-tree file
223 SYMLINK_LOOP = -5,
224 NOT_DIR = -6, /*
225 * Somewhere along the symlink chain, a path is
226 * requested which contains a file as a
227 * non-final element.
231 #ifdef USE_THE_REPOSITORY_VARIABLE
232 # include "repository.h"
233 # define the_hash_algo the_repository->hash_algo
234 #endif
236 /* A suitably aligned type for stack allocations of hash contexts. */
237 union git_hash_ctx {
238 git_SHA_CTX sha1;
239 git_SHA_CTX_unsafe sha1_unsafe;
241 git_SHA256_CTX sha256;
243 typedef union git_hash_ctx git_hash_ctx;
245 typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
246 typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
247 typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
248 typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
249 typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);
251 struct git_hash_algo {
253 * The name of the algorithm, as appears in the config file and in
254 * messages.
256 const char *name;
258 /* A four-byte version identifier, used in pack indices. */
259 uint32_t format_id;
261 /* The length of the hash in binary. */
262 size_t rawsz;
264 /* The length of the hash in hex characters. */
265 size_t hexsz;
267 /* The block size of the hash. */
268 size_t blksz;
270 /* The hash initialization function. */
271 git_hash_init_fn init_fn;
273 /* The hash context cloning function. */
274 git_hash_clone_fn clone_fn;
276 /* The hash update function. */
277 git_hash_update_fn update_fn;
279 /* The hash finalization function. */
280 git_hash_final_fn final_fn;
282 /* The hash finalization function for object IDs. */
283 git_hash_final_oid_fn final_oid_fn;
285 /* The non-cryptographic hash initialization function. */
286 git_hash_init_fn unsafe_init_fn;
288 /* The non-cryptographic hash context cloning function. */
289 git_hash_clone_fn unsafe_clone_fn;
291 /* The non-cryptographic hash update function. */
292 git_hash_update_fn unsafe_update_fn;
294 /* The non-cryptographic hash finalization function. */
295 git_hash_final_fn unsafe_final_fn;
297 /* The non-cryptographic hash finalization function. */
298 git_hash_final_oid_fn unsafe_final_oid_fn;
300 /* The OID of the empty tree. */
301 const struct object_id *empty_tree;
303 /* The OID of the empty blob. */
304 const struct object_id *empty_blob;
306 /* The all-zeros OID. */
307 const struct object_id *null_oid;
309 extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];
312 * Return a GIT_HASH_* constant based on the name. Returns GIT_HASH_UNKNOWN if
313 * the name doesn't match a known algorithm.
315 int hash_algo_by_name(const char *name);
316 /* Identical, except based on the format ID. */
317 int hash_algo_by_id(uint32_t format_id);
318 /* Identical, except based on the length. */
319 int hash_algo_by_length(int len);
320 /* Identical, except for a pointer to struct git_hash_algo. */
321 static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
323 return p - hash_algos;
326 const struct object_id *null_oid(void);
328 static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
331 * Teach the compiler that there are only two possibilities of hash size
332 * here, so that it can optimize for this case as much as possible.
334 if (algop->rawsz == GIT_MAX_RAWSZ)
335 return memcmp(sha1, sha2, GIT_MAX_RAWSZ);
336 return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
339 static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
342 * We write this here instead of deferring to hashcmp so that the
343 * compiler can properly inline it and avoid calling memcmp.
345 if (algop->rawsz == GIT_MAX_RAWSZ)
346 return !memcmp(sha1, sha2, GIT_MAX_RAWSZ);
347 return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
350 static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,
351 const struct git_hash_algo *algop)
353 memcpy(sha_dst, sha_src, algop->rawsz);
356 static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)
358 memset(hash, 0, algop->rawsz);
361 static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)
363 return memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);
366 static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)
368 return !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);
371 static inline void oidcpy(struct object_id *dst, const struct object_id *src)
373 memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
374 dst->algo = src->algo;
377 static inline void oidread(struct object_id *oid, const unsigned char *hash,
378 const struct git_hash_algo *algop)
380 memcpy(oid->hash, hash, algop->rawsz);
381 if (algop->rawsz < GIT_MAX_RAWSZ)
382 memset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);
383 oid->algo = hash_algo_by_ptr(algop);
386 static inline void oidclr(struct object_id *oid,
387 const struct git_hash_algo *algop)
389 memset(oid->hash, 0, GIT_MAX_RAWSZ);
390 oid->algo = hash_algo_by_ptr(algop);
393 static inline struct object_id *oiddup(const struct object_id *src)
395 struct object_id *dst = xmalloc(sizeof(struct object_id));
396 oidcpy(dst, src);
397 return dst;
400 static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)
402 oid->algo = hash_algo_by_ptr(algop);
406 * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code
407 * for use in hash tables. Cryptographic hashes are supposed to have
408 * uniform distribution, so in contrast to `memhash()`, this just copies
409 * the first `sizeof(int)` bytes without shuffling any bits. Note that
410 * the results will be different on big-endian and little-endian
411 * platforms, so they should not be stored or transferred over the net.
413 static inline unsigned int oidhash(const struct object_id *oid)
416 * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on
417 * platforms that don't support unaligned reads.
419 unsigned int hash;
420 memcpy(&hash, oid->hash, sizeof(hash));
421 return hash;
424 static inline int is_null_oid(const struct object_id *oid)
426 static const unsigned char null_hash[GIT_MAX_RAWSZ];
427 return !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);
430 const char *empty_tree_oid_hex(const struct git_hash_algo *algop);
432 static inline int is_empty_blob_oid(const struct object_id *oid,
433 const struct git_hash_algo *algop)
435 return oideq(oid, algop->empty_blob);
438 static inline int is_empty_tree_oid(const struct object_id *oid,
439 const struct git_hash_algo *algop)
441 return oideq(oid, algop->empty_tree);
444 #endif