src/LLC/hash/SK/skein.cpp
int Skein1024_Final(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
{
    size_t i,n,byteCnt;
    u64b_t X[SKEIN1024_STATE_WORDS];
    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */

    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */
    if(ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)            /* zero pad b[] if necessary */
        memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);

    Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */

    /* now output the result */
    byteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */

    /* run Threefish in "counter mode" to generate output */
    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */
    //memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */
    uint8_t *dst = (uint8_t *)X;
    uint8_t *src = (uint8_t *)ctx->X;
    std::copy(src, src + sizeof(X), dst);

    for(i=0; i*SKEIN1024_BLOCK_BYTES < byteCnt; ++i)
    {
        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */
        Skein_Start_New_Type(ctx,OUT_FINAL);
        Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */
        n = byteCnt - i*SKEIN1024_BLOCK_BYTES;   /* number of output bytes left to go */
        if(n >= SKEIN1024_BLOCK_BYTES)
            n  = SKEIN1024_BLOCK_BYTES;
        Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n);   /* "output" the ctr mode bytes */
        Skein_Show_Final(1024,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);
        //memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */
        dst = (uint8_t *)ctx->X;
        src = (uint8_t *)X;
        std::copy(src, src + sizeof(X), dst);
    }

    return SKEIN_SUCCESS;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* finalize the hash computation and output the result */
finalize the hash computation and output the result
finalize the hash computation and output the result
int Skein1024_Final(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)
{
    size_t i,n,byteCnt;
    u64b_t X[SKEIN1024_STATE_WORDS];
    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    
    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 
    if(ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)            
        memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);
    Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  
    byteCnt = (ctx->h.hashBitLen + 7) >> 3;             
    memset(ctx->b,0,sizeof(ctx->b));  
    uint8_t *dst = (uint8_t *)X;
    uint8_t *src = (uint8_t *)ctx->X;
    std::copy(src, src + sizeof(X), dst);
    for(i=0; i*SKEIN1024_BLOCK_BYTES < byteCnt; ++i)
    {
        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); 
        Skein_Start_New_Type(ctx,OUT_FINAL);
        Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); 
        n = byteCnt - i*SKEIN1024_BLOCK_BYTES;   
        if(n >= SKEIN1024_BLOCK_BYTES)
            n  = SKEIN1024_BLOCK_BYTES;
        Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n);   
        Skein_Show_Final(1024,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);
        dst = (uint8_t *)ctx->X;
        src = (uint8_t *)X;
        std::copy(src, src + sizeof(X), dst);
    }
    return SKEIN_SUCCESS;
}
int Skein1024_Final ( Skein1024_Ctxt_t * ctx , u08b_t * hashVal ) { size_t i , n , byteCnt ; u64b_t X [ SKEIN1024_STATE_WORDS ] ; Skein_Assert ( ctx -> h . bCnt <= SKEIN1024_BLOCK_BYTES , SKEIN_FAIL ) ; ctx -> h . T [ 1 ] |= SKEIN_T1_FLAG_FINAL ; if ( ctx -> h . bCnt < SKEIN1024_BLOCK_BYTES ) memset ( & ctx -> b [ ctx -> h . bCnt ] , 0 , SKEIN1024_BLOCK_BYTES - ctx -> h . bCnt ) ; Skein1024_Process_Block ( ctx , ctx -> b , 1 , ctx -> h . bCnt ) ; byteCnt = ( ctx -> h . hashBitLen + 7 ) >> 3 ; memset ( ctx -> b , 0 , sizeof ( ctx -> b ) ) ; uint8_t * dst = ( uint8_t * ) X ; uint8_t * src = ( uint8_t * ) ctx -> X ; std :: copy ( src , src + sizeof ( X ) , dst ) ; for ( i = 0 ; i * SKEIN1024_BLOCK_BYTES < byteCnt ; ++ i ) { ( ( u64b_t * ) ctx -> b ) [ 0 ] = Skein_Swap64 ( ( u64b_t ) i ) ; Skein_Start_New_Type ( ctx , OUT_FINAL ) ; Skein1024_Process_Block ( ctx , ctx -> b , 1 , sizeof ( u64b_t ) ) ; n = byteCnt - i * SKEIN1024_BLOCK_BYTES ; if ( n >= SKEIN1024_BLOCK_BYTES ) n = SKEIN1024_BLOCK_BYTES ; Skein_Put64_LSB_First ( hashVal + i * SKEIN1024_BLOCK_BYTES , ctx -> X , n ) ; Skein_Show_Final ( 1024 , & ctx -> h , n , hashVal + i * SKEIN1024_BLOCK_BYTES ) ; dst = ( uint8_t * ) ctx -> X ; src = ( uint8_t * ) X ; std :: copy ( src , src + sizeof ( X ) , dst ) ; } return SKEIN_SUCCESS ; }
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
finalize the hash computation and output the result
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ finalize the hash computation and output the result
/* catch uninitialized context */ /* tag as the final block */ /* zero pad b[] if necessary */ /* process the final block */ /* now output the result */ /* total number of output bytes */ /* run Threefish in "counter mode" to generate output */ /* zero out b[], so it can hold the counter */ //memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */ /* build the counter block */ /* run "counter mode" */ /* number of output bytes left to go */ /* "output" the ctr mode bytes */ //memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */