Replace slow generic sha3 implementation by https://github.com/gvanas/KeccakCodePackage

Fix hash_copy() tests by using correct size for sha3 context

sync config.w32 with with new sha3 files

Move dependency on KeccakHash.h to hash_sha3.c so we do not rely on it to install php_hash_sha3.h

Allocate memory for KeccacInstance in hash_sha3.c so header files do not need to know about implementation details while keeping API backward compatible to original sha3 implementation

Fix memory leak because hash_copy is called after init which already allocates the hashinstance
This commit is contained in:
Christian Schneider 2017-04-05 17:30:23 +02:00 committed by Anatol Belski
parent 41b41825d6
commit 91663a92d1
27 changed files with 6379 additions and 187 deletions

View File

@ -25,15 +25,24 @@ if test "$PHP_HASH" != "no"; then
AC_CHECK_SIZEOF(long, 4)
AC_CHECK_SIZEOF(long long, 8)
PHP_CHECK_64BIT([
SHA3_DIR="sha3/generic32lc"
SHA3_OPT_SRC="$SHA3_DIR/KeccakP-1600-inplace32BI.c"
],[
SHA3_DIR="sha3/generic64lc"
SHA3_OPT_SRC="$SHA3_DIR/KeccakP-1600-opt64.c"
])
EXT_HASH_SHA3_SOURCES="$SHA3_OPT_SRC $SHA3_DIR/KeccakHash.c $SHA3_DIR/KeccakSponge.c"
PHP_HASH_CFLAGS="-I@ext_srcdir@/$SHA3_DIR -DKeccakP200_excluded -DKeccakP400_excluded -DKeccakP800_excluded"
EXT_HASH_SOURCES="hash.c hash_md.c hash_sha.c hash_ripemd.c hash_haval.c \
hash_tiger.c hash_gost.c hash_snefru.c hash_whirlpool.c hash_adler32.c \
hash_crc32.c hash_fnv.c hash_joaat.c hash_sha3.c"
hash_crc32.c hash_fnv.c hash_joaat.c hash_sha3.c $EXT_HASH_SHA3_SOURCES"
EXT_HASH_HEADERS="php_hash.h php_hash_md.h php_hash_sha.h php_hash_ripemd.h \
php_hash_haval.h php_hash_tiger.h php_hash_gost.h php_hash_snefru.h \
php_hash_whirlpool.h php_hash_adler32.h php_hash_crc32.h \
php_hash_fnv.h php_hash_joaat.h php_hash_sha3.h"
PHP_NEW_EXTENSION(hash, $EXT_HASH_SOURCES, $ext_shared)
PHP_NEW_EXTENSION(hash, $EXT_HASH_SOURCES, $ext_shared,,$PHP_HASH_CFLAGS)
ifdef([PHP_INSTALL_HEADERS], [
PHP_INSTALL_HEADERS(ext/hash, $EXT_HASH_HEADERS)
])

View File

@ -12,13 +12,24 @@ if (PHP_MHASH != "no") {
}
if (PHP_HASH != "no") {
AC_DEFINE('HAVE_HASH_EXT', 1);
EXTENSION("hash", "hash.c hash_md.c hash_sha.c hash_ripemd.c hash_haval.c "
+ "hash_tiger.c hash_gost.c hash_snefru.c hash_whirlpool.c "
+ "hash_adler32.c hash_crc32.c hash_joaat.c hash_fnv.c hash_sha3.c");
var sha3_arch_dir = "sha3/" + (X64 ? "generic64lc" : "generic32lc");
var sha3_dir = "ext/hash/" + sha3_arch_dir;
if (CHECK_HEADER_ADD_INCLUDE("KeccakHash.h", "CFLAGS_HASH", PHP_HASH + ";" + sha3_dir)) {
AC_DEFINE('HAVE_HASH_EXT', 1);
EXTENSION("hash", "hash.c hash_md.c hash_sha.c hash_ripemd.c hash_haval.c "
+ "hash_tiger.c hash_gost.c hash_snefru.c hash_whirlpool.c "
+ "hash_adler32.c hash_crc32.c hash_joaat.c hash_fnv.c hash_sha3.c");
ADD_SOURCES(sha3_dir, "KeccakHash.c KeccakSponge.c " + (X64 ? "KeccakP-1600-opt64.c" : "KeccakP-1600-inplace32BI.c"),
"hash");
ADD_FLAG("CFLAGS_HASH", "/DKeccakP200_excluded /DKeccakP400_excluded /DKeccakP800_excluded");
PHP_INSTALL_HEADERS("ext/hash/", "php_hash.h php_hash_md.h php_hash_sha.h php_hash_ripemd.h " +
"php_hash_haval.h php_hash_tiger.h php_hash_gost.h php_hash_snefru.h " +
"php_hash_whirlpool.h php_hash_adler32.h php_hash_crc32.h php_hash_sha3.h");
"php_hash_whirlpool.h php_hash_adler32.h php_hash_crc32.h php_hash_sha3.h ");
} else {
WARNING("gd not enabled; libraries and headers not found");
}
}

View File

