private byte[] DecodeBlock(
byte[] input,
int inOff,
int inLen)
{
byte[] block = engine.ProcessBlock(input, inOff, inLen);
int r = 1;
int t = (bitSize + 13) / 16;
BigInteger iS = new BigInteger(1, block);
BigInteger iR;
if (iS.Mod(Sixteen).Equals(Six))
{
iR = iS;
}
else
{
iR = modulus.Subtract(iS);
if (!iR.Mod(Sixteen).Equals(Six))
throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16");
}
block = iR.ToByteArrayUnsigned();
if ((block[block.Length - 1] & 0x0f) != 0x6)
throw new InvalidCipherTextException("invalid forcing byte in block");
block[block.Length - 1] =
(byte)(((ushort)(block[block.Length - 1] & 0xff) >> 4)
| ((inverse[(block[block.Length - 2] & 0xff) >> 4]) << 4));
block[0] = (byte)((shadows[(uint) (block[1] & 0xff) >> 4] << 4)
| shadows[block[1] & 0x0f]);
bool boundaryFound = false;
int boundary = 0;
for (int i = block.Length - 1; i >= block.Length - 2 * t; i -= 2)
{
int val = ((shadows[(uint) (block[i] & 0xff) >> 4] << 4)
| shadows[block[i] & 0x0f]);
if (((block[i - 1] ^ val) & 0xff) != 0)
{
if (!boundaryFound)
{
boundaryFound = true;
r = (block[i - 1] ^ val) & 0xff;
boundary = i - 1;
}
else
{
throw new InvalidCipherTextException("invalid tsums in block");
}
}
}
block[boundary] = 0;
byte[] nblock = new byte[(block.Length - boundary) / 2];
for (int i = 0; i < nblock.Length; i++)
{
nblock[i] = block[2 * i + boundary + 1];
}
padBits = r - 1;
return nblock;
}
}