aboutsummaryrefslogtreecommitdiffstats
path: root/digest.c
diff options
context:
space:
mode:
Diffstat (limited to 'digest.c')
-rw-r--r--digest.c67
1 files changed, 39 insertions, 28 deletions
diff --git a/digest.c b/digest.c
index bcd318f..c15e2fa 100644
--- a/digest.c
+++ b/digest.c
@@ -13,8 +13,7 @@
void
libsha2_digest(struct libsha2_state *restrict state, const char *restrict message, size_t msglen, char *output)
{
- char *appendix;
- size_t i, j, k, n;
+ size_t off, i, n;
if (msglen & ~(size_t)7) {
libsha2_update(state, message, msglen & ~(size_t)7);
@@ -22,40 +21,52 @@ libsha2_digest(struct libsha2_state *restrict state, const char *restrict messag
msglen &= (size_t)7;
}
- k = 8 * state->chunk_size;
- n = state->chunk_size + 8;
- n = (k + (n % k)) % k;
- n = n / 8 - 1;
-
- appendix = state->appendix;
+ off = (state->message_size / 8) % state->chunk_size;
if (msglen) {
- j = 7 - msglen;
- *appendix = *message;
- *appendix |= (char)(1 << j);
- *appendix &= (char)~((1 << j) - 1);
+ state->chunk[off] = *message;
+ state->chunk[off] |= (char)(1 << (7 - msglen));
+ state->chunk[off] &= (char)~((1 << (7 - msglen)) - 1);
+ state->message_size += msglen;
} else {
- *appendix = (char)128;
+ state->chunk[off] = 0x80;
}
+ off += 1;
- k = state->message_size + msglen;
- i = state->chunk_size / 8;
- appendix += n + i - 1;
- for (i = i < sizeof(size_t) ? i : sizeof(size_t); i--;)
- *(appendix - i) = (char)((k >> (i * 8)) & 255);
+ if (off > state->chunk_size - 8 * (1 + (state->algorithm > LIBSHA2_256))) {
+ memset(state->chunk + off, 0, state->chunk_size - off);
+ off = 0;
+ libsha2_process(state, state->chunk);
+ }
- n += state->chunk_size;
- libsha2_update(state, state->appendix, n);
+ memset(state->chunk + off, 0, state->chunk_size - 8 - off);
+ state->chunk[state->chunk_size - 8] = (char)(state->message_size >> 56);
+ state->chunk[state->chunk_size - 7] = (char)(state->message_size >> 48);
+ state->chunk[state->chunk_size - 6] = (char)(state->message_size >> 40);
+ state->chunk[state->chunk_size - 5] = (char)(state->message_size >> 32);
+ state->chunk[state->chunk_size - 4] = (char)(state->message_size >> 24);
+ state->chunk[state->chunk_size - 3] = (char)(state->message_size >> 16);
+ state->chunk[state->chunk_size - 2] = (char)(state->message_size >> 8);
+ state->chunk[state->chunk_size - 1] = (char)(state->message_size >> 0);
+ libsha2_process(state, state->chunk);
n = libsha2_algorithm_output_size(state->algorithm);
if (state->algorithm <= LIBSHA2_256) {
- for (i = 0; i < 8; i++)
- for (j = 0; j < (state->chunk_size / 16); j++)
- if (k = (i + 1) * (state->chunk_size / 16) - j - 1, k < n)
- output[k] = (char)((state->h.b32[i] >> (8 * j)) & 255);
+ for (i = 0, n /= 4; i < n; i++) {
+ output[4 * i + 0] = (char)(state->h.b32[i] >> 24);
+ output[4 * i + 1] = (char)(state->h.b32[i] >> 16);
+ output[4 * i + 2] = (char)(state->h.b32[i] >> 8);
+ output[4 * i + 3] = (char)(state->h.b32[i] >> 0);
+ }
} else {
- for (i = 0; i < 8; i++)
- for (j = 0; j < (state->chunk_size / 16); j++)
- if (k = (i + 1) * (state->chunk_size / 16) - j - 1, k < n)
- output[k] = (char)((state->h.b64[i] >> (8 * j)) & 255);
+ for (i = 0, n = (n + 7) / 8; i < n; i++) {
+ output[8 * i + 0] = (char)(state->h.b64[i] >> 56);
+ output[8 * i + 1] = (char)(state->h.b64[i] >> 48);
+ output[8 * i + 2] = (char)(state->h.b64[i] >> 40);
+ output[8 * i + 3] = (char)(state->h.b64[i] >> 32);
+ output[8 * i + 4] = (char)(state->h.b64[i] >> 24);
+ output[8 * i + 5] = (char)(state->h.b64[i] >> 16);
+ output[8 * i + 6] = (char)(state->h.b64[i] >> 8);
+ output[8 * i + 7] = (char)(state->h.b64[i] >> 0);
+ }
}
}