@ -19,204 +19,41 @@
#include "php_hash.h"
#include "php_hash_sha3.h"
#if (defined(__APPLE__) || defined(__APPLE_CC__)) && \
(defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
# if defined(__LITTLE_ENDIAN__)
# undef WORDS_BIGENDIAN
# else
# if defined(__BIG_ENDIAN__)
# define WORDS_BIGENDIAN
# endif
# endif
#endif
#define SUCCESS SHA3_SUCCESS /* Avoid conflict between KeccacHash.h and zend_types.h */
#include "KeccakHash.h"
static inline uint64_t rol64(uint64_t v, unsigned char b) {
return (v << b) | (v >> (64 - b));
}
static inline unsigned char idx(unsigned char x, unsigned char y) {
return x + (5 * y);
}
#ifdef WORDS_BIGENDIAN
static inline uint64_t load64(const unsigned char* x) {
char i;
uint64_t ret = 0;
for (i = 7; i >= 0; --i) {
ret <<= 8;
ret |= x[i];
}
return ret;
}
static inline void store64(unsigned char* x, uint64_t val) {
char i;
for (i = 0; i < 8; ++i) {
x[i] = val & 0xFF;
val >>= 8;
}
}
static inline void xor64(unsigned char* x, uint64_t val) {
char i;
for (i = 0; i < 8; ++i) {
x[i] ^= val & 0xFF;
val >>= 8;
}
}
# define readLane(x, y) load64(ctx->state+sizeof(uint64_t)*idx(x, y))
# define writeLane(x, y, v) store64(ctx->state+sizeof(uint64_t)*idx(x, y), v)
# define XORLane(x, y, v) xor64(ctx->state+sizeof(uint64_t)*idx(x, y), v)
#else
# define readLane(x, y) (((uint64_t*)ctx->state)[idx(x,y)])
# define writeLane(x, y, v) (((uint64_t*)ctx->state)[idx(x,y)] = v)
# define XORLane(x, y, v) (((uint64_t*)ctx->state)[idx(x,y)] ^= v)
#endif
// ==========================================================================
static inline char LFSR86540(unsigned char* pLFSR)
static int hash_sha3_copy(const void *ops, void *orig_context, void *dest_context)
{
unsigned char LFSR = *pLFSR;
char result = LFSR & 0x01;
if (LFSR & 0x80) {
// Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
LFSR = (LFSR << 1) ^ 0x71;
} else {
LFSR <<= 1;
}
*pLFSR = LFSR;
return result;
PHP_SHA3_CTX* orig = (PHP_SHA3_CTX*)orig_context;
PHP_SHA3_CTX* dest = (PHP_SHA3_CTX*)dest_context;
memcpy(dest->hashinstance, orig->hashinstance, sizeof(Keccak_HashInstance));
return SUCCESS;
}
static void permute(PHP_SHA3_CTX* ctx) {
unsigned char LFSRstate = 0x01;
unsigned char round;
for (round = 0; round < 24; ++round) {
{ // Theta step (see [Keccak Reference, Section 2.3.2])
uint64_t C[5], D;
unsigned char x, y;
for (x = 0; x < 5; ++x) {
C[x] = readLane(x, 0) ^ readLane(x, 1) ^
readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4);
}
for (x = 0; x < 5; ++x) {
D = C[(x+4)%5] ^ rol64(C[(x+1)%5], 1);
for (y = 0; y < 5; ++y) {
XORLane(x, y, D);
}
}
}
{ // p and Pi steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4])
unsigned char x = 1, y = 0, t;
uint64_t current = readLane(x, y);
for (t = 0; t < 24; ++t) {
unsigned char r = ((t + 1) * (t + 2) / 2) % 64;
unsigned char Y = (2*x + 3*y) % 5;
uint64_t temp;
x = y;
y = Y;
temp = readLane(x, y);
writeLane(x, y, rol64(current, r));
current = temp;
}
}
{ // X step (see [Keccak Reference, Section 2.3.1])
unsigned char x, y;
for (y = 0; y < 5; ++y) {
uint64_t temp[5];
for (x = 0; x < 5; ++x) {
temp[x] = readLane(x, y);
}
for (x = 0; x < 5; ++x) {
writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5]));
}
}
}
{ // i step (see [Keccak Reference, Section 2.3.5])
unsigned char j;
for (j = 0; j < 7; ++j) {
if (LFSR86540(&LFSRstate)) {
uint64_t bitPos = (1<<j) - 1;
XORLane(0, 0, (uint64_t)1 << bitPos);
}
}
}
}
}
// ==========================================================================
static void PHP_SHA3_Init(PHP_SHA3_CTX* ctx,
int bits) {
memset(ctx, 0, sizeof(PHP_SHA3_CTX));
}
static void PHP_SHA3_Update(PHP_SHA3_CTX* ctx,
const unsigned char* buf,
unsigned int count,
size_t block_size) {
while (count > 0) {
unsigned int len = block_size - ctx->pos;
if (len > count) len = count;
count -= len;
while (len-- > 0) {
ctx->state[ctx->pos++] ^= *(buf++);
}
if (ctx->pos >= block_size) {
permute(ctx);
ctx->pos = 0;
}
}
}
static void PHP_SHA3_Final(unsigned char* digest,
PHP_SHA3_CTX* ctx,
int block_size,
int digest_size) {
int len = digest_size;
// Pad state to finalize
ctx->state[ctx->pos++] ^= 0x06;
ctx->state[block_size-1] ^= 0x80;
permute(ctx);
// Square output for digest
for(;;) {
int bs = (len < block_size) ? len : block_size;
memcpy(digest, ctx->state, bs);
digest += bs;
len -= bs;
if (!len) break;
permute(ctx);
}
// Zero out context
memset(ctx, 0, sizeof(PHP_SHA3_CTX));
}
// ==========================================================================
#define DECLARE_SHA3_OPS(bits) \
void PHP_SHA3##bits##Init(PHP_SHA3_##bits##_CTX* ctx) { \
PHP_SHA3_Init(ctx, bits); \
ctx->hashinstance = emalloc(sizeof(Keccak_HashInstance)); \
Keccak_HashInitialize_SHA3_##bits((Keccak_HashInstance *)ctx->hashinstance); \
} \
void PHP_SHA3##bits##Update(PHP_SHA3_##bits##_CTX* ctx, \
const unsigned char* input, \
unsigned int inputLen) { \
PHP_SHA3_Update(ctx, input, inputLen, \
(1600 - (2 * bits)) >> 3); \
Keccak_HashUpdate((Keccak_HashInstance *)ctx->hashinstance, input, inputLen * 8); \
} \
void PHP_SHA3##bits##Final(unsigned char* digest, \
PHP_SHA3_##bits##_CTX* ctx) { \
PHP_SHA3_Final(digest, ctx, \
(1600 - (2 * bits)) >> 3, \
bits >> 3); \
Keccak_HashFinal((Keccak_HashInstance *)ctx->hashinstance, digest); \
efree(ctx->hashinstance); \
ctx->hashinstance = NULL; \
} \
const php_hash_ops php_hash_sha3_##bits##_ops = { \
(php_hash_init_func_t) PHP_SHA3##bits##Init, \
(php_hash_update_func_t) PHP_SHA3##bits##Update, \
(php_hash_final_func_t) PHP_SHA3##bits##Final, \
php_hash_copy, \
hash_sha3_copy, \
bits >> 3, \
(1600 - (2 * bits)) >> 3, \
sizeof(PHP_SHA3_##bits##_CTX), \

View File

@ -22,8 +22,7 @@
#include "php.h"
typedef struct {
unsigned char state[200]; // 5 * 5 * sizeof(uint64)
uint32_t pos;
void *hashinstance;
} PHP_SHA3_CTX;
typedef PHP_SHA3_CTX PHP_SHA3_224_CTX;

View File

@ -0,0 +1,80 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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, DataLength 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 | ((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, DataLength databitlen)
{
if ((databitlen % 8) != 0)
return FAIL;
return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8);
}

View File

@ -0,0 +1,113 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 "KeccakSponge.h"
#include <string.h>
typedef unsigned char BitSequence;
typedef size_t DataLength;
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).
* @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, DataLength 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, DataLength databitlen);
#endif
#endif

