/* This file is part of limb https://lila.oss/limb
* Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */
/* Based on RHash: http://rhash.sourceforge.net/
* Based on The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
* by Guido Bertoni, Joan Daemen, Michaƫl Peeters and Gilles Van Assche
* Copyright (c) 2013 Aleksey Kravchenko */
/* SPDX-License-Identifier: 0BSD */
#include <assert.h>
#include <string.h>
#include "sha3/sha3.h"
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param msg message chunk
* @param mlen length of the message chunk
* @param ctx the algorithm context containing current hashing state
*/
void
sha3_update(const void *msg_, size_t mlen, void *ctx_)
{
sha3_ctx *ctx = ctx_;
const unsigned char *msg = msg_;
size_t index = (size_t) ctx->rest;
size_t block_size = (size_t) ctx->block_size;
if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */
ctx->rest = (unsigned) ((ctx->rest + mlen) % block_size);
/* fill partial block */
if (index) {
size_t left = block_size - index;
memcpy((char*) ctx->message + index, msg, (mlen < left ? mlen : left));
if (mlen < left) return;
/* process partial block */
rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
msg += left;
mlen -= left;
}
while (mlen >= block_size) {
u64 *aligned_message_block;
if (IS_ALIGNED_64(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
aligned_message_block = (u64 *) msg;
} else {
memcpy(ctx->message, msg, block_size);
aligned_message_block = ctx->message;
}
rhash_sha3_process_block(ctx->hash, aligned_message_block, block_size);
msg += block_size;
mlen -= block_size;
}
if (mlen)
memcpy(ctx->message, msg, mlen); /* save leftovers */
}