From c64e115f8b6631df419a207f11d394c1b241d2bd Mon Sep 17 00:00:00 2001 From: kremlin Date: Fri, 19 Sep 2014 21:26:41 -0400 Subject: [PATCH] bring in keccak symbols --- .../assets/KremKeccak/KeccakF-1600-int-set.h | 6 + .../KremKeccak/KeccakF-1600-interface.h | 46 ++++++ .../assets/KremKeccak/KeccakNISTInterface.h | 70 +++++++++ DH-Keccak/assets/KremKeccak/KeccakSponge.h | 76 ++++++++++ DH-Keccak/assets/KremKeccak/brg_endian.h | 142 ++++++++++++++++++ .../KremKeccak/displayIntermediateValues.h | 29 ++++ DH-Keccak/assets/KremKeccak/krem-keccak | Bin 0 -> 29961 bytes DH-Keccak/assets/KremKeccak/krem_keccak.c | 6 +- 8 files changed, 372 insertions(+), 3 deletions(-) create mode 100755 DH-Keccak/assets/KremKeccak/KeccakF-1600-int-set.h create mode 100755 DH-Keccak/assets/KremKeccak/KeccakF-1600-interface.h create mode 100755 DH-Keccak/assets/KremKeccak/KeccakNISTInterface.h create mode 100755 DH-Keccak/assets/KremKeccak/KeccakSponge.h create mode 100755 DH-Keccak/assets/KremKeccak/brg_endian.h create mode 100755 DH-Keccak/assets/KremKeccak/displayIntermediateValues.h create mode 100755 DH-Keccak/assets/KremKeccak/krem-keccak diff --git a/DH-Keccak/assets/KremKeccak/KeccakF-1600-int-set.h b/DH-Keccak/assets/KremKeccak/KeccakF-1600-int-set.h new file mode 100755 index 0000000..0ed1d80 --- /dev/null +++ b/DH-Keccak/assets/KremKeccak/KeccakF-1600-int-set.h @@ -0,0 +1,6 @@ +#define ProvideFast576 +#define ProvideFast832 +#define ProvideFast1024 +#define ProvideFast1088 +#define ProvideFast1152 +#define ProvideFast1344 diff --git a/DH-Keccak/assets/KremKeccak/KeccakF-1600-interface.h b/DH-Keccak/assets/KremKeccak/KeccakF-1600-interface.h new file mode 100755 index 0000000..22185a4 --- /dev/null +++ b/DH-Keccak/assets/KremKeccak/KeccakF-1600-interface.h @@ -0,0 +1,46 @@ +/* +The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, +Michaël Peeters and Gilles Van Assche. For more information, feedback or +questions, please refer to our website: http://keccak.noekeon.org/ + +Implementation by the designers, +hereby denoted as "the implementer". + +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 _KeccakPermutationInterface_h_ +#define _KeccakPermutationInterface_h_ + +#include "KeccakF-1600-int-set.h" + +void KeccakInitialize( void ); +void KeccakInitializeState(unsigned char *state); +void KeccakPermutation(unsigned char *state); +#ifdef ProvideFast576 +void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data); +#endif +#ifdef ProvideFast832 +void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data); +#endif +#ifdef ProvideFast1024 +void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data); +#endif +#ifdef ProvideFast1088 +void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data); +#endif +#ifdef ProvideFast1152 +void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data); +#endif +#ifdef ProvideFast1344 +void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data); +#endif +void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount); +#ifdef ProvideFast1024 +void KeccakExtract1024bits(const unsigned char *state, unsigned char *data); +#endif +void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount); + +#endif diff --git a/DH-Keccak/assets/KremKeccak/KeccakNISTInterface.h b/DH-Keccak/assets/KremKeccak/KeccakNISTInterface.h new file mode 100755 index 0000000..c6987d4 --- /dev/null +++ b/DH-Keccak/assets/KremKeccak/KeccakNISTInterface.h @@ -0,0 +1,70 @@ +/* +The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, +Michaël Peeters and Gilles Van Assche. For more information, feedback or +questions, please refer to our website: http://keccak.noekeon.org/ + +Implementation by the designers, +hereby denoted as "the implementer". + +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 _KeccakNISTInterface_h_ +#define _KeccakNISTInterface_h_ + +#include "KeccakSponge.h" + +typedef unsigned char BitSequence; +typedef unsigned long long DataLength; +typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; + +typedef spongeState hashState; + +/** + * Function to initialize the state of the Keccak[r, c] sponge function. + * The rate r and capacity c values are determined from @a hashbitlen. + * @param state Pointer to the state of the sponge function to be initialized. + * @param hashbitlen The desired number of output bits, + * or 0 for Keccak[] with default parameters + * and arbitrarily-long output. + * @pre The value of hashbitlen must be one of 0, 224, 256, 384 and 512. + * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect. + */ +HashReturn Init(hashState *state, int hashbitlen); +/** + * Function to give input data for the sponge function to absorb. + * @param state Pointer to the state of the sponge function initialized by Init(). + * @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 most significant bits of the last byte. + * @param databitLen The number of input bits provided in the input data. + * @pre In the previous call to Absorb(), databitLen was a multiple of 8. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen); +/** + * Function to squeeze output data from the sponge function. + * If @a hashbitlen was not 0 in the call to Init(), the number of output bits is equal to @a hashbitlen. + * If @a hashbitlen was 0 in the call to Init(), the output bits must be extracted using the Squeeze() function. + * @param state Pointer to the state of the sponge function initialized by Init(). + * @param hashval Pointer to the buffer where to store the output data. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Final(hashState *state, BitSequence *hashval); +/** + * Function to compute a hash using the Keccak[r, c] sponge function. + * The rate r and capacity c values are determined from @a hashbitlen. + * @param hashbitlen The desired number of output bits. + * @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 most significant bits of the last byte. + * @param databitLen The number of input bits provided in the input data. + * @param hashval Pointer to the buffer where to store the output data. + * @pre The value of hashbitlen must be one of 224, 256, 384 and 512. + * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect. + */ +HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); + +#endif diff --git a/DH-Keccak/assets/KremKeccak/KeccakSponge.h b/DH-Keccak/assets/KremKeccak/KeccakSponge.h new file mode 100755 index 0000000..df3d797 --- /dev/null +++ b/DH-Keccak/assets/KremKeccak/KeccakSponge.h @@ -0,0 +1,76 @@ +/* +The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, +Michaël Peeters and Gilles Van Assche. For more information, feedback or +questions, please refer to our website: http://keccak.noekeon.org/ + +Implementation by the designers, +hereby denoted as "the implementer". + +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_ + +#define KeccakPermutationSize 1600 +#define KeccakPermutationSizeInBytes (KeccakPermutationSize/8) +#define KeccakMaximumRate 1536 +#define KeccakMaximumRateInBytes (KeccakMaximumRate/8) + +#if defined(__GNUC__) +#define ALIGN __attribute__ ((aligned(32))) +#elif defined(_MSC_VER) +#define ALIGN __declspec(align(32)) +#else +#define ALIGN +#endif + +ALIGN typedef struct spongeStateStruct { + ALIGN unsigned char state[KeccakPermutationSizeInBytes]; + ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes]; + unsigned int rate; + unsigned int capacity; + unsigned int bitsInQueue; + unsigned int fixedOutputLength; + int squeezing; + unsigned int bitsAvailableForSqueezing; +} spongeState; + +/** + * Function to initialize the state of the Keccak[r, c] sponge function. + * The sponge function is set to the absorbing phase. + * @param state Pointer to the state of the sponge function to be initialized. + * @param rate The value of the rate r. + * @param capacity The value of the capacity c. + * @pre One must have r+c=1600 and the rate a multiple of 64 bits in this implementation. + * @return Zero if successful, 1 otherwise. + */ +int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity); +/** + * Function to give input data for the sponge function to absorb. + * @param state Pointer to the state of the sponge function initialized by InitSponge(). + * @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. + * @param databitLen The number of input bits provided in the input data. + * @pre In the previous call to Absorb(), databitLen was a multiple of 8. + * @pre The sponge function must be in the absorbing phase, + * i.e., Squeeze() must not have been called before. + * @return Zero if successful, 1 otherwise. + */ +int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen); +/** + * Function to squeeze output data from the sponge function. + * If the sponge function was in the absorbing phase, this function + * switches it to the squeezing phase. + * @param state Pointer to the state of the sponge function initialized by InitSponge(). + * @param output Pointer to the buffer where to store the output data. + * @param outputLength The number of output bits desired. + * It must be a multiple of 8. + * @return Zero if successful, 1 otherwise. + */ +int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength); + +#endif diff --git a/DH-Keccak/assets/KremKeccak/brg_endian.h b/DH-Keccak/assets/KremKeccak/brg_endian.h new file mode 100755 index 0000000..7226eb3 --- /dev/null +++ b/DH-Keccak/assets/KremKeccak/brg_endian.h @@ -0,0 +1,142 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 20/12/2007 + Changes for ARM 9/9/2010 +*/ + +#ifndef _BRG_ENDIAN_H +#define _BRG_ENDIAN_H + +#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ +#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ + +#if 0 +/* Include files where endian defines and byteswap functions may reside */ +#if defined( __sun ) +# include +#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) +# include +#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ + defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) +# include +#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) +# if !defined( __MINGW32__ ) && !defined( _AIX ) +# include +# if !defined( __BEOS__ ) +# include +# endif +# endif +#endif +#endif + +/* Now attempt to set the define for platform byte order using any */ +/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ +/* seem to encompass most endian symbol definitions */ + +#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) +# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) +# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( _BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( _LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) +# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( __BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( __LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) +# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( __BIG_ENDIAN__ ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( __LITTLE_ENDIAN__ ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +/* if the platform byte order could not be determined, then try to */ +/* set this define using common machine defines */ +#if !defined(PLATFORM_BYTE_ORDER) + +#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ + defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ + defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ + defined( vax ) || defined( vms ) || defined( VMS ) || \ + defined( __VMS ) || defined( _M_X64 ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN + +#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ + defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ + defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ + defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ + defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ + defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ + defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN + +#elif defined(__arm__) +# ifdef __BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# else +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif 1 /* **** EDIT HERE IF NECESSARY **** */ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#elif 0 /* **** EDIT HERE IF NECESSARY **** */ +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#else +# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order +#endif + +#endif + +#endif diff --git a/DH-Keccak/assets/KremKeccak/displayIntermediateValues.h b/DH-Keccak/assets/KremKeccak/displayIntermediateValues.h new file mode 100755 index 0000000..1d6c6c8 --- /dev/null +++ b/DH-Keccak/assets/KremKeccak/displayIntermediateValues.h @@ -0,0 +1,29 @@ +/* +The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, +Michaël Peeters and Gilles Van Assche. For more information, feedback or +questions, please refer to our website: http://keccak.noekeon.org/ + +Implementation by the designers, +hereby denoted as "the implementer". + +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 _displayIntermediateValues_h_ +#define _displayIntermediateValues_h_ + +#include + +void displaySetIntermediateValueFile(FILE *f); +void displaySetLevel(int level); +void displayBytes(int level, const char *text, const unsigned char *bytes, unsigned int size); +void displayBits(int level, const char *text, const unsigned char *data, unsigned int size, int MSBfirst); +void displayStateAsBytes(int level, const char *text, const unsigned char *state); +void displayStateAs32bitWords(int level, const char *text, const unsigned int *state); +void displayStateAs64bitWords(int level, const char *text, const unsigned long long int *state); +void displayRoundNumber(int level, unsigned int i); +void displayText(int level, const char *text); + +#endif diff --git a/DH-Keccak/assets/KremKeccak/krem-keccak b/DH-Keccak/assets/KremKeccak/krem-keccak new file mode 100755 index 0000000000000000000000000000000000000000..27228dd018efb4baf0ef94565580aaaaf8027188 GIT binary patch literal 29961 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