private byte[] Transform(byte[] data, int offset, int length)
{
Array.Reverse(data, offset, length);
var inputBytes = new byte[length + 1];
Buffer.BlockCopy(data, offset, inputBytes, 0, length);
var input = new BigInteger(inputBytes);
BigInteger result;
if (_isPrivate)
{
var random = BigInteger.One;
var max = _key.Modulus - 1;
var bitLength = _key.Modulus.BitLength;
if (max < BigInteger.One)
throw new SshException("Invalid RSA key.");
while (random <= BigInteger.One || random >= max)
{
random = BigInteger.Random(bitLength);
}
var blindedInput = BigInteger.PositiveMod((BigInteger.ModPow(random, _key.Exponent, _key.Modulus) * input), _key.Modulus);
// mP = ((input Mod p) ^ dP)) Mod p
var mP = BigInteger.ModPow((blindedInput % _key.P), _key.DP, _key.P);
// mQ = ((input Mod q) ^ dQ)) Mod q
var mQ = BigInteger.ModPow((blindedInput % _key.Q), _key.DQ, _key.Q);
var h = BigInteger.PositiveMod(((mP - mQ) * _key.InverseQ), _key.P);
var m = h * _key.Q + mQ;
var rInv = BigInteger.ModInverse(random, _key.Modulus);
result = BigInteger.PositiveMod((m * rInv), _key.Modulus);
}
else
{
result = BigInteger.ModPow(input, _key.Exponent, _key.Modulus);
}
return result.ToByteArray().Reverse();
}
}