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