View File

@ -0,0 +1,38 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 _KeccakP_1600_SnP_h_
#define _KeccakP_1600_SnP_h_
/** For the documentation, see SnP-documentation.h.
*/
#define KeccakP1600_implementation "in-place 32-bit optimized implementation"
#define KeccakP1600_stateSizeInBytes 200
#define KeccakP1600_stateAlignment 8
#define KeccakP1600_StaticInitialize()
void KeccakP1600_Initialize(void *state);
void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset);
void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount);
void KeccakP1600_Permute_Nrounds(void *state, unsigned int nrounds);
void KeccakP1600_Permute_12rounds(void *state);
void KeccakP1600_Permute_24rounds(void *state);
void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 "KeccakSponge.h"
#ifdef KeccakReference
#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
#if defined(KeccakF200_FastLoop_supported)
#define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb
#endif
#include "KeccakSponge.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#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
#if defined(KeccakF400_FastLoop_supported)
#define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb
#endif
#include "KeccakSponge.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#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
#if defined(KeccakF800_FastLoop_supported)
#define SnP_FastLoop_Absorb KeccakF800_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
#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

View File

@ -0,0 +1,178 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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_
/** General information
*
* The following type and functions are not actually implemented. Their
* documentation is generic, with the prefix Prefix replaced by
* - KeccakWidth200 for a sponge function based on Keccak-f[200]
* - KeccakWidth400 for a sponge function based on Keccak-f[400]
* - KeccakWidth800 for a sponge function based on Keccak-f[800]
* - KeccakWidth1600 for a sponge function based on Keccak-f[1600]
*
* In all these functions, the rate and capacity must sum to the width of the
* chosen permutation. For instance, to use the sponge function
* Keccak[r=1344, c=256], one must use KeccakWidth1600_Sponge() or a combination
* of KeccakWidth1600_SpongeInitialize(), KeccakWidth1600_SpongeAbsorb(),
* KeccakWidth1600_SpongeAbsorbLastFewBits() and
* KeccakWidth1600_SpongeSqueeze().
*
* The Prefix_SpongeInstance contains the sponge instance attributes for use
* with the Prefix_Sponge* functions.
* It gathers the state processed by the permutation as well as the rate,
* the position of input/output bytes in the state and the phase
* (absorbing or squeezing).
*/
#ifdef DontReallyInclude_DocumentationOnly
/** Function to evaluate the sponge function Keccak[r, c] in a single call.
* @param rate The value of the rate r.
* @param capacity The value of the capacity c.
* @param input Pointer to the input message (before the suffix).
* @param inputByteLen The length of the input message in bytes.
* @param suffix Byte containing from 0 to 7 suffix bits
* that must be absorbed after @a input.
* These <i>n</i> bits must be in the least significant bit positions.
* These bits must be delimited with a bit 1 at position <i>n</i>
* (counting from 0=LSB to 7=MSB) and followed by bits 0
* from position <i>n</i>+1 to position 7.
* Some examples:
* - If no bits are to be absorbed, then @a suffix must be 0x01.
* - If the 2-bit sequence 0,0 is to be absorbed, @a suffix must be 0x04.
* - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a suffix must be 0x32.
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a suffix must be 0x8B.
* .
* @param output Pointer to the output buffer.
* @param outputByteLen The desired number of output bytes.
* @pre One must have r+c equal to the supported width of this implementation
* and the rate a multiple of 8 bits (one byte) in this implementation.
* @pre @a suffix 0x00
* @return Zero if successful, 1 otherwise.
*/
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);
/**
* Function to initialize the state of the Keccak[r, c] sponge function.
* The phase of the sponge function is set to absorbing.
* @param spongeInstance Pointer to the sponge instance 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 equal to the supported width of this implementation
* and the rate a multiple of 8 bits (one byte) in this implementation.
* @return Zero if successful, 1 otherwise.
*/
int Prefix_SpongeInitialize(Prefix_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity);
/**
* Function to give input data bytes for the sponge function to absorb.
* @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
* @param data Pointer to the input data.
* @param dataByteLen The number of input bytes provided in the input data.
* @pre The sponge function must be in the absorbing phase,
* i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits()
* must not have been called before.
* @return Zero if successful, 1 otherwise.
*/
int Prefix_SpongeAbsorb(Prefix_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen);
/**
* Function to give input data bits for the sponge function to absorb
* and then to switch to the squeezing phase.
* @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
* @param delimitedData Byte containing from 0 to 7 trailing bits
* that must be absorbed.
* These <i>n</i> bits must be in the least significant bit positions.
* These bits must be delimited with a bit 1 at position <i>n</i>
* (counting from 0=LSB to 7=MSB) and followed by bits 0
* from position <i>n</i>+1 to position 7.
* Some examples:
* - If no bits are to be absorbed, then @a delimitedData must be 0x01.
* - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04.
* - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32.
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B.
* .
* @pre The sponge function must be in the absorbing phase,
* i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits()
* must not have been called before.
* @pre @a delimitedData 0x00
* @return Zero if successful, 1 otherwise.
*/
int Prefix_SpongeAbsorbLastFewBits(Prefix_SpongeInstance *spongeInstance, unsigned char delimitedData);
/**
* 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
* as if Prefix_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called.
* @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
* @param data Pointer to the buffer where to store the output data.
* @param dataByteLen The number of output bytes desired.
* @return Zero if successful, 1 otherwise.
*/
int Prefix_SpongeSqueeze(Prefix_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen);
#endif
#include <string.h>
#include "align.h"
#define KCP_DeclareSpongeStructure(prefix, size, alignment) \
ALIGN(alignment) 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);
#ifndef KeccakP200_excluded
#include "KeccakP-200-SnP.h"
KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment)
KCP_DeclareSpongeFunctions(KeccakWidth200)
#endif
#ifndef KeccakP400_excluded
#include "KeccakP-400-SnP.h"
KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment)
KCP_DeclareSpongeFunctions(KeccakWidth400)
#endif
#ifndef KeccakP800_excluded
#include "KeccakP-800-SnP.h"
KCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment)
KCP_DeclareSpongeFunctions(KeccakWidth800)
#endif
#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

View File

@ -0,0 +1,313 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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

View File

