// Apply the private key to a value. private byte[] ApplyPrivate(byte[] value) { if (rsaParams.P != null) { // Use the Chinese Remainder Theorem exponents. // Based on the description in PKCS #1. byte[] m1 = CryptoMethods.NumPow(value, rsaParams.DP, rsaParams.P); byte[] m2 = CryptoMethods.NumPow(value, rsaParams.DQ, rsaParams.Q); byte[] diff = CryptoMethods.NumSub(m1, m2, null); byte[] h = CryptoMethods.NumMul(diff, rsaParams.InverseQ, rsaParams.P); byte[] prod = CryptoMethods.NumMul(rsaParams.Q, h, null); byte[] m = CryptoMethods.NumAdd(m2, prod, null); // Clear all temporary values. Array.Clear(m1, 0, m1.Length); Array.Clear(m2, 0, m2.Length); Array.Clear(diff, 0, diff.Length); Array.Clear(h, 0, h.Length); Array.Clear(prod, 0, prod.Length); // Return the decrypted message. return(m); } else if (rsaParams.D != null) { // Use the private exponent directly. return(CryptoMethods.NumPow(value, rsaParams.D, rsaParams.Modulus)); } else { // Insufficient parameters for private key operations. throw new CryptographicException (_("Crypto_RSAParamsNotSet")); } }