Esempio n. 1
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="p">First prime number</param>
        /// <param name="q">Second prime number</param>
        /// <param name="privateKey">Private key d</param>
        /// <param name="hashFunction">hashfunction to use in algorithm</param>
        /// <param name="ChecksNeeded">check if data is right </param>
        public RsaSignature(BigInteger p, BigInteger q, BigInteger privateKey, HashFunction hashFunction, bool ChecksNeeded)
        {
            if (ChecksNeeded)
            {
                if ((!p.CheckIfPrime()) || (!q.CheckIfPrime()))
                {
                    throw new ArgumentException("p and q must be prime numbers!");
                }
                //if privatekey = 1 then signature == h
                //if privateKey == phi(n) - 1; then s == 1
                //if privateKey > phi(n) then there'll problem with multipl. inversion in equation d*e = 1 mod phi(n)
                if ((privateKey < 2) || (privateKey > (p - 1) * (q - 1) - 1))
                {
                    throw new ArgumentException("Private key should be 2 < < (p - 1) * (q - 1) - 1)!");
                }
                //We need private key to be prime with phi(n) to find open key later
                if (!NumericAlgorithms.GCD(privateKey, (p - 1) * (q - 1)).Equals(1))
                {
                    throw new ArgumentException("D should be mutually prime with (p - 1) * (q - 1)");
                }
            }

            Modulus = p * q;

            PublicExp = NumericAlgorithms.ExtendedGCD((p - 1) * (q - 1), privateKey);

            PrivateExp = privateKey;

            HashFunc = (hashFunction == HashFunction.MD5) ? null : new HashFunctionFactory().NewHashFunction(Modulus, hashFunction);
        }
Esempio n. 2
0
        private BigInteger[] Decrypt(BigInteger FirstPrime, BigInteger SecondPrime, BigInteger cipherText)
        {
            var publicKey = CalculatePublicKey(FirstPrime, SecondPrime);

            if (cipherText > publicKey)
            {
                throw new ArgumentException("c", "Ciphertext is larger than public key");
            }

            BigInteger r = NumericAlgorithms.FastExp(cipherText, (FirstPrime + 1) / 4, FirstPrime);
            BigInteger s = NumericAlgorithms.FastExp(cipherText, (SecondPrime + 1) / 4, SecondPrime);

            BigInteger a, b;

            NumericAlgorithms.ExtendedGCD(FirstPrime, SecondPrime, out a, out b);

            //(a*p*r + b*q*s) % n

            BigInteger m1 = (a * FirstPrime * s + b * SecondPrime * r) % publicKey;

            if (m1 < 0)
            {
                m1 += publicKey;
            }
            BigInteger m2 = publicKey - m1;
            BigInteger m3 = (a * FirstPrime * s - b * SecondPrime * r) % publicKey;

            if (m3 < 0)
            {
                m3 += publicKey;
            }
            BigInteger m4 = publicKey - m3;

            return(new BigInteger[] { m1, m2, m3, m4 });
        }
Esempio n. 3
0
        /// <summary>
        /// Hash "image" used in RSA digital signature algorithm
        /// </summary>
        /// <param name="message"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        protected virtual BigInteger HashImage(BigInteger message, BigInteger key)
        {
            if (((message > 0) ? message : -message) >= Modulus)
            {
                throw new ArgumentException("Modulus p * q was too small.");
            }

            return(NumericAlgorithms.FastExp(message, key, Modulus));
        }
Esempio n. 4
0
        private BigInteger GenerateHash(byte[] message)
        {
            var returnValue = startHashValue;

            for (int i = 0; i < message.Length; ++i)
            {
                returnValue = NumericAlgorithms.FastExp(returnValue + (BigInteger)message[i], 2, modulus);
                var x = returnValue.ToString();
            }

            return(returnValue);
        }
Esempio n. 5
0
        private int[] Decrypt(int FirstPrime, int SecondPrime, int b, int cipherText)
        {
            var publicKey = CalculatePublicKey(FirstPrime, SecondPrime);

            if (cipherText > publicKey)
            {
                throw new ArgumentException("cipherText", "Ciphertext is larger then public key");
            }

            var D = (b * b + (4 * cipherText)) % publicKey;

            int mp = NumericAlgorithms.FastExp(D, (FirstPrime + 1) / 4, FirstPrime);
            int mq = NumericAlgorithms.FastExp(D, (SecondPrime + 1) / 4, SecondPrime);


            NumericAlgorithms.ExtendedGCD(FirstPrime, SecondPrime, out int yp, out int yq);

            int d1, d2, d3, d4;

            d1 = (yp * FirstPrime * mq + yq * SecondPrime * mp) % publicKey;
            d1 = (d1 >= 0) ? d1 : NumericAlgorithms.NegativeMod(yp * FirstPrime * mq + yq * SecondPrime * mp, publicKey);
            // do { d1 += publicKey; } while (d1 <= 0);

            d2 = publicKey - d1;

            d3 = (yp * FirstPrime * mq - yq * SecondPrime * mp) % publicKey;
            d3 = (d3 >= 0) ? d3 : NumericAlgorithms.NegativeMod(yp * FirstPrime * mq - yq * SecondPrime * mp, publicKey);
            //do { d3 += publicKey; } while (d3 <= 0);

            d4 = publicKey - d3;

            d1 = Math.Abs(CalculateRoot(b, d1, publicKey));
            d2 = Math.Abs(CalculateRoot(b, d2, publicKey));
            d3 = Math.Abs(CalculateRoot(b, d3, publicKey));
            d4 = Math.Abs(CalculateRoot(b, d4, publicKey));

            return(new int[] { d1, d2, d3, d4 });
        }
Esempio n. 6
0
 /// <summary>
 /// Encrypts a message
 /// </summary>
 /// <param name="FirstPrime"> First prime (part of secret key)</param>
 /// <param name="SecondPrime">Second prime (part of secret key)</param>
 /// <param name="Message">Message to encrypt</param>
 /// <returns></returns>
 private byte[] Encrypt(BigInteger FirstPrime, BigInteger SecondPrime, byte[] plainText)
 {
     return(NumericAlgorithms.FastExp(new BigInteger(plainText), 2, CalculatePublicKey(FirstPrime, SecondPrime)).ToByteArray());
 }