/// <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; }
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]); } }
/// <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>); }
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>); }
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); }
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); }
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; }
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); }
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(); }
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)); }
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; }
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)); }
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)); }
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(); } }
// 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); } }
/// <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>); }
// 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); } }
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; } }
public Record this[Array8 indices] => new Record(indices, Tab);
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); }
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); }
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); }
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)); }; }
public Record(Array8 indices, ITable table) { this.indices = indices; this.table = table; }
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; }
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(); } }