nettle-0.2.1: src/nettle-hash.c
#include "nettle-hash.h"
#undef NDEBUG
#include <assert.h>
#if (NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR < 2)
void hs_nettle_sha3_224_digest(struct sha3_224_ctx *ctx, size_t length, uint8_t *digest) {
nettle_sha3_224_digest(ctx, length, digest);
}
void hs_nettle_sha3_256_digest(struct sha3_256_ctx *ctx, size_t length, uint8_t *digest) {
nettle_sha3_256_digest(ctx, length, digest);
}
void hs_nettle_sha3_384_digest(struct sha3_384_ctx *ctx, size_t length, uint8_t *digest) {
nettle_sha3_384_digest(ctx, length, digest);
}
void hs_nettle_sha3_512_digest(struct sha3_512_ctx *ctx, size_t length, uint8_t *digest) {
nettle_sha3_512_digest(ctx, length, digest);
}
#else
/* copy some internal functions from nettle */
#include <stddef.h>
#include <string.h>
#include <nettle/memxor.h>
#include <nettle/macros.h>
static void sha3_absorb(struct sha3_state *state, unsigned length, const uint8_t *data) {
assert((length & 7) == 0);
#if WORDS_BIGENDIAN
{
uint64_t *p;
for (p = state->a; length > 0; p++, length -= 8, data += 8)
*p ^= LE_READ_UINT64(data);
}
#else /* !WORDS_BIGENDIAN */
nettle_memxor(state->a, data, length);
#endif
nettle_sha3_permute(state);
}
static void _pre_finalized_sha3_pad(struct sha3_state *state, unsigned block_size, uint8_t *block, unsigned pos) {
assert(pos < block_size);
block[pos++] = 1; /* in nettle 3.2 this became `6` */
memset(block + pos, 0, block_size - pos);
block[block_size - 1] |= 0x80;
sha3_absorb(state, block_size, block);
}
static void _nettle_write_le64(size_t length, uint8_t *dst, uint64_t *src) {
size_t i;
size_t words;
unsigned leftover;
words = length / 8;
leftover = length % 8;
for (i = 0; i < words; i++, dst += 8)
LE_WRITE_UINT64(dst, src[i]);
if (leftover) {
uint64_t word;
word = src[i];
do
{
*dst++ = word & 0xff;
word >>= 8;
} while (--leftover);
}
}
void hs_nettle_sha3_224_digest(struct sha3_224_ctx *ctx, size_t length, uint8_t *digest) {
_pre_finalized_sha3_pad(&ctx->state, SHA3_224_BLOCK_SIZE, ctx->block, ctx->index);
_nettle_write_le64(length, digest, ctx->state.a);
sha3_224_init(ctx);
}
void hs_nettle_sha3_256_digest(struct sha3_256_ctx *ctx, size_t length, uint8_t *digest) {
_pre_finalized_sha3_pad(&ctx->state, SHA3_256_BLOCK_SIZE, ctx->block, ctx->index);
_nettle_write_le64(length, digest, ctx->state.a);
sha3_256_init(ctx);
}
void hs_nettle_sha3_384_digest(struct sha3_384_ctx *ctx, size_t length, uint8_t *digest) {
_pre_finalized_sha3_pad(&ctx->state, SHA3_384_BLOCK_SIZE, ctx->block, ctx->index);
_nettle_write_le64(length, digest, ctx->state.a);
sha3_384_init(ctx);
}
void hs_nettle_sha3_512_digest(struct sha3_512_ctx *ctx, size_t length, uint8_t *digest) {
_pre_finalized_sha3_pad(&ctx->state, SHA3_512_BLOCK_SIZE, ctx->block, ctx->index);
_nettle_write_le64(length, digest, ctx->state.a);
sha3_512_init(ctx);
}
#endif