HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval) { HashReturn ret = Keccak_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix); if (ret == SUCCESS) return Keccak_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8); else return ret; }
void displaySpongeIntermediateValuesOne(const unsigned char *message, unsigned int messageLength, unsigned int rate, unsigned int capacity) { Keccak_SpongeInstance sponge; unsigned char output[512]; unsigned char *messageInternal; messageInternal = malloc((messageLength+7)/8); alignLastByteOnLSB(message, messageInternal, messageLength); displayBytes(1, "Input message (last byte aligned on MSB)", message, (messageLength+7)/8); displayBits(2, "Input message (in bits)", message, messageLength, 1); displayBits(2, "Input message (in bits, after the formal bit reordering)", messageInternal, messageLength, 0); displayBytes(2, "Input message (last byte aligned on LSB)", messageInternal, (messageLength+7)/8); Keccak_SpongeInitialize(&sponge, rate, capacity); displayStateAsBytes(1, "Initial state", sponge.state); Keccak_SpongeAbsorb(&sponge, messageInternal, messageLength/8); if ((messageLength % 8) != 0) Keccak_SpongeAbsorbLastFewBits(&sponge, messageInternal[messageLength/8] | (1 << (messageLength % 8))); Keccak_SpongeSqueeze(&sponge, output, sizeof(output)); free(messageInternal); }
int Keccak_SpongeSqueeze(Keccak_SpongeInstance *instance, unsigned char *data, unsigned long long dataByteLen) { unsigned long long i, j; unsigned int partialBlock; unsigned int rateInBytes = instance->rate/8; unsigned char *curData; if (!instance->squeezing) Keccak_SpongeAbsorbLastFewBits(instance, 0x01); i = 0; curData = data; while(i < dataByteLen) { if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { // fast lane: processing whole blocks first for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { KeccakF1600_StateXORPermuteExtract(instance->state, 0, 0, curData, rateInBytes/KeccakF_laneInBytes); if ((rateInBytes % KeccakF_laneInBytes) > 0) KeccakF1600_StateExtractBytesInLane(instance->state, rateInBytes/KeccakF_laneInBytes, curData+(rateInBytes/KeccakF_laneInBytes)*KeccakF_laneInBytes, 0, rateInBytes%KeccakF_laneInBytes); #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) { KeccakF1600_StatePermute(instance->state); instance->byteIOIndex = 0; } partialBlock = (unsigned int)(dataByteLen - i); if (partialBlock+instance->byteIOIndex > rateInBytes) partialBlock = rateInBytes-instance->byteIOIndex; i += partialBlock; if ((instance->byteIOIndex == 0) && (partialBlock >= KeccakF_laneInBytes)) { KeccakF1600_StateExtractLanes(instance->state, curData, partialBlock/KeccakF_laneInBytes); #ifdef KeccakReference displayBytes(1, "Squeezed block (part)", curData, (partialBlock/KeccakF_laneInBytes)*KeccakF_laneInBytes); #endif curData += (partialBlock/KeccakF_laneInBytes)*KeccakF_laneInBytes; instance->byteIOIndex += (partialBlock/KeccakF_laneInBytes)*KeccakF_laneInBytes; partialBlock -= (partialBlock/KeccakF_laneInBytes)*KeccakF_laneInBytes; } while(partialBlock > 0) { unsigned int offsetInLane = instance->byteIOIndex % KeccakF_laneInBytes; unsigned int bytesInLane = KeccakF_laneInBytes-offsetInLane; if (bytesInLane > partialBlock) bytesInLane = partialBlock; KeccakF1600_StateExtractBytesInLane(instance->state, instance->byteIOIndex/KeccakF_laneInBytes, curData, offsetInLane, bytesInLane); #ifdef KeccakReference displayBytes(1, "Squeezed block (part)", curData, bytesInLane); #endif curData += bytesInLane; instance->byteIOIndex += bytesInLane; partialBlock -= bytesInLane; } } } return 0; }
void testSponge(FILE *f, unsigned int rate, unsigned int capacity, int usingQueue) { #define inputByteSize 512 #define outputByteSize 512 unsigned char input[inputByteSize]; unsigned char output[outputByteSize]; unsigned char acc[outputByteSize]; unsigned int inputBitLength, offset, size; int result; Keccak_SpongeInstance sponge; // Acumulated test vector memset(acc, 0x00, sizeof(acc)); for(inputBitLength = 0; inputBitLength <= (inputByteSize*8); inputBitLength += (inputBitLength < 1600) ? 1 : 8) { unsigned int i; unsigned int inputByteLengthCeiling = (inputBitLength + 7) / 8; for(i=0; i<inputByteLengthCeiling; i++) input[i] = inputBitLength - i; if ((inputBitLength % 8) != 0) input[inputByteLengthCeiling-1] &= (1 << (inputBitLength % 8)) - 1; result = Keccak_SpongeInitialize(&sponge, rate, capacity); if (usingQueue) { for(offset = 0; offset < inputBitLength/8; offset += size) { unsigned int p = (inputBitLength/8)%11; // vary sizes if (p < 1) size = 1; // byte per byte else if (p < 5) size = (rand() % 20); // small random else if (p < 9) size = (rand() % 200); // big random else size = ((rand() % (inputBitLength/8 - offset)) + 1); // converging random if (size > (inputBitLength/8 - offset)) size = inputBitLength/8 - offset; result = Keccak_SpongeAbsorb(&sponge, input + offset, size); } } else result = Keccak_SpongeAbsorb(&sponge, input, inputBitLength/8); if ((inputBitLength % 8) != 0) result = Keccak_SpongeAbsorbLastFewBits(&sponge, input[inputByteLengthCeiling-1] | (1 << (inputBitLength % 8))); if (usingQueue) { unsigned char filler = 0xAA + inputBitLength; memset(output, filler, sizeof(output)); for(offset = 0; offset < outputByteSize; offset += size) { unsigned int p = (inputBitLength/8)%11; // vary sizes if (p < 1) size = 1; // byte per byte else if (p < 5) size = (rand() % 20); // small random else if (p < 9) size = (rand() % 200); // big random else size = ((rand() % (outputByteSize - offset)) + 1); // converging random if (size > (outputByteSize - offset)) size = outputByteSize - offset; result = Keccak_SpongeSqueeze(&sponge, output + offset, size); for(i = offset + size; i<sizeof(output); i++) if (output[i] != filler) { printf("Out of range data written!\n"); abort(); } } } else result = Keccak_SpongeSqueeze(&sponge, output, outputByteSize); for (i = 0; i < outputByteSize; i++) acc[i] ^= output[i]; } fprintf(f, "Keccak[r=%d, c=%d]: ", rate, capacity); for(offset=0; offset<outputByteSize; offset++) fprintf(f, "%02x ", acc[offset]); fprintf(f, "\n\n"); #undef inputByteSize #undef outputByteSize }