Welcome to little lamb

Code » limb » release » tree

[release] / src / liblimb / sha3.h / sha3_update.c

/* 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 */
}