Git fork

Add a base implementation of SHA-256 support

SHA-1 is weak and we need to transition to a new hash function. For
some time, we have referred to this new function as NewHash. Recently,
we decided to pick SHA-256 as NewHash. The reasons behind the choice of
SHA-256 are outlined in the thread starting at [1] and in the commit
history for the hash function transition document.

Add a basic implementation of SHA-256 based off libtomcrypt, which is in
the public domain. Optimize it and restructure it to meet our coding
standards. Pull in the update and final functions from the SHA-1 block
implementation, as we know these function correctly with all compilers.
This implementation is slower than SHA-1, but more performant
implementations will be introduced in future commits.

Wire up SHA-256 in the list of hash algorithms, and add a test that the
algorithm works correctly.

Note that with this patch, it is still not possible to switch to using
SHA-256 in Git. Additional patches are needed to prepare the code to
handle a larger hash algorithm and further test fixes are needed.

[1] https://public-inbox.org/git/20180609224913.GC38834@genre.crustytoothpaste.net/

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

authored by

brian m. carlson and committed by
Junio C Hamano
13eeedb5 c1665998

+331 -4
+4
Makefile
··· 739 739 TEST_BUILTINS_OBJS += test-scrap-cache-tree.o 740 740 TEST_BUILTINS_OBJS += test-sha1.o 741 741 TEST_BUILTINS_OBJS += test-sha1-array.o 742 + TEST_BUILTINS_OBJS += test-sha256.o 742 743 TEST_BUILTINS_OBJS += test-sigchain.o 743 744 TEST_BUILTINS_OBJS += test-strcmp-offset.o 744 745 TEST_BUILTINS_OBJS += test-string-list.o ··· 1632 1633 endif 1633 1634 endif 1634 1635 endif 1636 + 1637 + LIB_OBJS += sha256/block/sha256.o 1638 + BASIC_CFLAGS += -DSHA256_BLK 1635 1639 1636 1640 ifdef SHA1_MAX_BLOCK_SIZE 1637 1641 LIB_OBJS += compat/sha1-chunked.o
+9 -3
cache.h
··· 48 48 /* The block size of SHA-1. */ 49 49 #define GIT_SHA1_BLKSZ 64 50 50 51 + /* The length in bytes and in hex digits of an object name (SHA-256 value). */ 52 + #define GIT_SHA256_RAWSZ 32 53 + #define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ) 54 + /* The block size of SHA-256. */ 55 + #define GIT_SHA256_BLKSZ 64 56 + 51 57 /* The length in byte and in hex digits of the largest possible hash value. */ 52 - #define GIT_MAX_RAWSZ GIT_SHA1_RAWSZ 53 - #define GIT_MAX_HEXSZ GIT_SHA1_HEXSZ 58 + #define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ 59 + #define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ 54 60 /* The largest possible block size for any supported hash. */ 55 - #define GIT_MAX_BLKSZ GIT_SHA1_BLKSZ 61 + #define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ 56 62 57 63 struct object_id { 58 64 unsigned char hash[GIT_MAX_RAWSZ];
+18 -1
hash.h
··· 15 15 #include "block-sha1/sha1.h" 16 16 #endif 17 17 18 + #include "sha256/block/sha256.h" 19 + 18 20 #ifndef platform_SHA_CTX 19 21 /* 20 22 * platform's underlying implementation of SHA-1; could be OpenSSL, ··· 34 36 #define git_SHA1_Update platform_SHA1_Update 35 37 #define git_SHA1_Final platform_SHA1_Final 36 38 39 + #ifndef platform_SHA256_CTX 40 + #define platform_SHA256_CTX SHA256_CTX 41 + #define platform_SHA256_Init SHA256_Init 42 + #define platform_SHA256_Update SHA256_Update 43 + #define platform_SHA256_Final SHA256_Final 44 + #endif 45 + 46 + #define git_SHA256_CTX platform_SHA256_CTX 47 + #define git_SHA256_Init platform_SHA256_Init 48 + #define git_SHA256_Update platform_SHA256_Update 49 + #define git_SHA256_Final platform_SHA256_Final 50 + 37 51 #ifdef SHA1_MAX_BLOCK_SIZE 38 52 #include "compat/sha1-chunked.h" 39 53 #undef git_SHA1_Update ··· 52 66 #define GIT_HASH_UNKNOWN 0 53 67 /* SHA-1 */ 54 68 #define GIT_HASH_SHA1 1 69 + /* SHA-256 */ 70 + #define GIT_HASH_SHA256 2 55 71 /* Number of algorithms supported (including unknown). */ 56 - #define GIT_HASH_NALGOS (GIT_HASH_SHA1 + 1) 72 + #define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1) 57 73 58 74 /* A suitably aligned type for stack allocations of hash contexts. */ 59 75 union git_hash_ctx { 60 76 git_SHA_CTX sha1; 77 + git_SHA256_CTX sha256; 61 78 }; 62 79 typedef union git_hash_ctx git_hash_ctx; 63 80
+45
sha1-file.c
··· 40 40 #define EMPTY_TREE_SHA1_BIN_LITERAL \ 41 41 "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \ 42 42 "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04" 43 + #define EMPTY_TREE_SHA256_BIN_LITERAL \ 44 + "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \ 45 + "\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \ 46 + "\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \ 47 + "\x53\x21" 43 48 44 49 #define EMPTY_BLOB_SHA1_BIN_LITERAL \ 45 50 "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \ 46 51 "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91" 52 + #define EMPTY_BLOB_SHA256_BIN_LITERAL \ 53 + "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \ 54 + "\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43" \ 55 + "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \ 56 + "\x18\x13" 47 57 48 58 const unsigned char null_sha1[GIT_MAX_RAWSZ]; 49 59 const struct object_id null_oid; ··· 53 63 static const struct object_id empty_blob_oid = { 54 64 EMPTY_BLOB_SHA1_BIN_LITERAL 55 65 }; 66 + static const struct object_id empty_tree_oid_sha256 = { 67 + EMPTY_TREE_SHA256_BIN_LITERAL 68 + }; 69 + static const struct object_id empty_blob_oid_sha256 = { 70 + EMPTY_BLOB_SHA256_BIN_LITERAL 71 + }; 56 72 57 73 static void git_hash_sha1_init(git_hash_ctx *ctx) 58 74 { ··· 69 85 git_SHA1_Final(hash, &ctx->sha1); 70 86 } 71 87 88 + 89 + static void git_hash_sha256_init(git_hash_ctx *ctx) 90 + { 91 + git_SHA256_Init(&ctx->sha256); 92 + } 93 + 94 + static void git_hash_sha256_update(git_hash_ctx *ctx, const void *data, size_t len) 95 + { 96 + git_SHA256_Update(&ctx->sha256, data, len); 97 + } 98 + 99 + static void git_hash_sha256_final(unsigned char *hash, git_hash_ctx *ctx) 100 + { 101 + git_SHA256_Final(hash, &ctx->sha256); 102 + } 103 + 72 104 static void git_hash_unknown_init(git_hash_ctx *ctx) 73 105 { 74 106 BUG("trying to init unknown hash"); ··· 110 142 &empty_tree_oid, 111 143 &empty_blob_oid, 112 144 }, 145 + { 146 + "sha256", 147 + /* "s256", big-endian */ 148 + 0x73323536, 149 + GIT_SHA256_RAWSZ, 150 + GIT_SHA256_HEXSZ, 151 + GIT_SHA256_BLKSZ, 152 + git_hash_sha256_init, 153 + git_hash_sha256_update, 154 + git_hash_sha256_final, 155 + &empty_tree_oid_sha256, 156 + &empty_blob_oid_sha256, 157 + } 113 158 }; 114 159 115 160 const char *empty_tree_oid_hex(void)
+196
sha256/block/sha256.c
··· 1 + #include "git-compat-util.h" 2 + #include "./sha256.h" 3 + 4 + #undef RND 5 + #undef BLKSIZE 6 + 7 + #define BLKSIZE blk_SHA256_BLKSIZE 8 + 9 + void blk_SHA256_Init(blk_SHA256_CTX *ctx) 10 + { 11 + ctx->offset = 0; 12 + ctx->size = 0; 13 + ctx->state[0] = 0x6a09e667ul; 14 + ctx->state[1] = 0xbb67ae85ul; 15 + ctx->state[2] = 0x3c6ef372ul; 16 + ctx->state[3] = 0xa54ff53aul; 17 + ctx->state[4] = 0x510e527ful; 18 + ctx->state[5] = 0x9b05688cul; 19 + ctx->state[6] = 0x1f83d9abul; 20 + ctx->state[7] = 0x5be0cd19ul; 21 + } 22 + 23 + static inline uint32_t ror(uint32_t x, unsigned n) 24 + { 25 + return (x >> n) | (x << (32 - n)); 26 + } 27 + 28 + static inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z) 29 + { 30 + return z ^ (x & (y ^ z)); 31 + } 32 + 33 + static inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z) 34 + { 35 + return ((x | y) & z) | (x & y); 36 + } 37 + 38 + static inline uint32_t sigma0(uint32_t x) 39 + { 40 + return ror(x, 2) ^ ror(x, 13) ^ ror(x, 22); 41 + } 42 + 43 + static inline uint32_t sigma1(uint32_t x) 44 + { 45 + return ror(x, 6) ^ ror(x, 11) ^ ror(x, 25); 46 + } 47 + 48 + static inline uint32_t gamma0(uint32_t x) 49 + { 50 + return ror(x, 7) ^ ror(x, 18) ^ (x >> 3); 51 + } 52 + 53 + static inline uint32_t gamma1(uint32_t x) 54 + { 55 + return ror(x, 17) ^ ror(x, 19) ^ (x >> 10); 56 + } 57 + 58 + static void blk_SHA256_Transform(blk_SHA256_CTX *ctx, const unsigned char *buf) 59 + { 60 + 61 + uint32_t S[8], W[64], t0, t1; 62 + int i; 63 + 64 + /* copy state into S */ 65 + for (i = 0; i < 8; i++) 66 + S[i] = ctx->state[i]; 67 + 68 + /* copy the state into 512-bits into W[0..15] */ 69 + for (i = 0; i < 16; i++, buf += sizeof(uint32_t)) 70 + W[i] = get_be32(buf); 71 + 72 + /* fill W[16..63] */ 73 + for (i = 16; i < 64; i++) 74 + W[i] = gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]; 75 + 76 + #define RND(a,b,c,d,e,f,g,h,i,ki) \ 77 + t0 = h + sigma1(e) + ch(e, f, g) + ki + W[i]; \ 78 + t1 = sigma0(a) + maj(a, b, c); \ 79 + d += t0; \ 80 + h = t0 + t1; 81 + 82 + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); 83 + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); 84 + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); 85 + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); 86 + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); 87 + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); 88 + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); 89 + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); 90 + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); 91 + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); 92 + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); 93 + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); 94 + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); 95 + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); 96 + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); 97 + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); 98 + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); 99 + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); 100 + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); 101 + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); 102 + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); 103 + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); 104 + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); 105 + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); 106 + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); 107 + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); 108 + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); 109 + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); 110 + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); 111 + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); 112 + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); 113 + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); 114 + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); 115 + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); 116 + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); 117 + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); 118 + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); 119 + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); 120 + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); 121 + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); 122 + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); 123 + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); 124 + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); 125 + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); 126 + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); 127 + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); 128 + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); 129 + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); 130 + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); 131 + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); 132 + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); 133 + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); 134 + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); 135 + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); 136 + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); 137 + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); 138 + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); 139 + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); 140 + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); 141 + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); 142 + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); 143 + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); 144 + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); 145 + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); 146 + 147 + for (i = 0; i < 8; i++) 148 + ctx->state[i] += S[i]; 149 + } 150 + 151 + void blk_SHA256_Update(blk_SHA256_CTX *ctx, const void *data, size_t len) 152 + { 153 + unsigned int len_buf = ctx->size & 63; 154 + 155 + ctx->size += len; 156 + 157 + /* Read the data into buf and process blocks as they get full */ 158 + if (len_buf) { 159 + unsigned int left = 64 - len_buf; 160 + if (len < left) 161 + left = len; 162 + memcpy(len_buf + ctx->buf, data, left); 163 + len_buf = (len_buf + left) & 63; 164 + len -= left; 165 + data = ((const char *)data + left); 166 + if (len_buf) 167 + return; 168 + blk_SHA256_Transform(ctx, ctx->buf); 169 + } 170 + while (len >= 64) { 171 + blk_SHA256_Transform(ctx, data); 172 + data = ((const char *)data + 64); 173 + len -= 64; 174 + } 175 + if (len) 176 + memcpy(ctx->buf, data, len); 177 + } 178 + 179 + void blk_SHA256_Final(unsigned char *digest, blk_SHA256_CTX *ctx) 180 + { 181 + static const unsigned char pad[64] = { 0x80 }; 182 + unsigned int padlen[2]; 183 + int i; 184 + 185 + /* Pad with a binary 1 (ie 0x80), then zeroes, then length */ 186 + padlen[0] = htonl((uint32_t)(ctx->size >> 29)); 187 + padlen[1] = htonl((uint32_t)(ctx->size << 3)); 188 + 189 + i = ctx->size & 63; 190 + blk_SHA256_Update(ctx, pad, 1 + (63 & (55 - i))); 191 + blk_SHA256_Update(ctx, padlen, 8); 192 + 193 + /* copy output */ 194 + for (i = 0; i < 8; i++, digest += sizeof(uint32_t)) 195 + put_be32(digest, ctx->state[i]); 196 + }
+24
sha256/block/sha256.h
··· 1 + #ifndef SHA256_BLOCK_SHA256_H 2 + #define SHA256_BLOCK_SHA256_H 3 + 4 + #define blk_SHA256_BLKSIZE 64 5 + 6 + struct blk_SHA256_CTX { 7 + uint32_t state[8]; 8 + uint64_t size; 9 + uint32_t offset; 10 + uint8_t buf[blk_SHA256_BLKSIZE]; 11 + }; 12 + 13 + typedef struct blk_SHA256_CTX blk_SHA256_CTX; 14 + 15 + void blk_SHA256_Init(blk_SHA256_CTX *ctx); 16 + void blk_SHA256_Update(blk_SHA256_CTX *ctx, const void *data, size_t len); 17 + void blk_SHA256_Final(unsigned char *digest, blk_SHA256_CTX *ctx); 18 + 19 + #define platform_SHA256_CTX blk_SHA256_CTX 20 + #define platform_SHA256_Init blk_SHA256_Init 21 + #define platform_SHA256_Update blk_SHA256_Update 22 + #define platform_SHA256_Final blk_SHA256_Final 23 + 24 + #endif
+7
t/helper/test-sha256.c
··· 1 + #include "test-tool.h" 2 + #include "cache.h" 3 + 4 + int cmd__sha256(int ac, const char **av) 5 + { 6 + return cmd_hash_impl(ac, av, GIT_HASH_SHA256); 7 + }
+1
t/helper/test-tool.c
··· 43 43 { "scrap-cache-tree", cmd__scrap_cache_tree }, 44 44 { "sha1", cmd__sha1 }, 45 45 { "sha1-array", cmd__sha1_array }, 46 + { "sha256", cmd__sha256 }, 46 47 { "sigchain", cmd__sigchain }, 47 48 { "strcmp-offset", cmd__strcmp_offset }, 48 49 { "string-list", cmd__string_list },
+1
t/helper/test-tool.h
··· 39 39 int cmd__scrap_cache_tree(int argc, const char **argv); 40 40 int cmd__sha1(int argc, const char **argv); 41 41 int cmd__sha1_array(int argc, const char **argv); 42 + int cmd__sha256(int argc, const char **argv); 42 43 int cmd__sigchain(int argc, const char **argv); 43 44 int cmd__strcmp_offset(int argc, const char **argv); 44 45 int cmd__string_list(int argc, const char **argv);
+26
t/t0015-hash.sh
··· 26 26 grep 4b825dc642cb6eb9a060e54bf8d69288fbee4904 actual 27 27 ' 28 28 29 + test_expect_success 'test basic SHA-256 hash values' ' 30 + test-tool sha256 </dev/null >actual && 31 + grep e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 actual && 32 + printf "a" | test-tool sha256 >actual && 33 + grep ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb actual && 34 + printf "abc" | test-tool sha256 >actual && 35 + grep ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad actual && 36 + printf "message digest" | test-tool sha256 >actual && 37 + grep f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650 actual && 38 + printf "abcdefghijklmnopqrstuvwxyz" | test-tool sha256 >actual && 39 + grep 71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73 actual && 40 + # Try to exercise the chunking code by turning autoflush on. 41 + perl -e "$| = 1; print q{aaaaaaaaaa} for 1..100000;" | \ 42 + test-tool sha256 >actual && 43 + grep cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0 actual && 44 + perl -e "$| = 1; print q{abcdefghijklmnopqrstuvwxyz} for 1..100000;" | \ 45 + test-tool sha256 >actual && 46 + grep e406ba321ca712ad35a698bf0af8d61fc4dc40eca6bdcea4697962724ccbde35 actual && 47 + printf "blob 0\0" | test-tool sha256 >actual && 48 + grep 473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813 actual && 49 + printf "blob 3\0abc" | test-tool sha256 >actual && 50 + grep c1cf6e465077930e88dc5136641d402f72a229ddd996f627d60e9639eaba35a6 actual && 51 + printf "tree 0\0" | test-tool sha256 >actual && 52 + grep 6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321 actual 53 + ' 54 + 29 55 test_done