@ -0,0 +1,134 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 _SnP_Relaned_h_
#define _SnP_Relaned_h_
#define SnP_AddBytes(state, data, offset, length, SnP_AddLanes, SnP_AddBytesInLane, SnP_laneLengthInBytes) \
{ \
if ((offset) == 0) { \
SnP_AddLanes(state, data, (length)/SnP_laneLengthInBytes); \
SnP_AddBytesInLane(state, \
(length)/SnP_laneLengthInBytes, \
(data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
0, \
(length)%SnP_laneLengthInBytes); \
} \
else { \
unsigned int _sizeLeft = (length); \
unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
const unsigned char *_curData = (data); \
while(_sizeLeft > 0) { \
unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
if (_bytesInLane > _sizeLeft) \
_bytesInLane = _sizeLeft; \
SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
_sizeLeft -= _bytesInLane; \
_lanePosition++; \
_offsetInLane = 0; \
_curData += _bytesInLane; \
} \
} \
}
#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \
{ \
if ((offset) == 0) { \
SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \
SnP_OverwriteBytesInLane(state, \
(length)/SnP_laneLengthInBytes, \
(data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
0, \
(length)%SnP_laneLengthInBytes); \
} \
else { \
unsigned int _sizeLeft = (length); \
unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
const unsigned char *_curData = (data); \
while(_sizeLeft > 0) { \
unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
if (_bytesInLane > _sizeLeft) \
_bytesInLane = _sizeLeft; \
SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
_sizeLeft -= _bytesInLane; \
_lanePosition++; \
_offsetInLane = 0; \
_curData += _bytesInLane; \
} \
} \
}
#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \
{ \
if ((offset) == 0) { \
SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \
SnP_ExtractBytesInLane(state, \
(length)/SnP_laneLengthInBytes, \
(data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
0, \
(length)%SnP_laneLengthInBytes); \
} \
else { \
unsigned int _sizeLeft = (length); \
unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
unsigned char *_curData = (data); \
while(_sizeLeft > 0) { \
unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
if (_bytesInLane > _sizeLeft) \
_bytesInLane = _sizeLeft; \
SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
_sizeLeft -= _bytesInLane; \
_lanePosition++; \
_offsetInLane = 0; \
_curData += _bytesInLane; \
} \
} \
}
#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \
{ \
if ((offset) == 0) { \
SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \
SnP_ExtractAndAddBytesInLane(state, \
(length)/SnP_laneLengthInBytes, \
(input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
(output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
0, \
(length)%SnP_laneLengthInBytes); \
} \
else { \
unsigned int _sizeLeft = (length); \
unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
const unsigned char *_curInput = (input); \
unsigned char *_curOutput = (output); \
while(_sizeLeft > 0) { \
unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
if (_bytesInLane > _sizeLeft) \
_bytesInLane = _sizeLeft; \
SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \
_sizeLeft -= _bytesInLane; \
_lanePosition++; \
_offsetInLane = 0; \
_curInput += _bytesInLane; \
_curOutput += _bytesInLane; \
} \
} \
}
#endif

View File

@ -0,0 +1,34 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 _align_h_
#define _align_h_
/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */
#ifdef ALIGN
#undef ALIGN
#endif
#if defined(__GNUC__)
#define ALIGN(x) __attribute__ ((aligned(x)))
#elif defined(_MSC_VER)
#define ALIGN(x) __declspec(align(x))
#elif defined(__ARMCC_VERSION)
#define ALIGN(x) __align(x)
#else
#define ALIGN(x)
#endif
#endif

View File

@ -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 <sys/isa_defs.h>
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
# include <sys/endian.h>
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
# include <machine/endian.h>
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
# if !defined( __MINGW32__ ) && !defined( _AIX )
# include <endian.h>
# if !defined( __BEOS__ )
# include <byteswap.h>
# 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

View File

@ -0,0 +1,80 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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, DataLength 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 | ((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, DataLength databitlen)
{
if ((databitlen % 8) != 0)
return FAIL;
return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8);
}

View File

@ -0,0 +1,113 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 "KeccakSponge.h"
#include <string.h>
typedef unsigned char BitSequence;
typedef size_t DataLength;
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).
* @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, DataLength 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, DataLength databitlen);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 _KeccakP_1600_SnP_h_
#define _KeccakP_1600_SnP_h_
/** For the documentation, see SnP-documentation.h.
*/
#include "brg_endian.h"
#include "KeccakP-1600-opt64-config.h"
#define KeccakP1600_implementation "generic 64-bit optimized implementation (" KeccakP1600_implementation_config ")"
#define KeccakP1600_stateSizeInBytes 200
#define KeccakP1600_stateAlignment 8
#define KeccakF1600_FastLoop_supported
#include <stddef.h>
#define KeccakP1600_StaticInitialize()
void KeccakP1600_Initialize(void *state);
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
#define KeccakP1600_AddByte(state, byte, offset) \
((unsigned char*)(state))[(offset)] ^= (byte)
#else
void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset);
#endif
void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount);
void KeccakP1600_Permute_Nrounds(void *state, unsigned int nrounds);
void KeccakP1600_Permute_12rounds(void *state);
void KeccakP1600_Permute_24rounds(void *state);
void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length);
size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen);
#endif

View File

@ -0,0 +1,3 @@
#define KeccakP1600_implementation_config "lane complementing, all rounds unrolled"
#define KeccakP1600_fullUnrolling
#define KeccakP1600_useLaneComplementing

View File

