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 KeccakF1600_StateXORPermuteExtract(void *state, const unsigned char *inData, unsigned int inLaneCount, unsigned char *outData, unsigned int outLaneCount) { KeccakF1600_StateXORLanes(state, inData, inLaneCount); KeccakF1600_StatePermute(state); KeccakF1600_StateExtractLanes(state, outData, outLaneCount); }