Example #1
0
        /// <summary>
        /// Finalizes SHA-512 hashing
        /// </summary>
        /// <param name="output">
        /// Output buffer
        /// </param>
        public void Finalize(ArraySegment <byte> output)
        {
            Update(Padding, 0, Padding.Length);
            Array16 <ulong> block;

            ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0);
            CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
            var bytesInBuffer = (int)_totalBytes & (BlockSize - 1);

            if (bytesInBuffer > BlockSize - 16)
            {
                Sha512Internal.Core(out _state, ref _state, ref block);
                block = default;
            }

            block.X15 = (_totalBytes - 1) * 8;
            Sha512Internal.Core(out _state, ref _state, ref block);

            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.X0);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.X1);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.X2);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.X3);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.X4);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.X5);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.X6);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.X7);
            _state = default;
        }
Example #2
0
 public static IEnumerable <T> ToSeq <T>(this Array8 <T> arr)
 {
     for (int i = 0; i < arr.m_size; i++)
     {
         yield return(arr.m_buffer[i]);
     }
 }
Example #3
0
        /// <summary>
        /// Finalizes SHA-512 hashing
        /// </summary>
        /// <param name="output">Output buffer</param>
        public void Finalize(ArraySegment <byte> output)
        {
            Contract.Requires <ArgumentNullException>(output.Array != null);
            Contract.Requires <ArgumentException>(output.Count == 64);

            Update(_padding, 0, _padding.Length);
            Array16 <ulong> block;

            ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0);
            CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
            int bytesInBuffer = (int)_totalBytes & (BlockSize - 1);

            if (bytesInBuffer > BlockSize - 16)
            {
                Sha512Internal.Core(out _state, ref _state, ref block);
                block = default(Array16 <ulong>);
            }
            block.x15 = (_totalBytes - 1) * 8;
            Sha512Internal.Core(out _state, ref _state, ref block);

            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.x0);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.x1);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.x2);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.x3);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.x4);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.x5);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.x6);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.x7);
            _state = default(Array8 <ulong>);
        }
Example #4
0
        public void Finish(ArraySegment <byte> output)
        {
            if (output.Array == null)
            {
                throw new ArgumentNullException(nameof(output));
            }
            if (output.Count != 64)
            {
                throw new ArgumentException("output.Count must be 64");
            }

            Update(Padding, 0, Padding.Length);
            ByteIntegerConverter.Array16LoadBigEndian64(out var block, _buffer, 0);
            CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
            var bytesInBuffer = (int)_totalBytes & (BlockSize - 1);

            if (bytesInBuffer > BlockSize - 16)
            {
                Sha512Internal.Core(out _state, ref _state, ref block);
                block = default(Array16 <ulong>);
            }

            block.x15 = (_totalBytes - 1) * 8;
            Sha512Internal.Core(out _state, ref _state, ref block);

            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.x0);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.x1);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.x2);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.x3);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.x4);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.x5);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.x6);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.x7);
            _state = default(Array8 <ulong>);
        }
Example #5
0
        public static void IterateLinkedList <T>(this Array8 <T> arr, uint startIndex, NextIndex8 <T> nextIndex, RefAction <T> action) where T : struct
        {
            var cur = startIndex;

            while (cur != 0)
            {
                action(cur, ref arr.m_buffer[cur]);
                cur = nextIndex(ref arr.m_buffer[cur]);
            }
        }
 internal static void Sha512Init(out Array8<UInt64> state)
 {
     state.x0 = 0x6a09e667f3bcc908;
     state.x1 = 0xbb67ae8584caa73b;
     state.x2 = 0x3c6ef372fe94f82b;
     state.x3 = 0xa54ff53a5f1d36f1;
     state.x4 = 0x510e527fade682d1;
     state.x5 = 0x9b05688c2b3e6c1f;
     state.x6 = 0x1f83d9abfb41bd6b;
     state.x7 = 0x5be0cd19137e2179;
 }
 public static void Array8LoadLittleEndian32(out Array8 <uint> output, byte[] input, int inputOffset)
 {
     output.x0 = LoadLittleEndian32(input, inputOffset + 0);
     output.x1 = LoadLittleEndian32(input, inputOffset + 4);
     output.x2 = LoadLittleEndian32(input, inputOffset + 8);
     output.x3 = LoadLittleEndian32(input, inputOffset + 12);
     output.x4 = LoadLittleEndian32(input, inputOffset + 16);
     output.x5 = LoadLittleEndian32(input, inputOffset + 20);
     output.x6 = LoadLittleEndian32(input, inputOffset + 24);
     output.x7 = LoadLittleEndian32(input, inputOffset + 28);
 }
Example #8
0
        public string[] getLanguageIndex()
        {
            Array8 <string> saida = new Array8 <string>((uint)locales.Length + 1);

            saida.m_buffer[0] = Locale.Get(prefix + "GAME_DEFAULT_LANGUAGE");
            for (int i = 0; i < locales.Length; i++)
            {
                saida.m_buffer[i + 1] = Locale.Get(prefix + "LANG", locales[i]);
            }
            return(saida.m_buffer);
        }
 internal static void Sha512Init(out Array8 <ulong> state)
 {
     state.x0 = 0x6a09e667f3bcc908;
     state.x1 = 0xbb67ae8584caa73b;
     state.x2 = 0x3c6ef372fe94f82b;
     state.x3 = 0xa54ff53a5f1d36f1;
     state.x4 = 0x510e527fade682d1;
     state.x5 = 0x9b05688c2b3e6c1f;
     state.x6 = 0x1f83d9abfb41bd6b;
     state.x7 = 0x5be0cd19137e2179;
 }
        /*public static void XorLittleEndian32(byte[] buf, int offset, UInt32 value)
        {
            buf[offset + 0] ^= (byte)value;
            buf[offset + 1] ^= (byte)(value >> 8);
            buf[offset + 2] ^= (byte)(value >> 16);
            buf[offset + 3] ^= (byte)(value >> 24);
        }*/

        /*public static void XorLittleEndian32(byte[] output, int outputOffset, byte[] input, int inputOffset, UInt32 value)
        {
            output[outputOffset + 0] = (byte)(input[inputOffset + 0] ^ value);
            output[outputOffset + 1] = (byte)(input[inputOffset + 1] ^ (value >> 8));
            output[outputOffset + 2] = (byte)(input[inputOffset + 2] ^ (value >> 16));
            output[outputOffset + 3] = (byte)(input[inputOffset + 3] ^ (value >> 24));
        }*/

        #endregion

        #region Array8

        public static void Array8LoadLittleEndian32(out Array8<UInt32> output, byte[] input, int inputOffset)
        {
            output.x0 = LoadLittleEndian32(input, inputOffset + 0);
            output.x1 = LoadLittleEndian32(input, inputOffset + 4);
            output.x2 = LoadLittleEndian32(input, inputOffset + 8);
            output.x3 = LoadLittleEndian32(input, inputOffset + 12);
            output.x4 = LoadLittleEndian32(input, inputOffset + 16);
            output.x5 = LoadLittleEndian32(input, inputOffset + 20);
            output.x6 = LoadLittleEndian32(input, inputOffset + 24);
            output.x7 = LoadLittleEndian32(input, inputOffset + 28);
        }
Example #11
0
        public void Finish(Span <byte> output)
        {
            if (output.Length != 64)
            {
                throw new ArgumentException("output.Count must be 64");
            }

            Update(_padding);
            Array16 <ulong> block;

            ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer);
            CryptoBytes.Wipe(_buffer, 0, _buffer.Length);
            int bytesInBuffer = (int)_totalBytes & (BlockSize - 1);

            if (bytesInBuffer > BlockSize - 16)
            {
                Sha512Internal.Core(out _state, in _state, in block);
                block = default;
            }
            block = new Array16 <ulong>(
                block.x0,
                block.x1,
                block.x2,
                block.x3,
                block.x4,
                block.x5,
                block.x6,
                block.x7,
                block.x8,
                block.x9,
                block.x10,
                block.x11,
                block.x12,
                block.x13,
                block.x14,
                (_totalBytes - 1) * 8);

            Sha512Internal.Core(out _state, in _state, in block);

            BinaryPrimitives.WriteUInt64BigEndian(output.Slice(0), _state.x0);
            BinaryPrimitives.WriteUInt64BigEndian(output.Slice(8), _state.x1);
            BinaryPrimitives.WriteUInt64BigEndian(output.Slice(16), _state.x2);
            BinaryPrimitives.WriteUInt64BigEndian(output.Slice(24), _state.x3);
            BinaryPrimitives.WriteUInt64BigEndian(output.Slice(32), _state.x4);
            BinaryPrimitives.WriteUInt64BigEndian(output.Slice(40), _state.x5);
            BinaryPrimitives.WriteUInt64BigEndian(output.Slice(48), _state.x6);
            BinaryPrimitives.WriteUInt64BigEndian(output.Slice(56), _state.x7);
            _state = default;
        }
Example #12
0
        private static InputSurface ReadSurface(
            ResourceManager rm,
            ref SlotConfig config,
            ref SlotSurfaceConfig surfaceConfig,
            ref Array8 <PlaneOffsets> offsets,
            int bytesPerPixel,
            int planes)
        {
            InputSurface surface = new InputSurface();

            surface.Initialize();

            int gobBlocksInY = 1 << surfaceConfig.SlotBlkHeight;

            bool linear = surfaceConfig.SlotBlkKind == 0;

            int lw = surfaceConfig.SlotLumaWidth + 1;
            int lh = surfaceConfig.SlotLumaHeight + 1;

            int cw = surfaceConfig.SlotChromaWidth + 1;
            int ch = surfaceConfig.SlotChromaHeight + 1;

            // Interlaced inputs have double the height when deinterlaced.
            int heightShift = config.FrameFormat.IsField() ? 1 : 0;

            surface.Width    = lw;
            surface.Height   = lh << heightShift;
            surface.UvWidth  = cw;
            surface.UvHeight = ch << heightShift;

            if (planes > 0)
            {
                surface.SetBuffer0(ReadBuffer(rm, ref config, ref offsets, linear, 0, lw, lh, bytesPerPixel, gobBlocksInY));
            }

            if (planes > 1)
            {
                surface.SetBuffer1(ReadBuffer(rm, ref config, ref offsets, linear, 1, cw, ch, planes == 2 ? 2 : 1, gobBlocksInY));
            }

            if (planes > 2)
            {
                surface.SetBuffer2(ReadBuffer(rm, ref config, ref offsets, linear, 2, cw, ch, 1, gobBlocksInY));
            }

            return(surface);
        }
