private void PadAndSwitchToSqueezingPhase()
        {
            Debug.Assert(bitsInQueue < rate);

            dataQueue[bitsInQueue >> 3] |= (byte)(1U << (bitsInQueue & 7));

            if (++bitsInQueue == rate)
            {
                KeccakAbsorb(dataQueue, 0);
                bitsInQueue = 0;
            }

            {
                int full = bitsInQueue >> 6, partial = bitsInQueue & 63;
                int off = 0;
                for (int i = 0; i < full; ++i)
                {
                    state[i] ^= PackingUtils.LE_To_UInt64(dataQueue, off);
                    off      += 8;
                }
                if (partial > 0)
                {
                    ulong mask = (1UL << partial) - 1UL;
                    state[full] ^= PackingUtils.LE_To_UInt64(dataQueue, off) & mask;
                }
                state[(rate - 1) >> 6] ^= (1UL << 63);
            }

            KeccakPermutation();

            KeccakExtract();
            bitsInQueue = rate;

            squeezing = true;
        }
        private void KeccakAbsorb(byte[] data, int off)
        {
            int count = rate >> 6;

            for (int i = 0; i < count; ++i)
            {
                state[i] ^= PackingUtils.LE_To_UInt64(data, off);
                off      += 8;
            }

            KeccakPermutation();
        }
 private void KeccakExtract()
 {
     PackingUtils.UInt64_To_LE(state, 0, rate >> 6, dataQueue, 0);
 }