@ -0,0 +1,484 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 <stdlib.h>
#include "brg_endian.h"
#include "KeccakP-1600-opt64-config.h"
typedef unsigned char UINT8;
typedef unsigned long long int UINT64;
#if defined(KeccakP1600_useLaneComplementing)
#define UseBebigokimisa
#endif
#if defined(_MSC_VER)
#define ROL64(a, offset) _rotl64(a, offset)
#elif defined(KeccakP1600_useSHLD)
#define ROL64(x,N) ({ \
register UINT64 __out; \
register UINT64 __in = x; \
__asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \
__out; \
})
#else
#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset)))
#endif
#include "KeccakP-1600-64.macros"
#ifdef KeccakP1600_fullUnrolling
#define FullUnrolling
#else
#define Unrolling KeccakP1600_unrolling
#endif
#include "KeccakP-1600-unrolling.macros"
#include "SnP-Relaned.h"
static const UINT64 KeccakF1600RoundConstants[24] = {
0x0000000000000001ULL,
0x0000000000008082ULL,
0x800000000000808aULL,
0x8000000080008000ULL,
0x000000000000808bULL,
0x0000000080000001ULL,
0x8000000080008081ULL,
0x8000000000008009ULL,
0x000000000000008aULL,
0x0000000000000088ULL,
0x0000000080008009ULL,
0x000000008000000aULL,
0x000000008000808bULL,
0x800000000000008bULL,
0x8000000000008089ULL,
0x8000000000008003ULL,
0x8000000000008002ULL,
0x8000000000000080ULL,
0x000000000000800aULL,
0x800000008000000aULL,
0x8000000080008081ULL,
0x8000000000008080ULL,
0x0000000080000001ULL,
0x8000000080008008ULL };
/* ---------------------------------------------------------------- */
void KeccakP1600_Initialize(void *state)
{
memset(state, 0, 200);
#ifdef KeccakP1600_useLaneComplementing
((UINT64*)state)[ 1] = ~(UINT64)0;
((UINT64*)state)[ 2] = ~(UINT64)0;
((UINT64*)state)[ 8] = ~(UINT64)0;
((UINT64*)state)[12] = ~(UINT64)0;
((UINT64*)state)[17] = ~(UINT64)0;
((UINT64*)state)[20] = ~(UINT64)0;
#endif
}
/* ---------------------------------------------------------------- */
void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length)
{
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
UINT64 lane;
if (length == 0)
return;
if (length == 1)
lane = data[0];
else {
lane = 0;
memcpy(&lane, data, length);
}
lane <<= offset*8;
#else
UINT64 lane = 0;
unsigned int i;
for(i=0; i<length; i++)
lane |= ((UINT64)data[i]) << ((i+offset)*8);
#endif
((UINT64*)state)[lanePosition] ^= lane;
}
/* ---------------------------------------------------------------- */
void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount)
{
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
unsigned int i = 0;
#ifdef NO_MISALIGNED_ACCESSES
/* If either pointer is misaligned, fall back to byte-wise xor. */
if (((((uintptr_t)state) & 7) != 0) || ((((uintptr_t)data) & 7) != 0)) {
for (i = 0; i < laneCount * 8; i++) {
((unsigned char*)state)[i] ^= data[i];
}
}
else
#endif
{
/* Otherwise... */
for( ; (i+8)<=laneCount; i+=8) {
((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0];
((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1];
((UINT64*)state)[i+2] ^= ((UINT64*)data)[i+2];
((UINT64*)state)[i+3] ^= ((UINT64*)data)[i+3];
((UINT64*)state)[i+4] ^= ((UINT64*)data)[i+4];
((UINT64*)state)[i+5] ^= ((UINT64*)data)[i+5];
((UINT64*)state)[i+6] ^= ((UINT64*)data)[i+6];
((UINT64*)state)[i+7] ^= ((UINT64*)data)[i+7];
}
for( ; (i+4)<=laneCount; i+=4) {
((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0];
((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1];
((UINT64*)state)[i+2] ^= ((UINT64*)data)[i+2];
((UINT64*)state)[i+3] ^= ((UINT64*)data)[i+3];
}
for( ; (i+2)<=laneCount; i+=2) {
((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0];
((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1];
}
if (i<laneCount) {
((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0];
}
}
#else
unsigned int i;
UINT8 *curData = data;
for(i=0; i<laneCount; i++, curData+=8) {
UINT64 lane = (UINT64)curData[0]
| ((UINT64)curData[1] << 8)
| ((UINT64)curData[2] << 16)
| ((UINT64)curData[3] << 24)
| ((UINT64)curData[4] <<32)
| ((UINT64)curData[5] << 40)
| ((UINT64)curData[6] << 48)
| ((UINT64)curData[7] << 56);
((UINT64*)state)[i] ^= lane;
}
#endif
}
/* ---------------------------------------------------------------- */
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset)
{
UINT64 lane = byte;
lane <<= (offset%8)*8;
((UINT64*)state)[offset/8] ^= lane;
}
#endif
/* ---------------------------------------------------------------- */
void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
{
SnP_AddBytes(state, data, offset, length, KeccakP1600_AddLanes, KeccakP1600_AddBytesInLane, 8);
}
/* ---------------------------------------------------------------- */
void KeccakP1600_OverwriteBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length)
{
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
#ifdef KeccakP1600_useLaneComplementing
if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) {
unsigned int i;
for(i=0; i<length; i++)
((unsigned char*)state)[lanePosition*8+offset+i] = ~data[i];
}
else
#endif
{
memcpy((unsigned char*)state+lanePosition*8+offset, data, length);
}
#else
#error "Not yet implemented"
#endif
}
/* ---------------------------------------------------------------- */
void KeccakP1600_OverwriteLanes(void *state, const unsigned char *data, unsigned int laneCount)
{
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
#ifdef KeccakP1600_useLaneComplementing
unsigned int lanePosition;
for(lanePosition=0; lanePosition<laneCount; lanePosition++)
if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
((UINT64*)state)[lanePosition] = ~((const UINT64*)data)[lanePosition];
else
((UINT64*)state)[lanePosition] = ((const UINT64*)data)[lanePosition];
#else
memcpy(state, data, laneCount*8);
#endif
#else
#error "Not yet implemented"
#endif
}
/* ---------------------------------------------------------------- */
void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
{
SnP_OverwriteBytes(state, data, offset, length, KeccakP1600_OverwriteLanes, KeccakP1600_OverwriteBytesInLane, 8);
}
/* ---------------------------------------------------------------- */
void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount)
{
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
#ifdef KeccakP1600_useLaneComplementing
unsigned int lanePosition;
for(lanePosition=0; lanePosition<byteCount/8; lanePosition++)
if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
((UINT64*)state)[lanePosition] = ~0;
else
((UINT64*)state)[lanePosition] = 0;
if (byteCount%8 != 0) {
lanePosition = byteCount/8;
if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
memset((unsigned char*)state+lanePosition*8, 0xFF, byteCount%8);
else
memset((unsigned char*)state+lanePosition*8, 0, byteCount%8);
}
#else
memset(state, 0, byteCount);
#endif
#else
#error "Not yet implemented"
#endif
}
/* ---------------------------------------------------------------- */
void KeccakP1600_Permute_Nrounds(void *state, unsigned int nr)
{
declareABCDE
unsigned int i;
UINT64 *stateAsLanes = (UINT64*)state;
copyFromState(A, stateAsLanes)
roundsN(nr)
copyToState(stateAsLanes, A)
}
/* ---------------------------------------------------------------- */
void KeccakP1600_Permute_24rounds(void *state)
{
declareABCDE
#ifndef KeccakP1600_fullUnrolling
unsigned int i;
#endif
UINT64 *stateAsLanes = (UINT64*)state;
copyFromState(A, stateAsLanes)
rounds24
copyToState(stateAsLanes, A)
}
/* ---------------------------------------------------------------- */
void KeccakP1600_Permute_12rounds(void *state)
{
declareABCDE
#ifndef KeccakP1600_fullUnrolling
unsigned int i;
#endif
UINT64 *stateAsLanes = (UINT64*)state;
copyFromState(A, stateAsLanes)
rounds12
copyToState(stateAsLanes, A)
}
/* ---------------------------------------------------------------- */
void KeccakP1600_ExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length)
{
UINT64 lane = ((UINT64*)state)[lanePosition];
#ifdef KeccakP1600_useLaneComplementing
if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
lane = ~lane;
#endif
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
{
UINT64 lane1[1];
lane1[0] = lane;
memcpy(data, (UINT8*)lane1+offset, length);
}
#else
unsigned int i;
lane >>= offset*8;
for(i=0; i<length; i++) {
data[i] = lane & 0xFF;
lane >>= 8;
}
#endif
}
/* ---------------------------------------------------------------- */
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
void fromWordToBytes(UINT8 *bytes, const UINT64 word)
{
unsigned int i;
for(i=0; i<(64/8); i++)
bytes[i] = (word >> (8*i)) & 0xFF;
}
#endif
void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount)
{
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
memcpy(data, state, laneCount*8);
#else
unsigned int i;
for(i=0; i<laneCount; i++)
fromWordToBytes(data+(i*8), ((const UINT64*)state)[i]);
#endif
#ifdef KeccakP1600_useLaneComplementing
if (laneCount > 1) {
((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1];
if (laneCount > 2) {
((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2];
if (laneCount > 8) {
((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8];
if (laneCount > 12) {
((UINT64*)data)[12] = ~((UINT64*)data)[12];
if (laneCount > 17) {
((UINT64*)data)[17] = ~((UINT64*)data)[17];
if (laneCount > 20) {
((UINT64*)data)[20] = ~((UINT64*)data)[20];
}
}
}
}
}
}
#endif
}
/* ---------------------------------------------------------------- */
void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
{
SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8);
}
/* ---------------------------------------------------------------- */
void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
{
UINT64 lane = ((UINT64*)state)[lanePosition];
#ifdef KeccakP1600_useLaneComplementing
if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20))
lane = ~lane;
#endif
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
{
unsigned int i;
UINT64 lane1[1];
lane1[0] = lane;
for(i=0; i<length; i++)
output[i] = input[i] ^ ((UINT8*)lane1)[offset+i];
}
#else
unsigned int i;
lane >>= offset*8;
for(i=0; i<length; i++) {
output[i] = input[i] ^ (lane & 0xFF);
lane >>= 8;
}
#endif
}
/* ---------------------------------------------------------------- */
void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount)
{
unsigned int i;
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
unsigned char temp[8];
unsigned int j;
#endif
for(i=0; i<laneCount; i++) {
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
((UINT64*)output)[i] = ((UINT64*)input)[i] ^ ((const UINT64*)state)[i];
#else
fromWordToBytes(temp, ((const UINT64*)state)[i]);
for(j=0; j<8; j++)
output[i*8+j] = input[i*8+j] ^ temp[j];
#endif
}
#ifdef KeccakP1600_useLaneComplementing
if (laneCount > 1) {
((UINT64*)output)[ 1] = ~((UINT64*)output)[ 1];
if (laneCount > 2) {
((UINT64*)output)[ 2] = ~((UINT64*)output)[ 2];
if (laneCount > 8) {
((UINT64*)output)[ 8] = ~((UINT64*)output)[ 8];
if (laneCount > 12) {
((UINT64*)output)[12] = ~((UINT64*)output)[12];
if (laneCount > 17) {
((UINT64*)output)[17] = ~((UINT64*)output)[17];
if (laneCount > 20) {
((UINT64*)output)[20] = ~((UINT64*)output)[20];
}
}
}
}
}
}
#endif
}
/* ---------------------------------------------------------------- */
void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
{
SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8);
}
/* ---------------------------------------------------------------- */
size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen)
{
size_t originalDataByteLen = dataByteLen;
declareABCDE
#ifndef KeccakP1600_fullUnrolling
unsigned int i;
#endif
UINT64 *stateAsLanes = (UINT64*)state;
UINT64 *inDataAsLanes = (UINT64*)data;
copyFromState(A, stateAsLanes)
while(dataByteLen >= laneCount*8) {
addInput(A, inDataAsLanes, laneCount)
rounds24
inDataAsLanes += laneCount;
dataByteLen -= laneCount*8;
}
copyToState(stateAsLanes, A)
return originalDataByteLen - dataByteLen;
}