Example #13
0
        public void DeclineTest()
        {
            ResourceIndustryDistrict.DistrictResource.getResource = () =>
            {
                Random r = new Random();
                NaturalResourceManager.ResourceCell[] resourcesFromMap = new NaturalResourceManager.ResourceCell[512 * 512];
                for (int i = 0; i < resourcesFromMap.Length; i++)
                {
                    resourcesFromMap[i].m_fertility = (byte)r.Next(0, 255);
                    resourcesFromMap[i].m_forest    = (byte)r.Next(0, 255);
                    resourcesFromMap[i].m_oil       = (byte)r.Next(0, 255);
                    resourcesFromMap[i].m_ore       = (byte)r.Next(0, 255);
                }
                return(resourcesFromMap);
            };
            ResourceIndustryDistrict.DistrictResource.getDistricts = () =>
            {
                DistrictManager.Cell[] districts = generateDistricts();
                return(districts);
            };
            ResourceIndustryDistrict.DistrictResource.getDistrictNames = () =>
            {
                Array8 <District> districtNames = new Array8 <District>(128);
                return(districtNames);
            };
            ResourceIndustryDistrict.DistrictResource.getDistrictNameFromId = (districtId) =>
            {
                return(districtId.ToString());
            };
            ResourceIndustryDistrict.DistrictResource.Calculate2();

            ResourceIndustryDistrict.DistrictResource.getResource = () =>
            {
                Random r = new Random();
                NaturalResourceManager.ResourceCell[] resourcesFromMap = new NaturalResourceManager.ResourceCell[512 * 512];
                for (int i = 0; i < resourcesFromMap.Length; i++)
                {
                    resourcesFromMap[i].m_fertility = (byte)r.Next(0, 2);
                    resourcesFromMap[i].m_forest    = (byte)r.Next(0, 2);
                    resourcesFromMap[i].m_oil       = (byte)r.Next(0, 2);
                    resourcesFromMap[i].m_ore       = (byte)r.Next(0, 2);
                }
                return(resourcesFromMap);
            };

            ResourceIndustryDistrict.DistrictResource.Calculate2();
        }
Example #14
0
        public static Surface Read(
            ResourceManager rm,
            ref SlotConfig config,
            ref SlotSurfaceConfig surfaceConfig,
            ref Array8 <PlaneOffsets> offsets)
        {
            switch (surfaceConfig.SlotPixelFormat)
            {
            case PixelFormat.Y8___V8U8_N420: return(ReadNv12(rm, ref config, ref surfaceConfig, ref offsets));
            }

            Logger.Error?.Print(LogClass.Vic, $"Unsupported pixel format \"{surfaceConfig.SlotPixelFormat}\".");

            int lw = surfaceConfig.SlotLumaWidth + 1;
            int lh = surfaceConfig.SlotLumaHeight + 1;

            return(new Surface(rm.SurfacePool, lw, lh));
        }
Example #15
0
        private static unsafe void ConvolveHoriz(
            byte *src,
            int srcStride,
            byte *dst,
            int dstStride,
            Array8 <short>[] xFilters,
            int x0Q4,
            int xStepQ4,
            int w,
            int h)
        {
            if (Sse41.IsSupported && UseIntrinsics && xStepQ4 == 1 << SubpelBits)
            {
                ConvolveHorizSse41(src, srcStride, dst, dstStride, xFilters, x0Q4, w, h);
                return;
            }

            int x, y;

            src -= SubpelTaps / 2 - 1;

            for (y = 0; y < h; ++y)
            {
                int xQ4 = x0Q4;
                for (x = 0; x < w; ++x)
                {
                    byte *srcX = &src[xQ4 >> SubpelBits];
                    ref Array8 <short> xFilter = ref xFilters[xQ4 & SubpelMask];
                    int k, sum = 0;
                    for (k = 0; k < SubpelTaps; ++k)
                    {
                        sum += srcX[k] * xFilter[k];
                    }

                    dst[x] = BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits));
                    xQ4   += xStepQ4;
                }
                src += srcStride;
                dst += dstStride;
            }
Example #16
0
        public void PassingTest()
        {
            Assert.Equal(4, Add(2, 2));
            ResourceIndustryDistrict.DistrictResource.getResource = () =>
            {
                Random r = new Random();
                NaturalResourceManager.ResourceCell[] resourcesFromMap = new NaturalResourceManager.ResourceCell[512 * 512];
                for (int i = 0; i < resourcesFromMap.Length; i++)
                {
                    resourcesFromMap[i].m_fertility = (byte)r.Next(0, 255);
                    resourcesFromMap[i].m_forest    = (byte)r.Next(0, 255);
                    resourcesFromMap[i].m_oil       = (byte)r.Next(0, 255);
                    resourcesFromMap[i].m_ore       = (byte)r.Next(0, 255);
                }
                return(resourcesFromMap);
            };
            ResourceIndustryDistrict.DistrictResource.getDistricts = () =>
            {
                DistrictManager.Cell[] districts = generateDistricts();
                return(districts);
            };
            ResourceIndustryDistrict.DistrictResource.getDistrictNames = () =>
            {
                Array8 <District> districtNames = new Array8 <District>(128);
                return(districtNames);
            };
            ResourceIndustryDistrict.DistrictResource.getDistrictNameFromId = (districtId) =>
            {
                return(districtId.ToString());
            };
            ResourceIndustryDistrict.DistrictResource.Calculate2();

            ResourceIndustryDistrict.DistrictResource.Calculate2();

            ResourceIndustryDistrict.DistrictResource.Calculate2();

            ResourceIndustryDistrict.DistrictResource.districtResourceList.Sort(new LineComparer("Size", true, false));
        }
Example #17
0
        public static Table Create(TableStore store)
        {
            IEnumerable <Array8> Snapshot()
            {
                foreach (var index in store.GetRows())
                {
                    Array8 r = new Array8(1);
                    r[0] = index;
                    yield return(r);
                }
            }

            IEnumerable <Array8> Test(Record record)
            {
                var(indices, table) = record;
                if (store == table && store.Test(indices[0]))
                {
                    yield return(indices);
                }
            }

            return(new Table(store, Snapshot, Test));
        }
