/** * Calculate message hash. * Can be called repeatedly with chunks of the message to be hashed. * * @param ctx the algorithm context containing current hashing state * @param msg message chunk * @param size length of the message chunk */ void Sha3Update(sha3_ctx *ctx, const unsigned char *msg, size_t size) { 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 + size) % block_size); /* fill partial block */ if (index) { size_t left = block_size - index; memcpy((char*)ctx->message + index, msg, (size < left ? size : left)); if (size < left) return; /* process partial block */ Sha3ProcessBlock(ctx->hash, ctx->message, block_size); msg += left; size -= left; } while (size >= block_size) { uint64_t* 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 = (uint64_t*)msg; } else { memcpy(ctx->message, msg, block_size); aligned_message_block = ctx->message; } Sha3ProcessBlock(ctx->hash, aligned_message_block, block_size); msg += block_size; size -= block_size; } if (size) { memcpy(ctx->message, msg, size); /* save leftovers */ } }
/** * Calculate message hash. * Can be called repeatedly with chunks of the message to be hashed. * * @param ctx the algorithm context containing current hashing state * @param msg message chunk * @param size length of the message chunk */ void whirlpool_update(whirlpool_ctx *ctx, const unsigned char* msg, size_t size) { unsigned index = (unsigned)ctx->length & 63; unsigned left; ctx->length += size; /* fill partial block */ if(index) { left = whirlpool_block_size - index; memcpy(ctx->message + index, msg, (size < left ? size : left)); if(size < left) return; /* process partial block */ whirlpool_process_block(ctx->hash, (uint64_t*)ctx->message); msg += left; size -= left; } while(size >= whirlpool_block_size) { uint64_t* 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 = (uint64_t*)msg; } else { memcpy(ctx->message, msg, whirlpool_block_size); aligned_message_block = (uint64_t*)ctx->message; } whirlpool_process_block(ctx->hash, aligned_message_block); msg += whirlpool_block_size; size -= whirlpool_block_size; } if(size) { /* save leftovers */ memcpy(ctx->message, msg, size); } }
/** * Calculate message hash. * Can be called repeatedly with chunks of the message to be hashed. * * @param ctx the algorithm context containing current hashing state * @param msg message chunk * @param size length of the message chunk */ void rhash_tiger_update(tiger_ctx *ctx, const unsigned char* msg, size_t size) { size_t index = (size_t)ctx->length & 63; ctx->length += size; /* fill partial block */ if(index) { size_t left = tiger_block_size - index; if(size < left) { memcpy(ctx->message + index, msg, size); return; } else { memcpy(ctx->message + index, msg, left); rhash_tiger_process_block(ctx->hash, (uint64_t*)ctx->message); msg += left; size -= left; } } while(size >= tiger_block_size) { if(IS_ALIGNED_64(msg)) { /* the most common case is processing of an already aligned message without copying it */ rhash_tiger_process_block(ctx->hash, (uint64_t*)msg); } else { memcpy(ctx->message, msg, tiger_block_size); rhash_tiger_process_block(ctx->hash, (uint64_t*)ctx->message); } msg += tiger_block_size; size -= tiger_block_size; } if(size) { /* save leftovers */ memcpy(ctx->message, msg, size); } }