View File

@ -0,0 +1,198 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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/
*/
#if (defined(FullUnrolling))
#define rounds24 \
prepareTheta \
thetaRhoPiChiIotaPrepareTheta( 0, A, E) \
thetaRhoPiChiIotaPrepareTheta( 1, E, A) \
thetaRhoPiChiIotaPrepareTheta( 2, A, E) \
thetaRhoPiChiIotaPrepareTheta( 3, E, A) \
thetaRhoPiChiIotaPrepareTheta( 4, A, E) \
thetaRhoPiChiIotaPrepareTheta( 5, E, A) \
thetaRhoPiChiIotaPrepareTheta( 6, A, E) \
thetaRhoPiChiIotaPrepareTheta( 7, E, A) \
thetaRhoPiChiIotaPrepareTheta( 8, A, E) \
thetaRhoPiChiIotaPrepareTheta( 9, E, A) \
thetaRhoPiChiIotaPrepareTheta(10, A, E) \
thetaRhoPiChiIotaPrepareTheta(11, E, A) \
thetaRhoPiChiIotaPrepareTheta(12, A, E) \
thetaRhoPiChiIotaPrepareTheta(13, E, A) \
thetaRhoPiChiIotaPrepareTheta(14, A, E) \
thetaRhoPiChiIotaPrepareTheta(15, E, A) \
thetaRhoPiChiIotaPrepareTheta(16, A, E) \
thetaRhoPiChiIotaPrepareTheta(17, E, A) \
thetaRhoPiChiIotaPrepareTheta(18, A, E) \
thetaRhoPiChiIotaPrepareTheta(19, E, A) \
thetaRhoPiChiIotaPrepareTheta(20, A, E) \
thetaRhoPiChiIotaPrepareTheta(21, E, A) \
thetaRhoPiChiIotaPrepareTheta(22, A, E) \
thetaRhoPiChiIota(23, E, A) \
#define rounds12 \
prepareTheta \
thetaRhoPiChiIotaPrepareTheta(12, A, E) \
thetaRhoPiChiIotaPrepareTheta(13, E, A) \
thetaRhoPiChiIotaPrepareTheta(14, A, E) \
thetaRhoPiChiIotaPrepareTheta(15, E, A) \
thetaRhoPiChiIotaPrepareTheta(16, A, E) \
thetaRhoPiChiIotaPrepareTheta(17, E, A) \
thetaRhoPiChiIotaPrepareTheta(18, A, E) \
thetaRhoPiChiIotaPrepareTheta(19, E, A) \
thetaRhoPiChiIotaPrepareTheta(20, A, E) \
thetaRhoPiChiIotaPrepareTheta(21, E, A) \
thetaRhoPiChiIotaPrepareTheta(22, A, E) \
thetaRhoPiChiIota(23, E, A) \
#elif (Unrolling == 12)
#define rounds24 \
prepareTheta \
for(i=0; i<24; i+=12) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \
} \
#define rounds12 \
prepareTheta \
thetaRhoPiChiIotaPrepareTheta(12, A, E) \
thetaRhoPiChiIotaPrepareTheta(13, E, A) \
thetaRhoPiChiIotaPrepareTheta(14, A, E) \
thetaRhoPiChiIotaPrepareTheta(15, E, A) \
thetaRhoPiChiIotaPrepareTheta(16, A, E) \
thetaRhoPiChiIotaPrepareTheta(17, E, A) \
thetaRhoPiChiIotaPrepareTheta(18, A, E) \
thetaRhoPiChiIotaPrepareTheta(19, E, A) \
thetaRhoPiChiIotaPrepareTheta(20, A, E) \
thetaRhoPiChiIotaPrepareTheta(21, E, A) \
thetaRhoPiChiIotaPrepareTheta(22, A, E) \
thetaRhoPiChiIota(23, E, A) \
#elif (Unrolling == 6)
#define rounds24 \
prepareTheta \
for(i=0; i<24; i+=6) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \
} \
#define rounds12 \
prepareTheta \
for(i=12; i<24; i+=6) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \
} \
#elif (Unrolling == 4)
#define rounds24 \
prepareTheta \
for(i=0; i<24; i+=4) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \
} \
#define rounds12 \
prepareTheta \
for(i=12; i<24; i+=4) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \
} \
#elif (Unrolling == 3)
#define rounds24 \
prepareTheta \
for(i=0; i<24; i+=3) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
copyStateVariables(A, E) \
} \
#define rounds12 \
prepareTheta \
for(i=12; i<24; i+=3) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \
copyStateVariables(A, E) \
} \
#elif (Unrolling == 2)
#define rounds24 \
prepareTheta \
for(i=0; i<24; i+=2) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
} \
#define rounds12 \
prepareTheta \
for(i=12; i<24; i+=2) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
} \
#elif (Unrolling == 1)
#define rounds24 \
prepareTheta \
for(i=0; i<24; i++) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
copyStateVariables(A, E) \
} \
#define rounds12 \
prepareTheta \
for(i=12; i<24; i++) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
copyStateVariables(A, E) \
} \
#else
#error "Unrolling is not correctly specified!"
#endif
#define roundsN(__nrounds) \
prepareTheta \
i = 24 - (__nrounds); \
if ((i&1) != 0) { \
thetaRhoPiChiIotaPrepareTheta(i, A, E) \
copyStateVariables(A, E) \
++i; \
} \
for( /* empty */; i<24; i+=2) { \
thetaRhoPiChiIotaPrepareTheta(i , A, E) \
thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \
}