Example #18
0
        public static void ResizeArray8 <T>(Array8 <T> array, byte newSize)
        {
            array.m_size = newSize;
            Array.Resize(ref array.m_buffer, (int)newSize);

            var unusedCount = (uint)array.GetType().GetField("m_unusedCount").GetValue(array);
            var unusedItems = (byte[])array.GetType().GetField("m_unusedItems").GetValue(array);

            byte[] newUnusedItems = new byte[newSize];
            Buffer.BlockCopy(unusedItems, 0, newUnusedItems, 0, 4 * unusedItems.Length);

            // Now add our own unused items
            for (uint i = (uint)unusedItems.Length; i < newSize + 1; i++)
            {
                newUnusedItems[i - 1] = (byte)i;
            }

            // Update the unusedCount to be in line with the new array size
            // This is just adding the newly sized additions.
            unusedCount += newSize - unusedCount;

            array.GetType().GetField("m_unusedCount").SetValue(array, unusedCount);
            array.GetType().GetField("m_unusedItems").SetValue(array, newUnusedItems);
        }
        internal static void Core(out Array8 <ulong> outputState, ref Array8 <ulong> inputState, ref Array16 <ulong> input)
        {
            unchecked
            {
                ulong a = inputState.x0;
                ulong b = inputState.x1;
                ulong c = inputState.x2;
                ulong d = inputState.x3;
                ulong e = inputState.x4;
                ulong f = inputState.x5;
                ulong g = inputState.x6;
                ulong h = inputState.x7;

                ulong w0  = input.x0;
                ulong w1  = input.x1;
                ulong w2  = input.x2;
                ulong w3  = input.x3;
                ulong w4  = input.x4;
                ulong w5  = input.x5;
                ulong w6  = input.x6;
                ulong w7  = input.x7;
                ulong w8  = input.x8;
                ulong w9  = input.x9;
                ulong w10 = input.x10;
                ulong w11 = input.x11;
                ulong w12 = input.x12;
                ulong w13 = input.x13;
                ulong w14 = input.x14;
                ulong w15 = input.x15;

                int t = 0;

                while (true)
                {
                    ulong t1, t2;

                    {
                        //0
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w0;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //1
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w1;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //2
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w2;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //3
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w3;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //4
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w4;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //5
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w5;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //6
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w6;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //7
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w7;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //8
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w8;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //9
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w9;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //10
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w10;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //11
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w11;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //12
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w12;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //13
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w13;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //14
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w14;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    {
                        //15
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w15;

                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }

                    if (t == 80)
                    {
                        break;
                    }

                    w0 += ((w14 >> 19) ^ (w14 << (64 - 19)) ^ (w14 >> 61) ^ (w14 << (64 - 61)) ^ (w14 >> 6)) +
                          w9 +
                          ((w1 >> 1) ^ (w1 << (64 - 1)) ^ (w1 >> 8) ^ (w1 << (64 - 8)) ^ (w1 >> 7));

                    w1 += ((w15 >> 19) ^ (w15 << (64 - 19)) ^ (w15 >> 61) ^ (w15 << (64 - 61)) ^ (w15 >> 6)) +
                          w10 +
                          ((w2 >> 1) ^ (w2 << (64 - 1)) ^ (w2 >> 8) ^ (w2 << (64 - 8)) ^ (w2 >> 7));

                    w2 += ((w0 >> 19) ^ (w0 << (64 - 19)) ^ (w0 >> 61) ^ (w0 << (64 - 61)) ^ (w0 >> 6)) +
                          w11 +
                          ((w3 >> 1) ^ (w3 << (64 - 1)) ^ (w3 >> 8) ^ (w3 << (64 - 8)) ^ (w3 >> 7));

                    w3 += ((w1 >> 19) ^ (w1 << (64 - 19)) ^ (w1 >> 61) ^ (w1 << (64 - 61)) ^ (w1 >> 6)) +
                          w12 +
                          ((w4 >> 1) ^ (w4 << (64 - 1)) ^ (w4 >> 8) ^ (w4 << (64 - 8)) ^ (w4 >> 7));

                    w4 += ((w2 >> 19) ^ (w2 << (64 - 19)) ^ (w2 >> 61) ^ (w2 << (64 - 61)) ^ (w2 >> 6)) +
                          w13 +
                          ((w5 >> 1) ^ (w5 << (64 - 1)) ^ (w5 >> 8) ^ (w5 << (64 - 8)) ^ (w5 >> 7));

                    w5 += ((w3 >> 19) ^ (w3 << (64 - 19)) ^ (w3 >> 61) ^ (w3 << (64 - 61)) ^ (w3 >> 6)) +
                          w14 +
                          ((w6 >> 1) ^ (w6 << (64 - 1)) ^ (w6 >> 8) ^ (w6 << (64 - 8)) ^ (w6 >> 7));

                    w6 += ((w4 >> 19) ^ (w4 << (64 - 19)) ^ (w4 >> 61) ^ (w4 << (64 - 61)) ^ (w4 >> 6)) +
                          w15 +
                          ((w7 >> 1) ^ (w7 << (64 - 1)) ^ (w7 >> 8) ^ (w7 << (64 - 8)) ^ (w7 >> 7));

                    w7 += ((w5 >> 19) ^ (w5 << (64 - 19)) ^ (w5 >> 61) ^ (w5 << (64 - 61)) ^ (w5 >> 6)) +
                          w0 +
                          ((w8 >> 1) ^ (w8 << (64 - 1)) ^ (w8 >> 8) ^ (w8 << (64 - 8)) ^ (w8 >> 7));

                    w8 += ((w6 >> 19) ^ (w6 << (64 - 19)) ^ (w6 >> 61) ^ (w6 << (64 - 61)) ^ (w6 >> 6)) +
                          w1 +
                          ((w9 >> 1) ^ (w9 << (64 - 1)) ^ (w9 >> 8) ^ (w9 << (64 - 8)) ^ (w9 >> 7));

                    w9 += ((w7 >> 19) ^ (w7 << (64 - 19)) ^ (w7 >> 61) ^ (w7 << (64 - 61)) ^ (w7 >> 6)) +
                          w2 +
                          ((w10 >> 1) ^ (w10 << (64 - 1)) ^ (w10 >> 8) ^ (w10 << (64 - 8)) ^ (w10 >> 7));

                    w10 += ((w8 >> 19) ^ (w8 << (64 - 19)) ^ (w8 >> 61) ^ (w8 << (64 - 61)) ^ (w8 >> 6)) +
                           w3 +
                           ((w11 >> 1) ^ (w11 << (64 - 1)) ^ (w11 >> 8) ^ (w11 << (64 - 8)) ^ (w11 >> 7));

                    w11 += ((w9 >> 19) ^ (w9 << (64 - 19)) ^ (w9 >> 61) ^ (w9 << (64 - 61)) ^ (w9 >> 6)) +
                           w4 +
                           ((w12 >> 1) ^ (w12 << (64 - 1)) ^ (w12 >> 8) ^ (w12 << (64 - 8)) ^ (w12 >> 7));

                    w12 += ((w10 >> 19) ^ (w10 << (64 - 19)) ^ (w10 >> 61) ^ (w10 << (64 - 61)) ^ (w10 >> 6)) +
                           w5 +
                           ((w13 >> 1) ^ (w13 << (64 - 1)) ^ (w13 >> 8) ^ (w13 << (64 - 8)) ^ (w13 >> 7));

                    w13 += ((w11 >> 19) ^ (w11 << (64 - 19)) ^ (w11 >> 61) ^ (w11 << (64 - 61)) ^ (w11 >> 6)) +
                           w6 +
                           ((w14 >> 1) ^ (w14 << (64 - 1)) ^ (w14 >> 8) ^ (w14 << (64 - 8)) ^ (w14 >> 7));

                    w14 += ((w12 >> 19) ^ (w12 << (64 - 19)) ^ (w12 >> 61) ^ (w12 << (64 - 61)) ^ (w12 >> 6)) +
                           w7 +
                           ((w15 >> 1) ^ (w15 << (64 - 1)) ^ (w15 >> 8) ^ (w15 << (64 - 8)) ^ (w15 >> 7));

                    w15 += ((w13 >> 19) ^ (w13 << (64 - 19)) ^ (w13 >> 61) ^ (w13 << (64 - 61)) ^ (w13 >> 6)) +
                           w8 +
                           ((w0 >> 1) ^ (w0 << (64 - 1)) ^ (w0 >> 8) ^ (w0 << (64 - 8)) ^ (w0 >> 7));
                }

                outputState.x0 = inputState.x0 + a;
                outputState.x1 = inputState.x1 + b;
                outputState.x2 = inputState.x2 + c;
                outputState.x3 = inputState.x3 + d;
                outputState.x4 = inputState.x4 + e;
                outputState.x5 = inputState.x5 + f;
                outputState.x6 = inputState.x6 + g;
                outputState.x7 = inputState.x7 + h;
            }
        }
        // written by floodyberry (Andrew M.)
        // original license: MIT or PUBLIC DOMAIN
        // https://github.com/floodyberry/poly1305-donna/blob/master/poly1305-donna-unrolled.c
        public static void poly1305_auth(byte[] output, int outputOffset, byte[] m, int mStart, int mLength, ref Array8<UInt32> key)
        {
            UInt32 t0, t1, t2, t3;
            UInt32 h0, h1, h2, h3, h4;
            UInt32 r0, r1, r2, r3, r4;
            UInt32 s1, s2, s3, s4;
            UInt32 b, nb;
            int j;
            UInt64 tt0, tt1, tt2, tt3, tt4;
            UInt64 f0, f1, f2, f3;
            UInt32 g0, g1, g2, g3, g4;
            UInt64 c;

            /* clamp key */
            t0 = key.x0;
            t1 = key.x1;
            t2 = key.x2;
            t3 = key.x3;

            /* precompute multipliers */
            r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
            r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
            r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
            r3 = t2 & 0x3f03fff; t3 >>= 8;
            r4 = t3 & 0x00fffff;

            s1 = r1 * 5;
            s2 = r2 * 5;
            s3 = r3 * 5;
            s4 = r4 * 5;

            /* init state */
            h0 = 0;
            h1 = 0;
            h2 = 0;
            h3 = 0;
            h4 = 0;

            /* full blocks */
            if (mLength < 16)
                goto poly1305_donna_atmost15bytes;

        poly1305_donna_16bytes:
            mStart += 16;
            mLength -= 16;

            t0 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 16);
            t1 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 12);
            t2 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 8);
            t3 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 4);

            h0 += t0 & 0x3ffffff;
            h1 += (uint)(((((UInt64)t1 << 32) | t0) >> 26) & 0x3ffffff);
            h2 += (uint)(((((UInt64)t2 << 32) | t1) >> 20) & 0x3ffffff);
            h3 += (uint)(((((UInt64)t3 << 32) | t2) >> 14) & 0x3ffffff);
            h4 += (t3 >> 8) | (1 << 24);


        poly1305_donna_mul:
            tt0 = (ulong)h0 * r0 + (ulong)h1 * s4 + (ulong)h2 * s3 + (ulong)h3 * s2 + (ulong)h4 * s1;
            tt1 = (ulong)h0 * r1 + (ulong)h1 * r0 + (ulong)h2 * s4 + (ulong)h3 * s3 + (ulong)h4 * s2;
            tt2 = (ulong)h0 * r2 + (ulong)h1 * r1 + (ulong)h2 * r0 + (ulong)h3 * s4 + (ulong)h4 * s3;
            tt3 = (ulong)h0 * r3 + (ulong)h1 * r2 + (ulong)h2 * r1 + (ulong)h3 * r0 + (ulong)h4 * s4;
            tt4 = (ulong)h0 * r4 + (ulong)h1 * r3 + (ulong)h2 * r2 + (ulong)h3 * r1 + (ulong)h4 * r0;

            h0 = (UInt32)tt0 & 0x3ffffff; c = (tt0 >> 26);
            tt1 += c; h1 = (UInt32)tt1 & 0x3ffffff; b = (UInt32)(tt1 >> 26);
            tt2 += b; h2 = (UInt32)tt2 & 0x3ffffff; b = (UInt32)(tt2 >> 26);
            tt3 += b; h3 = (UInt32)tt3 & 0x3ffffff; b = (UInt32)(tt3 >> 26);
            tt4 += b; h4 = (UInt32)tt4 & 0x3ffffff; b = (UInt32)(tt4 >> 26);
            h0 += b * 5;

            if (mLength >= 16)
                goto poly1305_donna_16bytes;

    /* final bytes */
        poly1305_donna_atmost15bytes:
            if (mLength == 0)
                goto poly1305_donna_finish;

            byte[] mp = new byte[16];//todo remove allocation

            for (j = 0; j < mLength; j++)
                mp[j] = m[mStart + j];
            mp[j++] = 1;
            for (; j < 16; j++)
                mp[j] = 0;
            mLength = 0;

            t0 = ByteIntegerConverter.LoadLittleEndian32(mp, 0);
            t1 = ByteIntegerConverter.LoadLittleEndian32(mp, 4);
            t2 = ByteIntegerConverter.LoadLittleEndian32(mp, 8);
            t3 = ByteIntegerConverter.LoadLittleEndian32(mp, 12);
            CryptoBytes.Wipe(mp);

            h0 += t0 & 0x3ffffff;
            h1 += (uint)(((((UInt64)t1 << 32) | t0) >> 26) & 0x3ffffff);
            h2 += (uint)(((((UInt64)t2 << 32) | t1) >> 20) & 0x3ffffff);
            h3 += (uint)(((((UInt64)t3 << 32) | t2) >> 14) & 0x3ffffff);
            h4 += t3 >> 8;

            goto poly1305_donna_mul;

        poly1305_donna_finish:
            b = h0 >> 26; h0 = h0 & 0x3ffffff;
            h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
            h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
            h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
            h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
            h0 += b * 5;

            g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
            g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
            g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
            g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
            g4 = h4 + b - (1 << 26);

            b = (g4 >> 31) - 1;
            nb = ~b;
            h0 = (h0 & nb) | (g0 & b);
            h1 = (h1 & nb) | (g1 & b);
            h2 = (h2 & nb) | (g2 & b);
            h3 = (h3 & nb) | (g3 & b);
            h4 = (h4 & nb) | (g4 & b);

            f0 = ((h0) | (h1 << 26)) + (UInt64)key.x4;
            f1 = ((h1 >> 6) | (h2 << 20)) + (UInt64)key.x5;
            f2 = ((h2 >> 12) | (h3 << 14)) + (UInt64)key.x6;
            f3 = ((h3 >> 18) | (h4 << 8)) + (UInt64)key.x7;

            ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 0, (uint)f0); f1 += (f0 >> 32);
            ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 4, (uint)f1); f2 += (f1 >> 32);
            ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 8, (uint)f2); f3 += (f2 >> 32);
            ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 12, (uint)f3);
        }
        public static void Array8LoadLittleEndian32(out Array8<uint> output, byte[] input, int inputOffset, int inputLength)
        {
#if DEBUG
            if (inputLength <= 0)
                throw new ArgumentException();
#endif
            int inputEnd = inputOffset + inputLength;
            UInt32 highestInt;
            switch (inputLength & 3)
            {
                case 1:
                    highestInt = input[inputEnd - 1];
                    break;
                case 2:
                    highestInt = (uint)(
                        (input[inputEnd - 1] << 8) |
                        (input[inputEnd - 2]));
                    break;
                case 3:
                    highestInt = (uint)(
                        (input[inputEnd - 1] << 16) |
                        (input[inputEnd - 2] << 8) |
                        (input[inputEnd - 3]));
                    break;
                case 0:
                    highestInt = (uint)(
                        (input[inputEnd - 1] << 24) |
                        (input[inputEnd - 2] << 16) |
                        (input[inputEnd - 3] << 8) |
                        (input[inputEnd - 4]));
                    break;
                default:
                    throw new InvalidOperationException();
            }
            switch ((inputLength - 1) >> 2)
            {
                case 7:
                    output.x7 = highestInt;
                    output.x6 = LoadLittleEndian32(input, inputOffset + 6 * 4);
                    output.x5 = LoadLittleEndian32(input, inputOffset + 5 * 4);
                    output.x4 = LoadLittleEndian32(input, inputOffset + 4 * 4);
                    output.x3 = LoadLittleEndian32(input, inputOffset + 3 * 4);
                    output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4);
                    output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4);
                    output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4);
                    return;
                case 6:
                    output.x7 = 0;
                    output.x6 = highestInt;
                    output.x5 = LoadLittleEndian32(input, inputOffset + 5 * 4);
                    output.x4 = LoadLittleEndian32(input, inputOffset + 4 * 4);
                    output.x3 = LoadLittleEndian32(input, inputOffset + 3 * 4);
                    output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4);
                    output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4);
                    output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4);
                    return;
                case 5:
                    output.x7 = 0;
                    output.x6 = 0;
                    output.x5 = highestInt;
                    output.x4 = LoadLittleEndian32(input, inputOffset + 4 * 4);
                    output.x3 = LoadLittleEndian32(input, inputOffset + 3 * 4);
                    output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4);
                    output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4);
                    output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4);
                    return;
                case 4:
                    output.x7 = 0;
                    output.x6 = 0;
                    output.x5 = 0;
                    output.x4 = highestInt;
                    output.x3 = LoadLittleEndian32(input, inputOffset + 3 * 4);
                    output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4);
                    output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4);
                    output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4);
                    return;
                case 3:
                    output.x7 = 0;
                    output.x6 = 0;
                    output.x5 = 0;
                    output.x4 = 0;
                    output.x3 = highestInt;
                    output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4);
                    output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4);
                    output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4);
                    return;
                case 2:
                    output.x7 = 0;
                    output.x6 = 0;
                    output.x5 = 0;
                    output.x4 = 0;
                    output.x3 = 0;
                    output.x2 = highestInt;
                    output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4);
                    output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4);
                    return;
                case 1:
                    output.x7 = 0;
                    output.x6 = 0;
                    output.x5 = 0;
                    output.x4 = 0;
                    output.x3 = 0;
                    output.x2 = 0;
                    output.x1 = highestInt;
                    output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4);
                    return;
                case 0:
                    output.x7 = 0;
                    output.x6 = 0;
                    output.x5 = 0;
                    output.x4 = 0;
                    output.x3 = 0;
                    output.x2 = 0;
                    output.x1 = 0;
                    output.x0 = highestInt;
                    return;
                default:
                    throw new InvalidOperationException();
            }
        }
