/*
* Implementation of the Skein hash function.
* Source code author: Doug Whiting, 2008.
* This algorithm and source code is released to the public domain.
*/
/* Copyright 2013 Doug Whiting. This code is released to the public domain. */
#include "skein_impl.h" /* get internal definitions */
/* External function to process blkCnt (nonzero) full block(s) of data. */
/* 256-bit Skein */
/* init the context for a straight hashing operation */
int
{
union {
switch (hashBitLen) { /* use pre-computed values, where available */
#ifndef SKEIN_NO_PRECOMP
case 256:
break;
case 224:
break;
case 160:
break;
case 128:
break;
#endif
default:
/* here if there is no precomputed IV value available */
/*
* precomputed)
*/
/* set tweaks: T0=0; T1=CFG | FINAL */
/* set the schema, version */
/* hash result length in bits */
/* zero pad config block */
/* compute the initial chaining values from config block */
/* zero the chaining variables */
break;
}
/*
* The chaining vars ctx->X are now initialized for the given
* hashBitLen.
* Set up to process the data message portion of the hash (default)
*/
return (SKEIN_SUCCESS);
}
/*
* [identical to Skein_256_Init() when keyBytes == 0 &&
* treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL]
*/
int
{
union {
/* compute the initial chaining values ctx->X[], based on key */
if (keyBytes == 0) { /* is there a key? */
/* no key: use all zeroes as key for config block */
} else { /* here to pre-process a key */
/* do a mini-Init right here */
/* set output hash bit count = state size */
/* set tweaks: T0 = 0; T1 = KEY type */
/* zero the initial chaining variables */
/* hash the key */
/* put result into cfg.b[] */
/* copy over into ctx->X[] */
#if SKEIN_NEED_SWAP
{
uint_t i;
/* convert key bytes to context words */
for (i = 0; i < SKEIN_256_STATE_WORDS; i++)
}
#endif
}
/*
* precomputed for each key)
*/
/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
/* compute the initial chaining values from config block */
/* The chaining vars ctx->X are now initialized */
/* Set up to process the data message portion of the hash (default) */
return (SKEIN_SUCCESS);
}
/* process the input bytes */
int
{
size_t n;
/* catch uninitialized context */
/* process full blocks, if any */
/* finish up any buffered message data */
/* # bytes free in buffer b[] */
if (n) {
/* check on our logic here */
Skein_assert(n < msgByteCnt);
msgByteCnt -= n;
msg += n;
}
}
/*
* now process any remaining full blocks, directly from input
* message data
*/
if (msgByteCnt > SKEIN_256_BLOCK_BYTES) {
/* number of full blocks to process */
msgByteCnt -= n * SKEIN_256_BLOCK_BYTES;
msg += n * SKEIN_256_BLOCK_BYTES;
}
}
/* copy any remaining source message data bytes into b[] */
if (msgByteCnt) {
}
return (SKEIN_SUCCESS);
}
/* finalize the hash computation and output the result */
int
{
/* catch uninitialized context */
/* 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 */
/* keep a local copy of counter mode "key" */
for (i = 0; i * SKEIN_256_BLOCK_BYTES < byteCnt; i++) {
/* build the counter block */
/* run "counter mode" */
/* number of output bytes left to go */
n = byteCnt - i * SKEIN_256_BLOCK_BYTES;
if (n >= SKEIN_256_BLOCK_BYTES)
ctx->X, n); /* "output" the ctr mode bytes */
hashVal + i * SKEIN_256_BLOCK_BYTES);
/* restore the counter mode key for next time */
}
return (SKEIN_SUCCESS);
}
/* 512-bit Skein */
/* init the context for a straight hashing operation */
int
{
union {
switch (hashBitLen) { /* use pre-computed values, where available */
#ifndef SKEIN_NO_PRECOMP
case 512:
break;
case 384:
break;
case 256:
break;
case 224:
break;
#endif
default:
/*
* here if there is no precomputed IV value available
* precomputed)
*/
/* set tweaks: T0=0; T1=CFG | FINAL */
/* set the schema, version */
/* hash result length in bits */
/* zero pad config block */
/* compute the initial chaining values from config block */
/* zero the chaining variables */
break;
}
/*
* The chaining vars ctx->X are now initialized for the given
* hashBitLen. Set up to process the data message portion of the
* hash (default)
*/
return (SKEIN_SUCCESS);
}
/*
* [identical to Skein_512_Init() when keyBytes == 0 &&
* treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL]
*/
int
{
union {
/* compute the initial chaining values ctx->X[], based on key */
if (keyBytes == 0) { /* is there a key? */
/* no key: use all zeroes as key for config block */
} else { /* here to pre-process a key */
/* do a mini-Init right here */
/* set output hash bit count = state size */
/* set tweaks: T0 = 0; T1 = KEY type */
/* zero the initial chaining variables */
/* put result into cfg.b[] */
/* copy over into ctx->X[] */
#if SKEIN_NEED_SWAP
{
uint_t i;
/* convert key bytes to context words */
for (i = 0; i < SKEIN_512_STATE_WORDS; i++)
}
#endif
}
/*
* precomputed for each key)
*/
/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
/* compute the initial chaining values from config block */
/* The chaining vars ctx->X are now initialized */
/* Set up to process the data message portion of the hash (default) */
return (SKEIN_SUCCESS);
}
/* process the input bytes */
int
{
size_t n;
/* catch uninitialized context */
/* process full blocks, if any */
/* finish up any buffered message data */
/* # bytes free in buffer b[] */
if (n) {
/* check on our logic here */
Skein_assert(n < msgByteCnt);
msgByteCnt -= n;
msg += n;
}
}
/*
* now process any remaining full blocks, directly from input
* message data
*/
if (msgByteCnt > SKEIN_512_BLOCK_BYTES) {
/* number of full blocks to process */
msgByteCnt -= n * SKEIN_512_BLOCK_BYTES;
msg += n * SKEIN_512_BLOCK_BYTES;
}
}
/* copy any remaining source message data bytes into b[] */
if (msgByteCnt) {
}
return (SKEIN_SUCCESS);
}
/* finalize the hash computation and output the result */
int
{
/* catch uninitialized context */
/* 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 */
/* keep a local copy of counter mode "key" */
for (i = 0; i * SKEIN_512_BLOCK_BYTES < byteCnt; i++) {
/* build the counter block */
/* run "counter mode" */
/* number of output bytes left to go */
n = byteCnt - i * SKEIN_512_BLOCK_BYTES;
if (n >= SKEIN_512_BLOCK_BYTES)
ctx->X, n); /* "output" the ctr mode bytes */
hashVal + i * SKEIN_512_BLOCK_BYTES);
/* restore the counter mode key for next time */
}
return (SKEIN_SUCCESS);
}
/* 1024-bit Skein */
/* init the context for a straight hashing operation */
int
{
union {
switch (hashBitLen) { /* use pre-computed values, where available */
#ifndef SKEIN_NO_PRECOMP
case 512:
break;
case 384:
break;
case 1024:
break;
#endif
default:
/* here if there is no precomputed IV value available */
/*
* precomputed)
*/
/* set tweaks: T0=0; T1=CFG | FINAL */
/* set the schema, version */
/* hash result length in bits */
/* zero pad config block */
/* compute the initial chaining values from config block */
/* zero the chaining variables */
break;
}
/*
* The chaining vars ctx->X are now initialized for the given
* hashBitLen. Set up to process the data message portion of the hash
* (default)
*/
return (SKEIN_SUCCESS);
}
/*
* [identical to Skein1024_Init() when keyBytes == 0 &&
* treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL]
*/
int
{
union {
/* compute the initial chaining values ctx->X[], based on key */
if (keyBytes == 0) { /* is there a key? */
/* no key: use all zeroes as key for config block */
} else { /* here to pre-process a key */
/* do a mini-Init right here */
/* set output hash bit count = state size */
/* set tweaks: T0 = 0; T1 = KEY type */
/* zero the initial chaining variables */
/* put result into cfg.b[] */
/* copy over into ctx->X[] */
#if SKEIN_NEED_SWAP
{
uint_t i;
/* convert key bytes to context words */
for (i = 0; i < SKEIN1024_STATE_WORDS; i++)
}
#endif
}
/*
* precomputed for each key)
*/
/* hash result length in bits */
/* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
/* compute the initial chaining values from config block */
/* The chaining vars ctx->X are now initialized */
/* Set up to process the data message portion of the hash (default) */
return (SKEIN_SUCCESS);
}
/* process the input bytes */
int
{
size_t n;
/* catch uninitialized context */
/* process full blocks, if any */
/* finish up any buffered message data */
/* # bytes free in buffer b[] */
if (n) {
/* check on our logic here */
Skein_assert(n < msgByteCnt);
msgByteCnt -= n;
msg += n;
}
}
/*
* now process any remaining full blocks, directly from
* input message data
*/
if (msgByteCnt > SKEIN1024_BLOCK_BYTES) {
/* number of full blocks to process */
msgByteCnt -= n * SKEIN1024_BLOCK_BYTES;
msg += n * SKEIN1024_BLOCK_BYTES;
}
}
/* copy any remaining source message data bytes into b[] */
if (msgByteCnt) {
}
return (SKEIN_SUCCESS);
}
/* finalize the hash computation and output the result */
int
{
/* catch uninitialized context */
/* 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 */
/* keep a local copy of counter mode "key" */
for (i = 0; i * SKEIN1024_BLOCK_BYTES < byteCnt; i++) {
/* build the counter block */
/* run "counter mode" */
/* number of output bytes left to go */
n = byteCnt - i * SKEIN1024_BLOCK_BYTES;
if (n >= SKEIN1024_BLOCK_BYTES)
ctx->X, n); /* "output" the ctr mode bytes */
hashVal + i * SKEIN1024_BLOCK_BYTES);
/* restore the counter mode key for next time */
}
return (SKEIN_SUCCESS);
}
/* (this code is identical for Optimized and Reference versions) */
/* finalize the hash computation and output the block, no OUTPUT stage */
int
{
/* catch uninitialized context */
/* zero pad b[] if necessary */
/* process the final block */
/* "output" the state bytes */
return (SKEIN_SUCCESS);
}
/* finalize the hash computation and output the block, no OUTPUT stage */
int
{
/* catch uninitialized context */
/* zero pad b[] if necessary */
/* process the final block */
/* "output" the state bytes */
return (SKEIN_SUCCESS);
}
/* finalize the hash computation and output the block, no OUTPUT stage */
int
{
/* catch uninitialized context */
/* tag as the final block */
/* zero pad b[] if necessary */
/* process the final block */
/* "output" the state bytes */
return (SKEIN_SUCCESS);
}
#if SKEIN_TREE_HASH
/* just do the OUTPUT stage */
int
{
/* catch uninitialized context */
/* 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 */
/* keep a local copy of counter mode "key" */
for (i = 0; i * SKEIN_256_BLOCK_BYTES < byteCnt; i++) {
/* build the counter block */
/* run "counter mode" */
/* number of output bytes left to go */
n = byteCnt - i * SKEIN_256_BLOCK_BYTES;
if (n >= SKEIN_256_BLOCK_BYTES)
ctx->X, n); /* "output" the ctr mode bytes */
hashVal + i * SKEIN_256_BLOCK_BYTES);
/* restore the counter mode key for next time */
}
return (SKEIN_SUCCESS);
}
/* just do the OUTPUT stage */
int
{
/* catch uninitialized context */
/* 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 */
/* keep a local copy of counter mode "key" */
for (i = 0; i * SKEIN_512_BLOCK_BYTES < byteCnt; i++) {
/* build the counter block */
/* run "counter mode" */
/* number of output bytes left to go */
n = byteCnt - i * SKEIN_512_BLOCK_BYTES;
if (n >= SKEIN_512_BLOCK_BYTES)
ctx->X, n); /* "output" the ctr mode bytes */
hashVal + i * SKEIN_512_BLOCK_BYTES);
/* restore the counter mode key for next time */
}
return (SKEIN_SUCCESS);
}
/* just do the OUTPUT stage */
int
{
/* catch uninitialized context */
/* 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 */
/* keep a local copy of counter mode "key" */
for (i = 0; i * SKEIN1024_BLOCK_BYTES < byteCnt; i++) {
/* build the counter block */
/* run "counter mode" */
/* number of output bytes left to go */
n = byteCnt - i * SKEIN1024_BLOCK_BYTES;
if (n >= SKEIN1024_BLOCK_BYTES)
ctx->X, n); /* "output" the ctr mode bytes */
hashVal + i * SKEIN1024_BLOCK_BYTES);
/* restore the counter mode key for next time */
}
return (SKEIN_SUCCESS);
}
#endif