View File

@ -0,0 +1,110 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 "KeccakSponge.h"
#ifdef KeccakReference
#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
#if defined(KeccakF200_FastLoop_supported)
#define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb
#endif
#include "KeccakSponge.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#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
#if defined(KeccakF400_FastLoop_supported)
#define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb
#endif
#include "KeccakSponge.inc"
#undef prefix
#undef SnP
#undef SnP_width
#undef SnP_Permute
#undef SnP_FastLoop_Absorb
#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
#if defined(KeccakF800_FastLoop_supported)
#define SnP_FastLoop_Absorb KeccakF800_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
#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

View File

@ -0,0 +1,178 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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_
/** General information
*
* The following type and functions are not actually implemented. Their
* documentation is generic, with the prefix Prefix replaced by
* - KeccakWidth200 for a sponge function based on Keccak-f[200]
* - KeccakWidth400 for a sponge function based on Keccak-f[400]
* - KeccakWidth800 for a sponge function based on Keccak-f[800]
* - KeccakWidth1600 for a sponge function based on Keccak-f[1600]
*
* In all these functions, the rate and capacity must sum to the width of the
* chosen permutation. For instance, to use the sponge function
* Keccak[r=1344, c=256], one must use KeccakWidth1600_Sponge() or a combination
* of KeccakWidth1600_SpongeInitialize(), KeccakWidth1600_SpongeAbsorb(),
* KeccakWidth1600_SpongeAbsorbLastFewBits() and
* KeccakWidth1600_SpongeSqueeze().
*
* The Prefix_SpongeInstance contains the sponge instance attributes for use
* with the Prefix_Sponge* functions.
* It gathers the state processed by the permutation as well as the rate,
* the position of input/output bytes in the state and the phase
* (absorbing or squeezing).
*/
#ifdef DontReallyInclude_DocumentationOnly
/** Function to evaluate the sponge function Keccak[r, c] in a single call.
* @param rate The value of the rate r.
* @param capacity The value of the capacity c.
* @param input Pointer to the input message (before the suffix).
* @param inputByteLen The length of the input message in bytes.
* @param suffix Byte containing from 0 to 7 suffix bits
* that must be absorbed after @a input.
* These <i>n</i> bits must be in the least significant bit positions.
* These bits must be delimited with a bit 1 at position <i>n</i>
* (counting from 0=LSB to 7=MSB) and followed by bits 0
* from position <i>n</i>+1 to position 7.
* Some examples:
* - If no bits are to be absorbed, then @a suffix must be 0x01.
* - If the 2-bit sequence 0,0 is to be absorbed, @a suffix must be 0x04.
* - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a suffix must be 0x32.
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a suffix must be 0x8B.
* .
* @param output Pointer to the output buffer.
* @param outputByteLen The desired number of output bytes.
* @pre One must have r+c equal to the supported width of this implementation
* and the rate a multiple of 8 bits (one byte) in this implementation.
* @pre @a suffix 0x00
* @return Zero if successful, 1 otherwise.
*/
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);
/**
* Function to initialize the state of the Keccak[r, c] sponge function.
* The phase of the sponge function is set to absorbing.
* @param spongeInstance Pointer to the sponge instance 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 equal to the supported width of this implementation
* and the rate a multiple of 8 bits (one byte) in this implementation.
* @return Zero if successful, 1 otherwise.
*/
int Prefix_SpongeInitialize(Prefix_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity);
/**
* Function to give input data bytes for the sponge function to absorb.
* @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
* @param data Pointer to the input data.
* @param dataByteLen The number of input bytes provided in the input data.
* @pre The sponge function must be in the absorbing phase,
* i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits()
* must not have been called before.
* @return Zero if successful, 1 otherwise.
*/
int Prefix_SpongeAbsorb(Prefix_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen);
/**
* Function to give input data bits for the sponge function to absorb
* and then to switch to the squeezing phase.
* @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
* @param delimitedData Byte containing from 0 to 7 trailing bits
* that must be absorbed.
* These <i>n</i> bits must be in the least significant bit positions.
* These bits must be delimited with a bit 1 at position <i>n</i>
* (counting from 0=LSB to 7=MSB) and followed by bits 0
* from position <i>n</i>+1 to position 7.
* Some examples:
* - If no bits are to be absorbed, then @a delimitedData must be 0x01.
* - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04.
* - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32.
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B.
* .
* @pre The sponge function must be in the absorbing phase,
* i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits()
* must not have been called before.
* @pre @a delimitedData 0x00
* @return Zero if successful, 1 otherwise.
*/
int Prefix_SpongeAbsorbLastFewBits(Prefix_SpongeInstance *spongeInstance, unsigned char delimitedData);
/**
* 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
* as if Prefix_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called.
* @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize().
* @param data Pointer to the buffer where to store the output data.
* @param dataByteLen The number of output bytes desired.
* @return Zero if successful, 1 otherwise.
*/
int Prefix_SpongeSqueeze(Prefix_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen);
#endif
#include <string.h>
#include "align.h"
#define KCP_DeclareSpongeStructure(prefix, size, alignment) \
ALIGN(alignment) 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);
#ifndef KeccakP200_excluded
#include "KeccakP-200-SnP.h"
KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment)
KCP_DeclareSpongeFunctions(KeccakWidth200)
#endif
#ifndef KeccakP400_excluded
#include "KeccakP-400-SnP.h"
KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment)
KCP_DeclareSpongeFunctions(KeccakWidth400)
#endif
#ifndef KeccakP800_excluded
#include "KeccakP-800-SnP.h"
KCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment)
KCP_DeclareSpongeFunctions(KeccakWidth800)
#endif
#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