Example #22
0
        // written by floodyberry (Andrew M.)
        // original license: MIT or PUBLIC DOMAIN
        // https://github.com/floodyberry/poly1305-donna/blob/master/poly1305-donna-unrolled.c
        public static void poly1305_auth(byte[] output, int outputOffset, byte[] m, int mStart, int mLength, ref Array8 <UInt32> key)
        {
            UInt32 t0, t1, t2, t3;
            UInt32 h0, h1, h2, h3, h4;
            UInt32 r0, r1, r2, r3, r4;
            UInt32 s1, s2, s3, s4;
            UInt32 b, nb;
            int    j;
            UInt64 tt0, tt1, tt2, tt3, tt4;
            UInt64 f0, f1, f2, f3;
            UInt32 g0, g1, g2, g3, g4;
            UInt64 c;

            /* clamp key */
            t0 = key.x0;
            t1 = key.x1;
            t2 = key.x2;
            t3 = key.x3;

            /* precompute multipliers */
            r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
            r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
            r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
            r3 = t2 & 0x3f03fff; t3 >>= 8;
            r4 = t3 & 0x00fffff;

            s1 = r1 * 5;
            s2 = r2 * 5;
            s3 = r3 * 5;
            s4 = r4 * 5;

            /* init state */
            h0 = 0;
            h1 = 0;
            h2 = 0;
            h3 = 0;
            h4 = 0;

            /* full blocks */
            if (mLength < 16)
            {
                goto poly1305_donna_atmost15bytes;
            }

poly1305_donna_16bytes:
            mStart  += 16;
            mLength -= 16;

            t0 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 16);
            t1 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 12);
            t2 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 8);
            t3 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 4);

            //todo: looks like these can be simplified a bit
            h0 += t0 & 0x3ffffff;
            h1 += (uint)(((((UInt64)t1 << 32) | t0) >> 26) & 0x3ffffff);
            h2 += (uint)(((((UInt64)t2 << 32) | t1) >> 20) & 0x3ffffff);
            h3 += (uint)(((((UInt64)t3 << 32) | t2) >> 14) & 0x3ffffff);
            h4 += (t3 >> 8) | (1 << 24);


poly1305_donna_mul:
            tt0 = (ulong)h0 * r0 + (ulong)h1 * s4 + (ulong)h2 * s3 + (ulong)h3 * s2 + (ulong)h4 * s1;
            tt1 = (ulong)h0 * r1 + (ulong)h1 * r0 + (ulong)h2 * s4 + (ulong)h3 * s3 + (ulong)h4 * s2;
            tt2 = (ulong)h0 * r2 + (ulong)h1 * r1 + (ulong)h2 * r0 + (ulong)h3 * s4 + (ulong)h4 * s3;
            tt3 = (ulong)h0 * r3 + (ulong)h1 * r2 + (ulong)h2 * r1 + (ulong)h3 * r0 + (ulong)h4 * s4;
            tt4 = (ulong)h0 * r4 + (ulong)h1 * r3 + (ulong)h2 * r2 + (ulong)h3 * r1 + (ulong)h4 * r0;

            unchecked
            {
                h0   = (UInt32)tt0 & 0x3ffffff; c = (tt0 >> 26);
                tt1 += c; h1 = (UInt32)tt1 & 0x3ffffff; b = (UInt32)(tt1 >> 26);
                tt2 += b; h2 = (UInt32)tt2 & 0x3ffffff; b = (UInt32)(tt2 >> 26);
                tt3 += b; h3 = (UInt32)tt3 & 0x3ffffff; b = (UInt32)(tt3 >> 26);
                tt4 += b; h4 = (UInt32)tt4 & 0x3ffffff; b = (UInt32)(tt4 >> 26);
            }
            h0 += b * 5;

            if (mLength >= 16)
            {
                goto poly1305_donna_16bytes;
            }

            /* final bytes */
poly1305_donna_atmost15bytes:
            if (mLength == 0)
            {
                goto poly1305_donna_finish;
            }

            byte[] mp = new byte[16];//todo remove allocation

            for (j = 0; j < mLength; j++)
            {
                mp[j] = m[mStart + j];
            }
            mp[j++] = 1;
            for (; j < 16; j++)
            {
                mp[j] = 0;
            }
            mLength = 0;

            t0 = ByteIntegerConverter.LoadLittleEndian32(mp, 0);
            t1 = ByteIntegerConverter.LoadLittleEndian32(mp, 4);
            t2 = ByteIntegerConverter.LoadLittleEndian32(mp, 8);
            t3 = ByteIntegerConverter.LoadLittleEndian32(mp, 12);
            CryptoExtensions.Wipe(mp);

            h0 += t0 & 0x3ffffff;
            h1 += (uint)(((((UInt64)t1 << 32) | t0) >> 26) & 0x3ffffff);
            h2 += (uint)(((((UInt64)t2 << 32) | t1) >> 20) & 0x3ffffff);
            h3 += (uint)(((((UInt64)t3 << 32) | t2) >> 14) & 0x3ffffff);
            h4 += t3 >> 8;

            goto poly1305_donna_mul;

poly1305_donna_finish:
            b   = h0 >> 26; h0 = h0 & 0x3ffffff;
            h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
            h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
            h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
            h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
            h0 += b * 5;

            g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
            g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
            g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
            g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
            g4 = unchecked (h4 + b - (1 << 26));

            b  = (g4 >> 31) - 1;
            nb = ~b;
            h0 = (h0 & nb) | (g0 & b);
            h1 = (h1 & nb) | (g1 & b);
            h2 = (h2 & nb) | (g2 & b);
            h3 = (h3 & nb) | (g3 & b);
            h4 = (h4 & nb) | (g4 & b);

            f0 = ((h0) | (h1 << 26)) + (UInt64)key.x4;
            f1 = ((h1 >> 6) | (h2 << 20)) + (UInt64)key.x5;
            f2 = ((h2 >> 12) | (h3 << 14)) + (UInt64)key.x6;
            f3 = ((h3 >> 18) | (h4 << 8)) + (UInt64)key.x7;

            unchecked
            {
                ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 0, (uint)f0); f1 += (f0 >> 32);
                ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 4, (uint)f1); f2 += (f1 >> 32);
                ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 8, (uint)f2); f3 += (f2 >> 32);
                ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 12, (uint)f3);
            }
        }
Example #23
0
        /// <summary>
        /// Finalizes SHA-512 hashing
        /// </summary>
        /// <param name="output">Output buffer</param>
        public void Finalize(ArraySegment<byte> output)
        {
            Contract.Requires<ArgumentNullException>(output.Array != null);
            Contract.Requires<ArgumentException>(output.Count == 64);

            Update(_padding, 0, _padding.Length);
            Array16<ulong> block;
            ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0);
            CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
            int bytesInBuffer = (int)_totalBytes & (BlockSize - 1);
            if (bytesInBuffer > BlockSize - 16)
            {
                Sha512Internal.Core(out _state, ref _state, ref block);
                block = default(Array16<ulong>);
            }
            block.x15 = (_totalBytes - 1) * 8;
            Sha512Internal.Core(out _state, ref _state, ref block);

            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.x0);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.x1);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.x2);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.x3);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.x4);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.x5);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.x6);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.x7);
            _state = default(Array8<ulong>);
        }
Example #24
0
        // written by floodyberry (Andrew M.)
        // original license: MIT or PUBLIC DOMAIN
        // https://github.com/floodyberry/poly1305-donna/blob/master/poly1305-donna-unrolled.c
        public static void poly1305_auth(byte[] output, int outputOffset, byte[] m, int mStart, int mLength,
                                         ref Array8 <uint> key)
        {
            uint b;
            int  j;

            /* clamp key */
            var t0 = key.x0;
            var t1 = key.x1;
            var t2 = key.x2;
            var t3 = key.x3;

            /* precompute multipliers */
            var r0 = t0 & 0x3ffffff;

            t0 >>= 26;
            t0  |= t1 << 6;
            var r1 = t0 & 0x3ffff03;

            t1 >>= 20;
            t1  |= t2 << 12;
            var r2 = t1 & 0x3ffc0ff;

            t2 >>= 14;
            t2  |= t3 << 18;
            var r3 = t2 & 0x3f03fff;

            t3 >>= 8;
            var r4 = t3 & 0x00fffff;

            var s1 = r1 * 5;
            var s2 = r2 * 5;
            var s3 = r3 * 5;
            var s4 = r4 * 5;

            /* init state */
            uint h0 = 0;
            uint h1 = 0;
            uint h2 = 0;
            uint h3 = 0;
            uint h4 = 0;

            /* full blocks */
            if (mLength < 16)
            {
                goto poly1305_donna_atmost15bytes;
            }

poly1305_donna_16bytes:
            mStart  += 16;
            mLength -= 16;

            t0 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 16);
            t1 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 12);
            t2 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 8);
            t3 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 4);


            h0 += t0 & 0x3ffffff;
            h1 += (uint)(((((ulong)t1 << 32) | t0) >> 26) & 0x3ffffff);
            h2 += (uint)(((((ulong)t2 << 32) | t1) >> 20) & 0x3ffffff);
            h3 += (uint)(((((ulong)t3 << 32) | t2) >> 14) & 0x3ffffff);
            h4 += (t3 >> 8) | (1 << 24);


