sha3: code shrink

function                                             old     new   delta
sha3_hash                                            155     101     -54

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2013-01-20 00:38:09 +01:00
parent 9980707efc
commit 2cfcc9e9d7
2 changed files with 61 additions and 34 deletions

View File

@ -1641,7 +1641,7 @@ typedef struct sha3_ctx_t {
unsigned bytes_queued; unsigned bytes_queued;
} sha3_ctx_t; } sha3_ctx_t;
void md5_begin(md5_ctx_t *ctx) FAST_FUNC; void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
#define sha1_hash md5_hash #define sha1_hash md5_hash
@ -1654,7 +1654,7 @@ void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
void sha3_end(sha3_ctx_t *ctx, uint8_t *resbuf) FAST_FUNC; void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC;
extern uint32_t *global_crc32_table; extern uint32_t *global_crc32_table;
uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;

View File

@ -56,7 +56,7 @@ static void FAST_FUNC common64_hash(md5_ctx_t *ctx, const void *buffer, size_t l
len -= remaining; len -= remaining;
buffer = (const char *)buffer + remaining; buffer = (const char *)buffer + remaining;
bufpos += remaining; bufpos += remaining;
/* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
bufpos -= 64; bufpos -= 64;
if (bufpos != 0) if (bufpos != 0)
break; break;
@ -839,7 +839,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
len -= remaining; len -= remaining;
buffer = (const char *)buffer + remaining; buffer = (const char *)buffer + remaining;
bufpos += remaining; bufpos += remaining;
/* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */ /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
bufpos -= 128; bufpos -= 128;
if (bufpos != 0) if (bufpos != 0)
break; break;
@ -1079,63 +1079,90 @@ void FAST_FUNC sha3_begin(sha3_ctx_t *ctx)
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
} }
void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buf, size_t bytes) void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len)
{ {
const uint8_t *data = buf; #if SHA3_SMALL
unsigned bytes_queued = ctx->bytes_queued; const uint8_t *data = buffer;
unsigned bufpos = ctx->bytes_queued;
while (1) {
unsigned remaining = SHA3_IBLK_BYTES - bufpos;
if (remaining > len)
remaining = len;
len -= remaining;
/* XOR data into buffer */
while (remaining != 0) {
uint8_t *buf = (uint8_t*)ctx->state;
buf[bufpos] ^= *data++;
bufpos++;
remaining--;
}
/* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
bufpos -= SHA3_IBLK_BYTES;
if (bufpos != 0)
break;
/* Buffer is filled up, process it */
sha3_process_block72(ctx->state);
/*bufpos = 0; - already is */
}
ctx->bytes_queued = bufpos + SHA3_IBLK_BYTES;
#else
/* +50 bytes code size, but a bit faster because of long-sized XORs */
const uint8_t *data = buffer;
unsigned bufpos = ctx->bytes_queued;
/* If already data in queue, continue queuing first */ /* If already data in queue, continue queuing first */
while (bytes != 0 && bytes_queued != 0) { while (len != 0 && bufpos != 0) {
uint8_t *buffer = (uint8_t*)ctx->state; uint8_t *buf = (uint8_t*)ctx->state;
buffer[bytes_queued] ^= *data++; buf[bufpos] ^= *data++;
bytes--; len--;
bytes_queued++; bufpos++;
if (bytes_queued == SHA3_IBLK_BYTES) { if (bufpos == SHA3_IBLK_BYTES) {
sha3_process_block72(ctx->state); bufpos = 0;
bytes_queued = 0; goto do_block;
} }
} }
/* Absorb complete blocks */ /* Absorb complete blocks */
while (bytes >= SHA3_IBLK_BYTES) { while (len >= SHA3_IBLK_BYTES) {
/* XOR data onto beginning of state[]. /* XOR data onto beginning of state[].
* We try to be efficient - operate on word at a time, not byte. * We try to be efficient - operate one word at a time, not byte.
* Yet safe wrt unaligned access: can't just use "*(long*)data"... * Careful wrt unaligned access: can't just use "*(long*)data"!
*/ */
unsigned count = SHA3_IBLK_BYTES / sizeof(long); unsigned count = SHA3_IBLK_BYTES / sizeof(long);
long *buffer = (long*)ctx->state; long *buf = (long*)ctx->state;
do { do {
long v; long v;
move_from_unaligned_long(v, (long*)data); move_from_unaligned_long(v, (long*)data);
*buffer++ ^= v; *buf++ ^= v;
data += sizeof(long); data += sizeof(long);
} while (--count); } while (--count);
len -= SHA3_IBLK_BYTES;
do_block:
sha3_process_block72(ctx->state); sha3_process_block72(ctx->state);
bytes -= SHA3_IBLK_BYTES;
} }
/* Queue remaining data bytes */ /* Queue remaining data bytes */
while (bytes != 0) { while (len != 0) {
uint8_t *buffer = (uint8_t*)ctx->state; uint8_t *buf = (uint8_t*)ctx->state;
buffer[bytes_queued] ^= *data++; buf[bufpos] ^= *data++;
bytes_queued++; bufpos++;
bytes--; len--;
} }
ctx->bytes_queued = bytes_queued; ctx->bytes_queued = bufpos;
#endif
} }
void FAST_FUNC sha3_end(sha3_ctx_t *ctx, uint8_t *hashval) void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
{ {
/* Padding */ /* Padding */
uint8_t *buffer = (uint8_t*)ctx->state; uint8_t *buf = (uint8_t*)ctx->state;
buffer[ctx->bytes_queued] ^= 1; buf[ctx->bytes_queued] ^= 1;
buffer[SHA3_IBLK_BYTES - 1] ^= 0x80; buf[SHA3_IBLK_BYTES - 1] ^= 0x80;
sha3_process_block72(ctx->state); sha3_process_block72(ctx->state);
/* Output */ /* Output */
memcpy(hashval, ctx->state, 64); memcpy(resbuf, ctx->state, 64);
} }