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;
}
Beispiel #2
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);
}