poly1305_donna_mul:
            var tt0 = (ulong)h0 * r0 + (ulong)h1 * s4 + (ulong)h2 * s3 + (ulong)h3 * s2 + (ulong)h4 * s1;
            var tt1 = (ulong)h0 * r1 + (ulong)h1 * r0 + (ulong)h2 * s4 + (ulong)h3 * s3 + (ulong)h4 * s2;
            var tt2 = (ulong)h0 * r2 + (ulong)h1 * r1 + (ulong)h2 * r0 + (ulong)h3 * s4 + (ulong)h4 * s3;
            var tt3 = (ulong)h0 * r3 + (ulong)h1 * r2 + (ulong)h2 * r1 + (ulong)h3 * r0 + (ulong)h4 * s4;
            var tt4 = (ulong)h0 * r4 + (ulong)h1 * r3 + (ulong)h2 * r2 + (ulong)h3 * r1 + (ulong)h4 * r0;

            unchecked
            {
                h0 = (uint)tt0 & 0x3ffffff;
                var c = tt0 >> 26;
                tt1 += c;
                h1   = (uint)tt1 & 0x3ffffff;
                b    = (uint)(tt1 >> 26);
                tt2 += b;
                h2   = (uint)tt2 & 0x3ffffff;
                b    = (uint)(tt2 >> 26);
                tt3 += b;
                h3   = (uint)tt3 & 0x3ffffff;
                b    = (uint)(tt3 >> 26);
                tt4 += b;
                h4   = (uint)tt4 & 0x3ffffff;
                b    = (uint)(tt4 >> 26);
            }

            h0 += b * 5;

            if (mLength >= 16)
            {
                goto poly1305_donna_16bytes;
            }

            /* final bytes */
poly1305_donna_atmost15bytes:
            if (mLength == 0)
            {
                goto poly1305_donna_finish;
            }

            var mp = new byte[16];

            for (j = 0; j < mLength; j++)
            {
                mp[j] = m[mStart + j];
            }
            mp[j++] = 1;
            for (; j < 16; j++)
            {
                mp[j] = 0;
            }
            mLength = 0;

            t0 = ByteIntegerConverter.LoadLittleEndian32(mp, 0);
            t1 = ByteIntegerConverter.LoadLittleEndian32(mp, 4);
            t2 = ByteIntegerConverter.LoadLittleEndian32(mp, 8);
            t3 = ByteIntegerConverter.LoadLittleEndian32(mp, 12);
            CryptoBytes.Wipe(mp);

            h0 += t0 & 0x3ffffff;
            h1 += (uint)(((((ulong)t1 << 32) | t0) >> 26) & 0x3ffffff);
            h2 += (uint)(((((ulong)t2 << 32) | t1) >> 20) & 0x3ffffff);
            h3 += (uint)(((((ulong)t3 << 32) | t2) >> 14) & 0x3ffffff);
            h4 += t3 >> 8;

            goto poly1305_donna_mul;

poly1305_donna_finish:
            b   = h0 >> 26;
            h0  = h0 & 0x3ffffff;
            h1 += b;
            b   = h1 >> 26;
            h1  = h1 & 0x3ffffff;
            h2 += b;
            b   = h2 >> 26;
            h2  = h2 & 0x3ffffff;
            h3 += b;
            b   = h3 >> 26;
            h3  = h3 & 0x3ffffff;
            h4 += b;
            b   = h4 >> 26;
            h4  = h4 & 0x3ffffff;
            h0 += b * 5;

            var g0 = h0 + 5;

            b   = g0 >> 26;
            g0 &= 0x3ffffff;
            var g1 = h1 + b;

            b   = g1 >> 26;
            g1 &= 0x3ffffff;
            var g2 = h2 + b;

            b   = g2 >> 26;
            g2 &= 0x3ffffff;
            var g3 = h3 + b;

            b   = g3 >> 26;
            g3 &= 0x3ffffff;
            var g4 = unchecked (h4 + b - (1 << 26));

            b = (g4 >> 31) - 1;
            var nb = ~b;

            h0 = (h0 & nb) | (g0 & b);
            h1 = (h1 & nb) | (g1 & b);
            h2 = (h2 & nb) | (g2 & b);
            h3 = (h3 & nb) | (g3 & b);
            h4 = (h4 & nb) | (g4 & b);

            var f0 = (h0 | (h1 << 26)) + (ulong)key.x4;
            var f1 = ((h1 >> 6) | (h2 << 20)) + (ulong)key.x5;
            var f2 = ((h2 >> 12) | (h3 << 14)) + (ulong)key.x6;
            var f3 = ((h3 >> 18) | (h4 << 8)) + (ulong)key.x7;

            unchecked
            {
                ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 0, (uint)f0);
                f1 += f0 >> 32;
                ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 4, (uint)f1);
                f2 += f1 >> 32;
                ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 8, (uint)f2);
                f3 += f2 >> 32;
                ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 12, (uint)f3);
            }
        }
Example #25
0
        internal static void Core(out Array8 <ulong> outputState, ref Array8 <ulong> inputState, ref Array16 <ulong> input)
        {
            unchecked
            {
                var a = inputState.X0;
                var b = inputState.X1;
                var c = inputState.X2;
                var d = inputState.X3;
                var e = inputState.X4;
                var f = inputState.X5;
                var g = inputState.X6;
                var h = inputState.X7;

                var w0  = input.X0;
                var w1  = input.X1;
                var w2  = input.X2;
                var w3  = input.X3;
                var w4  = input.X4;
                var w5  = input.X5;
                var w6  = input.X6;
                var w7  = input.X7;
                var w8  = input.X8;
                var w9  = input.X9;
                var w10 = input.X10;
                var w11 = input.X11;
                var w12 = input.X12;
                var w13 = input.X13;
                var w14 = input.X14;
                var w15 = input.X15;

                var t = 0;
                while (true)
                {
                    ulong t1, t2;

                    {
                        //0
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w0;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //1
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w1;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //2
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w2;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //3
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w3;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //4
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w4;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //5
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w5;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //6
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w6;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //7
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w7;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //8
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w8;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //9
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w9;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //10
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w10;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //11
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w11;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //12
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w12;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //13
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w13;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //14
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w14;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    {
                        //15
                        t1 = h +
                             ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^
                              (e << (64 - 41))) +
                             //Sigma1(e)
                             ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                             K[t] + w15;
                        t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^
                              (a << (64 - 39))) +
                             //Sigma0(a)
                             ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                        h = g;
                        g = f;
                        f = e;
                        e = d + t1;
                        d = c;
                        c = b;
                        b = a;
                        a = t1 + t2;
                        t++;
                    }
                    if (t == 80)
                    {
                        break;
                    }

                    w0 += ((w14 >> 19) ^ (w14 << (64 - 19)) ^ (w14 >> 61) ^ (w14 << (64 - 61)) ^ (w14 >> 6)) +
                          w9 +
                          ((w1 >> 1) ^ (w1 << (64 - 1)) ^ (w1 >> 8) ^ (w1 << (64 - 8)) ^ (w1 >> 7));
                    w1 += ((w15 >> 19) ^ (w15 << (64 - 19)) ^ (w15 >> 61) ^ (w15 << (64 - 61)) ^ (w15 >> 6)) +
                          w10 +
                          ((w2 >> 1) ^ (w2 << (64 - 1)) ^ (w2 >> 8) ^ (w2 << (64 - 8)) ^ (w2 >> 7));
                    w2 += ((w0 >> 19) ^ (w0 << (64 - 19)) ^ (w0 >> 61) ^ (w0 << (64 - 61)) ^ (w0 >> 6)) +
                          w11 +
                          ((w3 >> 1) ^ (w3 << (64 - 1)) ^ (w3 >> 8) ^ (w3 << (64 - 8)) ^ (w3 >> 7));
                    w3 += ((w1 >> 19) ^ (w1 << (64 - 19)) ^ (w1 >> 61) ^ (w1 << (64 - 61)) ^ (w1 >> 6)) +
                          w12 +
                          ((w4 >> 1) ^ (w4 << (64 - 1)) ^ (w4 >> 8) ^ (w4 << (64 - 8)) ^ (w4 >> 7));
                    w4 += ((w2 >> 19) ^ (w2 << (64 - 19)) ^ (w2 >> 61) ^ (w2 << (64 - 61)) ^ (w2 >> 6)) +
                          w13 +
                          ((w5 >> 1) ^ (w5 << (64 - 1)) ^ (w5 >> 8) ^ (w5 << (64 - 8)) ^ (w5 >> 7));
                    w5 += ((w3 >> 19) ^ (w3 << (64 - 19)) ^ (w3 >> 61) ^ (w3 << (64 - 61)) ^ (w3 >> 6)) +
                          w14 +
                          ((w6 >> 1) ^ (w6 << (64 - 1)) ^ (w6 >> 8) ^ (w6 << (64 - 8)) ^ (w6 >> 7));
                    w6 += ((w4 >> 19) ^ (w4 << (64 - 19)) ^ (w4 >> 61) ^ (w4 << (64 - 61)) ^ (w4 >> 6)) +
                          w15 +
                          ((w7 >> 1) ^ (w7 << (64 - 1)) ^ (w7 >> 8) ^ (w7 << (64 - 8)) ^ (w7 >> 7));
                    w7 += ((w5 >> 19) ^ (w5 << (64 - 19)) ^ (w5 >> 61) ^ (w5 << (64 - 61)) ^ (w5 >> 6)) +
                          w0 +
                          ((w8 >> 1) ^ (w8 << (64 - 1)) ^ (w8 >> 8) ^ (w8 << (64 - 8)) ^ (w8 >> 7));
                    w8 += ((w6 >> 19) ^ (w6 << (64 - 19)) ^ (w6 >> 61) ^ (w6 << (64 - 61)) ^ (w6 >> 6)) +
                          w1 +
                          ((w9 >> 1) ^ (w9 << (64 - 1)) ^ (w9 >> 8) ^ (w9 << (64 - 8)) ^ (w9 >> 7));
                    w9 += ((w7 >> 19) ^ (w7 << (64 - 19)) ^ (w7 >> 61) ^ (w7 << (64 - 61)) ^ (w7 >> 6)) +
                          w2 +
                          ((w10 >> 1) ^ (w10 << (64 - 1)) ^ (w10 >> 8) ^ (w10 << (64 - 8)) ^ (w10 >> 7));
                    w10 += ((w8 >> 19) ^ (w8 << (64 - 19)) ^ (w8 >> 61) ^ (w8 << (64 - 61)) ^ (w8 >> 6)) +
                           w3 +
                           ((w11 >> 1) ^ (w11 << (64 - 1)) ^ (w11 >> 8) ^ (w11 << (64 - 8)) ^ (w11 >> 7));
                    w11 += ((w9 >> 19) ^ (w9 << (64 - 19)) ^ (w9 >> 61) ^ (w9 << (64 - 61)) ^ (w9 >> 6)) +
                           w4 +
                           ((w12 >> 1) ^ (w12 << (64 - 1)) ^ (w12 >> 8) ^ (w12 << (64 - 8)) ^ (w12 >> 7));
                    w12 += ((w10 >> 19) ^ (w10 << (64 - 19)) ^ (w10 >> 61) ^ (w10 << (64 - 61)) ^ (w10 >> 6)) +
                           w5 +
                           ((w13 >> 1) ^ (w13 << (64 - 1)) ^ (w13 >> 8) ^ (w13 << (64 - 8)) ^ (w13 >> 7));
                    w13 += ((w11 >> 19) ^ (w11 << (64 - 19)) ^ (w11 >> 61) ^ (w11 << (64 - 61)) ^ (w11 >> 6)) +
                           w6 +
                           ((w14 >> 1) ^ (w14 << (64 - 1)) ^ (w14 >> 8) ^ (w14 << (64 - 8)) ^ (w14 >> 7));
                    w14 += ((w12 >> 19) ^ (w12 << (64 - 19)) ^ (w12 >> 61) ^ (w12 << (64 - 61)) ^ (w12 >> 6)) +
                           w7 +
                           ((w15 >> 1) ^ (w15 << (64 - 1)) ^ (w15 >> 8) ^ (w15 << (64 - 8)) ^ (w15 >> 7));
                    w15 += ((w13 >> 19) ^ (w13 << (64 - 19)) ^ (w13 >> 61) ^ (w13 << (64 - 61)) ^ (w13 >> 6)) +
                           w8 +
                           ((w0 >> 1) ^ (w0 << (64 - 1)) ^ (w0 >> 8) ^ (w0 << (64 - 8)) ^ (w0 >> 7));
                }

                outputState.X0 = inputState.X0 + a;
                outputState.X1 = inputState.X1 + b;
                outputState.X2 = inputState.X2 + c;
                outputState.X3 = inputState.X3 + d;
                outputState.X4 = inputState.X4 + e;
                outputState.X5 = inputState.X5 + f;
                outputState.X6 = inputState.X6 + g;
                outputState.X7 = inputState.X7 + h;
            }
        }