View File

@ -0,0 +1,313 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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

View File

@ -0,0 +1,134 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 _SnP_Relaned_h_
#define _SnP_Relaned_h_
#define SnP_AddBytes(state, data, offset, length, SnP_AddLanes, SnP_AddBytesInLane, SnP_laneLengthInBytes) \
{ \
if ((offset) == 0) { \
SnP_AddLanes(state, data, (length)/SnP_laneLengthInBytes); \
SnP_AddBytesInLane(state, \
(length)/SnP_laneLengthInBytes, \
(data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
0, \
(length)%SnP_laneLengthInBytes); \
} \
else { \
unsigned int _sizeLeft = (length); \
unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
const unsigned char *_curData = (data); \
while(_sizeLeft > 0) { \
unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
if (_bytesInLane > _sizeLeft) \
_bytesInLane = _sizeLeft; \
SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
_sizeLeft -= _bytesInLane; \
_lanePosition++; \
_offsetInLane = 0; \
_curData += _bytesInLane; \
} \
} \
}
#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \
{ \
if ((offset) == 0) { \
SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \
SnP_OverwriteBytesInLane(state, \
(length)/SnP_laneLengthInBytes, \
(data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
0, \
(length)%SnP_laneLengthInBytes); \
} \
else { \
unsigned int _sizeLeft = (length); \
unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
const unsigned char *_curData = (data); \
while(_sizeLeft > 0) { \
unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
if (_bytesInLane > _sizeLeft) \
_bytesInLane = _sizeLeft; \
SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
_sizeLeft -= _bytesInLane; \
_lanePosition++; \
_offsetInLane = 0; \
_curData += _bytesInLane; \
} \
} \
}
#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \
{ \
if ((offset) == 0) { \
SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \
SnP_ExtractBytesInLane(state, \
(length)/SnP_laneLengthInBytes, \
(data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
0, \
(length)%SnP_laneLengthInBytes); \
} \
else { \
unsigned int _sizeLeft = (length); \
unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
unsigned char *_curData = (data); \
while(_sizeLeft > 0) { \
unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
if (_bytesInLane > _sizeLeft) \
_bytesInLane = _sizeLeft; \
SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \
_sizeLeft -= _bytesInLane; \
_lanePosition++; \
_offsetInLane = 0; \
_curData += _bytesInLane; \
} \
} \
}
#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \
{ \
if ((offset) == 0) { \
SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \
SnP_ExtractAndAddBytesInLane(state, \
(length)/SnP_laneLengthInBytes, \
(input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
(output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \
0, \
(length)%SnP_laneLengthInBytes); \
} \
else { \
unsigned int _sizeLeft = (length); \
unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \
unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \
const unsigned char *_curInput = (input); \
unsigned char *_curOutput = (output); \
while(_sizeLeft > 0) { \
unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \
if (_bytesInLane > _sizeLeft) \
_bytesInLane = _sizeLeft; \
SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \
_sizeLeft -= _bytesInLane; \
_lanePosition++; \
_offsetInLane = 0; \
_curInput += _bytesInLane; \
_curOutput += _bytesInLane; \
} \
} \
}
#endif

View File

@ -0,0 +1,34 @@
/*
Implementation by the Keccak, Keyak and Ketje Teams, 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 websites:
http://keccak.noekeon.org/
http://keyak.noekeon.org/
http://ketje.noekeon.org/
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 _align_h_
#define _align_h_
/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */
#ifdef ALIGN
#undef ALIGN
#endif
#if defined(__GNUC__)
#define ALIGN(x) __attribute__ ((aligned(x)))
#elif defined(_MSC_VER)
#define ALIGN(x) __declspec(align(x))
#elif defined(__ARMCC_VERSION)
#define ALIGN(x) __align(x)
#else
#define ALIGN(x)
#endif
#endif

View File

@ -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 <sys/isa_defs.h>
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
# include <sys/endian.h>
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
# include <machine/endian.h>
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
# if !defined( __MINGW32__ ) && !defined( _AIX )
# include <endian.h>
# if !defined( __BEOS__ )
# include <byteswap.h>
# 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