HashReturn_gr update_and_final_groestl( hashState_groestl* ctx, void* output, const void* input, DataLength_gr databitlen ) { const int len = (int)databitlen / 128; const int hashlen_m128i = ctx->hashlen / 16; // bytes to __m128i const int hash_offset = SIZE512 - hashlen_m128i; int rem = ctx->rem_ptr; int blocks = len / SIZE512; __m128i* in = (__m128i*)input; int i; // --- update --- // digest any full blocks, process directly from input for ( i = 0; i < blocks; i++ ) TF1024( ctx->chaining, &in[ i * SIZE512 ] ); ctx->buf_ptr = blocks * SIZE512; // copy any remaining data to buffer, it may already contain data // from a previous update for a midstate precalc for ( i = 0; i < len % SIZE512; i++ ) ctx->buffer[ rem + i ] = in[ ctx->buf_ptr + i ]; i += rem; // use i as rem_ptr in final //--- final --- blocks++; // adjust for final block if ( i == len -1 ) { // only 128 bits left in buffer, all padding at once ctx->buffer[i] = _mm_set_epi8( blocks,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0x80 ); } else { // add first padding ctx->buffer[i] = _mm_set_epi8( 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0x80 ); // add zero padding for ( i += 1; i < SIZE512 - 1; i++ ) ctx->buffer[i] = _mm_setzero_si128(); // add length padding, second last byte is zero unless blocks > 255 ctx->buffer[i] = _mm_set_epi8( blocks, blocks>>8, 0,0, 0,0,0,0, 0, 0 ,0,0, 0,0,0,0 ); } // digest final padding block and do output transform TF1024( ctx->chaining, ctx->buffer ); OF1024( ctx->chaining ); // store hash result in output for ( i = 0; i < hashlen_m128i; i++ ) casti_m128i( output, i ) = ctx->chaining[ hash_offset + i ]; return SUCCESS_GR; }
// use only for midstate precalc HashReturn_gr update_groestl( hashState_groestl* ctx, const void* input, DataLength_gr databitlen ) { __m128i* in = (__m128i*)input; const int len = (int)databitlen / 128; // bits to __m128i const int blocks = len / SIZE512; // __M128i to blocks int rem = ctx->rem_ptr; int i; ctx->blk_count = blocks; ctx->databitlen = databitlen; // digest any full blocks for ( i = 0; i < blocks; i++ ) TF1024( ctx->chaining, &in[ i * SIZE512 ] ); // adjust buf_ptr to last block ctx->buf_ptr = blocks * SIZE512; // copy any remaining data to buffer for final hash, it may already // contain data from a previous update for a midstate precalc for ( i = 0; i < len % SIZE512; i++ ) ctx->buffer[ rem + i ] = in[ ctx->buf_ptr + i ]; // adjust rem_ptr for possible new data ctx->rem_ptr += i; return SUCCESS_GR; }
/* digest up to len bytes of input (full blocks only) */ void Transform(hashState *ctx, const u8 *in, unsigned long long len) { /* increment block counter */ ctx->block_counter += len/SIZE; /* digest message, one block at a time */ for (; len >= SIZE; len -= SIZE, in += SIZE) #if LENGTH<=256 TF512((u64*)ctx->chaining, (u64*)in); #else TF1024((u64*)ctx->chaining, (u64*)in); #endif asm volatile ("emms"); }
// deprecated do not use HashReturn_gr final_groestl( hashState_groestl* ctx, void* output ) { const int len = (int)ctx->databitlen / 128; // bits to __m128i const int blocks = ctx->blk_count + 1; // adjust for final block const int rem_ptr = ctx->rem_ptr; // end of data start of padding const int hashlen_m128i = ctx->hashlen / 16; // bytes to __m128i const int hash_offset = SIZE512 - hashlen_m128i; // where in buffer int i; // first pad byte = 0x80, last pad byte = block count // everything in between is zero if ( rem_ptr == len - 1 ) { // only 128 bits left in buffer, all padding at once ctx->buffer[rem_ptr] = _mm_set_epi8( blocks,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0x80 ); } else { // add first padding ctx->buffer[rem_ptr] = _mm_set_epi8( 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0x80 ); // add zero padding for ( i = rem_ptr + 1; i < SIZE512 - 1; i++ ) ctx->buffer[i] = _mm_setzero_si128(); // add length padding, second last byte is zero unless blocks > 255 ctx->buffer[i] = _mm_set_epi8( blocks, blocks>>8, 0,0, 0,0,0,0, 0, 0 ,0,0, 0,0,0,0 ); } // digest final padding block and do output transform TF1024( ctx->chaining, ctx->buffer ); OF1024( ctx->chaining ); // store hash result in output for ( i = 0; i < hashlen_m128i; i++ ) casti_m128i( output, i ) = ctx->chaining[ hash_offset + i]; return SUCCESS_GR; }