[Solved] C# Error: a is not convertible in Windows Application

Last Reply 17 days ago By dharmendr

Posted 17 days ago

I have C# code which does the encryption successfully, however I want to set my own p and q primes, so I try to do it but;

When I try to edit p and q primes manually inside "Create()", it gives conversion error at "ModInverse()" method.

It says System.ArgumentException: 'a is not convertible.' at ModInverse() method at the throw ArgumentException part

Can you please help?

        public void RSACompatibility()
        {
            var rsa = new RSACryptoServiceProvider(512);
            var parameters = rsa.ExportParameters(true);

            var recreatedParameters = Create(parameters.P, parameters.Q, parameters.Exponent, parameters.Modulus);
            var recreatedRSA = new RSACryptoServiceProvider();
            recreatedRSA.ImportParameters(recreatedParameters);

            byte[] message = Encoding.UTF8.GetBytes("hello");
            var ciphertext = rsa.Encrypt(message, false);
            var plaintext = recreatedRSA.Decrypt(ciphertext, false);
            string recreatedMessage = Encoding.UTF8.GetString(plaintext);

            var bw = new BinaryWriter(File.Open("path", FileMode.OpenOrCreate));
            bw.Write(ciphertext);
        }

        private static RSAParameters Create(byte[] p, byte[] q, byte[] exponent, byte[] modulus)
        {
            //set number to byte array
            int intValueP = 51;
            int intValueQ = 7;
            byte[] intBytes = BitConverter.GetBytes(intValueP);
            byte[] intBytes2 = BitConverter.GetBytes(intValueQ);
            var addlParameters = GetFullPrivateParameters(
                p: new BigInteger(CopyAndReverse(intBytes)),
                q: new BigInteger(CopyAndReverse(intBytes2)),
                e: new BigInteger(CopyAndReverse(exponent)),
                modulus: new BigInteger(CopyAndReverse(modulus)));

            return new RSAParameters
            {
                P = p,
                Q = q,
                Exponent = exponent,
                Modulus = modulus,
                D = addlParameters.D,
                DP = addlParameters.DP,
                DQ = addlParameters.DQ,
                InverseQ = addlParameters.InverseQ,
            };
        }

        private static RSAParameters GetFullPrivateParameters(BigInteger p, BigInteger q, BigInteger e, BigInteger modulus)
        {            
            var n = p * q;
            var phiOfN = n - p - q + 1; // OR: (p - 1) * (q - 1);

            var d = ModInverse(e, phiOfN);
            //Assert.Equal(1, (d * e) % phiOfN);

            var dp = d % (p - 1);
            var dq = d % (q - 1);

            var qInv = ModInverse(q, p);
            //Assert.Equal(1, (qInv * q) % p);

            return new RSAParameters
            {
                D = CopyAndReverse(d.ToByteArray()),
                DP = CopyAndReverse(dp.ToByteArray()),
                DQ = CopyAndReverse(dq.ToByteArray()),
                InverseQ = CopyAndReverse(qInv.ToByteArray()),
            };
        }

        public static BigInteger ModInverse(BigInteger a, BigInteger n)
        {
            BigInteger t = 0, nt = 1, r = n, nr = a;

            if (n < 0)
            {
                n = -n;
            }

            if (a < 0)
            {
                a = n - (-a % n);
            }

            while (nr != 0)
            {
                var quot = r / nr;

                var tmp = nt; nt = t - quot * nt; t = tmp;
                tmp = nr; nr = r - quot * nr; r = tmp;
            }

            if (r > 1) throw new ArgumentException(nameof(a) + " is not convertible.");
            if (t < 0) t = t + n;
            return t;
        }

        private static byte[] CopyAndReverse(byte[] data)
        {
            byte[] reversed = new byte[data.Length];
            Array.Copy(data, 0, reversed, 0, data.Length);
            Array.Reverse(reversed);
            return reversed;
        }

 

You are viewing reply posted by: dharmendr 17 days ago.
Posted 17 days ago
Dan97 says:
if (r > 1) throw new ArgumentException(nameof(a) + " is not convertible.");

 Please check the condition.

You are getting the r value greater than 1. So as per the condition it throughs the error.