-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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/[email protected]/ Signed-off-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
- Loading branch information
Showing
10 changed files
with
331 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
#include "git-compat-util.h" | ||
#include "./sha256.h" | ||
|
||
#undef RND | ||
#undef BLKSIZE | ||
|
||
#define BLKSIZE blk_SHA256_BLKSIZE | ||
|
||
void blk_SHA256_Init(blk_SHA256_CTX *ctx) | ||
{ | ||
ctx->offset = 0; | ||
ctx->size = 0; | ||
ctx->state[0] = 0x6a09e667ul; | ||
ctx->state[1] = 0xbb67ae85ul; | ||
ctx->state[2] = 0x3c6ef372ul; | ||
ctx->state[3] = 0xa54ff53aul; | ||
ctx->state[4] = 0x510e527ful; | ||
ctx->state[5] = 0x9b05688cul; | ||
ctx->state[6] = 0x1f83d9abul; | ||
ctx->state[7] = 0x5be0cd19ul; | ||
} | ||
|
||
static inline uint32_t ror(uint32_t x, unsigned n) | ||
{ | ||
return (x >> n) | (x << (32 - n)); | ||
} | ||
|
||
static inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z) | ||
{ | ||
return z ^ (x & (y ^ z)); | ||
} | ||
|
||
static inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z) | ||
{ | ||
return ((x | y) & z) | (x & y); | ||
} | ||
|
||
static inline uint32_t sigma0(uint32_t x) | ||
{ | ||
return ror(x, 2) ^ ror(x, 13) ^ ror(x, 22); | ||
} | ||
|
||
static inline uint32_t sigma1(uint32_t x) | ||
{ | ||
return ror(x, 6) ^ ror(x, 11) ^ ror(x, 25); | ||
} | ||
|
||
static inline uint32_t gamma0(uint32_t x) | ||
{ | ||
return ror(x, 7) ^ ror(x, 18) ^ (x >> 3); | ||
} | ||
|
||
static inline uint32_t gamma1(uint32_t x) | ||
{ | ||
return ror(x, 17) ^ ror(x, 19) ^ (x >> 10); | ||
} | ||
|
||
static void blk_SHA256_Transform(blk_SHA256_CTX *ctx, const unsigned char *buf) | ||
{ | ||
|
||
uint32_t S[8], W[64], t0, t1; | ||
int i; | ||
|
||
/* copy state into S */ | ||
for (i = 0; i < 8; i++) | ||
S[i] = ctx->state[i]; | ||
|
||
/* copy the state into 512-bits into W[0..15] */ | ||
for (i = 0; i < 16; i++, buf += sizeof(uint32_t)) | ||
W[i] = get_be32(buf); | ||
|
||
/* fill W[16..63] */ | ||
for (i = 16; i < 64; i++) | ||
W[i] = gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]; | ||
|
||
#define RND(a,b,c,d,e,f,g,h,i,ki) \ | ||
t0 = h + sigma1(e) + ch(e, f, g) + ki + W[i]; \ | ||
t1 = sigma0(a) + maj(a, b, c); \ | ||
d += t0; \ | ||
h = t0 + t1; | ||
|
||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); | ||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); | ||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); | ||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); | ||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); | ||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); | ||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); | ||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); | ||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); | ||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); | ||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); | ||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); | ||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); | ||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); | ||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); | ||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); | ||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); | ||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); | ||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); | ||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); | ||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); | ||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); | ||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); | ||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); | ||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); | ||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); | ||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); | ||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); | ||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); | ||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); | ||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); | ||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); | ||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); | ||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); | ||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); | ||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); | ||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); | ||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); | ||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); | ||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); | ||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); | ||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); | ||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); | ||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); | ||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); | ||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); | ||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); | ||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); | ||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); | ||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); | ||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); | ||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); | ||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); | ||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); | ||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); | ||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); | ||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); | ||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); | ||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); | ||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); | ||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); | ||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); | ||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); | ||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); | ||
|
||
for (i = 0; i < 8; i++) | ||
ctx->state[i] += S[i]; | ||
} | ||
|
||
void blk_SHA256_Update(blk_SHA256_CTX *ctx, const void *data, size_t len) | ||
{ | ||
unsigned int len_buf = ctx->size & 63; | ||
|
||
ctx->size += len; | ||
|
||
/* Read the data into buf and process blocks as they get full */ | ||
if (len_buf) { | ||
unsigned int left = 64 - len_buf; | ||
if (len < left) | ||
left = len; | ||
memcpy(len_buf + ctx->buf, data, left); | ||
len_buf = (len_buf + left) & 63; | ||
len -= left; | ||
data = ((const char *)data + left); | ||
if (len_buf) | ||
return; | ||
blk_SHA256_Transform(ctx, ctx->buf); | ||
} | ||
while (len >= 64) { | ||
blk_SHA256_Transform(ctx, data); | ||
data = ((const char *)data + 64); | ||
len -= 64; | ||
} | ||
if (len) | ||
memcpy(ctx->buf, data, len); | ||
} | ||
|
||
void blk_SHA256_Final(unsigned char *digest, blk_SHA256_CTX *ctx) | ||
{ | ||
static const unsigned char pad[64] = { 0x80 }; | ||
unsigned int padlen[2]; | ||
int i; | ||
|
||
/* Pad with a binary 1 (ie 0x80), then zeroes, then length */ | ||
padlen[0] = htonl((uint32_t)(ctx->size >> 29)); | ||
padlen[1] = htonl((uint32_t)(ctx->size << 3)); | ||
|
||
i = ctx->size & 63; | ||
blk_SHA256_Update(ctx, pad, 1 + (63 & (55 - i))); | ||
blk_SHA256_Update(ctx, padlen, 8); | ||
|
||
/* copy output */ | ||
for (i = 0; i < 8; i++, digest += sizeof(uint32_t)) | ||
put_be32(digest, ctx->state[i]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#ifndef SHA256_BLOCK_SHA256_H | ||
#define SHA256_BLOCK_SHA256_H | ||
|
||
#define blk_SHA256_BLKSIZE 64 | ||
|
||
struct blk_SHA256_CTX { | ||
uint32_t state[8]; | ||
uint64_t size; | ||
uint32_t offset; | ||
uint8_t buf[blk_SHA256_BLKSIZE]; | ||
}; | ||
|
||
typedef struct blk_SHA256_CTX blk_SHA256_CTX; | ||
|
||
void blk_SHA256_Init(blk_SHA256_CTX *ctx); | ||
void blk_SHA256_Update(blk_SHA256_CTX *ctx, const void *data, size_t len); | ||
void blk_SHA256_Final(unsigned char *digest, blk_SHA256_CTX *ctx); | ||
|
||
#define platform_SHA256_CTX blk_SHA256_CTX | ||
#define platform_SHA256_Init blk_SHA256_Init | ||
#define platform_SHA256_Update blk_SHA256_Update | ||
#define platform_SHA256_Final blk_SHA256_Final | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include "test-tool.h" | ||
#include "cache.h" | ||
|
||
int cmd__sha256(int ac, const char **av) | ||
{ | ||
return cmd_hash_impl(ac, av, GIT_HASH_SHA256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.