static void PadAndSwitchToSqueezingPhase(spongeState *state) { // Note: the bits are numbered from 0=LSB to 7=MSB if (state->bitsInQueue + 1 == state->rate) { state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8); AbsorbQueue(state); memset(state->dataQueue, 0, state->rate/8); } else { memset(state->dataQueue + (state->bitsInQueue+7)/8, 0, state->rate/8 - (state->bitsInQueue+7)/8); state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8); } state->dataQueue[(state->rate-1)/8] |= 1 << ((state->rate-1) % 8); AbsorbQueue(state); #ifdef KeccakReference displayText(1, "--- Switching to squeezing phase ---"); #endif #ifdef ProvideFast1024 if (state->rate == 1024) { KeccakExtract1024bits(state->state, state->dataQueue); state->bitsAvailableForSqueezing = 1024; } else #endif { KeccakExtract(state->state, state->dataQueue, state->rate/64); state->bitsAvailableForSqueezing = state->rate; } #ifdef KeccakReference displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8); #endif state->squeezing = 1; }
static int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen) { unsigned long long i, j, wholeBlocks; unsigned int partialBlock, partialByte; const unsigned char *curData; if ((state->bitsInQueue % 8) != 0) return 1; // Only the last call may contain a partial byte if (state->squeezing) return 1; // Too late for additional input i = 0; while(i < databitlen) { if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) { wholeBlocks = (databitlen-i)/state->rate; curData = data+i/8; #ifdef ProvideFast576 if (state->rate == 576) { for(j=0; j<wholeBlocks; j++, curData+=576/8) { #ifdef KeccakReference displayBytes(1, "Block to be absorbed", curData, state->rate/8); #endif KeccakAbsorb576bits(state->state, curData); } } else #endif #ifdef ProvideFast832 if (state->rate == 832) { for(j=0; j<wholeBlocks; j++, curData+=832/8) { #ifdef KeccakReference displayBytes(1, "Block to be absorbed", curData, state->rate/8); #endif KeccakAbsorb832bits(state->state, curData); } } else #endif #ifdef ProvideFast1024 if (state->rate == 1024) { for(j=0; j<wholeBlocks; j++, curData+=1024/8) { #ifdef KeccakReference displayBytes(1, "Block to be absorbed", curData, state->rate/8); #endif KeccakAbsorb1024bits(state->state, curData); } } else #endif #ifdef ProvideFast1088 if (state->rate == 1088) { for(j=0; j<wholeBlocks; j++, curData+=1088/8) { #ifdef KeccakReference displayBytes(1, "Block to be absorbed", curData, state->rate/8); #endif KeccakAbsorb1088bits(state->state, curData); } } else #endif #ifdef ProvideFast1152 if (state->rate == 1152) { for(j=0; j<wholeBlocks; j++, curData+=1152/8) { #ifdef KeccakReference displayBytes(1, "Block to be absorbed", curData, state->rate/8); #endif KeccakAbsorb1152bits(state->state, curData); } } else #endif #ifdef ProvideFast1344 if (state->rate == 1344) { for(j=0; j<wholeBlocks; j++, curData+=1344/8) { #ifdef KeccakReference displayBytes(1, "Block to be absorbed", curData, state->rate/8); #endif KeccakAbsorb1344bits(state->state, curData); } } else #endif { for(j=0; j<wholeBlocks; j++, curData+=state->rate/8) { #ifdef KeccakReference displayBytes(1, "Block to be absorbed", curData, state->rate/8); #endif KeccakAbsorb(state->state, curData, state->rate/64); } } i += wholeBlocks*state->rate; } else { partialBlock = (unsigned int)(databitlen - i); if (partialBlock+state->bitsInQueue > state->rate) partialBlock = state->rate-state->bitsInQueue; partialByte = partialBlock % 8; partialBlock -= partialByte; memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8); state->bitsInQueue += partialBlock; i += partialBlock; if (state->bitsInQueue == state->rate) AbsorbQueue(state); if (partialByte > 0) { unsigned char mask = (1 << partialByte)-1; state->dataQueue[state->bitsInQueue/8] = data[i/8] & mask; state->bitsInQueue += partialByte; i += partialByte; } } } return 0; }
HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen) { DataLength i, j; DataLength partialBlock, partialByte, wholeBlocks; BitSequence lastByte; const BitSequence *curData; if ((state->bitsInQueue % 8) != 0) return FAIL; // Only the last call may contain a partial byte if (state->squeezing) return FAIL; // Too late for additional input i = 0; while(i < databitlen) { if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) { wholeBlocks = (databitlen-i)/state->rate; curData = data+i/8; #ifdef ProvideFast576 if (state->rate == 576) { for(j=0; j<wholeBlocks; j++, curData+=576/8) { #ifdef KeccakReference displayBytes(1, "Data to be absorbed", curData, state->rate/8); #endif KeccakAbsorb576bits(state->state, curData); } } else #endif #ifdef ProvideFast832 if (state->rate == 832) { for(j=0; j<wholeBlocks; j++, curData+=832/8) { #ifdef KeccakReference displayBytes(1, "Data to be absorbed", curData, state->rate/8); #endif KeccakAbsorb832bits(state->state, curData); } } else #endif #ifdef ProvideFast1024 if (state->rate == 1024) { for(j=0; j<wholeBlocks; j++, curData+=1024/8) { #ifdef KeccakReference displayBytes(1, "Data to be absorbed", curData, state->rate/8); #endif KeccakAbsorb1024bits(state->state, curData); } } else #endif #ifdef ProvideFast1088 if (state->rate == 1088) { for(j=0; j<wholeBlocks; j++, curData+=1088/8) { #ifdef KeccakReference displayBytes(1, "Data to be absorbed", curData, state->rate/8); #endif KeccakAbsorb1088bits(state->state, curData); } } else #endif #ifdef ProvideFast1152 if (state->rate == 1152) { for(j=0; j<wholeBlocks; j++, curData+=1152/8) { #ifdef KeccakReference displayBytes(1, "Data to be absorbed", curData, state->rate/8); #endif KeccakAbsorb1152bits(state->state, curData); } } else #endif #ifdef ProvideFast1344 if (state->rate == 1344) { for(j=0; j<wholeBlocks; j++, curData+=1344/8) { #ifdef KeccakReference displayBytes(1, "Data to be absorbed", curData, state->rate/8); #endif KeccakAbsorb1344bits(state->state, curData); } } else #endif { for(j=0; j<wholeBlocks; j++, curData+=state->rate/8) { #ifdef KeccakReference displayBytes(1, "Data to be absorbed", curData, state->rate/8); #endif KeccakAbsorb(state->state, curData, state->rate/64); } } i += wholeBlocks*state->rate; } else { partialBlock = databitlen - i; if (partialBlock+state->bitsInQueue > state->rate) partialBlock = state->rate-state->bitsInQueue; partialByte = partialBlock % 8; partialBlock -= partialByte; memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8); state->bitsInQueue += partialBlock; i += partialBlock; if (state->bitsInQueue == state->rate) AbsorbQueue(state); if (partialByte > 0) { // Align the last partial byte to the least significant bits lastByte = data[i/8] >> (8-partialByte); state->dataQueue[state->bitsInQueue/8] = lastByte; state->bitsInQueue += partialByte; i += partialByte; } } }