sha: reduce sha256/512 context size. Make sha1/sha256 code more similar
function old new delta sha512_end 182 204 +22 sha256_end 137 147 +10 sha1_hash 113 108 -5 sha1_end 143 129 -14 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/2 up/down: 32/-19) Total: 13 bytes
This commit is contained in:
parent
4a43057268
commit
c8329c9568
@ -1322,7 +1322,7 @@ void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_F
|
|||||||
|
|
||||||
typedef struct sha1_ctx_t {
|
typedef struct sha1_ctx_t {
|
||||||
uint64_t total64;
|
uint64_t total64;
|
||||||
uint32_t wbuffer[16]; /* NB: always correctly aligned for uint64_t */
|
uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */
|
||||||
uint32_t hash[5];
|
uint32_t hash[5];
|
||||||
} sha1_ctx_t;
|
} sha1_ctx_t;
|
||||||
void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
|
void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
|
||||||
@ -1331,7 +1331,7 @@ void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC;
|
|||||||
typedef struct sha256_ctx_t {
|
typedef struct sha256_ctx_t {
|
||||||
uint64_t total64;
|
uint64_t total64;
|
||||||
uint32_t hash[8];
|
uint32_t hash[8];
|
||||||
char wbuffer[64*2]; /* NB: always correctly aligned for uint64_t */
|
uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */
|
||||||
} sha256_ctx_t;
|
} sha256_ctx_t;
|
||||||
void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
|
void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
|
||||||
void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC;
|
void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC;
|
||||||
@ -1339,7 +1339,7 @@ void sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC;
|
|||||||
typedef struct sha512_ctx_t {
|
typedef struct sha512_ctx_t {
|
||||||
uint64_t total64[2];
|
uint64_t total64[2];
|
||||||
uint64_t hash[8];
|
uint64_t hash[8];
|
||||||
char wbuffer[128*2]; /* NB: always correctly aligned for uint64_t */
|
uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */
|
||||||
} sha512_ctx_t;
|
} sha512_ctx_t;
|
||||||
void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
|
void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
|
||||||
void sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) FAST_FUNC;
|
void sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) FAST_FUNC;
|
||||||
|
141
libbb/sha1.c
141
libbb/sha1.c
@ -60,12 +60,13 @@ static void sha1_process_block64(sha1_ctx_t *ctx)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
uint32_t w[80], a, b, c, d, e, t;
|
uint32_t w[80], a, b, c, d, e, t;
|
||||||
|
uint32_t *words;
|
||||||
|
|
||||||
/* note that words are compiled from the buffer into 32-bit */
|
words = (uint32_t*) ctx->wbuffer;
|
||||||
/* words in big-endian order so an order reversal is needed */
|
for (i = 0; i < SHA1_BLOCK_SIZE / 4; ++i) {
|
||||||
/* here on little endian machines */
|
w[i] = ntohl(*words);
|
||||||
for (i = 0; i < SHA1_BLOCK_SIZE / 4; ++i)
|
words++;
|
||||||
w[i] = ntohl(ctx->wbuffer[i]);
|
}
|
||||||
|
|
||||||
for (/*i = SHA1_BLOCK_SIZE / 4*/; i < 80; ++i) {
|
for (/*i = SHA1_BLOCK_SIZE / 4*/; i < 80; ++i) {
|
||||||
t = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
|
t = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
|
||||||
@ -232,7 +233,7 @@ static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t
|
|||||||
/* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */
|
/* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */
|
||||||
for (t = 0; t < 16; ++t) {
|
for (t = 0; t < 16; ++t) {
|
||||||
W[t] = ntohl(*words);
|
W[t] = ntohl(*words);
|
||||||
++words;
|
words++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (/*t = 16*/; t < 64; ++t)
|
for (/*t = 16*/; t < 64; ++t)
|
||||||
@ -302,7 +303,7 @@ static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t
|
|||||||
/* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */
|
/* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */
|
||||||
for (t = 0; t < 16; ++t) {
|
for (t = 0; t < 16; ++t) {
|
||||||
W[t] = ntoh64(*words);
|
W[t] = ntoh64(*words);
|
||||||
++words;
|
words++;
|
||||||
}
|
}
|
||||||
for (/*t = 16*/; t < 80; ++t)
|
for (/*t = 16*/; t < 80; ++t)
|
||||||
W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
|
W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
|
||||||
@ -399,7 +400,7 @@ void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx)
|
|||||||
ctx->total64 += len;
|
ctx->total64 += len;
|
||||||
|
|
||||||
while (len >= add) { /* transfer whole blocks while possible */
|
while (len >= add) { /* transfer whole blocks while possible */
|
||||||
memcpy(((unsigned char *) ctx->wbuffer) + in_buf, buffer, add);
|
memcpy(ctx->wbuffer + in_buf, buffer, add);
|
||||||
buffer = (const char *)buffer + add;
|
buffer = (const char *)buffer + add;
|
||||||
len -= add;
|
len -= add;
|
||||||
add = SHA1_BLOCK_SIZE;
|
add = SHA1_BLOCK_SIZE;
|
||||||
@ -407,7 +408,7 @@ void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx)
|
|||||||
sha1_process_block64(ctx);
|
sha1_process_block64(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(((unsigned char *) ctx->wbuffer) + in_buf, buffer, len);
|
memcpy(ctx->wbuffer + in_buf, buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
|
void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
|
||||||
@ -424,19 +425,14 @@ void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
|
|||||||
if (in_buf != 0) {
|
if (in_buf != 0) {
|
||||||
unsigned add;
|
unsigned add;
|
||||||
|
|
||||||
/* NB: 1/2 of wbuffer is used only in sha256_end
|
add = sizeof(ctx->wbuffer) - in_buf;
|
||||||
* when length field is added and hashed.
|
|
||||||
* With buffer twice as small, it may happen that
|
|
||||||
* we have it almost full and can't add length field. */
|
|
||||||
|
|
||||||
add = sizeof(ctx->wbuffer)/2 - in_buf;
|
|
||||||
if (add > len)
|
if (add > len)
|
||||||
add = len;
|
add = len;
|
||||||
memcpy(&ctx->wbuffer[in_buf], buffer, add);
|
memcpy(ctx->wbuffer + in_buf, buffer, add);
|
||||||
in_buf += add;
|
in_buf += add;
|
||||||
|
|
||||||
/* If we still didn't collect full wbuffer, bail out */
|
/* If we still didn't collect full wbuffer, bail out */
|
||||||
if (in_buf < sizeof(ctx->wbuffer)/2)
|
if (in_buf < sizeof(ctx->wbuffer))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sha256_process_block64(ctx->wbuffer, 64, ctx);
|
sha256_process_block64(ctx->wbuffer, 64, ctx);
|
||||||
@ -460,9 +456,8 @@ void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Move remaining bytes into internal buffer. */
|
/* Move remaining bytes into internal buffer. */
|
||||||
if (len > 0) {
|
if (len > 0)
|
||||||
memcpy(ctx->wbuffer, buffer, len);
|
memcpy(ctx->wbuffer, buffer, len);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
|
void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
|
||||||
@ -479,13 +474,13 @@ void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
|
|||||||
if (in_buf != 0) {
|
if (in_buf != 0) {
|
||||||
unsigned add;
|
unsigned add;
|
||||||
|
|
||||||
add = sizeof(ctx->wbuffer)/2 - in_buf;
|
add = sizeof(ctx->wbuffer) - in_buf;
|
||||||
if (add > len)
|
if (add > len)
|
||||||
add = len;
|
add = len;
|
||||||
memcpy(&ctx->wbuffer[in_buf], buffer, add);
|
memcpy(ctx->wbuffer + in_buf, buffer, add);
|
||||||
in_buf += add;
|
in_buf += add;
|
||||||
|
|
||||||
if (in_buf < sizeof(ctx->wbuffer)/2)
|
if (in_buf < sizeof(ctx->wbuffer))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sha512_process_block128(ctx->wbuffer, 128, ctx);
|
sha512_process_block128(ctx->wbuffer, 128, ctx);
|
||||||
@ -507,9 +502,8 @@ void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > 0) {
|
if (len > 0)
|
||||||
memcpy(ctx->wbuffer, buffer, len);
|
memcpy(ctx->wbuffer, buffer, len);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -517,31 +511,29 @@ void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx)
|
|||||||
{
|
{
|
||||||
unsigned i, pad, in_buf;
|
unsigned i, pad, in_buf;
|
||||||
|
|
||||||
/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
|
|
||||||
in_buf = ctx->total64 & SHA1_MASK;
|
in_buf = ctx->total64 & SHA1_MASK;
|
||||||
((uint8_t *)ctx->wbuffer)[in_buf++] = 0x80;
|
/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
|
||||||
pad = SHA1_BLOCK_SIZE - in_buf;
|
ctx->wbuffer[in_buf++] = 0x80;
|
||||||
memset(((uint8_t *)ctx->wbuffer) + in_buf, 0, pad);
|
|
||||||
|
|
||||||
/* We need 1+8 or more empty positions, one for the padding byte
|
/* This loop iterates either once or twice, no more, no less */
|
||||||
* (above) and eight for the length count.
|
while (1) {
|
||||||
* If there is not enough space, empty the buffer. */
|
pad = SHA1_BLOCK_SIZE - in_buf;
|
||||||
if (pad < 8) {
|
memset(ctx->wbuffer + in_buf, 0, pad);
|
||||||
|
in_buf = 0;
|
||||||
|
/* Do we have enough space for the length count? */
|
||||||
|
if (pad >= 8) {
|
||||||
|
/* Store the 64-bit counter of bits in the buffer in BE format */
|
||||||
|
uint64_t t = ctx->total64 << 3;
|
||||||
|
t = hton64(t);
|
||||||
|
/* wbuffer is suitably aligned for this */
|
||||||
|
*(uint64_t *) (&ctx->wbuffer[SHA1_BLOCK_SIZE - 8]) = t;
|
||||||
|
}
|
||||||
sha1_process_block64(ctx);
|
sha1_process_block64(ctx);
|
||||||
memset(ctx->wbuffer, 0, SHA1_BLOCK_SIZE - 8);
|
if (pad >= 8)
|
||||||
((uint8_t *)ctx->wbuffer)[0] = 0x80;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the 64-bit counter of bits in the buffer in BE format */
|
/* This way we do not impose alignment constraints on resbuf: */
|
||||||
{
|
|
||||||
uint64_t t = ctx->total64 << 3;
|
|
||||||
t = hton64(t);
|
|
||||||
/* wbuffer is suitably aligned for this */
|
|
||||||
*(uint64_t *) &ctx->wbuffer[14] = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
sha1_process_block64(ctx);
|
|
||||||
|
|
||||||
#if BB_LITTLE_ENDIAN
|
#if BB_LITTLE_ENDIAN
|
||||||
for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
|
for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
|
||||||
ctx->hash[i] = htonl(ctx->hash[i]);
|
ctx->hash[i] = htonl(ctx->hash[i]);
|
||||||
@ -553,24 +545,26 @@ void FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx)
|
|||||||
{
|
{
|
||||||
unsigned i, pad, in_buf;
|
unsigned i, pad, in_buf;
|
||||||
|
|
||||||
/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0...
|
|
||||||
(FIPS 180-2:5.1.1) */
|
|
||||||
in_buf = ctx->total64 & 63;
|
in_buf = ctx->total64 & 63;
|
||||||
pad = (in_buf >= 56 ? 64 + 56 - in_buf : 56 - in_buf);
|
/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0...
|
||||||
memset(&ctx->wbuffer[in_buf], 0, pad);
|
* (FIPS 180-2:5.1.1)
|
||||||
ctx->wbuffer[in_buf] = 0x80;
|
*/
|
||||||
|
ctx->wbuffer[in_buf++] = 0x80;
|
||||||
|
|
||||||
/* Put the 64-bit file length in *bits* at the end of the buffer. */
|
while (1) {
|
||||||
{
|
pad = 64 - in_buf;
|
||||||
uint64_t t = ctx->total64 << 3;
|
memset(ctx->wbuffer + in_buf, 0, pad);
|
||||||
t = hton64(t);
|
in_buf = 0;
|
||||||
/* wbuffer is suitably aligned for this */
|
if (pad >= 8) {
|
||||||
*(uint64_t *) &ctx->wbuffer[in_buf + pad] = t;
|
uint64_t t = ctx->total64 << 3;
|
||||||
|
t = hton64(t);
|
||||||
|
*(uint64_t *) (&ctx->wbuffer[64 - 8]) = t;
|
||||||
|
}
|
||||||
|
sha256_process_block64(ctx->wbuffer, 64, ctx);
|
||||||
|
if (pad >= 8)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process last bytes. */
|
|
||||||
sha256_process_block64(ctx->wbuffer, in_buf + pad + 8, ctx);
|
|
||||||
|
|
||||||
#if BB_LITTLE_ENDIAN
|
#if BB_LITTLE_ENDIAN
|
||||||
for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
|
for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
|
||||||
ctx->hash[i] = htonl(ctx->hash[i]);
|
ctx->hash[i] = htonl(ctx->hash[i]);
|
||||||
@ -582,17 +576,30 @@ void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx)
|
|||||||
{
|
{
|
||||||
unsigned i, pad, in_buf;
|
unsigned i, pad, in_buf;
|
||||||
|
|
||||||
/* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0...
|
|
||||||
(FIPS 180-2:5.1.2) */
|
|
||||||
in_buf = ctx->total64[0] & 127;
|
in_buf = ctx->total64[0] & 127;
|
||||||
pad = in_buf >= 112 ? 128 + 112 - in_buf : 112 - in_buf;
|
/* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0...
|
||||||
memset(&ctx->wbuffer[in_buf], 0, pad);
|
* (FIPS 180-2:5.1.2)
|
||||||
ctx->wbuffer[in_buf] = 0x80;
|
*/
|
||||||
|
ctx->wbuffer[in_buf++] = 0x80;
|
||||||
|
|
||||||
*(uint64_t *) &ctx->wbuffer[in_buf + pad + 8] = hton64(ctx->total64[0] << 3);
|
while (1) {
|
||||||
*(uint64_t *) &ctx->wbuffer[in_buf + pad] = hton64((ctx->total64[1] << 3) | (ctx->total64[0] >> 61));
|
pad = 128 - in_buf;
|
||||||
|
memset(ctx->wbuffer + in_buf, 0, pad);
|
||||||
sha512_process_block128(ctx->wbuffer, in_buf + pad + 16, ctx);
|
in_buf = 0;
|
||||||
|
if (pad >= 16) {
|
||||||
|
/* Store the 128-bit counter of bits in the buffer in BE format */
|
||||||
|
uint64_t t;
|
||||||
|
t = ctx->total64[0] << 3;
|
||||||
|
t = hton64(t);
|
||||||
|
*(uint64_t *) (&ctx->wbuffer[128 - 8]) = t;
|
||||||
|
t = (ctx->total64[1] << 3) | (ctx->total64[0] >> 61);
|
||||||
|
t = hton64(t);
|
||||||
|
*(uint64_t *) (&ctx->wbuffer[128 - 16]) = t;
|
||||||
|
}
|
||||||
|
sha512_process_block128(ctx->wbuffer, 128, ctx);
|
||||||
|
if (pad >= 16)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#if BB_LITTLE_ENDIAN
|
#if BB_LITTLE_ENDIAN
|
||||||
for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
|
for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user