// The whole point of the diffuser is to diffuse bits, that's why we'll pick least significant words // with most significant word bits. This alone does some diffusion. private static byte[] GetBigIntegerBytesWithLeastSignificantWordFirstUsing16BitMsbFirstWords(BigInteger input, out int actualBytesWithoutPadding) { byte[] bigEndianBytes = input.ToUnsignedBigEndianBytes(); actualBytesWithoutPadding = bigEndianBytes.Length; bool isOddNumberOfBytes = bigEndianBytes.Length % 2 != 0; if (isOddNumberOfBytes) { // make sure it's even byte[] newBigEndianBytes = new byte[bigEndianBytes.Length + 1]; // Since it's big endian, we need to shift it right by a byte and fill MSB with zeroes. Array.Copy(bigEndianBytes, 0, newBigEndianBytes, 1, bigEndianBytes.Length); bigEndianBytes = newBigEndianBytes; } byte[] result = new byte[bigEndianBytes.Length]; int ixResultByte = 0; for (int ixWord = bigEndianBytes.Length - 2; ixWord >= 0; ixWord -= 2) { for (int wordByteOffset = 0; wordByteOffset < 2; wordByteOffset++) { // need to flip individual bytes result[ixResultByte++] = bigEndianBytes[ixWord + wordByteOffset]; } } bool hasExtraPaddingByte = bigEndianBytes.Length != actualBytesWithoutPadding; if (hasExtraPaddingByte) { result[bigEndianBytes.Length - 2] = result[bigEndianBytes.Length - 1]; } return result; }