/* finalize the hash computation and output the result */ void skein512::finalize( hash &hashVal ) { size_t n,byteCnt; uint64_t Y[8]; _T[1] |= SKEIN_T1_FLAG_FINAL; /* tag as the final block */ if ( _block_size < 64 ) /* zero pad b[] if necessary */ memset( &_block[_block_size], 0, 64 - _block_size ); process( _block, 1, _block_size ); /* process the final block */ /* now output the result */ byteCnt = (512 + 7) >> 3; /* total number of output bytes */ /* run Threefish in "counter mode" to generate output */ memset( _block, 0, sizeof(_block) ); /* zero out b[], so it can hold the counter */ memcpy( Y, _X, sizeof(_X) ); /* keep a local copy of counter mode "key" */ for ( size_t i = 0; i * 64 < byteCnt; i++ ) { _block64[0] = Skein_Swap64( uint64_t(i) ); /* build the counter block */ start_new_type( SKEIN_T1_BLK_TYPE_OUT_FINAL ); process( _block, 1, sizeof(uint64_t) ); /* run "counter mode" */ n = byteCnt - i*64; /* number of output bytes left to go */ if (n >= 64) n = 64; Skein_Put64_LSB_First(hashVal.data()+i*64,_X,n); /* "output" the ctr mode bytes */ memcpy(_X,Y,sizeof(_X)); /* restore the counter mode key for next time */ } }