<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

XoodyakDigest

public sealed class XoodyakDigest : IDigest
using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Digests { public sealed class XoodyakDigest : IDigest { private static readonly uint[] RC = new uint[12] { 88, 56, 960, 208, 288, 20, 96, 44, 896, 240, 416, 18 }; private const int f_bPrime = 48; private const int MAXROUNDS = 12; private const int TAGLEN = 16; private const int Rabsorb = 16; private readonly byte[] m_state = new byte[48]; private readonly byte[] m_buf = new byte[16]; private int m_bufPos; private bool m_updated; public string AlgorithmName => "Xoodyak Hash"; public XoodyakDigest() { Reset(); } public int GetDigestSize() { return 32; } public int GetByteLength() { return 16; } public void Update(byte input) { m_buf[m_bufPos] = input; if (++m_bufPos == 16) { Down(m_buf, 0, 16); Up(); m_updated = true; m_bufPos = 0; } } public void BlockUpdate(byte[] input, int inOff, int inLen) { Check.DataLength(input, inOff, inLen, "input buffer too short"); if (inLen >= 1) { int num = 16 - m_bufPos; if (inLen < num) { Array.Copy(input, inOff, m_buf, m_bufPos, inLen); m_bufPos += inLen; } else { int num2 = 0; if (m_bufPos > 0) { Array.Copy(input, inOff, m_buf, m_bufPos, num); num2 += num; Down(m_buf, 0, 16); Up(); m_updated = true; } int num3; while ((num3 = inLen - num2) >= 16) { Down(input, inOff + num2, 16); Up(); m_updated = true; num2 += 16; } Array.Copy(input, inOff + num2, m_buf, 0, num3); m_bufPos = num3; } } } public int DoFinal(byte[] output, int outOff) { Check.OutputLength(output, outOff, 32, "output buffer too short"); if (m_bufPos > 0 || !m_updated) { Down(m_buf, 0, m_bufPos); Up(); } Array.Copy(m_state, 0, output, outOff, 16); m_state[0] ^= 1; Up(); Array.Copy(m_state, 0, output, outOff + 16, 16); Reset(); return 32; } public void Reset() { Arrays.Fill(m_state, 0); Arrays.Fill(m_buf, 0); m_bufPos = 0; m_updated = false; m_state[47] ^= 1; } private void Up() { uint num = Pack.LE_To_UInt32(m_state, 0); uint num2 = Pack.LE_To_UInt32(m_state, 4); uint num3 = Pack.LE_To_UInt32(m_state, 8); uint num4 = Pack.LE_To_UInt32(m_state, 12); uint num5 = Pack.LE_To_UInt32(m_state, 16); uint num6 = Pack.LE_To_UInt32(m_state, 20); uint num7 = Pack.LE_To_UInt32(m_state, 24); uint num8 = Pack.LE_To_UInt32(m_state, 28); uint num9 = Pack.LE_To_UInt32(m_state, 32); uint num10 = Pack.LE_To_UInt32(m_state, 36); uint num11 = Pack.LE_To_UInt32(m_state, 40); uint num12 = Pack.LE_To_UInt32(m_state, 44); for (int i = 0; i < 12; i++) { uint i2 = num ^ num5 ^ num9; uint i3 = num2 ^ num6 ^ num10; uint i4 = num3 ^ num7 ^ num11; uint i5 = num4 ^ num8 ^ num12; uint num13 = Integers.RotateLeft(i5, 5) ^ Integers.RotateLeft(i5, 14); uint num14 = Integers.RotateLeft(i2, 5) ^ Integers.RotateLeft(i2, 14); uint num15 = Integers.RotateLeft(i3, 5) ^ Integers.RotateLeft(i3, 14); uint num16 = Integers.RotateLeft(i4, 5) ^ Integers.RotateLeft(i4, 14); num ^= num13; num5 ^= num13; num9 ^= num13; num2 ^= num14; num6 ^= num14; num10 ^= num14; num3 ^= num15; num7 ^= num15; num11 ^= num15; num4 ^= num16; num8 ^= num16; num12 ^= num16; uint num17 = num; uint num18 = num2; uint num19 = num3; uint num20 = num4; uint num21 = num8; uint num22 = num5; uint num23 = num6; uint num24 = num7; uint num25 = Integers.RotateLeft(num9, 11); uint num26 = Integers.RotateLeft(num10, 11); uint num27 = Integers.RotateLeft(num11, 11); uint num28 = Integers.RotateLeft(num12, 11); num17 ^= RC[i]; num = (num17 ^ (~num21 & num25)); num2 = (num18 ^ (~num22 & num26)); num3 = (num19 ^ (~num23 & num27)); num4 = (num20 ^ (~num24 & num28)); num5 = (num21 ^ (~num25 & num17)); num6 = (num22 ^ (~num26 & num18)); num7 = (num23 ^ (~num27 & num19)); num8 = (num24 ^ (~num28 & num20)); num25 ^= (~num17 & num21); num26 ^= (~num18 & num22); num27 ^= (~num19 & num23); num28 ^= (~num20 & num24); num5 = Integers.RotateLeft(num5, 1); num6 = Integers.RotateLeft(num6, 1); num7 = Integers.RotateLeft(num7, 1); num8 = Integers.RotateLeft(num8, 1); num9 = Integers.RotateLeft(num27, 8); num10 = Integers.RotateLeft(num28, 8); num11 = Integers.RotateLeft(num25, 8); num12 = Integers.RotateLeft(num26, 8); } Pack.UInt32_To_LE(num, m_state, 0); Pack.UInt32_To_LE(num2, m_state, 4); Pack.UInt32_To_LE(num3, m_state, 8); Pack.UInt32_To_LE(num4, m_state, 12); Pack.UInt32_To_LE(num5, m_state, 16); Pack.UInt32_To_LE(num6, m_state, 20); Pack.UInt32_To_LE(num7, m_state, 24); Pack.UInt32_To_LE(num8, m_state, 28); Pack.UInt32_To_LE(num9, m_state, 32); Pack.UInt32_To_LE(num10, m_state, 36); Pack.UInt32_To_LE(num11, m_state, 40); Pack.UInt32_To_LE(num12, m_state, 44); } private void Down(byte[] Xi, int XiOff, int XiLen) { for (int i = 0; i < XiLen; i++) { m_state[i] ^= Xi[XiOff++]; } m_state[XiLen] ^= 1; } } }