summaryrefslogtreecommitdiff
path: root/Modules/_sha3/kcp/KeccakSponge.inc
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_sha3/kcp/KeccakSponge.inc')
-rw-r--r--Modules/_sha3/kcp/KeccakSponge.inc332
1 files changed, 332 insertions, 0 deletions
diff --git a/Modules/_sha3/kcp/KeccakSponge.inc b/Modules/_sha3/kcp/KeccakSponge.inc
new file mode 100644
index 0000000000..e10739deaf
--- /dev/null
+++ b/Modules/_sha3/kcp/KeccakSponge.inc
@@ -0,0 +1,332 @@
+/*
+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