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>

brian m. carlson committed Nov 14, 2018 at 04:09 UTC 13eeedb5d17ca3539600b6618d103b652ecc8ab0
10 files changed +331 -4
Makefile
+4
@@ -739,6 +739,7 @@ TEST_BUILTINS_OBJS += test-run-command.o
739 TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
740 TEST_BUILTINS_OBJS += test-sha1.o
741 TEST_BUILTINS_OBJS += test-sha1-array.o
742 +TEST_BUILTINS_OBJS += test-sha256.o
743 TEST_BUILTINS_OBJS += test-sigchain.o
744 TEST_BUILTINS_OBJS += test-strcmp-offset.o
745 TEST_BUILTINS_OBJS += test-string-list.o
@@ -1633,6 +1634,9 @@ endif
1634 endif
1635 endif
1636
1637 +LIB_OBJS += sha256/block/sha256.o
1638 +BASIC_CFLAGS += -DSHA256_BLK
1639 +
1640 ifdef SHA1_MAX_BLOCK_SIZE
1641 LIB_OBJS += compat/sha1-chunked.o
1642 BASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE="$(SHA1_MAX_BLOCK_SIZE)"
cache.h
+9 -3
@@ -48,11 +48,17 @@ unsigned long git_deflate_bound(git_zstream *, unsigned long);
48 /* The block size of SHA-1. */
49 #define GIT_SHA1_BLKSZ 64
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 +
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
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
62
63 struct object_id {
64 unsigned char hash[GIT_MAX_RAWSZ];
hash.h
+18 -1
@@ -15,6 +15,8 @@
15 #include "block-sha1/sha1.h"
16 #endif
17
18 +#include "sha256/block/sha256.h"
19 +
20 #ifndef platform_SHA_CTX
21 /*
22 * platform's underlying implementation of SHA-1; could be OpenSSL,
@@ -34,6 +36,18 @@
36 #define git_SHA1_Update platform_SHA1_Update
37 #define git_SHA1_Final platform_SHA1_Final
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 +
51 #ifdef SHA1_MAX_BLOCK_SIZE
52 #include "compat/sha1-chunked.h"
53 #undef git_SHA1_Update
@@ -52,12 +66,15 @@
66 #define GIT_HASH_UNKNOWN 0
67 /* SHA-1 */
68 #define GIT_HASH_SHA1 1
69 +/* SHA-256 */
70 +#define GIT_HASH_SHA256 2
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)
73
74 /* A suitably aligned type for stack allocations of hash contexts. */
75 union git_hash_ctx {
76 git_SHA_CTX sha1;
77 + git_SHA256_CTX sha256;
78 };
79 typedef union git_hash_ctx git_hash_ctx;
80
sha1-file.c
+45
@@ -40,10 +40,20 @@
40 #define EMPTY_TREE_SHA1_BIN_LITERAL \
41 "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
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"
48
49 #define EMPTY_BLOB_SHA1_BIN_LITERAL \
50 "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
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"
57
58 const unsigned char null_sha1[GIT_MAX_RAWSZ];
59 const struct object_id null_oid;
@@ -53,6 +63,12 @@ static const struct object_id empty_tree_oid = {
63 static const struct object_id empty_blob_oid = {
64 EMPTY_BLOB_SHA1_BIN_LITERAL
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 +};
72
73 static void git_hash_sha1_init(git_hash_ctx *ctx)
74 {
@@ -69,6 +85,22 @@ static void git_hash_sha1_final(unsigned char *hash, git_hash_ctx *ctx)
85 git_SHA1_Final(hash, &ctx->sha1);
86 }
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 +
104 static void git_hash_unknown_init(git_hash_ctx *ctx)
105 {
106 BUG("trying to init unknown hash");
@@ -110,6 +142,19 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
142 &empty_tree_oid,
143 &empty_blob_oid,
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 + }
158 };
159
160 const char *empty_tree_oid_hex(void)
sha256/block/sha256.c new
+196
@@ -0,0 +1,196 @@
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 +}
sha256/block/sha256.h new
+24
@@ -0,0 +1,24 @@
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
t/helper/test-sha256.c new
+7
@@ -0,0 +1,7 @@
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 +}
t/helper/test-tool.c
+1
@@ -43,6 +43,7 @@ static struct test_cmd cmds[] = {
43 { "scrap-cache-tree", cmd__scrap_cache_tree },
44 { "sha1", cmd__sha1 },
45 { "sha1-array", cmd__sha1_array },
46 + { "sha256", cmd__sha256 },
47 { "sigchain", cmd__sigchain },
48 { "strcmp-offset", cmd__strcmp_offset },
49 { "string-list", cmd__string_list },
t/helper/test-tool.h
+1
@@ -39,6 +39,7 @@ int cmd__run_command(int argc, const char **argv);
39 int cmd__scrap_cache_tree(int argc, const char **argv);
40 int cmd__sha1(int argc, const char **argv);
41 int cmd__sha1_array(int argc, const char **argv);
42 +int cmd__sha256(int argc, const char **argv);
43 int cmd__sigchain(int argc, const char **argv);
44 int cmd__strcmp_offset(int argc, const char **argv);
45 int cmd__string_list(int argc, const char **argv);
t/t0015-hash.sh
+26
@@ -26,4 +26,30 @@ test_expect_success 'test basic SHA-1 hash values' '
26 grep 4b825dc642cb6eb9a060e54bf8d69288fbee4904 actual
27 '
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 +
55 test_done