Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • car/libdap-crypto
1 result
Show changes
Showing
with 1258 additions and 0 deletions
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <string.h>
#include "KeccakHash.h"
/* ---------------------------------------------------------------- */
HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix)
{
HashReturn result;
if (delimitedSuffix == 0)
return FAIL;
result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity);
if (result != SUCCESS)
return result;
instance->fixedOutputLength = hashbitlen;
instance->delimitedSuffix = delimitedSuffix;
return SUCCESS;
}
/* ---------------------------------------------------------------- */
HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, BitLength databitlen)
{
if ((databitlen % 8) == 0)
return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8);
else {
HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8);
if (ret == SUCCESS) {
/* The last partial byte is assumed to be aligned on the least significant bits */
unsigned char lastByte = data[databitlen/8];
/* Concatenate the last few bits provided here with those of the suffix */
unsigned short delimitedLastBytes = (unsigned short)((unsigned short)(lastByte & ((1 << (databitlen % 8)) - 1)) | ((unsigned short)instance->delimitedSuffix << (databitlen % 8)));
if ((delimitedLastBytes & 0xFF00) == 0x0000) {
instance->delimitedSuffix = delimitedLastBytes & 0xFF;
}
else {
unsigned char oneByte[1];
oneByte[0] = delimitedLastBytes & 0xFF;
ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1);
instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF;
}
}
return ret;
}
}
/* ---------------------------------------------------------------- */
HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval)
{
HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix);
if (ret == SUCCESS)
return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8);
else
return ret;
}
/* ---------------------------------------------------------------- */
HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, BitLength databitlen)
{
if ((databitlen % 8) != 0)
return FAIL;
return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8);
}
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakHashInterface_h_
#define _KeccakHashInterface_h_
#ifndef KeccakP1600_excluded
#include "KeccakSpongeWidth1600.h"
#include <string.h>
#ifndef _Keccak_BitTypes_
#define _Keccak_BitTypes_
typedef unsigned char BitSequence;
typedef size_t BitLength;
#endif
typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn;
typedef struct {
KeccakWidth1600_SpongeInstance sponge;
unsigned int fixedOutputLength;
unsigned char delimitedSuffix;
} Keccak_HashInstance;
/**
* Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode.
* @param hashInstance Pointer to the hash instance to be initialized.
* @param rate The value of the rate r.
* @param capacity The value of the capacity c.
* @param hashbitlen The desired number of output bits,
* or 0 for an arbitrarily-long output.
* @param delimitedSuffix Bits that will be automatically appended to the end
* of the input message, as in domain separation.
* This is a byte containing from 0 to 7 bits
* formatted like the @a delimitedData parameter of
* the Keccak_SpongeAbsorbLastFewBits() function.
* @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation.
* @return SUCCESS if successful, FAIL otherwise.
*/
HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix);
/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard.
*/
#define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F)
/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard.
*/
#define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F)
/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard.
*/
#define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06)
/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard.
*/
#define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06)
/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard.
*/
#define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06)
/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard.
*/
#define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06)
/**
* Function to give input data to be absorbed.
* @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize().
* @param data Pointer to the input data.
* When @a databitLen is not a multiple of 8, the last bits of data must be
* in the least significant bits of the last byte (little-endian convention).
* In this case, the (8 - @a databitLen mod 8) most significant bits
* of the last byte are ignored.
* @param databitLen The number of input bits provided in the input data.
* @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8.
* @return SUCCESS if successful, FAIL otherwise.
*/
HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, BitLength databitlen);
/**
* Function to call after all input blocks have been input and to get
* output bits if the length was specified when calling Keccak_HashInitialize().
* @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize().
* If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of
* output bits is equal to @a hashbitlen.
* If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits
* must be extracted using the Keccak_HashSqueeze() function.
* @param hashval Pointer to the buffer where to store the output data.
* @return SUCCESS if successful, FAIL otherwise.
*/
HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval);
/**
* Function to squeeze output data.
* @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize().
* @param data Pointer to the buffer where to store the output data.
* @param databitlen The number of output bits desired (must be a multiple of 8).
* @pre Keccak_HashFinal() must have been already called.
* @pre @a databitlen is a multiple of 8.
* @return SUCCESS if successful, FAIL otherwise.
*/
HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, BitLength databitlen);
#endif
#endif
/*
Implementation by Gilles Van Assche, hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "SimpleFIPS202.h"
int SHAKE128(unsigned char *output, size_t outputByteLen, const unsigned char *input, size_t inputByteLen)
{
return KeccakWidth1600_Sponge(1344, 256, input, inputByteLen, 0x1F, output, outputByteLen);
}
int SHAKE256(unsigned char *output, size_t outputByteLen, const unsigned char *input, size_t inputByteLen)
{
return KeccakWidth1600_Sponge(1088, 512, input, inputByteLen, 0x1F, output, outputByteLen);
}
int SHA3_224(unsigned char *output, const unsigned char *input, size_t inputByteLen)
{
return KeccakWidth1600_Sponge(1152, 448, input, inputByteLen, 0x06, output, 224/8);
}
int SHA3_256(unsigned char *output, const unsigned char *input, size_t inputByteLen)
{
return KeccakWidth1600_Sponge(1088, 512, input, inputByteLen, 0x06, output, 256/8);
}
int SHA3_384(unsigned char *output, const unsigned char *input, size_t inputByteLen)
{
return KeccakWidth1600_Sponge( 832, 768, input, inputByteLen, 0x06, output, 384/8);
}
int SHA3_512(unsigned char *output, const unsigned char *input, size_t inputByteLen)
{
return KeccakWidth1600_Sponge(576, 1024, input, inputByteLen, 0x06, output, 512/8);
}
/*
Implementation by Gilles Van Assche, hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _SimpleFIPS202_h_
#define _SimpleFIPS202_h_
#include "KeccakSpongeWidth1600.h"
#include <string.h>
/** Implementation of the SHAKE128 extendable output function (XOF) [FIPS 202].
* @param output Pointer to the output buffer.
* @param outputByteLen The desired number of output bytes.
* @param input Pointer to the input message.
* @param inputByteLen The length of the input message in bytes.
* @return 0 if successful, 1 otherwise.
*/
/** Implementation of the SHAKE256 extendable output function (XOF) [FIPS 202].
* @param output Pointer to the output buffer.
* @param outputByteLen The desired number of output bytes.
* @param input Pointer to the input message.
* @param inputByteLen The length of the input message in bytes.
* @return 0 if successful, 1 otherwise.
*/
/** Implementation of SHA3-224 [FIPS 202].
* @param output Pointer to the output buffer (28 bytes).
* @param input Pointer to the input message.
* @param inputByteLen The length of the input message in bytes.
* @return 0 if successful, 1 otherwise.
*/
/** Implementation of SHA3-256 [FIPS 202].
* @param output Pointer to the output buffer (32 bytes).
* @param input Pointer to the input message.
* @param inputByteLen The length of the input message in bytes.
* @return 0 if successful, 1 otherwise.
*/
/** Implementation of SHA3-384 [FIPS 202].
* @param output Pointer to the output buffer (48 bytes).
* @param input Pointer to the input message.
* @param inputByteLen The length of the input message in bytes.
* @return 0 if successful, 1 otherwise.
*/
/** Implementation of SHA3-512 [FIPS 202].
* @param output Pointer to the output buffer (64 bytes).
* @param input Pointer to the input message.
* @param inputByteLen The length of the input message in bytes.
* @return 0 if successful, 1 otherwise.
*/
int SHAKE128(unsigned char *output, size_t outputByteLen, const unsigned char *input, size_t inputByteLen);
int SHAKE256(unsigned char *output, size_t outputByteLen, const unsigned char *input, size_t inputByteLen);
int SHA3_224(unsigned char *output, const unsigned char *input, size_t inputByteLen);
int SHA3_256(unsigned char *output, const unsigned char *input, size_t inputByteLen);
int SHA3_384(unsigned char *output, const unsigned char *input, size_t inputByteLen);
int SHA3_512(unsigned char *output, const unsigned char *input, size_t inputByteLen);
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakDuplexCommon_h_
#define _KeccakDuplexCommon_h_
#include "align.h"
#define KCP_DeclareDuplexStructure(prefix, size, alignment) \
ALIGN(alignment) typedef struct prefix##_DuplexInstanceStruct { \
unsigned char state[size]; \
unsigned int rate; \
unsigned int byteInputIndex; \
unsigned int byteOutputIndex; \
} prefix##_DuplexInstance;
#define KCP_DeclareDuplexFunctions(prefix) \
int prefix##_DuplexInitialize(prefix##_DuplexInstance *duplexInstance, unsigned int rate, unsigned int capacity); \
int prefix##_Duplexing(prefix##_DuplexInstance *duplexInstance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd); \
int prefix##_DuplexingFeedPartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \
int prefix##_DuplexingFeedZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \
int prefix##_DuplexingOverwritePartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \
int prefix##_DuplexingOverwriteWithZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \
int prefix##_DuplexingGetFurtherOutput(prefix##_DuplexInstance *duplexInstance, unsigned char *out, unsigned int outByteLen); \
int prefix##_DuplexingGetFurtherOutputAndAdd(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen);
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakDuplex_h_
#define _KeccakDuplex_h_
/* For the documentation, please follow the link: */
/* #include "KeccakDuplex-documentation.h" */
#include "KeccakDuplexWidth200.h"
#include "KeccakDuplexWidth400.h"
#include "KeccakDuplexWidth800.h"
#include "KeccakDuplexWidth1600.h"
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#define JOIN0(a, b) a ## b
#define JOIN(a, b) JOIN0(a, b)
#define DuplexInstance JOIN(prefix, _DuplexInstance)
#define DuplexInitialize JOIN(prefix, _DuplexInitialize)
#define Duplexing JOIN(prefix, _Duplexing)
#define DuplexingFeedPartialInput JOIN(prefix, _DuplexingFeedPartialInput)
#define DuplexingFeedZeroes JOIN(prefix, _DuplexingFeedZeroes)
#define DuplexingOverwritePartialInput JOIN(prefix, _DuplexingOverwritePartialInput)
#define DuplexingOverwriteWithZeroes JOIN(prefix, _DuplexingOverwriteWithZeroes)
#define DuplexingGetFurtherOutput JOIN(prefix, _DuplexingGetFurtherOutput)
#define DuplexingGetFurtherOutputAndAdd JOIN(prefix, _DuplexingGetFurtherOutputAndAdd)
#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes)
#define SnP_stateAlignment JOIN(SnP, _stateAlignment)
#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize)
#define SnP_Initialize JOIN(SnP, _Initialize)
#define SnP_AddByte JOIN(SnP, _AddByte)
#define SnP_AddBytes JOIN(SnP, _AddBytes)
#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes)
#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes)
#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes)
#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes)
int DuplexInitialize(DuplexInstance *instance, unsigned int rate, unsigned int capacity)
{
if (rate+capacity != SnP_width)
return 1;
if ((rate <= 2) || (rate > SnP_width))
return 1;
SnP_StaticInitialize();
instance->rate = rate;
SnP_Initialize(instance->state);
instance->byteInputIndex = 0;
instance->byteOutputIndex = (instance->rate+7)/8;
return 0;
}
int Duplexing(DuplexInstance *instance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd)
{
const unsigned int rho_max = instance->rate - 2;
if (delimitedSigmaEnd == 0)
return 1;
if ((instance->byteInputIndex+sigmaBeginByteLen)*8 > rho_max)
return 1;
if (rho_max - sigmaBeginByteLen*8 < 7) {
unsigned int maxBitsInDelimitedSigmaEnd = rho_max - sigmaBeginByteLen*8;
if (delimitedSigmaEnd >= (1 << (maxBitsInDelimitedSigmaEnd+1)))
return 1;
}
if (ZByteLen > (instance->rate+7)/8)
return 1; /* The output length must not be greater than the rate (rounded up to a byte) */
SnP_AddBytes(instance->state, sigmaBegin, instance->byteInputIndex, sigmaBeginByteLen);
#ifdef KeccakReference
{
unsigned char block[SnP_width/8];
memcpy(block, sigmaBegin, sigmaBeginByteLen);
block[sigmaBeginByteLen] = delimitedSigmaEnd;
memset(block+sigmaBeginByteLen+1, 0, sizeof(block)-sigmaBeginByteLen-1);
block[(instance->rate-1)/8] |= 1 << ((instance->rate-1) % 8);
displayBytes(1, "Block to be absorbed (after padding)", block, (instance->rate+7)/8);
}
#endif
/* Last few bits, whose delimiter coincides with first bit of padding */
SnP_AddByte(instance->state, delimitedSigmaEnd, instance->byteInputIndex+sigmaBeginByteLen);
/* Second bit of padding */
SnP_AddByte(instance->state, (unsigned char)1 << ((instance->rate - 1)%8), (instance->rate - 1)/8);
SnP_Permute(instance->state);
SnP_ExtractBytes(instance->state, Z, 0, ZByteLen);
if (ZByteLen*8 > instance->rate) {
unsigned char mask = (unsigned char)(1 << (instance->rate % 8)) - 1;
Z[ZByteLen-1] &= mask;
}
instance->byteInputIndex = 0;
instance->byteOutputIndex = ZByteLen;
return 0;
}
int DuplexingFeedPartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen)
{
const unsigned int rho_max = instance->rate - 2;
if ((instance->byteInputIndex+inputByteLen)*8 > rho_max)
return 1;
SnP_AddBytes(instance->state, input, instance->byteInputIndex, inputByteLen);
instance->byteInputIndex += inputByteLen;
return 0;
}
int DuplexingFeedZeroes(DuplexInstance *instance, unsigned int inputByteLen)
{
const unsigned int rho_max = instance->rate - 2;
if ((instance->byteInputIndex+inputByteLen)*8 > rho_max)
return 1;
instance->byteInputIndex += inputByteLen;
return 0;
}
int DuplexingOverwritePartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen)
{
const unsigned int rho_max = instance->rate - 2;
if ((instance->byteInputIndex+inputByteLen)*8 > rho_max)
return 1;
SnP_OverwriteBytes(instance->state, input, instance->byteInputIndex, inputByteLen);
instance->byteInputIndex += inputByteLen;
return 0;
}
int DuplexingOverwriteWithZeroes(DuplexInstance *instance, unsigned int inputByteLen)
{
const unsigned int rho_max = instance->rate - 2;
if ((instance->byteInputIndex != 0) || (inputByteLen*8 > rho_max))
return 1;
SnP_OverwriteWithZeroes(instance->state, inputByteLen);
instance->byteInputIndex = inputByteLen;
return 0;
}
int DuplexingGetFurtherOutput(DuplexInstance *instance, unsigned char *output, unsigned int outputByteLen)
{
if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8)
return 1; /* The output length must not be greater than the rate (rounded up to a byte) */
SnP_ExtractBytes(instance->state, output, instance->byteOutputIndex, outputByteLen);
instance->byteOutputIndex += outputByteLen;
if (instance->byteOutputIndex*8 > instance->rate) {
unsigned char mask = (1 << (instance->rate % 8)) - 1;
output[outputByteLen-1] &= mask;
}
return 0;
}
int DuplexingGetFurtherOutputAndAdd(DuplexInstance *instance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen)
{
if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8)
return 1; /* The output length must not be greater than the rate (rounded up to a byte) */
SnP_ExtractAndAddBytes(instance->state, input, output, instance->byteOutputIndex, outputByteLen);
instance->byteOutputIndex += outputByteLen;
if (instance->byteOutputIndex*8 > instance->rate) {
unsigned char mask = (1 << (instance->rate % 8)) - 1;
output[outputByteLen-1] &= mask;
}
return 0;
}
#undef DuplexInstance
#undef DuplexInitialize
#undef Duplexing
#undef DuplexingFeedPartialInput
#undef DuplexingFeedZeroes
#undef DuplexingOverwritePartialInput
#undef DuplexingOverwriteWithZeroes
#undef DuplexingGetFurtherOutput
#undef DuplexingGetFurtherOutputAndAdd
#undef SnP_stateSizeInBytes
#undef SnP_stateAlignment
#undef SnP_StaticInitialize
#undef SnP_Initialize
#undef SnP_AddByte
#undef SnP_AddBytes
#undef SnP_OverwriteBytes
#undef SnP_OverwriteWithZeroes
#undef SnP_ExtractBytes
#undef SnP_ExtractAndAddBytes
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "KeccakDuplexWidth1600.h"
#ifdef KeccakReference
#include <string.h>
#include "displayIntermediateValues.h"
#endif
#ifndef KeccakP1600_excluded
#include "KeccakP-1600-SnP.h"
#define prefix KeccakWidth1600
#define SnP KeccakP1600
#define SnP_width 1600
#define SnP_Permute KeccakP1600_Permute_24rounds
#include "KeccakDuplex.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakDuplexWidth1600_h_
#define _KeccakDuplexWidth1600_h_
#include "KeccakDuplex-common.h"
#ifndef KeccakP1600_excluded
#include "KeccakP-1600-SnP.h"
KCP_DeclareDuplexStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment)
KCP_DeclareDuplexFunctions(KeccakWidth1600)
#endif
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "KeccakDuplexWidth200.h"
#ifdef KeccakReference
#include <string.h>
#include "displayIntermediateValues.h"
#endif
#ifndef KeccakP200_excluded
#include "KeccakP-200-SnP.h"
#define prefix KeccakWidth200
#define SnP KeccakP200
#define SnP_width 200
#define SnP_Permute KeccakP200_Permute_18rounds
#include "KeccakDuplex.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakDuplexWidth200_h_
#define _KeccakDuplexWidth200_h_
#include "KeccakDuplex-common.h"
#ifndef KeccakP200_excluded
#include "KeccakP-200-SnP.h"
KCP_DeclareDuplexStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment)
KCP_DeclareDuplexFunctions(KeccakWidth200)
#endif
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "KeccakDuplexWidth400.h"
#ifdef KeccakReference
#include <string.h>
#include "displayIntermediateValues.h"
#endif
#ifndef KeccakP400_excluded
#include "KeccakP-400-SnP.h"
#define prefix KeccakWidth400
#define SnP KeccakP400
#define SnP_width 400
#define SnP_Permute KeccakP400_Permute_20rounds
#include "KeccakDuplex.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakDuplexWidth400_h_
#define _KeccakDuplexWidth400_h_
#include "KeccakDuplex-common.h"
#ifndef KeccakP400_excluded
#include "KeccakP-400-SnP.h"
KCP_DeclareDuplexStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment)
KCP_DeclareDuplexFunctions(KeccakWidth400)
#endif
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "KeccakDuplexWidth800.h"
#ifdef KeccakReference
#include <string.h>
#include "displayIntermediateValues.h"
#endif
#ifndef KeccakP800_excluded
#include "KeccakP-800-SnP.h"
#define prefix KeccakWidth800
#define SnP KeccakP800
#define SnP_width 800
#define SnP_Permute KeccakP800_Permute_22rounds
#include "KeccakDuplex.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakDuplexWidth800_h_
#define _KeccakDuplexWidth800_h_
#include "KeccakDuplex-common.h"
#ifndef KeccakP800_excluded
#include "KeccakP-800-SnP.h"
KCP_DeclareDuplexStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment)
KCP_DeclareDuplexFunctions(KeccakWidth800)
#endif
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakSpongeCommon_h_
#define _KeccakSpongeCommon_h_
#include <string.h>
#include "align.h"
#define KCP_DeclareSpongeStructure(prefix, size, alignment) \
ALIGN(64) typedef struct prefix##_SpongeInstanceStruct { \
unsigned char state[size]; \
unsigned int rate; \
unsigned int byteIOIndex; \
int squeezing; \
} prefix##_SpongeInstance;
#define KCP_DeclareSpongeFunctions(prefix) \
int prefix##_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); \
int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); \
int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); \
int prefix##_SpongeAbsorbLastFewBits(prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \
int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen);
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakSponge_h_
#define _KeccakSponge_h_
/* For the documentation, please follow the link: */
/* #include "KeccakSponge-documentation.h" */
#include "KeccakSpongeWidth200.h"
#include "KeccakSpongeWidth400.h"
#include "KeccakSpongeWidth800.h"
#include "KeccakSpongeWidth1600.h"
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#define JOIN0(a, b) a ## b
#define JOIN(a, b) JOIN0(a, b)
#define Sponge JOIN(prefix, _Sponge)
#define SpongeInstance JOIN(prefix, _SpongeInstance)
#define SpongeInitialize JOIN(prefix, _SpongeInitialize)
#define SpongeAbsorb JOIN(prefix, _SpongeAbsorb)
#define SpongeAbsorbLastFewBits JOIN(prefix, _SpongeAbsorbLastFewBits)
#define SpongeSqueeze JOIN(prefix, _SpongeSqueeze)
#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes)
#define SnP_stateAlignment JOIN(SnP, _stateAlignment)
#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize)
#define SnP_Initialize JOIN(SnP, _Initialize)
#define SnP_AddByte JOIN(SnP, _AddByte)
#define SnP_AddBytes JOIN(SnP, _AddBytes)
#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes)
int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen)
{
ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes];
unsigned int partialBlock;
const unsigned char *curInput = input;
unsigned char *curOutput = output;
unsigned int rateInBytes = rate/8;
if (rate+capacity != SnP_width)
return 1;
if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
return 1;
if (suffix == 0)
return 1;
/* Initialize the state */
SnP_StaticInitialize();
SnP_Initialize(state);
/* First, absorb whole blocks */
#ifdef SnP_FastLoop_Absorb
if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) {
/* fast lane: whole lane rate */
size_t j;
j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen);
curInput += j;
inputByteLen -= j;
}
#endif
while(inputByteLen >= (size_t)rateInBytes) {
#ifdef KeccakReference
displayBytes(1, "Block to be absorbed", curInput, rateInBytes);
#endif
SnP_AddBytes(state, curInput, 0, rateInBytes);
SnP_Permute(state);
curInput += rateInBytes;
inputByteLen -= rateInBytes;
}
/* Then, absorb what remains */
partialBlock = (unsigned int)inputByteLen;
#ifdef KeccakReference
displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock);
#endif
SnP_AddBytes(state, curInput, 0, partialBlock);
/* Finally, absorb the suffix */
#ifdef KeccakReference
{
unsigned char delimitedData1[1];
delimitedData1[0] = suffix;
displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
}
#endif
/* Last few bits, whose delimiter coincides with first bit of padding */
SnP_AddByte(state, suffix, partialBlock);
/* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1)))
SnP_Permute(state);
/* Second bit of padding */
SnP_AddByte(state, 0x80, rateInBytes-1);
#ifdef KeccakReference
{
unsigned char block[SnP_width/8];
memset(block, 0, SnP_width/8);
block[rateInBytes-1] = 0x80;
displayBytes(1, "Second bit of padding", block, rateInBytes);
}
#endif
SnP_Permute(state);
#ifdef KeccakReference
displayText(1, "--- Switching to squeezing phase ---");
#endif
/* First, output whole blocks */
while(outputByteLen > (size_t)rateInBytes) {
SnP_ExtractBytes(state, curOutput, 0, rateInBytes);
SnP_Permute(state);
#ifdef KeccakReference
displayBytes(1, "Squeezed block", curOutput, rateInBytes);
#endif
curOutput += rateInBytes;
outputByteLen -= rateInBytes;
}
/* Finally, output what remains */
partialBlock = (unsigned int)outputByteLen;
SnP_ExtractBytes(state, curOutput, 0, partialBlock);
#ifdef KeccakReference
displayBytes(1, "Squeezed block (part)", curOutput, partialBlock);
#endif
return 0;
}
/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity)
{
if (rate+capacity != SnP_width)
return 1;
if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
return 1;
SnP_StaticInitialize();
SnP_Initialize(instance->state);
instance->rate = rate;
instance->byteIOIndex = 0;
instance->squeezing = 0;
return 0;
}
/* ---------------------------------------------------------------- */
int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen)
{
size_t i, j;
unsigned int partialBlock;
const unsigned char *curData;
unsigned int rateInBytes = instance->rate/8;
if (instance->squeezing)
return 1; /* Too late for additional input */
i = 0;
curData = data;
while(i < dataByteLen) {
if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) {
#ifdef SnP_FastLoop_Absorb
/* processing full blocks first */
if ((rateInBytes % (SnP_width/200)) == 0) {
/* fast lane: whole lane rate */
j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i);
i += j;
curData += j;
}
else {
#endif
for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
#ifdef KeccakReference
displayBytes(1, "Block to be absorbed", curData, rateInBytes);
#endif
SnP_AddBytes(instance->state, curData, 0, rateInBytes);
SnP_Permute(instance->state);
curData+=rateInBytes;
}
i = dataByteLen - j;
#ifdef SnP_FastLoop_Absorb
}
#endif
}
else {
/* normal lane: using the message queue */
partialBlock = (unsigned int)(dataByteLen - i);
if (partialBlock+instance->byteIOIndex > rateInBytes)
partialBlock = rateInBytes-instance->byteIOIndex;
#ifdef KeccakReference
displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
#endif
i += partialBlock;
SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
curData += partialBlock;
instance->byteIOIndex += partialBlock;
if (instance->byteIOIndex == rateInBytes) {
SnP_Permute(instance->state);
instance->byteIOIndex = 0;
}
}
}
return 0;
}
/* ---------------------------------------------------------------- */
int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData)
{
unsigned int rateInBytes = instance->rate/8;
if (delimitedData == 0)
return 1;
if (instance->squeezing)
return 1; /* Too late for additional input */
#ifdef KeccakReference
{
unsigned char delimitedData1[1];
delimitedData1[0] = delimitedData;
displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
}
#endif
/* Last few bits, whose delimiter coincides with first bit of padding */
SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex);
/* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1)))
SnP_Permute(instance->state);
/* Second bit of padding */
SnP_AddByte(instance->state, 0x80, rateInBytes-1);
#ifdef KeccakReference
{
unsigned char block[SnP_width/8];
memset(block, 0, SnP_width/8);
block[rateInBytes-1] = 0x80;
displayBytes(1, "Second bit of padding", block, rateInBytes);
}
#endif
SnP_Permute(instance->state);
instance->byteIOIndex = 0;
instance->squeezing = 1;
#ifdef KeccakReference
displayText(1, "--- Switching to squeezing phase ---");
#endif
return 0;
}
/* ---------------------------------------------------------------- */
int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen)
{
size_t i, j;
unsigned int partialBlock;
unsigned int rateInBytes = instance->rate/8;
unsigned char *curData;
if (!instance->squeezing)
SpongeAbsorbLastFewBits(instance, 0x01);
i = 0;
curData = data;
while(i < dataByteLen) {
if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) {
for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
SnP_Permute(instance->state);
SnP_ExtractBytes(instance->state, curData, 0, rateInBytes);
#ifdef KeccakReference
displayBytes(1, "Squeezed block", curData, rateInBytes);
#endif
curData+=rateInBytes;
}
i = dataByteLen - j;
}
else {
/* normal lane: using the message queue */
if (instance->byteIOIndex == rateInBytes) {
SnP_Permute(instance->state);
instance->byteIOIndex = 0;
}
partialBlock = (unsigned int)(dataByteLen - i);
if (partialBlock+instance->byteIOIndex > rateInBytes)
partialBlock = rateInBytes-instance->byteIOIndex;
i += partialBlock;
SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
#ifdef KeccakReference
displayBytes(1, "Squeezed block (part)", curData, partialBlock);
#endif
curData += partialBlock;
instance->byteIOIndex += partialBlock;
}
}
return 0;
}
/* ---------------------------------------------------------------- */
#undef Sponge
#undef SpongeInstance
#undef SpongeInitialize
#undef SpongeAbsorb
#undef SpongeAbsorbLastFewBits
#undef SpongeSqueeze
#undef SnP_stateSizeInBytes
#undef SnP_stateAlignment
#undef SnP_StaticInitialize
#undef SnP_Initialize
#undef SnP_AddByte
#undef SnP_AddBytes
#undef SnP_ExtractBytes
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "KeccakSpongeWidth1600.h"
#ifdef KeccakReference
#include "displayIntermediateValues.h"
#endif
#ifndef KeccakP1600_excluded
#include "KeccakP-1600-SnP.h"
#define prefix KeccakWidth1600
#define SnP KeccakP1600
#define SnP_width 1600
#define SnP_Permute KeccakP1600_Permute_24rounds
#if defined(KeccakF1600_FastLoop_supported)
#define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb
#endif
#include "KeccakSponge.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#endif
#ifndef KeccakP1600_excluded
#include "KeccakP-1600-SnP.h"
#define prefix KeccakWidth1600_12rounds
#define SnP KeccakP1600
#define SnP_width 1600
#define SnP_Permute KeccakP1600_Permute_12rounds
#if defined(KeccakP1600_12rounds_FastLoop_supported)
#define SnP_FastLoop_Absorb KeccakP1600_12rounds_FastLoop_Absorb
#endif
#include "KeccakSponge.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#endif
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakSpongeWidth1600_h_
#define _KeccakSpongeWidth1600_h_
#include "KeccakSponge-common.h"
#ifndef KeccakP1600_excluded
#include "KeccakP-1600-SnP.h"
KCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment)
KCP_DeclareSpongeFunctions(KeccakWidth1600)
#endif
#ifndef KeccakP1600_excluded
#include "KeccakP-1600-SnP.h"
KCP_DeclareSpongeStructure(KeccakWidth1600_12rounds, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment)
KCP_DeclareSpongeFunctions(KeccakWidth1600_12rounds)
#endif
#endif