Example #26
0
 public          Record this[Array8 indices] => new Record(indices, Tab);
Example #27
0
 public static void RemoveUnused <T>(this Array8 <T> arr, byte id)
 {
     ArrayXHelper <Array8 <T>, byte> .RemoveUnused(arr, id, "Array8");
 }
 public static void Array8StoreLittleEndian32(byte[] output, int outputOffset, ref Array8 <uint> input)
 {
     StoreLittleEndian32(output, outputOffset + 0, input.x0);
     StoreLittleEndian32(output, outputOffset + 4, input.x1);
     StoreLittleEndian32(output, outputOffset + 8, input.x2);
     StoreLittleEndian32(output, outputOffset + 12, input.x3);
     StoreLittleEndian32(output, outputOffset + 16, input.x4);
     StoreLittleEndian32(output, outputOffset + 20, input.x5);
     StoreLittleEndian32(output, outputOffset + 24, input.x6);
     StoreLittleEndian32(output, outputOffset + 28, input.x7);
 }
 public static void Array8StoreLittleEndian32(byte[] output, int outputOffset, ref Array8<uint> input)
 {
     StoreLittleEndian32(output, outputOffset + 0, input.x0);
     StoreLittleEndian32(output, outputOffset + 4, input.x1);
     StoreLittleEndian32(output, outputOffset + 8, input.x2);
     StoreLittleEndian32(output, outputOffset + 12, input.x3);
     StoreLittleEndian32(output, outputOffset + 16, input.x4);
     StoreLittleEndian32(output, outputOffset + 20, input.x5);
     StoreLittleEndian32(output, outputOffset + 24, input.x6);
     StoreLittleEndian32(output, outputOffset + 28, input.x7);
 }
Example #30
0
        private static RentedBuffer ReadBuffer(
            ResourceManager rm,
            ref SlotConfig config,
            ref Array8 <PlaneOffsets> offsets,
            bool linear,
            int plane,
            int width,
            int height,
            int bytesPerPixel,
            int gobBlocksInY)
        {
            FrameFormat frameFormat = config.FrameFormat;
            bool        isLuma      = plane == 0;
            bool        isField     = frameFormat.IsField();
            bool        isTopField  = frameFormat.IsTopField(isLuma);
            int         stride      = GetPitch(width, bytesPerPixel);
            uint        offset      = GetOffset(ref offsets[0], plane);

            int dstStart  = 0;
            int dstStride = stride;

            if (isField)
            {
                dstStart  = isTopField ? 0 : stride;
                dstStride = stride * 2;
            }

            RentedBuffer buffer;

            if (linear)
            {
                buffer = ReadBufferLinear(rm, offset, width, height, dstStart, dstStride, bytesPerPixel);
            }
            else
            {
                buffer = ReadBufferBlockLinear(rm, offset, width, height, dstStart, dstStride, bytesPerPixel, gobBlocksInY);
            }

            if (isField || frameFormat.IsInterlaced())
            {
                RentedBuffer prevBuffer = RentedBuffer.Empty;
                RentedBuffer nextBuffer = RentedBuffer.Empty;

                if (config.PrevFieldEnable)
                {
                    prevBuffer = ReadBufferNoDeinterlace(rm, ref offsets[1], linear, plane, width, height, bytesPerPixel, gobBlocksInY);
                }

                if (config.NextFieldEnable)
                {
                    nextBuffer = ReadBufferNoDeinterlace(rm, ref offsets[2], linear, plane, width, height, bytesPerPixel, gobBlocksInY);
                }

                int w = width * bytesPerPixel;

                switch (config.DeinterlaceMode)
                {
                case DeinterlaceMode.Weave:
                    Scaler.DeinterlaceWeave(buffer.Data, prevBuffer.Data, w, stride, isTopField);
                    break;

                case DeinterlaceMode.BobField:
                    Scaler.DeinterlaceBob(buffer.Data, w, stride, isTopField);
                    break;

                case DeinterlaceMode.Bob:
                    bool isCurrentTop = isLuma ? config.IsEven : config.ChromaEven;
                    Scaler.DeinterlaceBob(buffer.Data, w, stride, isCurrentTop ^ frameFormat.IsInterlacedBottomFirst());
                    break;

                case DeinterlaceMode.NewBob:
                case DeinterlaceMode.Disi1:
                    Scaler.DeinterlaceMotionAdaptive(buffer.Data, prevBuffer.Data, nextBuffer.Data, w, stride, isTopField);
                    break;

                case DeinterlaceMode.WeaveLumaBobFieldChroma:
                    if (isLuma)
                    {
                        Scaler.DeinterlaceWeave(buffer.Data, prevBuffer.Data, w, stride, isTopField);
                    }
                    else
                    {
                        Scaler.DeinterlaceBob(buffer.Data, w, stride, isTopField);
                    }
                    break;

                default:
                    Logger.Error?.Print(LogClass.Vic, $"Unsupported deinterlace mode \"{config.DeinterlaceMode}\".");
                    break;
                }

                prevBuffer.Return(rm.BufferPool);
                nextBuffer.Return(rm.BufferPool);
            }

            return(buffer);
        }
Example #31
0
        public override long OnUpdateMoneyAmount(long internalMoneyAmount)
        {
            try
            {
                DistrictManager   DMinstance = Singleton <DistrictManager> .instance;
                Array8 <District> dm_array   = DMinstance.m_districts;
                District          d;

                Debugger.Write("\r\n== OnUpdateMoneyAmount ==");

                double sec_per_day     = 75600.0;             // for some reason
                double sec_per_week    = 7 * sec_per_day;
                double week_proportion = 0.0;
                int    export_earnings = 0;
                int    earnings_shown  = 0;

                if (dm_array == null)
                {
                    Debugger.Write("early return, dm_array is null");
                    return(internalMoneyAmount);
                }

                d = dm_array.m_buffer[0];

                if (!updated)
                {
                    updated  = true;
                    prevDate = this.managers.threading.simulationTime;
                    Debugger.Write("first run");
                }
                else
                {
                    System.DateTime newDate  = this.managers.threading.simulationTime;
                    System.TimeSpan timeDiff = newDate.Subtract(prevDate);
                    week_proportion = (((double)timeDiff.TotalSeconds) / sec_per_week);
                    if (week_proportion > 0.0)
                    {
                        Debugger.Write("proportion: " + week_proportion.ToString());
                        EconomyManager EM = Singleton <EconomyManager> .instance;
                        if (EM != null)
                        {
                            // add income
                            export_earnings = (int)ExpmHolder.get().CalculateIncome(d, week_proportion);
                            earnings_shown  = export_earnings / 100;
                            Debugger.Write("Total earnings: " + earnings_shown.ToString());
                            EM.AddResource(EconomyManager.Resource.PublicIncome,
                                           export_earnings,
                                           ItemClass.Service.None,
                                           ItemClass.SubService.None,
                                           ItemClass.Level.None);
                        }
                    }
                    else
                    {
                        Debugger.Write("week_proportion zero");
                    }
                    prevDate = newDate;
                }
            }
            catch (Exception ex)
            {
                // shouldn't happen, but if it does, start logging
                Debugger.Write("Exception " + ex.Message.ToString());
            }
            return(internalMoneyAmount);
        }
