<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.1" />

IsapDigest

public sealed class IsapDigest : IDigest
using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; using System; using System.Runtime.CompilerServices; namespace Org.BouncyCastle.Crypto.Digests { public sealed class IsapDigest : IDigest { private readonly byte[] m_buf = new byte[8]; private int m_bufPos; private ulong x0 = 17191252062196199485; private ulong x1 = 10066134719181819906; private ulong x2 = 13009371945472744034; private ulong x3 = 4834782570098516968; private ulong x4 = 3787428097924915520; public string AlgorithmName => "ISAP Hash"; public int GetDigestSize() { return 32; } public int GetByteLength() { return 8; } public void Update(byte input) { m_buf[m_bufPos] = input; if (++m_bufPos == 8) { x0 ^= Pack.BE_To_UInt64(m_buf, 0); P12(); 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 = 8 - 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; x0 ^= Pack.BE_To_UInt64(m_buf, 0); P12(); } int num3; while ((num3 = inLen - num2) >= 8) { x0 ^= Pack.BE_To_UInt64(input, inOff + num2); P12(); num2 += 8; } 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"); FinishAbsorbing(); for (int i = 0; i < 4; i++) { P12(); Pack.UInt64_To_BE(x0, output, outOff + (i << 3)); } Reset(); return 32; } public void Reset() { Array.Clear(m_buf, 0, m_buf.Length); m_bufPos = 0; x0 = 17191252062196199485; x1 = 10066134719181819906; x2 = 13009371945472744034; x3 = 4834782570098516968; x4 = 3787428097924915520; } private void FinishAbsorbing() { m_buf[m_bufPos] = 128; x0 ^= (ulong)((long)Pack.BE_To_UInt64(m_buf, 0) & (-1 << 56 - (m_bufPos << 3))); } private void P12() { ROUND(240); ROUND(225); ROUND(210); ROUND(195); ROUND(180); ROUND(165); ROUND(150); ROUND(135); ROUND(120); ROUND(105); ROUND(90); ROUND(75); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ROUND(ulong c) { ulong num = x0 ^ x1 ^ x2 ^ x3 ^ c ^ (x1 & (x0 ^ x2 ^ x4 ^ c)); ulong num2 = x0 ^ x2 ^ x3 ^ x4 ^ c ^ ((x1 ^ x2 ^ c) & (x1 ^ x3)); ulong num3 = x1 ^ x2 ^ x4 ^ c ^ (x3 & x4); ulong num4 = x0 ^ x1 ^ x2 ^ c ^ (~x0 & (x3 ^ x4)); ulong num5 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); x0 = (num ^ Longs.RotateRight(num, 19) ^ Longs.RotateRight(num, 28)); x1 = (num2 ^ Longs.RotateRight(num2, 39) ^ Longs.RotateRight(num2, 61)); x2 = ~(num3 ^ Longs.RotateRight(num3, 1) ^ Longs.RotateRight(num3, 6)); x3 = (num4 ^ Longs.RotateRight(num4, 10) ^ Longs.RotateRight(num4, 17)); x4 = (num5 ^ Longs.RotateRight(num5, 7) ^ Longs.RotateRight(num5, 41)); } } }