Example #32
0
        private unsafe static Surface ReadNv12(
            ResourceManager rm,
            ref SlotConfig config,
            ref SlotSurfaceConfig surfaceConfig,
            ref Array8 <PlaneOffsets> offsets)
        {
            InputSurface input = ReadSurface(rm, ref config, ref surfaceConfig, ref offsets, 1, 2);

            int width  = input.Width;
            int height = input.Height;

            int yStride  = GetPitch(width, 1);
            int uvStride = GetPitch(input.UvWidth, 2);

            Surface output = new Surface(rm.SurfacePool, width, height);

            if (Sse41.IsSupported)
            {
                Vector128 <byte> shufMask = Vector128.Create(
                    (byte)0, (byte)2, (byte)3, (byte)1,
                    (byte)4, (byte)6, (byte)7, (byte)5,
                    (byte)8, (byte)10, (byte)11, (byte)9,
                    (byte)12, (byte)14, (byte)15, (byte)13);
                Vector128 <short> alphaMask = Vector128.Create(0xffUL << 48).AsInt16();

                int yStrideGap  = yStride - width;
                int uvStrideGap = uvStride - input.UvWidth;

                int widthTrunc = width & ~0xf;

                fixed(Pixel *dstPtr = output.Data)
                {
                    Pixel *op = dstPtr;

                    fixed(byte *src0Ptr = input.Buffer0, src1Ptr = input.Buffer1)
                    {
                        byte *i0p = src0Ptr;

                        for (int y = 0; y < height; y++)
                        {
                            byte *i1p = src1Ptr + (y >> 1) * uvStride;

                            int x = 0;

                            for (; x < widthTrunc; x += 16, i0p += 16, i1p += 16)
                            {
                                Vector128 <short> ya0 = Sse41.ConvertToVector128Int16(i0p);
                                Vector128 <short> ya1 = Sse41.ConvertToVector128Int16(i0p + 8);

                                Vector128 <byte> uv = Sse2.LoadVector128(i1p);

                                Vector128 <short> uv0 = Sse2.UnpackLow(uv.AsInt16(), uv.AsInt16());
                                Vector128 <short> uv1 = Sse2.UnpackHigh(uv.AsInt16(), uv.AsInt16());

                                Vector128 <short> rgba0 = Sse2.UnpackLow(ya0, uv0);
                                Vector128 <short> rgba1 = Sse2.UnpackHigh(ya0, uv0);
                                Vector128 <short> rgba2 = Sse2.UnpackLow(ya1, uv1);
                                Vector128 <short> rgba3 = Sse2.UnpackHigh(ya1, uv1);

                                rgba0 = Ssse3.Shuffle(rgba0.AsByte(), shufMask).AsInt16();
                                rgba1 = Ssse3.Shuffle(rgba1.AsByte(), shufMask).AsInt16();
                                rgba2 = Ssse3.Shuffle(rgba2.AsByte(), shufMask).AsInt16();
                                rgba3 = Ssse3.Shuffle(rgba3.AsByte(), shufMask).AsInt16();

                                Vector128 <short> rgba16_0 = Sse41.ConvertToVector128Int16(rgba0.AsByte());
                                Vector128 <short> rgba16_1 = Sse41.ConvertToVector128Int16(HighToLow(rgba0.AsByte()));
                                Vector128 <short> rgba16_2 = Sse41.ConvertToVector128Int16(rgba1.AsByte());
                                Vector128 <short> rgba16_3 = Sse41.ConvertToVector128Int16(HighToLow(rgba1.AsByte()));
                                Vector128 <short> rgba16_4 = Sse41.ConvertToVector128Int16(rgba2.AsByte());
                                Vector128 <short> rgba16_5 = Sse41.ConvertToVector128Int16(HighToLow(rgba2.AsByte()));
                                Vector128 <short> rgba16_6 = Sse41.ConvertToVector128Int16(rgba3.AsByte());
                                Vector128 <short> rgba16_7 = Sse41.ConvertToVector128Int16(HighToLow(rgba3.AsByte()));

                                rgba16_0 = Sse2.Or(rgba16_0, alphaMask);
                                rgba16_1 = Sse2.Or(rgba16_1, alphaMask);
                                rgba16_2 = Sse2.Or(rgba16_2, alphaMask);
                                rgba16_3 = Sse2.Or(rgba16_3, alphaMask);
                                rgba16_4 = Sse2.Or(rgba16_4, alphaMask);
                                rgba16_5 = Sse2.Or(rgba16_5, alphaMask);
                                rgba16_6 = Sse2.Or(rgba16_6, alphaMask);
                                rgba16_7 = Sse2.Or(rgba16_7, alphaMask);

                                rgba16_0 = Sse2.ShiftLeftLogical(rgba16_0, 2);
                                rgba16_1 = Sse2.ShiftLeftLogical(rgba16_1, 2);
                                rgba16_2 = Sse2.ShiftLeftLogical(rgba16_2, 2);
                                rgba16_3 = Sse2.ShiftLeftLogical(rgba16_3, 2);
                                rgba16_4 = Sse2.ShiftLeftLogical(rgba16_4, 2);
                                rgba16_5 = Sse2.ShiftLeftLogical(rgba16_5, 2);
                                rgba16_6 = Sse2.ShiftLeftLogical(rgba16_6, 2);
                                rgba16_7 = Sse2.ShiftLeftLogical(rgba16_7, 2);

                                Sse2.Store((short *)(op + (uint)x + 0), rgba16_0);
                                Sse2.Store((short *)(op + (uint)x + 2), rgba16_1);
                                Sse2.Store((short *)(op + (uint)x + 4), rgba16_2);
                                Sse2.Store((short *)(op + (uint)x + 6), rgba16_3);
                                Sse2.Store((short *)(op + (uint)x + 8), rgba16_4);
                                Sse2.Store((short *)(op + (uint)x + 10), rgba16_5);
                                Sse2.Store((short *)(op + (uint)x + 12), rgba16_6);
                                Sse2.Store((short *)(op + (uint)x + 14), rgba16_7);
                            }

                            for (; x < width; x++, i1p += (x & 1) * 2)
                            {
                                Pixel *px = op + (uint)x;

                                px->R = Upsample(*i0p++);
                                px->G = Upsample(*i1p);
                                px->B = Upsample(*(i1p + 1));
                                px->A = 0x3ff;
                            }

                            op  += width;
                            i0p += yStrideGap;
                            i1p += uvStrideGap;
                        }
                    }
                }
            }
            else
            {
                for (int y = 0; y < height; y++)
                {
                    int uvBase = (y >> 1) * uvStride;

                    for (int x = 0; x < width; x++)
                    {
                        output.SetR(x, y, Upsample(input.Buffer0[y * yStride + x]));

                        int uvOffs = uvBase + (x & ~1);

                        output.SetG(x, y, Upsample(input.Buffer1[uvOffs]));
                        output.SetB(x, y, Upsample(input.Buffer1[uvOffs + 1]));
                        output.SetA(x, y, 0x3ff);
                    }
                }
            }

            input.Return(rm.BufferPool);

            return(output);
        }
        public override void OnLevelLoaded(LoadMode mode)
        {
            if (mode != LoadMode.LoadGame && mode != LoadMode.NewGame && mode != LoadMode.NewMap && mode != LoadMode.LoadMap)
            {
                return;
            }
            _mode = mode;

            buildingWindowGameObject = new GameObject("buildingWindowObject");

            var view = UIView.GetAView();

            this.buildingWindow = buildingWindowGameObject.AddComponent <ResourceIndustryDistrictWindow>();
            this.buildingWindow.transform.parent = view.transform;
            this.buildingWindow.position         = new Vector3(300, 122);
            this.buildingWindow.Hide();


            UITabstrip strip = null;

            if (mode == LoadMode.NewGame || mode == LoadMode.LoadGame)
            {
                strip = ToolsModifierControl.mainToolbar.component as UITabstrip;
            }
            else
            {
                strip = UIView.Find <UITabstrip>("MainToolstrip");
            }

            buttonObject  = UITemplateManager.GetAsGameObject("MainToolbarButtonTemplate");
            buttonObject2 = UITemplateManager.GetAsGameObject("ScrollablePanelTemplate");
            menuButton    = strip.AddTab("ResourceIndustryDistrict", buttonObject, buttonObject2, new Type[] { }) as UIButton;

            string sprite = "ToolbarIconDistrictPressed";

            menuButton.normalFgSprite   = sprite;
            menuButton.focusedFgSprite  = sprite;
            menuButton.hoveredFgSprite  = sprite;
            menuButton.pressedFgSprite  = sprite;
            menuButton.disabledFgSprite = sprite;
            menuButton.tooltip          = "RDI";

            menuButton.eventClick += uiButton_eventClick;

            DistrictResource.getResource = () =>
            {
                NaturalResourceManager.ResourceCell[] resourcesFromMap = new NaturalResourceManager.ResourceCell[NaturalResourceManager.instance.m_naturalResources.Length];
                Array.Copy(NaturalResourceManager.instance.m_naturalResources, resourcesFromMap, resourcesFromMap.Length);
                return(resourcesFromMap);
            };
            DistrictResource.getDistricts = () =>
            {
                DistrictManager.Cell[] districts = DistrictManager.instance.m_districtGrid;
                return(districts);
            };
            DistrictResource.getDistrictNames = () =>
            {
                Array8 <District> districtNames = DistrictManager.instance.m_districts;
                return(districtNames);
            };
            DistrictResource.getDistrictNameFromId = (districtId) =>
            {
                return(DistrictManager.instance.GetDistrictName(districtId));
            };
        }
Example #34
0
 public Record(Array8 indices, ITable table)
 {
     this.indices = indices;
     this.table   = table;
 }
Example #35
0
        public byte[] Finish()
        {
            Update(_padding, 0, _padding.Length);
            Array16<ulong> block;
            ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0);
            CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
            int bytesInBuffer = (int)_totalBytes & (BlockSize - 1);
            if (bytesInBuffer > BlockSize - 16)
            {
                Sha512Internal.Core(out _state, ref _state, ref block);
                block = default(Array16<ulong>);
            }
            block.x15 = (_totalBytes - 1) * 8;
            Sha512Internal.Core(out _state, ref _state, ref block);

            var result = new byte[64];
            ByteIntegerConverter.StoreBigEndian64(result, 0, _state.x0);
            ByteIntegerConverter.StoreBigEndian64(result, 8, _state.x1);
            ByteIntegerConverter.StoreBigEndian64(result, 16, _state.x2);
            ByteIntegerConverter.StoreBigEndian64(result, 24, _state.x3);
            ByteIntegerConverter.StoreBigEndian64(result, 32, _state.x4);
            ByteIntegerConverter.StoreBigEndian64(result, 40, _state.x5);
            ByteIntegerConverter.StoreBigEndian64(result, 48, _state.x6);
            ByteIntegerConverter.StoreBigEndian64(result, 56, _state.x7);
            _state = default(Array8<ulong>);
            return result;
        }
Example #36
0
 internal void Deconstruct(out Array8 indices, out ITable table)
 {
     indices = this.indices;
     table   = this.table;
 }
        internal static void Core(out Array8<UInt64> outputState, ref Array8<UInt64> inputState, ref Array16<UInt64> input)
        {
            UInt64 a = inputState.x0;
            UInt64 b = inputState.x1;
            UInt64 c = inputState.x2;
            UInt64 d = inputState.x3;
            UInt64 e = inputState.x4;
            UInt64 f = inputState.x5;
            UInt64 g = inputState.x6;
            UInt64 h = inputState.x7;

            UInt64 w0 = input.x0;
            UInt64 w1 = input.x1;
            UInt64 w2 = input.x2;
            UInt64 w3 = input.x3;
            UInt64 w4 = input.x4;
            UInt64 w5 = input.x5;
            UInt64 w6 = input.x6;
            UInt64 w7 = input.x7;
            UInt64 w8 = input.x8;
            UInt64 w9 = input.x9;
            UInt64 w10 = input.x10;
            UInt64 w11 = input.x11;
            UInt64 w12 = input.x12;
            UInt64 w13 = input.x13;
            UInt64 w14 = input.x14;
            UInt64 w15 = input.x15;

            int t = 0;
            while (true)
            {
                ulong t1, t2;

                {//0
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w0;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//1
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w1;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//2
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w2;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//3
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w3;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//4
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w4;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//5
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w5;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//6
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w6;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//7
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w7;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//8
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w8;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//9
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w9;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//10
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w10;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//11
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w11;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//12
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w12;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//13
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w13;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//14
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w14;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                {//15
                    t1 = h +
                         ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
                        //Sigma1(e)
                         ((e & f) ^ (~e & g)) + //Ch(e,f,g)
                         K[t] + w15;
                    t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
                        //Sigma0(a)
                         ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                    t++;
                }
                if (t == 80)
                    break;

                w0 += ((w14 >> 19) ^ (w14 << (64 - 19)) ^ (w14 >> 61) ^ (w14 << (64 - 61)) ^ (w14 >> 6)) +
                      w9 +
                      ((w1 >> 1) ^ (w1 << (64 - 1)) ^ (w1 >> 8) ^ (w1 << (64 - 8)) ^ (w1 >> 7));
                w1 += ((w15 >> 19) ^ (w15 << (64 - 19)) ^ (w15 >> 61) ^ (w15 << (64 - 61)) ^ (w15 >> 6)) +
                     w10 +
                     ((w2 >> 1) ^ (w2 << (64 - 1)) ^ (w2 >> 8) ^ (w2 << (64 - 8)) ^ (w2 >> 7));
                w2 += ((w0 >> 19) ^ (w0 << (64 - 19)) ^ (w0 >> 61) ^ (w0 << (64 - 61)) ^ (w0 >> 6)) +
                     w11 +
                     ((w3 >> 1) ^ (w3 << (64 - 1)) ^ (w3 >> 8) ^ (w3 << (64 - 8)) ^ (w3 >> 7));
                w3 += ((w1 >> 19) ^ (w1 << (64 - 19)) ^ (w1 >> 61) ^ (w1 << (64 - 61)) ^ (w1 >> 6)) +
                     w12 +
                     ((w4 >> 1) ^ (w4 << (64 - 1)) ^ (w4 >> 8) ^ (w4 << (64 - 8)) ^ (w4 >> 7));
                w4 += ((w2 >> 19) ^ (w2 << (64 - 19)) ^ (w2 >> 61) ^ (w2 << (64 - 61)) ^ (w2 >> 6)) +
                     w13 +
                     ((w5 >> 1) ^ (w5 << (64 - 1)) ^ (w5 >> 8) ^ (w5 << (64 - 8)) ^ (w5 >> 7));
                w5 += ((w3 >> 19) ^ (w3 << (64 - 19)) ^ (w3 >> 61) ^ (w3 << (64 - 61)) ^ (w3 >> 6)) +
                     w14 +
                     ((w6 >> 1) ^ (w6 << (64 - 1)) ^ (w6 >> 8) ^ (w6 << (64 - 8)) ^ (w6 >> 7));
                w6 += ((w4 >> 19) ^ (w4 << (64 - 19)) ^ (w4 >> 61) ^ (w4 << (64 - 61)) ^ (w4 >> 6)) +
                     w15 +
                     ((w7 >> 1) ^ (w7 << (64 - 1)) ^ (w7 >> 8) ^ (w7 << (64 - 8)) ^ (w7 >> 7));
                w7 += ((w5 >> 19) ^ (w5 << (64 - 19)) ^ (w5 >> 61) ^ (w5 << (64 - 61)) ^ (w5 >> 6)) +
                     w0 +
                     ((w8 >> 1) ^ (w8 << (64 - 1)) ^ (w8 >> 8) ^ (w8 << (64 - 8)) ^ (w8 >> 7));
                w8 += ((w6 >> 19) ^ (w6 << (64 - 19)) ^ (w6 >> 61) ^ (w6 << (64 - 61)) ^ (w6 >> 6)) +
                     w1 +
                     ((w9 >> 1) ^ (w9 << (64 - 1)) ^ (w9 >> 8) ^ (w9 << (64 - 8)) ^ (w9 >> 7));
                w9 += ((w7 >> 19) ^ (w7 << (64 - 19)) ^ (w7 >> 61) ^ (w7 << (64 - 61)) ^ (w7 >> 6)) +
                     w2 +
                     ((w10 >> 1) ^ (w10 << (64 - 1)) ^ (w10 >> 8) ^ (w10 << (64 - 8)) ^ (w10 >> 7));
                w10 += ((w8 >> 19) ^ (w8 << (64 - 19)) ^ (w8 >> 61) ^ (w8 << (64 - 61)) ^ (w8 >> 6)) +
                      w3 +
                      ((w11 >> 1) ^ (w11 << (64 - 1)) ^ (w11 >> 8) ^ (w11 << (64 - 8)) ^ (w11 >> 7));
                w11 += ((w9 >> 19) ^ (w9 << (64 - 19)) ^ (w9 >> 61) ^ (w9 << (64 - 61)) ^ (w9 >> 6)) +
                      w4 +
                      ((w12 >> 1) ^ (w12 << (64 - 1)) ^ (w12 >> 8) ^ (w12 << (64 - 8)) ^ (w12 >> 7));
                w12 += ((w10 >> 19) ^ (w10 << (64 - 19)) ^ (w10 >> 61) ^ (w10 << (64 - 61)) ^ (w10 >> 6)) +
                      w5 +
                      ((w13 >> 1) ^ (w13 << (64 - 1)) ^ (w13 >> 8) ^ (w13 << (64 - 8)) ^ (w13 >> 7));
                w13 += ((w11 >> 19) ^ (w11 << (64 - 19)) ^ (w11 >> 61) ^ (w11 << (64 - 61)) ^ (w11 >> 6)) +
                      w6 +
                      ((w14 >> 1) ^ (w14 << (64 - 1)) ^ (w14 >> 8) ^ (w14 << (64 - 8)) ^ (w14 >> 7));
                w14 += ((w12 >> 19) ^ (w12 << (64 - 19)) ^ (w12 >> 61) ^ (w12 << (64 - 61)) ^ (w12 >> 6)) +
                      w7 +
                      ((w15 >> 1) ^ (w15 << (64 - 1)) ^ (w15 >> 8) ^ (w15 << (64 - 8)) ^ (w15 >> 7));
                w15 += ((w13 >> 19) ^ (w13 << (64 - 19)) ^ (w13 >> 61) ^ (w13 << (64 - 61)) ^ (w13 >> 6)) +
                      w8 +
                      ((w0 >> 1) ^ (w0 << (64 - 1)) ^ (w0 >> 8) ^ (w0 << (64 - 8)) ^ (w0 >> 7));
            }

            outputState.x0 = inputState.x0 + a;
            outputState.x1 = inputState.x1 + b;
            outputState.x2 = inputState.x2 + c;
            outputState.x3 = inputState.x3 + d;
            outputState.x4 = inputState.x4 + e;
            outputState.x5 = inputState.x5 + f;
            outputState.x6 = inputState.x6 + g;
            outputState.x7 = inputState.x7 + h;
        }
        public static void Array8XorLittleEndian(byte[] output, int outputOffset, byte[] input, int inputOffset, ref Array8<uint> keyStream, int length)
        {
#if DEBUG
            if (length <= 0)
                throw new ArgumentException();
#endif
            int outputEnd = outputOffset + length;
            UInt32 highestInt;
            switch ((length - 1) >> 2)
            {
                case 7:
                    highestInt = keyStream.x7;
                    XorLittleEndian32(output, outputOffset + 6 * 4, input, inputOffset + 6 * 4, keyStream.x6);
                    XorLittleEndian32(output, outputOffset + 5 * 4, input, inputOffset + 6 * 4, keyStream.x5);
                    XorLittleEndian32(output, outputOffset + 4 * 4, input, inputOffset + 6 * 4, keyStream.x4);
                    XorLittleEndian32(output, outputOffset + 3 * 4, input, inputOffset + 6 * 4, keyStream.x3);
                    XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2);
                    XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1);
                    XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0);
                    break;
                case 6:
                    highestInt = keyStream.x6;
                    XorLittleEndian32(output, outputOffset + 5 * 4, input, inputOffset + 6 * 4, keyStream.x5);
                    XorLittleEndian32(output, outputOffset + 4 * 4, input, inputOffset + 6 * 4, keyStream.x4);
                    XorLittleEndian32(output, outputOffset + 3 * 4, input, inputOffset + 6 * 4, keyStream.x3);
                    XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2);
                    XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1);
                    XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0);
                    break;
                case 5:
                    highestInt = keyStream.x5;
                    XorLittleEndian32(output, outputOffset + 4 * 4, input, inputOffset + 6 * 4, keyStream.x4);
                    XorLittleEndian32(output, outputOffset + 3 * 4, input, inputOffset + 6 * 4, keyStream.x3);
                    XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2);
                    XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1);
                    XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0);
                    break;
                case 4:
                    highestInt = keyStream.x4;
                    XorLittleEndian32(output, outputOffset + 3 * 4, input, inputOffset + 6 * 4, keyStream.x3);
                    XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2);
                    XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1);
                    XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0);
                    break;
                case 3:
                    highestInt = keyStream.x3;
                    XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2);
                    XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1);
                    XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0);
                    break;
                case 2:
                    highestInt = keyStream.x2;
                    XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1);
                    XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0);
                    break;
                case 1:
                    highestInt = keyStream.x1;
                    XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0);
                    break;
                case 0:
                    highestInt = keyStream.x0;
                    break;
                default:
                    throw new InvalidOperationException();
            }
            switch (length & 3)
            {
                case 1:
                    output[outputEnd - 1] ^= (byte)highestInt;
                    break;
                case 2:
                    output[outputEnd - 1] ^= (byte)(highestInt >> 8);
                    output[outputEnd - 2] ^= (byte)highestInt;
                    break;
                case 3:
                    output[outputEnd - 1] ^= (byte)(highestInt >> 16);
                    output[outputEnd - 2] ^= (byte)(highestInt >> 8);
                    output[outputEnd - 3] ^= (byte)highestInt;
                    break;
                case 0:
                    output[outputEnd - 1] ^= (byte)(highestInt >> 24);
                    output[outputEnd - 2] ^= (byte)(highestInt >> 16);
                    output[outputEnd - 3] ^= (byte)(highestInt >> 8);
                    output[outputEnd - 4] ^= (byte)highestInt;
                    break;
                default:
                    throw new InvalidOperationException();
            }
        }